github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/signer/fourbyte/abi_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-aigar library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package fourbyte 19 20 import ( 21 "math/big" 22 "reflect" 23 "strings" 24 "testing" 25 26 "github.com/AigarNetwork/aigar/accounts/abi" 27 "github.com/AigarNetwork/aigar/common" 28 ) 29 30 func verify(t *testing.T, jsondata, calldata string, exp []interface{}) { 31 abispec, err := abi.JSON(strings.NewReader(jsondata)) 32 if err != nil { 33 t.Fatal(err) 34 } 35 cd := common.Hex2Bytes(calldata) 36 sigdata, argdata := cd[:4], cd[4:] 37 method, err := abispec.MethodById(sigdata) 38 if err != nil { 39 t.Fatal(err) 40 } 41 data, err := method.Inputs.UnpackValues(argdata) 42 if err != nil { 43 t.Fatal(err) 44 } 45 if len(data) != len(exp) { 46 t.Fatalf("Mismatched length, expected %d, got %d", len(exp), len(data)) 47 } 48 for i, elem := range data { 49 if !reflect.DeepEqual(elem, exp[i]) { 50 t.Fatalf("Unpack error, arg %d, got %v, want %v", i, elem, exp[i]) 51 } 52 } 53 } 54 55 func TestNewUnpacker(t *testing.T) { 56 type unpackTest struct { 57 jsondata string 58 calldata string 59 exp []interface{} 60 } 61 testcases := []unpackTest{ 62 { // https://solidity.readthedocs.io/en/develop/abi-spec.html#use-of-dynamic-types 63 `[{"type":"function","name":"f", "inputs":[{"type":"uint256"},{"type":"uint32[]"},{"type":"bytes10"},{"type":"bytes"}]}]`, 64 // 0x123, [0x456, 0x789], "1234567890", "Hello, world!" 65 "8be65246" + "00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000", 66 []interface{}{ 67 big.NewInt(0x123), 68 []uint32{0x456, 0x789}, 69 [10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48}, 70 common.Hex2Bytes("48656c6c6f2c20776f726c6421"), 71 }, 72 }, { // https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#examples 73 `[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`, 74 // "dave", true and [1,2,3] 75 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 76 []interface{}{ 77 []byte{0x64, 0x61, 0x76, 0x65}, 78 true, 79 []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, 80 }, 81 }, { 82 `[{"type":"function","name":"send","inputs":[{"type":"uint256"}]}]`, 83 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 84 []interface{}{big.NewInt(0x12)}, 85 }, { 86 `[{"type":"function","name":"compareAndApprove","inputs":[{"type":"address"},{"type":"uint256"},{"type":"uint256"}]}]`, 87 "751e107900000000000000000000000000000133700000deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 88 []interface{}{ 89 common.HexToAddress("0x00000133700000deadbeef000000000000000000"), 90 new(big.Int).SetBytes([]byte{0x00}), 91 big.NewInt(0x1), 92 }, 93 }, 94 } 95 for _, c := range testcases { 96 verify(t, c.jsondata, c.calldata, c.exp) 97 } 98 } 99 100 func TestCalldataDecoding(t *testing.T) { 101 // send(uint256) : a52c101e 102 // compareAndApprove(address,uint256,uint256) : 751e1079 103 // issue(address[],uint256) : 42958b54 104 jsondata := ` 105 [ 106 {"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]}, 107 {"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]}, 108 {"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]}, 109 {"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]} 110 ]` 111 // Expected failures 112 for i, hexdata := range []string{ 113 "a52c101e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 114 "a52c101e000000000000000000000000000000000000000000000000000000000000001200", 115 "a52c101e00000000000000000000000000000000000000000000000000000000000000", 116 "a52c101e", 117 "a52c10", 118 "", 119 // Too short 120 "751e10790000000000000000000000000000000000000000000000000000000000000012", 121 "751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 122 // Not valid multiple of 32 123 "deadbeef00000000000000000000000000000000000000000000000000000000000000", 124 // Too short 'issue' 125 "42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 126 // Too short compareAndApprove 127 "a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 128 // From https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI 129 // contains a bool with illegal values 130 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 131 } { 132 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 133 if err == nil { 134 t.Errorf("test %d: expected decoding to fail: %s", i, hexdata) 135 } 136 } 137 // Expected success 138 for i, hexdata := range []string{ 139 // From https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI 140 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 141 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 142 "a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 143 "751e1079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 144 "42958b54" + 145 // start of dynamic type 146 "0000000000000000000000000000000000000000000000000000000000000040" + 147 // uint256 148 "0000000000000000000000000000000000000000000000000000000000000001" + 149 // length of array 150 "0000000000000000000000000000000000000000000000000000000000000002" + 151 // array values 152 "000000000000000000000000000000000000000000000000000000000000dead" + 153 "000000000000000000000000000000000000000000000000000000000000beef", 154 } { 155 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 156 if err != nil { 157 t.Errorf("test %d: unexpected failure on input %s:\n %v (%d bytes) ", i, hexdata, err, len(common.Hex2Bytes(hexdata))) 158 } 159 } 160 } 161 162 func TestMaliciousABIStrings(t *testing.T) { 163 tests := []string{ 164 "func(uint256,uint256,[]uint256)", 165 "func(uint256,uint256,uint256,)", 166 "func(,uint256,uint256,uint256)", 167 } 168 data := common.Hex2Bytes("4401a6e40000000000000000000000000000000000000000000000000000000000000012") 169 for i, tt := range tests { 170 _, err := verifySelector(tt, data) 171 if err == nil { 172 t.Errorf("test %d: expected error for selector '%v'", i, tt) 173 } 174 } 175 }