github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/signer/core/abihelper_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:42</date> 10 //</624450110226436096> 11 12 13 package core 14 15 import ( 16 "fmt" 17 "strings" 18 "testing" 19 20 "io/ioutil" 21 "math/big" 22 "reflect" 23 24 "github.com/ethereum/go-ethereum/accounts/abi" 25 "github.com/ethereum/go-ethereum/common" 26 ) 27 28 func verify(t *testing.T, jsondata, calldata string, exp []interface{}) { 29 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 func TestNewUnpacker(t *testing.T) { 54 type unpackTest struct { 55 jsondata string 56 calldata string 57 exp []interface{} 58 } 59 testcases := []unpackTest{ 60 { //https://solidity.readthedocs.io/en/develop/abi-spec.html使用动态类型 61 `[{"type":"function","name":"f", "inputs":[{"type":"uint256"},{"type":"uint32[]"},{"type":"bytes10"},{"type":"bytes"}]}]`, 62 //0x123,[0x456,0x789],“1234567890”,“你好,世界!” 63 "8be65246" + "00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000", 64 []interface{}{ 65 big.NewInt(0x123), 66 []uint32{0x456, 0x789}, 67 [10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48}, 68 common.Hex2Bytes("48656c6c6f2c20776f726c6421"), 69 }, 70 }, { //https://github.com/ethereum/wiki/wiki/ethereum contract abi示例 71 `[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`, 72 //“Dave”,真的和[1,2,3] 73 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 74 []interface{}{ 75 []byte{0x64, 0x61, 0x76, 0x65}, 76 true, 77 []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, 78 }, 79 }, { 80 `[{"type":"function","name":"send","inputs":[{"type":"uint256"}]}]`, 81 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 82 []interface{}{big.NewInt(0x12)}, 83 }, { 84 `[{"type":"function","name":"compareAndApprove","inputs":[{"type":"address"},{"type":"uint256"},{"type":"uint256"}]}]`, 85 "751e107900000000000000000000000000000133700000deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 86 []interface{}{ 87 common.HexToAddress("0x00000133700000deadbeef000000000000000000"), 88 new(big.Int).SetBytes([]byte{0x00}), 89 big.NewInt(0x1), 90 }, 91 }, 92 } 93 for _, c := range testcases { 94 verify(t, c.jsondata, c.calldata, c.exp) 95 } 96 97 } 98 99 func TestCalldataDecoding(t *testing.T) { 100 101 //发送(uint256):a52c101e 102 //比较数据证明(地址,uint256,uint256):751E1079 103 //问题(地址[],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 //预期故障 112 for i, hexdata := range []string{ 113 "a52c101e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 114 "a52c101e000000000000000000000000000000000000000000000000000000000000001200", 115 "a52c101e00000000000000000000000000000000000000000000000000000000000000", 116 "a52c101e", 117 "a52c10", 118 "", 119 //太短 120 "751e10790000000000000000000000000000000000000000000000000000000000000012", 121 "751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 122 //不是32的有效倍数 123 "deadbeef00000000000000000000000000000000000000000000000000000000000000", 124 //“问题”太短 125 "42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 126 //比较过短,不适用 127 "a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 128 //来自https://github.com/ethereum/wiki/wiki/ethereum-contract-abi 129 //包含具有非法值的bool 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 //预期成功 138 for i, hexdata := range []string{ 139 //来自https://github.com/ethereum/wiki/wiki/ethereum-contract-abi 140 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 141 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 142 "a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 143 "751e1079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 144 "42958b54" + 145 //动态类型的开始 146 "0000000000000000000000000000000000000000000000000000000000000040" + 147 //UIT2525 148 "0000000000000000000000000000000000000000000000000000000000000001" + 149 //阵列长度 150 "0000000000000000000000000000000000000000000000000000000000000002" + 151 //数组值 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 TestSelectorUnmarshalling(t *testing.T) { 163 var ( 164 db *AbiDb 165 err error 166 abistring []byte 167 abistruct abi.ABI 168 ) 169 170 db, err = NewAbiDBFromFile("../../cmd/clef/4byte.json") 171 if err != nil { 172 t.Fatal(err) 173 } 174 fmt.Printf("DB size %v\n", db.Size()) 175 for id, selector := range db.db { 176 177 abistring, err = MethodSelectorToAbi(selector) 178 if err != nil { 179 t.Error(err) 180 return 181 } 182 abistruct, err = abi.JSON(strings.NewReader(string(abistring))) 183 if err != nil { 184 t.Error(err) 185 return 186 } 187 m, err := abistruct.MethodById(common.Hex2Bytes(id[2:])) 188 if err != nil { 189 t.Error(err) 190 return 191 } 192 if m.Sig() != selector { 193 t.Errorf("Expected equality: %v != %v", m.Sig(), selector) 194 } 195 } 196 197 } 198 199 func TestCustomABI(t *testing.T) { 200 d, err := ioutil.TempDir("", "signer-4byte-test") 201 if err != nil { 202 t.Fatal(err) 203 } 204 filename := fmt.Sprintf("%s/4byte_custom.json", d) 205 abidb, err := NewAbiDBFromFiles("../../cmd/clef/4byte.json", filename) 206 if err != nil { 207 t.Fatal(err) 208 } 209 //现在我们将删除所有现有签名 210 abidb.db = make(map[string]string) 211 calldata := common.Hex2Bytes("a52c101edeadbeef") 212 _, err = abidb.LookupMethodSelector(calldata) 213 if err == nil { 214 t.Fatalf("Should not find a match on empty db") 215 } 216 if err = abidb.AddSignature("send(uint256)", calldata); err != nil { 217 t.Fatalf("Failed to save file: %v", err) 218 } 219 _, err = abidb.LookupMethodSelector(calldata) 220 if err != nil { 221 t.Fatalf("Should find a match for abi signature, got: %v", err) 222 } 223 //检查它是否写入文件 224 abidb2, err := NewAbiDBFromFile(filename) 225 if err != nil { 226 t.Fatalf("Failed to create new abidb: %v", err) 227 } 228 _, err = abidb2.LookupMethodSelector(calldata) 229 if err != nil { 230 t.Fatalf("Save failed: should find a match for abi signature after loading from disk") 231 } 232 } 233 234 func TestMaliciousAbiStrings(t *testing.T) { 235 tests := []string{ 236 "func(uint256,uint256,[]uint256)", 237 "func(uint256,uint256,uint256,)", 238 "func(,uint256,uint256,uint256)", 239 } 240 data := common.Hex2Bytes("4401a6e40000000000000000000000000000000000000000000000000000000000000012") 241 for i, tt := range tests { 242 _, err := testSelector(tt, data) 243 if err == nil { 244 t.Errorf("test %d: expected error for selector '%v'", i, tt) 245 } 246 } 247 } 248