github.com/MetalBlockchain/metalgo@v1.11.9/vms/components/avax/base_tx.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package avax 5 6 import ( 7 "errors" 8 "fmt" 9 10 "github.com/MetalBlockchain/metalgo/ids" 11 "github.com/MetalBlockchain/metalgo/snow" 12 "github.com/MetalBlockchain/metalgo/vms/types" 13 ) 14 15 // MaxMemoSize is the maximum number of bytes in the memo field 16 const MaxMemoSize = 256 17 18 var ( 19 ErrNilTx = errors.New("nil tx is not valid") 20 ErrWrongNetworkID = errors.New("tx has wrong network ID") 21 ErrWrongChainID = errors.New("tx has wrong chain ID") 22 ErrMemoTooLarge = errors.New("memo exceeds maximum length") 23 ) 24 25 // BaseTx is the basis of all standard transactions. 26 type BaseTx struct { 27 NetworkID uint32 `serialize:"true" json:"networkID"` // ID of the network this chain lives on 28 BlockchainID ids.ID `serialize:"true" json:"blockchainID"` // ID of the chain on which this transaction exists (prevents replay attacks) 29 Outs []*TransferableOutput `serialize:"true" json:"outputs"` // The outputs of this transaction 30 Ins []*TransferableInput `serialize:"true" json:"inputs"` // The inputs to this transaction 31 Memo types.JSONByteSlice `serialize:"true" json:"memo"` // Memo field contains arbitrary bytes, up to maxMemoSize 32 } 33 34 // InputUTXOs track which UTXOs this transaction is consuming. 35 func (t *BaseTx) InputUTXOs() []*UTXOID { 36 utxos := make([]*UTXOID, len(t.Ins)) 37 for i, in := range t.Ins { 38 utxos[i] = &in.UTXOID 39 } 40 return utxos 41 } 42 43 // NumCredentials returns the number of expected credentials 44 func (t *BaseTx) NumCredentials() int { 45 return len(t.Ins) 46 } 47 48 // Verify ensures that transaction metadata is valid 49 func (t *BaseTx) Verify(ctx *snow.Context) error { 50 switch { 51 case t == nil: 52 return ErrNilTx 53 case t.NetworkID != ctx.NetworkID: 54 return ErrWrongNetworkID 55 case t.BlockchainID != ctx.ChainID: 56 return ErrWrongChainID 57 case len(t.Memo) > MaxMemoSize: 58 return fmt.Errorf( 59 "%w: %d > %d", 60 ErrMemoTooLarge, 61 len(t.Memo), 62 MaxMemoSize, 63 ) 64 default: 65 return nil 66 } 67 } 68 69 func VerifyMemoFieldLength(memo types.JSONByteSlice, isDurangoActive bool) error { 70 if !isDurangoActive { 71 // SyntacticVerify validates this field pre-Durango 72 return nil 73 } 74 75 if len(memo) != 0 { 76 return fmt.Errorf( 77 "%w: %d > %d", 78 ErrMemoTooLarge, 79 len(memo), 80 0, 81 ) 82 } 83 84 return nil 85 }