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