github.com/ethereum/go-ethereum@v1.16.1/accounts/abi/pack_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package abi 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "fmt" 23 "math" 24 "math/big" 25 "reflect" 26 "strconv" 27 "strings" 28 "testing" 29 30 "github.com/ethereum/go-ethereum/common" 31 ) 32 33 // TestPack tests the general pack/unpack tests in packing_test.go 34 func TestPack(t *testing.T) { 35 t.Parallel() 36 for i, test := range packUnpackTests { 37 t.Run(strconv.Itoa(i), func(t *testing.T) { 38 t.Parallel() 39 encb, err := hex.DecodeString(test.packed) 40 if err != nil { 41 t.Fatalf("invalid hex %s: %v", test.packed, err) 42 } 43 inDef := fmt.Sprintf(`[{ "name" : "method", "type": "function", "inputs": %s}]`, test.def) 44 inAbi, err := JSON(strings.NewReader(inDef)) 45 if err != nil { 46 t.Fatalf("invalid ABI definition %s, %v", inDef, err) 47 } 48 var packed []byte 49 packed, err = inAbi.Pack("method", test.unpacked) 50 51 if err != nil { 52 t.Fatalf("test %d (%v) failed: %v", i, test.def, err) 53 } 54 if !reflect.DeepEqual(packed[4:], encb) { 55 t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, encb, packed[4:]) 56 } 57 }) 58 } 59 } 60 61 func TestMethodPack(t *testing.T) { 62 t.Parallel() 63 abi, err := JSON(strings.NewReader(jsondata)) 64 if err != nil { 65 t.Fatal(err) 66 } 67 68 sig := abi.Methods["slice"].ID 69 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 70 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 71 72 packed, err := abi.Pack("slice", []uint32{1, 2}) 73 if err != nil { 74 t.Error(err) 75 } 76 77 if !bytes.Equal(packed, sig) { 78 t.Errorf("expected %x got %x", sig, packed) 79 } 80 81 var addrA, addrB = common.Address{1}, common.Address{2} 82 sig = abi.Methods["sliceAddress"].ID 83 sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...) 84 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 85 sig = append(sig, common.LeftPadBytes(addrA[:], 32)...) 86 sig = append(sig, common.LeftPadBytes(addrB[:], 32)...) 87 88 packed, err = abi.Pack("sliceAddress", []common.Address{addrA, addrB}) 89 if err != nil { 90 t.Fatal(err) 91 } 92 if !bytes.Equal(packed, sig) { 93 t.Errorf("expected %x got %x", sig, packed) 94 } 95 96 var addrC, addrD = common.Address{3}, common.Address{4} 97 sig = abi.Methods["sliceMultiAddress"].ID 98 sig = append(sig, common.LeftPadBytes([]byte{64}, 32)...) 99 sig = append(sig, common.LeftPadBytes([]byte{160}, 32)...) 100 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 101 sig = append(sig, common.LeftPadBytes(addrA[:], 32)...) 102 sig = append(sig, common.LeftPadBytes(addrB[:], 32)...) 103 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 104 sig = append(sig, common.LeftPadBytes(addrC[:], 32)...) 105 sig = append(sig, common.LeftPadBytes(addrD[:], 32)...) 106 107 packed, err = abi.Pack("sliceMultiAddress", []common.Address{addrA, addrB}, []common.Address{addrC, addrD}) 108 if err != nil { 109 t.Fatal(err) 110 } 111 if !bytes.Equal(packed, sig) { 112 t.Errorf("expected %x got %x", sig, packed) 113 } 114 115 sig = abi.Methods["slice256"].ID 116 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 117 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 118 119 packed, err = abi.Pack("slice256", []*big.Int{big.NewInt(1), big.NewInt(2)}) 120 if err != nil { 121 t.Error(err) 122 } 123 124 if !bytes.Equal(packed, sig) { 125 t.Errorf("expected %x got %x", sig, packed) 126 } 127 128 a := [2][2]*big.Int{{big.NewInt(1), big.NewInt(1)}, {big.NewInt(2), big.NewInt(0)}} 129 sig = abi.Methods["nestedArray"].ID 130 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 131 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 132 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 133 sig = append(sig, common.LeftPadBytes([]byte{0}, 32)...) 134 sig = append(sig, common.LeftPadBytes([]byte{0xa0}, 32)...) 135 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 136 sig = append(sig, common.LeftPadBytes(addrC[:], 32)...) 137 sig = append(sig, common.LeftPadBytes(addrD[:], 32)...) 138 packed, err = abi.Pack("nestedArray", a, []common.Address{addrC, addrD}) 139 if err != nil { 140 t.Fatal(err) 141 } 142 if !bytes.Equal(packed, sig) { 143 t.Errorf("expected %x got %x", sig, packed) 144 } 145 146 sig = abi.Methods["nestedArray2"].ID 147 sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) 148 sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) 149 sig = append(sig, common.LeftPadBytes([]byte{0x80}, 32)...) 150 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 151 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 152 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 153 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 154 packed, err = abi.Pack("nestedArray2", [2][]uint8{{1}, {1}}) 155 if err != nil { 156 t.Fatal(err) 157 } 158 if !bytes.Equal(packed, sig) { 159 t.Errorf("expected %x got %x", sig, packed) 160 } 161 162 sig = abi.Methods["nestedSlice"].ID 163 sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) 164 sig = append(sig, common.LeftPadBytes([]byte{0x02}, 32)...) 165 sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) 166 sig = append(sig, common.LeftPadBytes([]byte{0xa0}, 32)...) 167 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 168 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 169 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 170 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 171 sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) 172 sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) 173 packed, err = abi.Pack("nestedSlice", [][]uint8{{1, 2}, {1, 2}}) 174 if err != nil { 175 t.Fatal(err) 176 } 177 if !bytes.Equal(packed, sig) { 178 t.Errorf("expected %x got %x", sig, packed) 179 } 180 181 // test that we can't pack a negative value for a parameter that is specified as a uint 182 if _, err := abi.Pack("send", big.NewInt(-1)); err == nil { 183 t.Fatal("expected error when trying to pack negative big.Int into uint256 value") 184 } 185 } 186 187 func TestPackNumber(t *testing.T) { 188 t.Parallel() 189 tests := []struct { 190 value reflect.Value 191 packed []byte 192 }{ 193 // Protocol limits 194 {reflect.ValueOf(0), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")}, 195 {reflect.ValueOf(1), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")}, 196 {reflect.ValueOf(-1), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")}, 197 198 // Type corner cases 199 {reflect.ValueOf(uint8(math.MaxUint8)), common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000ff")}, 200 {reflect.ValueOf(uint16(math.MaxUint16)), common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000ffff")}, 201 {reflect.ValueOf(uint32(math.MaxUint32)), common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000ffffffff")}, 202 {reflect.ValueOf(uint64(math.MaxUint64)), common.Hex2Bytes("000000000000000000000000000000000000000000000000ffffffffffffffff")}, 203 204 {reflect.ValueOf(int8(math.MaxInt8)), common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000007f")}, 205 {reflect.ValueOf(int16(math.MaxInt16)), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000007fff")}, 206 {reflect.ValueOf(int32(math.MaxInt32)), common.Hex2Bytes("000000000000000000000000000000000000000000000000000000007fffffff")}, 207 {reflect.ValueOf(int64(math.MaxInt64)), common.Hex2Bytes("0000000000000000000000000000000000000000000000007fffffffffffffff")}, 208 209 {reflect.ValueOf(int8(math.MinInt8)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80")}, 210 {reflect.ValueOf(int16(math.MinInt16)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000")}, 211 {reflect.ValueOf(int32(math.MinInt32)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000")}, 212 {reflect.ValueOf(int64(math.MinInt64)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000")}, 213 } 214 for i, tt := range tests { 215 packed := packNum(tt.value) 216 if !bytes.Equal(packed, tt.packed) { 217 t.Errorf("test %d: pack mismatch: have %x, want %x", i, packed, tt.packed) 218 } 219 } 220 }