github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:46</date> 10 //</624342666179514368> 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 38 if err != nil { 39 t.Fatal(err) 40 } 41 42 data, err := method.Inputs.UnpackValues(argdata) 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 /* 100 func测试反射(t*testing.t) 101 A:=big.newint(0) 102 b:=new(big.int).setbytes([]字节0x00) 103 如果!反射。深度(A,B) 104 t.fatalf(“不,%v!= %V“,A,B” 105 } 106 } 107 **/ 108 109 110 func TestCalldataDecoding(t *testing.T) { 111 112 //发送(uint256):a52c101e 113 //比较数据证明(地址,uint256,uint256):751E1079 114 //问题(地址[],uint256):42958b54 115 jsondata := ` 116 [ 117 {"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]}, 118 {"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]}, 119 {"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]}, 120 {"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]} 121 ]` 122 //预期故障 123 for _, hexdata := range []string{ 124 "a52c101e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 125 "a52c101e000000000000000000000000000000000000000000000000000000000000001200", 126 "a52c101e00000000000000000000000000000000000000000000000000000000000000", 127 "a52c101e", 128 "a52c10", 129 "", 130 //太短 131 "751e10790000000000000000000000000000000000000000000000000000000000000012", 132 "751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 133 //不是32的有效倍数 134 "deadbeef00000000000000000000000000000000000000000000000000000000000000", 135 // 136 "42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 137 //比较过短,不适用 138 "a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042", 139 //来自https://github.com/ethereum/wiki/wiki/ethereum-contract-abi 140 //包含具有非法值的bool 141 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 142 } { 143 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 144 if err == nil { 145 t.Errorf("Expected decoding to fail: %s", hexdata) 146 } 147 } 148 149 //预期成功 150 for _, hexdata := range []string{ 151 //来自https://github.com/ethereum/wiki/wiki/ethereum-contract-abi 152 "a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", 153 "a52c101e0000000000000000000000000000000000000000000000000000000000000012", 154 "a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 155 "751e1079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 156 "42958b54" + 157 //动态类型的开始 158 "0000000000000000000000000000000000000000000000000000000000000040" + 159 //UIT2525 160 "0000000000000000000000000000000000000000000000000000000000000001" + 161 //阵列长度 162 "0000000000000000000000000000000000000000000000000000000000000002" + 163 //数组值 164 "000000000000000000000000000000000000000000000000000000000000dead" + 165 "000000000000000000000000000000000000000000000000000000000000beef", 166 } { 167 _, err := parseCallData(common.Hex2Bytes(hexdata), jsondata) 168 if err != nil { 169 t.Errorf("Unexpected failure on input %s:\n %v (%d bytes) ", hexdata, err, len(common.Hex2Bytes(hexdata))) 170 } 171 } 172 } 173 174 func TestSelectorUnmarshalling(t *testing.T) { 175 var ( 176 db *AbiDb 177 err error 178 abistring []byte 179 abistruct abi.ABI 180 ) 181 182 db, err = NewAbiDBFromFile("../../cmd/clef/4byte.json") 183 if err != nil { 184 t.Fatal(err) 185 } 186 fmt.Printf("DB size %v\n", db.Size()) 187 for id, selector := range db.db { 188 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 //现在我们将删除所有现有签名 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 //检查它是否写入文件 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 } 245