github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/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/vntchain/go-vnt/accounts/abi" 29 "github.com/vntchain/go-vnt/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 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 data, err := method.Inputs.UnpackValues(argdata) 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 }, { 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 /* 104 func TestReflect(t *testing.T) { 105 a := big.NewInt(0) 106 b := new(big.Int).SetBytes([]byte{0x00}) 107 if !reflect.DeepEqual(a, b) { 108 t.Fatalf("Nope, %v != %v", a, b) 109 } 110 } 111 */ 112 113 func TestCalldataDecoding(t *testing.T) { 114 115 // send(uint256) : a52c101e 116 // compareAndApprove(address,uint256,uint256) : 751e1079 117 // issue(address[],uint256) : 42958b54 118 jsondata := ` 119 [ 120 {"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]}, 121 {"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]}, 122 {"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]}, 123 {"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]} 124 ]` 125 //Expected failures 126 for _, hexdata := range []string{ 127 "a52c101e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 128 "a52c101e000000000000000000000000000000000000000000000000000000000000001200", 129 "a52c101e00000000000000000000000000000000000000000000000000000000000000", 130 "a52c101e", 131 "a52c10", 132 "", 133 // Too short 134 "751e10790000000000000000000000000000000000000000000000000000000000000012", 135 "751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 136 //Not valid multiple of 32 137 "deadbeef00000000000000000000000000000000000000000000000000000000000000", 138 //Too short 'issue' 139 "42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 140 // Too short compareAndApprove 141 "a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 142 // contains a bool with illegal values 143 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 144 } { 145 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 146 if err == nil { 147 t.Errorf("Expected decoding to fail: %s", hexdata) 148 } 149 } 150 151 //Expected success 152 for _, hexdata := range []string{ 153 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 154 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 155 "a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 156 "751e1079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 157 "42958b54" + 158 // start of dynamic type 159 "0000000000000000000000000000000000000000000000000000000000000040" + 160 //uint256 161 "0000000000000000000000000000000000000000000000000000000000000001" + 162 // length of array 163 "0000000000000000000000000000000000000000000000000000000000000002" + 164 // array values 165 "000000000000000000000000000000000000000000000000000000000000dead" + 166 "000000000000000000000000000000000000000000000000000000000000beef", 167 } { 168 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 169 if err != nil { 170 t.Errorf("Unexpected failure on input %s:\n %v (%d bytes) ", hexdata, err, len(common.Hex2Bytes(hexdata))) 171 } 172 } 173 } 174 175 func TestSelectorUnmarshalling(t *testing.T) { 176 var ( 177 db *AbiDb 178 err error 179 abistring []byte 180 abistruct abi.ABI 181 ) 182 183 db, err = NewAbiDBFromFile("../../cmd/clef/4byte.json") 184 if err != nil { 185 t.Fatal(err) 186 } 187 t.Logf("DB size %v\n", db.Size()) 188 for id, selector := range db.db { 189 abistring, err = MethodSelectorToAbi(selector) 190 if err != nil { 191 t.Error(err) 192 return 193 } 194 abistruct, err = abi.JSON(strings.NewReader(string(abistring))) 195 if err != nil { 196 t.Error(err) 197 return 198 } 199 m, err := abistruct.MethodById(common.Hex2Bytes(id[2:])) 200 if err != nil { 201 t.Error(err) 202 return 203 } 204 if m.Sig() != selector { 205 t.Errorf("Expected equality: %v != %v", m.Sig(), selector) 206 } 207 } 208 209 } 210 211 func TestCustomABI(t *testing.T) { 212 d, err := ioutil.TempDir("", "signer-4byte-test") 213 if err != nil { 214 t.Fatal(err) 215 } 216 filename := fmt.Sprintf("%s/4byte_custom.json", d) 217 abidb, err := NewAbiDBFromFiles("../../cmd/clef/4byte.json", filename) 218 if err != nil { 219 t.Fatal(err) 220 } 221 // Now we'll remove all existing signatures 222 abidb.db = make(map[string]string) 223 calldata := common.Hex2Bytes("a52c101edeadbeef") 224 _, err = abidb.LookupMethodSelector(calldata) 225 if err == nil { 226 t.Fatalf("Should not find a match on empty db") 227 } 228 if err = abidb.AddSignature("send(uint256)", calldata); err != nil { 229 t.Fatalf("Failed to save file: %v", err) 230 } 231 _, err = abidb.LookupMethodSelector(calldata) 232 if err != nil { 233 t.Fatalf("Should find a match for abi signature, got: %v", err) 234 } 235 //Check that it wrote to file 236 abidb2, err := NewAbiDBFromFile(filename) 237 if err != nil { 238 t.Fatalf("Failed to create new abidb: %v", err) 239 } 240 _, err = abidb2.LookupMethodSelector(calldata) 241 if err != nil { 242 t.Fatalf("Save failed: should find a match for abi signature after loading from disk") 243 } 244 }