github.com/MetalBlockchain/metalgo@v1.11.9/vms/avm/txs/base_tx_test.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package txs 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/MetalBlockchain/metalgo/ids" 12 "github.com/MetalBlockchain/metalgo/utils/constants" 13 "github.com/MetalBlockchain/metalgo/utils/crypto/secp256k1" 14 "github.com/MetalBlockchain/metalgo/vms/avm/fxs" 15 "github.com/MetalBlockchain/metalgo/vms/components/avax" 16 "github.com/MetalBlockchain/metalgo/vms/components/verify" 17 "github.com/MetalBlockchain/metalgo/vms/secp256k1fx" 18 ) 19 20 var ( 21 chainID = ids.ID{5, 4, 3, 2, 1} 22 assetID = ids.ID{1, 2, 3} 23 keys = secp256k1.TestKeys() 24 ) 25 26 func TestBaseTxSerialization(t *testing.T) { 27 require := require.New(t) 28 29 expected := []byte{ 30 // Codec version: 31 0x00, 0x00, 32 // txID: 33 0x00, 0x00, 0x00, 0x00, 34 // networkID: 35 0x00, 0x00, 0x00, 0x0a, 36 // blockchainID: 37 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 // number of outs: 42 0x00, 0x00, 0x00, 0x01, 43 // output[0]: 44 // assetID: 45 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 // fxID: 50 0x00, 0x00, 0x00, 0x07, 51 // secp256k1 Transferable Output: 52 // amount: 53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 54 // locktime: 55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 // threshold: 57 0x00, 0x00, 0x00, 0x01, 58 // number of addresses 59 0x00, 0x00, 0x00, 0x01, 60 // address[0] 61 0xfc, 0xed, 0xa8, 0xf9, 0x0f, 0xcb, 0x5d, 0x30, 62 0x61, 0x4b, 0x99, 0xd7, 0x9f, 0xc4, 0xba, 0xa2, 63 0x93, 0x07, 0x76, 0x26, 64 // number of inputs: 65 0x00, 0x00, 0x00, 0x01, 66 // txID: 67 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 68 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 69 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, 70 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 71 // utxo index: 72 0x00, 0x00, 0x00, 0x01, 73 // assetID: 74 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 // fxID: 79 0x00, 0x00, 0x00, 0x05, 80 // amount: 81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31, 82 // number of signatures: 83 0x00, 0x00, 0x00, 0x01, 84 // signature index[0]: 85 0x00, 0x00, 0x00, 0x02, 86 // Memo length: 87 0x00, 0x00, 0x00, 0x04, 88 // Memo: 89 0x00, 0x01, 0x02, 0x03, 90 // Number of credentials 91 0x00, 0x00, 0x00, 0x00, 92 } 93 94 tx := &Tx{Unsigned: &BaseTx{BaseTx: avax.BaseTx{ 95 NetworkID: constants.UnitTestID, 96 BlockchainID: chainID, 97 Outs: []*avax.TransferableOutput{{ 98 Asset: avax.Asset{ID: assetID}, 99 Out: &secp256k1fx.TransferOutput{ 100 Amt: 12345, 101 OutputOwners: secp256k1fx.OutputOwners{ 102 Threshold: 1, 103 Addrs: []ids.ShortID{keys[0].PublicKey().Address()}, 104 }, 105 }, 106 }}, 107 Ins: []*avax.TransferableInput{{ 108 UTXOID: avax.UTXOID{ 109 TxID: ids.ID{ 110 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 111 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 112 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, 113 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 114 }, 115 OutputIndex: 1, 116 }, 117 Asset: avax.Asset{ID: assetID}, 118 In: &secp256k1fx.TransferInput{ 119 Amt: 54321, 120 Input: secp256k1fx.Input{ 121 SigIndices: []uint32{2}, 122 }, 123 }, 124 }}, 125 Memo: []byte{0x00, 0x01, 0x02, 0x03}, 126 }}} 127 128 parser, err := NewParser( 129 []fxs.Fx{ 130 &secp256k1fx.Fx{}, 131 }, 132 ) 133 require.NoError(err) 134 135 require.NoError(tx.Initialize(parser.Codec())) 136 require.Equal("zeqT8FTnRAxes7QQQYkaWhNkHavd9d6aCdH8TQu2Mx5KEydEz", tx.ID().String()) 137 138 result := tx.Bytes() 139 require.Equal(expected, result) 140 141 credBytes := []byte{ 142 // type id 143 0x00, 0x00, 0x00, 0x09, 144 145 // there are two signers (thus two signatures) 146 0x00, 0x00, 0x00, 0x02, 147 148 // 65 bytes 149 0x7d, 0x89, 0x8e, 0xe9, 0x8a, 0xf8, 0x33, 0x5d, 0x37, 0xe6, 150 0xfa, 0xda, 0x0c, 0xbb, 0x44, 0xa1, 0x44, 0x05, 0xd3, 0xbb, 151 0x94, 0x0d, 0xfc, 0x0d, 0x99, 0xa6, 0xd3, 0xff, 0x5c, 0x71, 152 0x5a, 0xff, 0x26, 0xd1, 0x84, 0x84, 0xf2, 0x9b, 0x28, 0x96, 153 0x44, 0x96, 0x8f, 0xed, 0xff, 0xeb, 0x23, 0xe0, 0x30, 0x66, 154 0x5d, 0x73, 0x6d, 0x94, 0xfc, 0x80, 0xbc, 0x73, 0x5f, 0x51, 155 0xc8, 0x06, 0xd7, 0x43, 0x00, 156 157 // 65 bytes 158 0x7d, 0x89, 0x8e, 0xe9, 0x8a, 0xf8, 0x33, 0x5d, 0x37, 0xe6, 159 0xfa, 0xda, 0x0c, 0xbb, 0x44, 0xa1, 0x44, 0x05, 0xd3, 0xbb, 160 0x94, 0x0d, 0xfc, 0x0d, 0x99, 0xa6, 0xd3, 0xff, 0x5c, 0x71, 161 0x5a, 0xff, 0x26, 0xd1, 0x84, 0x84, 0xf2, 0x9b, 0x28, 0x96, 162 0x44, 0x96, 0x8f, 0xed, 0xff, 0xeb, 0x23, 0xe0, 0x30, 0x66, 163 0x5d, 0x73, 0x6d, 0x94, 0xfc, 0x80, 0xbc, 0x73, 0x5f, 0x51, 164 0xc8, 0x06, 0xd7, 0x43, 0x00, 165 166 // type id 167 0x00, 0x00, 0x00, 0x09, 168 169 // there are two signers (thus two signatures) 170 0x00, 0x00, 0x00, 0x02, 171 172 // 65 bytes 173 0x7d, 0x89, 0x8e, 0xe9, 0x8a, 0xf8, 0x33, 0x5d, 0x37, 0xe6, 174 0xfa, 0xda, 0x0c, 0xbb, 0x44, 0xa1, 0x44, 0x05, 0xd3, 0xbb, 175 0x94, 0x0d, 0xfc, 0x0d, 0x99, 0xa6, 0xd3, 0xff, 0x5c, 0x71, 176 0x5a, 0xff, 0x26, 0xd1, 0x84, 0x84, 0xf2, 0x9b, 0x28, 0x96, 177 0x44, 0x96, 0x8f, 0xed, 0xff, 0xeb, 0x23, 0xe0, 0x30, 0x66, 178 0x5d, 0x73, 0x6d, 0x94, 0xfc, 0x80, 0xbc, 0x73, 0x5f, 0x51, 179 0xc8, 0x06, 0xd7, 0x43, 0x00, 180 181 // 65 bytes 182 0x7d, 0x89, 0x8e, 0xe9, 0x8a, 0xf8, 0x33, 0x5d, 0x37, 0xe6, 183 0xfa, 0xda, 0x0c, 0xbb, 0x44, 0xa1, 0x44, 0x05, 0xd3, 0xbb, 184 0x94, 0x0d, 0xfc, 0x0d, 0x99, 0xa6, 0xd3, 0xff, 0x5c, 0x71, 185 0x5a, 0xff, 0x26, 0xd1, 0x84, 0x84, 0xf2, 0x9b, 0x28, 0x96, 186 0x44, 0x96, 0x8f, 0xed, 0xff, 0xeb, 0x23, 0xe0, 0x30, 0x66, 187 0x5d, 0x73, 0x6d, 0x94, 0xfc, 0x80, 0xbc, 0x73, 0x5f, 0x51, 188 0xc8, 0x06, 0xd7, 0x43, 0x00, 189 } 190 191 require.NoError(tx.SignSECP256K1Fx( 192 parser.Codec(), 193 [][]*secp256k1.PrivateKey{ 194 {keys[0], keys[0]}, 195 {keys[0], keys[0]}, 196 }, 197 )) 198 require.Equal("QnTUuie2qe6BKyYrC2jqd73bJ828QNhYnZbdA2HWsnVRPjBfV", tx.ID().String()) 199 200 // there are two credentials 201 expected[len(expected)-1] = 0x02 202 expected = append(expected, credBytes...) 203 204 result = tx.Bytes() 205 require.Equal(expected, result) 206 } 207 208 func TestBaseTxNotState(t *testing.T) { 209 require := require.New(t) 210 211 intf := interface{}(&BaseTx{}) 212 _, ok := intf.(verify.State) 213 require.False(ok, "should not be marked as state") 214 }