github.com/felberj/go-ethereum@v1.8.23/signer/core/abihelper_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU 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 // go-ethereum 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 General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "fmt" 21 "strings" 22 "testing" 23 24 "io/ioutil" 25 "math/big" 26 "reflect" 27 28 "github.com/ethereum/go-ethereum/accounts/abi" 29 "github.com/ethereum/go-ethereum/common" 30 ) 31 32 func verify(t *testing.T, jsondata, calldata string, exp []interface{}) { 33 34 abispec, err := abi.JSON(strings.NewReader(jsondata)) 35 if err != nil { 36 t.Fatal(err) 37 } 38 cd := common.Hex2Bytes(calldata) 39 sigdata, argdata := cd[:4], cd[4:] 40 method, err := abispec.MethodById(sigdata) 41 if err != nil { 42 t.Fatal(err) 43 } 44 data, err := method.Inputs.UnpackValues(argdata) 45 if err != nil { 46 t.Fatal(err) 47 } 48 if len(data) != len(exp) { 49 t.Fatalf("Mismatched length, expected %d, got %d", len(exp), len(data)) 50 } 51 for i, elem := range data { 52 if !reflect.DeepEqual(elem, exp[i]) { 53 t.Fatalf("Unpack error, arg %d, got %v, want %v", i, elem, exp[i]) 54 } 55 } 56 } 57 func TestNewUnpacker(t *testing.T) { 58 type unpackTest struct { 59 jsondata string 60 calldata string 61 exp []interface{} 62 } 63 testcases := []unpackTest{ 64 { // https://solidity.readthedocs.io/en/develop/abi-spec.html#use-of-dynamic-types 65 `[{"type":"function","name":"f", "inputs":[{"type":"uint256"},{"type":"uint32[]"},{"type":"bytes10"},{"type":"bytes"}]}]`, 66 // 0x123, [0x456, 0x789], "1234567890", "Hello, world!" 67 "8be65246" + "00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000", 68 []interface{}{ 69 big.NewInt(0x123), 70 []uint32{0x456, 0x789}, 71 [10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48}, 72 common.Hex2Bytes("48656c6c6f2c20776f726c6421"), 73 }, 74 }, { // https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#examples 75 `[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`, 76 // "dave", true and [1,2,3] 77 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 78 []interface{}{ 79 []byte{0x64, 0x61, 0x76, 0x65}, 80 true, 81 []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, 82 }, 83 }, { 84 `[{"type":"function","name":"send","inputs":[{"type":"uint256"}]}]`, 85 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 86 []interface{}{big.NewInt(0x12)}, 87 }, { 88 `[{"type":"function","name":"compareAndApprove","inputs":[{"type":"address"},{"type":"uint256"},{"type":"uint256"}]}]`, 89 "751e107900000000000000000000000000000133700000deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 90 []interface{}{ 91 common.HexToAddress("0x00000133700000deadbeef000000000000000000"), 92 new(big.Int).SetBytes([]byte{0x00}), 93 big.NewInt(0x1), 94 }, 95 }, 96 } 97 for _, c := range testcases { 98 verify(t, c.jsondata, c.calldata, c.exp) 99 } 100 101 } 102 103 func TestCalldataDecoding(t *testing.T) { 104 105 // send(uint256) : a52c101e 106 // compareAndApprove(address,uint256,uint256) : 751e1079 107 // issue(address[],uint256) : 42958b54 108 jsondata := ` 109 [ 110 {"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]}, 111 {"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]}, 112 {"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]}, 113 {"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]} 114 ]` 115 //Expected failures 116 for i, hexdata := range []string{ 117 "a52c101e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 118 "a52c101e000000000000000000000000000000000000000000000000000000000000001200", 119 "a52c101e00000000000000000000000000000000000000000000000000000000000000", 120 "a52c101e", 121 "a52c10", 122 "", 123 // Too short 124 "751e10790000000000000000000000000000000000000000000000000000000000000012", 125 "751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 126 //Not valid multiple of 32 127 "deadbeef00000000000000000000000000000000000000000000000000000000000000", 128 //Too short 'issue' 129 "42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 130 // Too short compareAndApprove 131 "a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 132 // From https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI 133 // contains a bool with illegal values 134 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 135 } { 136 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 137 if err == nil { 138 t.Errorf("test %d: expected decoding to fail: %s", i, hexdata) 139 } 140 } 141 //Expected success 142 for i, hexdata := range []string{ 143 // From https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI 144 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 145 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 146 "a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 147 "751e1079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 148 "42958b54" + 149 // start of dynamic type 150 "0000000000000000000000000000000000000000000000000000000000000040" + 151 //uint256 152 "0000000000000000000000000000000000000000000000000000000000000001" + 153 // length of array 154 "0000000000000000000000000000000000000000000000000000000000000002" + 155 // array values 156 "000000000000000000000000000000000000000000000000000000000000dead" + 157 "000000000000000000000000000000000000000000000000000000000000beef", 158 } { 159 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 160 if err != nil { 161 t.Errorf("test %d: unexpected failure on input %s:\n %v (%d bytes) ", i, hexdata, err, len(common.Hex2Bytes(hexdata))) 162 } 163 } 164 } 165 166 func TestSelectorUnmarshalling(t *testing.T) { 167 var ( 168 db *AbiDb 169 err error 170 abistring []byte 171 abistruct abi.ABI 172 ) 173 174 db, err = NewAbiDBFromFile("../../cmd/clef/4byte.json") 175 if err != nil { 176 t.Fatal(err) 177 } 178 fmt.Printf("DB size %v\n", db.Size()) 179 for id, selector := range db.db { 180 181 abistring, err = MethodSelectorToAbi(selector) 182 if err != nil { 183 t.Error(err) 184 return 185 } 186 abistruct, err = abi.JSON(strings.NewReader(string(abistring))) 187 if err != nil { 188 t.Error(err) 189 return 190 } 191 m, err := abistruct.MethodById(common.Hex2Bytes(id[2:])) 192 if err != nil { 193 t.Error(err) 194 return 195 } 196 if m.Sig() != selector { 197 t.Errorf("Expected equality: %v != %v", m.Sig(), selector) 198 } 199 } 200 201 } 202 203 func TestCustomABI(t *testing.T) { 204 d, err := ioutil.TempDir("", "signer-4byte-test") 205 if err != nil { 206 t.Fatal(err) 207 } 208 filename := fmt.Sprintf("%s/4byte_custom.json", d) 209 abidb, err := NewAbiDBFromFiles("../../cmd/clef/4byte.json", filename) 210 if err != nil { 211 t.Fatal(err) 212 } 213 // Now we'll remove all existing signatures 214 abidb.db = make(map[string]string) 215 calldata := common.Hex2Bytes("a52c101edeadbeef") 216 _, err = abidb.LookupMethodSelector(calldata) 217 if err == nil { 218 t.Fatalf("Should not find a match on empty db") 219 } 220 if err = abidb.AddSignature("send(uint256)", calldata); err != nil { 221 t.Fatalf("Failed to save file: %v", err) 222 } 223 _, err = abidb.LookupMethodSelector(calldata) 224 if err != nil { 225 t.Fatalf("Should find a match for abi signature, got: %v", err) 226 } 227 //Check that it wrote to file 228 abidb2, err := NewAbiDBFromFile(filename) 229 if err != nil { 230 t.Fatalf("Failed to create new abidb: %v", err) 231 } 232 _, err = abidb2.LookupMethodSelector(calldata) 233 if err != nil { 234 t.Fatalf("Save failed: should find a match for abi signature after loading from disk") 235 } 236 } 237 238 func TestMaliciousAbiStrings(t *testing.T) { 239 tests := []string{ 240 "func(uint256,uint256,[]uint256)", 241 "func(uint256,uint256,uint256,)", 242 "func(,uint256,uint256,uint256)", 243 } 244 data := common.Hex2Bytes("4401a6e40000000000000000000000000000000000000000000000000000000000000012") 245 for i, tt := range tests { 246 _, err := testSelector(tt, data) 247 if err == nil { 248 t.Errorf("test %d: expected error for selector '%v'", i, tt) 249 } 250 } 251 }