github.com/core-coin/go-core/v2@v2.1.9/signer/fourbyte/abi_test.go (about) 1 // Copyright 2019 by the Authors 2 // This file is part of the go-core library. 3 // 4 // The go-core 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-core 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-core library. If not, see <http://www.gnu.org/licenses/>. 16 17 package fourbyte 18 19 import ( 20 "math/big" 21 "reflect" 22 "strings" 23 "testing" 24 25 "github.com/core-coin/go-core/v2/accounts/abi" 26 "github.com/core-coin/go-core/v2/common" 27 ) 28 29 func verify(t *testing.T, jsondata, calldata string, exp []interface{}) { 30 abispec, err := abi.JSON(strings.NewReader(jsondata)) 31 if err != nil { 32 t.Fatal(err) 33 } 34 cd := common.Hex2Bytes(calldata) 35 sigdata, argdata := cd[:4], cd[4:] 36 method, err := abispec.MethodById(sigdata) 37 if err != nil { 38 t.Fatal(err) 39 } 40 data, err := method.Inputs.UnpackValues(argdata) 41 if err != nil { 42 t.Fatal(err) 43 } 44 if len(data) != len(exp) { 45 t.Fatalf("Mismatched length, expected %d, got %d", len(exp), len(data)) 46 } 47 for i, elem := range data { 48 if !reflect.DeepEqual(elem, exp[i]) { 49 t.Fatalf("Unpack error, arg %d, got %v, want %v", i, elem, exp[i]) 50 } 51 } 52 } 53 54 func TestNewUnpacker(t *testing.T) { 55 type unpackTest struct { 56 jsondata string 57 calldata string 58 exp []interface{} 59 } 60 addr, err := common.HexToAddress("cb4900000133700000deadbeef000000000000000000") 61 if err != nil { 62 t.Error(err) 63 } 64 testcases := []unpackTest{ 65 { // https://ylem.readthedocs.io/en/develop/abi-spec.html#use-of-dynamic-types 66 `[{"type":"function","name":"f", "inputs":[{"type":"uint256"},{"type":"uint32[]"},{"type":"bytes10"},{"type":"bytes"}]}]`, 67 // 0x123, [0x456, 0x789], "1234567890", "Hello, world!" 68 "41cc790900000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000", 69 []interface{}{ 70 big.NewInt(0x123), 71 []uint32{0x456, 0x789}, 72 [10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48}, 73 common.Hex2Bytes("48656c6c6f2c20776f726c6421"), 74 }, 75 }, 76 { // https://github.com/core/wiki/wiki/Core-Contract-ABI#examples 77 `[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`, 78 // "dave", true and [1,2,3] 79 "cf3d9ff50000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 80 []interface{}{ 81 []byte{0x64, 0x61, 0x76, 0x65}, 82 true, 83 []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, 84 }, 85 }, 86 { 87 `[{"type":"function","name":"send","inputs":[{"type":"uint256"}]}]`, 88 "e10c92510000000000000000000000000000000000000000000000000000000000000012", 89 []interface{}{big.NewInt(0x12)}, 90 }, 91 { 92 `[{"type":"function","name":"compareAndApprove","inputs":[{"type":"address"},{"type":"uint256"},{"type":"uint256"}]}]`, 93 "db33183a00000000000000000000cb4900000133700000deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 94 []interface{}{ 95 addr, 96 new(big.Int).SetBytes([]byte{0x00}), 97 big.NewInt(0x1), 98 }, 99 }, 100 } 101 for _, c := range testcases { 102 verify(t, c.jsondata, c.calldata, c.exp) 103 } 104 } 105 106 func TestCalldataDecoding(t *testing.T) { 107 // send(uint256) : e10c9251 108 // compareAndApprove(address,uint256,uint256) : db33183a 109 // issue(address[],uint256) : 649cfa14 110 jsondata := ` 111 [ 112 {"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]}, 113 {"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]}, 114 {"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]}, 115 {"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]} 116 ]` 117 // Expected failures 118 for i, hexdata := range []string{ 119 "e10c925100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 120 "e10c9251000000000000000000000000000000000000000000000000000000000000001200", 121 "e10c925100000000000000000000000000000000000000000000000000000000000000", 122 "e10c9251", 123 "a52c10", 124 "", 125 // Too short 126 "db33183a0000000000000000000000000000000000000000000000000000000000000012", 127 "db33183aFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 128 // Not valid multiple of 32 129 "deadbeef00000000000000000000000000000000000000000000000000000000000000", 130 // Too short 'issue' 131 "649cfa1400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 132 // Too short compareAndApprove 133 "e10c925100ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 134 } { 135 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 136 if err == nil { 137 t.Errorf("test %d: expected decoding to fail: %s", i, hexdata) 138 } 139 } 140 // Expected success 141 for i, hexdata := range []string{ 142 // From https://github.com/core/wiki/wiki/Core-Contract-ABI 143 "e10c92510000000000000000000000000000000000000000000000000000000000000012", 144 "e10c9251FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 145 "db33183a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 146 "649cfa14" + 147 // start of dynamic type 148 "0000000000000000000000000000000000000000000000000000000000000040" + 149 // uint256 150 "0000000000000000000000000000000000000000000000000000000000000001" + 151 // length of array 152 "0000000000000000000000000000000000000000000000000000000000000002" + 153 // array values 154 "000000000000000000000000000000000000000000000000000000000000dead" + 155 "000000000000000000000000000000000000000000000000000000000000beef", 156 } { 157 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 158 if err != nil { 159 t.Errorf("test %d: unexpected failure on input %s:\n %v (%d bytes) ", i, hexdata, err, len(common.Hex2Bytes(hexdata))) 160 } 161 } 162 } 163 164 func TestMaliciousABIStrings(t *testing.T) { 165 tests := []string{ 166 "func(uint256,uint256,[]uint256)", 167 "func(uint256,uint256,uint256,)", 168 "func(,uint256,uint256,uint256)", 169 } 170 data := common.Hex2Bytes("4401a6e40000000000000000000000000000000000000000000000000000000000000012") 171 for i, tt := range tests { 172 _, err := verifySelector(tt, data) 173 if err == nil { 174 t.Errorf("test %d: expected error for selector '%v'", i, tt) 175 } 176 } 177 }