github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/accounts/abi/abi_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2015 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package abi 26 27 import ( 28 "bytes" 29 "encoding/hex" 30 "fmt" 31 "log" 32 "math/big" 33 "strings" 34 "testing" 35 36 "reflect" 37 38 "github.com/ethereum/go-ethereum/common" 39 "github.com/ethereum/go-ethereum/crypto" 40 ) 41 42 const jsondata = ` 43 [ 44 { "type" : "function", "name" : "balance", "constant" : true }, 45 { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] } 46 ]` 47 48 const jsondata2 = ` 49 [ 50 { "type" : "function", "name" : "balance", "constant" : true }, 51 { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }, 52 { "type" : "function", "name" : "test", "constant" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] }, 53 { "type" : "function", "name" : "string", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] }, 54 { "type" : "function", "name" : "bool", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] }, 55 { "type" : "function", "name" : "address", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] }, 56 { "type" : "function", "name" : "uint64[2]", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] }, 57 { "type" : "function", "name" : "uint64[]", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] }, 58 { "type" : "function", "name" : "foo", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] }, 59 { "type" : "function", "name" : "bar", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] }, 60 { "type" : "function", "name" : "slice", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] }, 61 { "type" : "function", "name" : "slice256", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }, 62 { "type" : "function", "name" : "sliceAddress", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] }, 63 { "type" : "function", "name" : "sliceMultiAddress", "constant" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] } 64 ]` 65 66 func TestReader(t *testing.T) { 67 Uint256, _ := NewType("uint256") 68 exp := ABI{ 69 Methods: map[string]Method{ 70 "balance": { 71 "balance", true, nil, nil, 72 }, 73 "send": { 74 "send", false, []Argument{ 75 {"amount", Uint256, false}, 76 }, nil, 77 }, 78 }, 79 } 80 81 abi, err := JSON(strings.NewReader(jsondata)) 82 if err != nil { 83 t.Error(err) 84 } 85 86 //深相等由于某种原因而失败 87 for name, expM := range exp.Methods { 88 gotM, exist := abi.Methods[name] 89 if !exist { 90 t.Errorf("Missing expected method %v", name) 91 } 92 if !reflect.DeepEqual(gotM, expM) { 93 t.Errorf("\nGot abi method: \n%v\ndoes not match expected method\n%v", gotM, expM) 94 } 95 } 96 97 for name, gotM := range abi.Methods { 98 expM, exist := exp.Methods[name] 99 if !exist { 100 t.Errorf("Found extra method %v", name) 101 } 102 if !reflect.DeepEqual(gotM, expM) { 103 t.Errorf("\nGot abi method: \n%v\ndoes not match expected method\n%v", gotM, expM) 104 } 105 } 106 } 107 108 func TestTestNumbers(t *testing.T) { 109 abi, err := JSON(strings.NewReader(jsondata2)) 110 if err != nil { 111 t.Error(err) 112 t.FailNow() 113 } 114 115 if _, err := abi.Pack("balance"); err != nil { 116 t.Error(err) 117 } 118 119 if _, err := abi.Pack("balance", 1); err == nil { 120 t.Error("expected error for balance(1)") 121 } 122 123 if _, err := abi.Pack("doesntexist", nil); err == nil { 124 t.Errorf("doesntexist shouldn't exist") 125 } 126 127 if _, err := abi.Pack("doesntexist", 1); err == nil { 128 t.Errorf("doesntexist(1) shouldn't exist") 129 } 130 131 if _, err := abi.Pack("send", big.NewInt(1000)); err != nil { 132 t.Error(err) 133 } 134 135 i := new(int) 136 *i = 1000 137 if _, err := abi.Pack("send", i); err == nil { 138 t.Errorf("expected send( ptr ) to throw, requires *big.Int instead of *int") 139 } 140 141 if _, err := abi.Pack("test", uint32(1000)); err != nil { 142 t.Error(err) 143 } 144 } 145 146 func TestTestString(t *testing.T) { 147 abi, err := JSON(strings.NewReader(jsondata2)) 148 if err != nil { 149 t.Error(err) 150 t.FailNow() 151 } 152 153 if _, err := abi.Pack("string", "hello world"); err != nil { 154 t.Error(err) 155 } 156 } 157 158 func TestTestBool(t *testing.T) { 159 abi, err := JSON(strings.NewReader(jsondata2)) 160 if err != nil { 161 t.Error(err) 162 t.FailNow() 163 } 164 165 if _, err := abi.Pack("bool", true); err != nil { 166 t.Error(err) 167 } 168 } 169 170 func TestTestSlice(t *testing.T) { 171 abi, err := JSON(strings.NewReader(jsondata2)) 172 if err != nil { 173 t.Error(err) 174 t.FailNow() 175 } 176 177 slice := make([]uint64, 2) 178 if _, err := abi.Pack("uint64[2]", slice); err != nil { 179 t.Error(err) 180 } 181 182 if _, err := abi.Pack("uint64[]", slice); err != nil { 183 t.Error(err) 184 } 185 } 186 187 func TestMethodSignature(t *testing.T) { 188 String, _ := NewType("string") 189 m := Method{"foo", false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} 190 exp := "foo(string,string)" 191 if m.Sig() != exp { 192 t.Error("signature mismatch", exp, "!=", m.Sig()) 193 } 194 195 idexp := crypto.Keccak256([]byte(exp))[:4] 196 if !bytes.Equal(m.Id(), idexp) { 197 t.Errorf("expected ids to match %x != %x", m.Id(), idexp) 198 } 199 200 uintt, _ := NewType("uint256") 201 m = Method{"foo", false, []Argument{{"bar", uintt, false}}, nil} 202 exp = "foo(uint256)" 203 if m.Sig() != exp { 204 t.Error("signature mismatch", exp, "!=", m.Sig()) 205 } 206 } 207 208 func TestMultiPack(t *testing.T) { 209 abi, err := JSON(strings.NewReader(jsondata2)) 210 if err != nil { 211 t.Error(err) 212 t.FailNow() 213 } 214 215 sig := crypto.Keccak256([]byte("bar(uint32,uint16)"))[:4] 216 sig = append(sig, make([]byte, 64)...) 217 sig[35] = 10 218 sig[67] = 11 219 220 packed, err := abi.Pack("bar", uint32(10), uint16(11)) 221 if err != nil { 222 t.Error(err) 223 t.FailNow() 224 } 225 226 if !bytes.Equal(packed, sig) { 227 t.Errorf("expected %x got %x", sig, packed) 228 } 229 } 230 231 func ExampleJSON() { 232 const definition = `[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isBar","outputs":[{"name":"","type":"bool"}],"type":"function"}]` 233 234 abi, err := JSON(strings.NewReader(definition)) 235 if err != nil { 236 log.Fatalln(err) 237 } 238 out, err := abi.Pack("isBar", common.HexToAddress("01")) 239 if err != nil { 240 log.Fatalln(err) 241 } 242 243 fmt.Printf("%x\n", out) 244 //输出: 245 //1FBC40920000000000000000000000000000000000000000000000000000000000000000001 246 } 247 248 func TestInputVariableInputLength(t *testing.T) { 249 const definition = `[ 250 { "type" : "function", "name" : "strOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" } ] }, 251 { "type" : "function", "name" : "bytesOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" } ] }, 252 { "type" : "function", "name" : "strTwo", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "str1", "type" : "string" } ] } 253 ]` 254 255 abi, err := JSON(strings.NewReader(definition)) 256 if err != nil { 257 t.Fatal(err) 258 } 259 260 //测试一个字符串 261 strin := "hello world" 262 strpack, err := abi.Pack("strOne", strin) 263 if err != nil { 264 t.Error(err) 265 } 266 267 offset := make([]byte, 32) 268 offset[31] = 32 269 length := make([]byte, 32) 270 length[31] = byte(len(strin)) 271 value := common.RightPadBytes([]byte(strin), 32) 272 exp := append(offset, append(length, value...)...) 273 274 //忽略输出的前4个字节。这是函数标识符 275 strpack = strpack[4:] 276 if !bytes.Equal(strpack, exp) { 277 t.Errorf("expected %x, got %x\n", exp, strpack) 278 } 279 280 //测试一个字节 281 btspack, err := abi.Pack("bytesOne", []byte(strin)) 282 if err != nil { 283 t.Error(err) 284 } 285 //忽略输出的前4个字节。这是函数标识符 286 btspack = btspack[4:] 287 if !bytes.Equal(btspack, exp) { 288 t.Errorf("expected %x, got %x\n", exp, btspack) 289 } 290 291 //测试两个字符串 292 str1 := "hello" 293 str2 := "world" 294 str2pack, err := abi.Pack("strTwo", str1, str2) 295 if err != nil { 296 t.Error(err) 297 } 298 299 offset1 := make([]byte, 32) 300 offset1[31] = 64 301 length1 := make([]byte, 32) 302 length1[31] = byte(len(str1)) 303 value1 := common.RightPadBytes([]byte(str1), 32) 304 305 offset2 := make([]byte, 32) 306 offset2[31] = 128 307 length2 := make([]byte, 32) 308 length2[31] = byte(len(str2)) 309 value2 := common.RightPadBytes([]byte(str2), 32) 310 311 exp2 := append(offset1, offset2...) 312 exp2 = append(exp2, append(length1, value1...)...) 313 exp2 = append(exp2, append(length2, value2...)...) 314 315 //忽略输出的前4个字节。这是函数标识符 316 str2pack = str2pack[4:] 317 if !bytes.Equal(str2pack, exp2) { 318 t.Errorf("expected %x, got %x\n", exp, str2pack) 319 } 320 321 //测试两个字符串,第一个>32,第二个<32 322 str1 = strings.Repeat("a", 33) 323 str2pack, err = abi.Pack("strTwo", str1, str2) 324 if err != nil { 325 t.Error(err) 326 } 327 328 offset1 = make([]byte, 32) 329 offset1[31] = 64 330 length1 = make([]byte, 32) 331 length1[31] = byte(len(str1)) 332 value1 = common.RightPadBytes([]byte(str1), 64) 333 offset2[31] = 160 334 335 exp2 = append(offset1, offset2...) 336 exp2 = append(exp2, append(length1, value1...)...) 337 exp2 = append(exp2, append(length2, value2...)...) 338 339 //忽略输出的前4个字节。这是函数标识符 340 str2pack = str2pack[4:] 341 if !bytes.Equal(str2pack, exp2) { 342 t.Errorf("expected %x, got %x\n", exp, str2pack) 343 } 344 345 //测试两个字符串,第一个>32,第二个>32 346 str1 = strings.Repeat("a", 33) 347 str2 = strings.Repeat("a", 33) 348 str2pack, err = abi.Pack("strTwo", str1, str2) 349 if err != nil { 350 t.Error(err) 351 } 352 353 offset1 = make([]byte, 32) 354 offset1[31] = 64 355 length1 = make([]byte, 32) 356 length1[31] = byte(len(str1)) 357 value1 = common.RightPadBytes([]byte(str1), 64) 358 359 offset2 = make([]byte, 32) 360 offset2[31] = 160 361 length2 = make([]byte, 32) 362 length2[31] = byte(len(str2)) 363 value2 = common.RightPadBytes([]byte(str2), 64) 364 365 exp2 = append(offset1, offset2...) 366 exp2 = append(exp2, append(length1, value1...)...) 367 exp2 = append(exp2, append(length2, value2...)...) 368 369 //忽略输出的前4个字节。这是函数标识符 370 str2pack = str2pack[4:] 371 if !bytes.Equal(str2pack, exp2) { 372 t.Errorf("expected %x, got %x\n", exp, str2pack) 373 } 374 } 375 376 func TestInputFixedArrayAndVariableInputLength(t *testing.T) { 377 const definition = `[ 378 { "type" : "function", "name" : "fixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, 379 { "type" : "function", "name" : "fixedArrBytes", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, 380 { "type" : "function", "name" : "mixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type": "uint256[2]" }, { "name" : "dynArr", "type": "uint256[]" } ] }, 381 { "type" : "function", "name" : "doubleFixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "fixedArr2", "type": "uint256[3]" } ] }, 382 { "type" : "function", "name" : "multipleMixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] } 383 ]` 384 385 abi, err := JSON(strings.NewReader(definition)) 386 if err != nil { 387 t.Error(err) 388 } 389 390 //测试字符串,固定数组uint256[2] 391 strin := "hello world" 392 arrin := [2]*big.Int{big.NewInt(1), big.NewInt(2)} 393 fixedArrStrPack, err := abi.Pack("fixedArrStr", strin, arrin) 394 if err != nil { 395 t.Error(err) 396 } 397 398 //生成预期输出 399 offset := make([]byte, 32) 400 offset[31] = 96 401 length := make([]byte, 32) 402 length[31] = byte(len(strin)) 403 strvalue := common.RightPadBytes([]byte(strin), 32) 404 arrinvalue1 := common.LeftPadBytes(arrin[0].Bytes(), 32) 405 arrinvalue2 := common.LeftPadBytes(arrin[1].Bytes(), 32) 406 exp := append(offset, arrinvalue1...) 407 exp = append(exp, arrinvalue2...) 408 exp = append(exp, append(length, strvalue...)...) 409 410 //忽略输出的前4个字节。这是函数标识符 411 fixedArrStrPack = fixedArrStrPack[4:] 412 if !bytes.Equal(fixedArrStrPack, exp) { 413 t.Errorf("expected %x, got %x\n", exp, fixedArrStrPack) 414 } 415 416 //测试字节数组,固定数组uint256[2] 417 bytesin := []byte(strin) 418 arrin = [2]*big.Int{big.NewInt(1), big.NewInt(2)} 419 fixedArrBytesPack, err := abi.Pack("fixedArrBytes", bytesin, arrin) 420 if err != nil { 421 t.Error(err) 422 } 423 424 //生成预期输出 425 offset = make([]byte, 32) 426 offset[31] = 96 427 length = make([]byte, 32) 428 length[31] = byte(len(strin)) 429 strvalue = common.RightPadBytes([]byte(strin), 32) 430 arrinvalue1 = common.LeftPadBytes(arrin[0].Bytes(), 32) 431 arrinvalue2 = common.LeftPadBytes(arrin[1].Bytes(), 32) 432 exp = append(offset, arrinvalue1...) 433 exp = append(exp, arrinvalue2...) 434 exp = append(exp, append(length, strvalue...)...) 435 436 //忽略输出的前4个字节。这是函数标识符 437 fixedArrBytesPack = fixedArrBytesPack[4:] 438 if !bytes.Equal(fixedArrBytesPack, exp) { 439 t.Errorf("expected %x, got %x\n", exp, fixedArrBytesPack) 440 } 441 442 //测试字符串,固定数组uint256[2],动态数组uint256[] 443 strin = "hello world" 444 fixedarrin := [2]*big.Int{big.NewInt(1), big.NewInt(2)} 445 dynarrin := []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)} 446 mixedArrStrPack, err := abi.Pack("mixedArrStr", strin, fixedarrin, dynarrin) 447 if err != nil { 448 t.Error(err) 449 } 450 451 //生成预期输出 452 stroffset := make([]byte, 32) 453 stroffset[31] = 128 454 strlength := make([]byte, 32) 455 strlength[31] = byte(len(strin)) 456 strvalue = common.RightPadBytes([]byte(strin), 32) 457 fixedarrinvalue1 := common.LeftPadBytes(fixedarrin[0].Bytes(), 32) 458 fixedarrinvalue2 := common.LeftPadBytes(fixedarrin[1].Bytes(), 32) 459 dynarroffset := make([]byte, 32) 460 dynarroffset[31] = byte(160 + ((len(strin)/32)+1)*32) 461 dynarrlength := make([]byte, 32) 462 dynarrlength[31] = byte(len(dynarrin)) 463 dynarrinvalue1 := common.LeftPadBytes(dynarrin[0].Bytes(), 32) 464 dynarrinvalue2 := common.LeftPadBytes(dynarrin[1].Bytes(), 32) 465 dynarrinvalue3 := common.LeftPadBytes(dynarrin[2].Bytes(), 32) 466 exp = append(stroffset, fixedarrinvalue1...) 467 exp = append(exp, fixedarrinvalue2...) 468 exp = append(exp, dynarroffset...) 469 exp = append(exp, append(strlength, strvalue...)...) 470 dynarrarg := append(dynarrlength, dynarrinvalue1...) 471 dynarrarg = append(dynarrarg, dynarrinvalue2...) 472 dynarrarg = append(dynarrarg, dynarrinvalue3...) 473 exp = append(exp, dynarrarg...) 474 475 //忽略输出的前4个字节。这是函数标识符 476 mixedArrStrPack = mixedArrStrPack[4:] 477 if !bytes.Equal(mixedArrStrPack, exp) { 478 t.Errorf("expected %x, got %x\n", exp, mixedArrStrPack) 479 } 480 481 //测试字符串,固定数组uint256[2],固定数组uint256[3] 482 strin = "hello world" 483 fixedarrin1 := [2]*big.Int{big.NewInt(1), big.NewInt(2)} 484 fixedarrin2 := [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)} 485 doubleFixedArrStrPack, err := abi.Pack("doubleFixedArrStr", strin, fixedarrin1, fixedarrin2) 486 if err != nil { 487 t.Error(err) 488 } 489 490 //生成预期输出 491 stroffset = make([]byte, 32) 492 stroffset[31] = 192 493 strlength = make([]byte, 32) 494 strlength[31] = byte(len(strin)) 495 strvalue = common.RightPadBytes([]byte(strin), 32) 496 fixedarrin1value1 := common.LeftPadBytes(fixedarrin1[0].Bytes(), 32) 497 fixedarrin1value2 := common.LeftPadBytes(fixedarrin1[1].Bytes(), 32) 498 fixedarrin2value1 := common.LeftPadBytes(fixedarrin2[0].Bytes(), 32) 499 fixedarrin2value2 := common.LeftPadBytes(fixedarrin2[1].Bytes(), 32) 500 fixedarrin2value3 := common.LeftPadBytes(fixedarrin2[2].Bytes(), 32) 501 exp = append(stroffset, fixedarrin1value1...) 502 exp = append(exp, fixedarrin1value2...) 503 exp = append(exp, fixedarrin2value1...) 504 exp = append(exp, fixedarrin2value2...) 505 exp = append(exp, fixedarrin2value3...) 506 exp = append(exp, append(strlength, strvalue...)...) 507 508 //忽略输出的前4个字节。这是函数标识符 509 doubleFixedArrStrPack = doubleFixedArrStrPack[4:] 510 if !bytes.Equal(doubleFixedArrStrPack, exp) { 511 t.Errorf("expected %x, got %x\n", exp, doubleFixedArrStrPack) 512 } 513 514 //测试字符串,固定数组uint256[2],动态数组uint256[],固定数组uint256[3] 515 strin = "hello world" 516 fixedarrin1 = [2]*big.Int{big.NewInt(1), big.NewInt(2)} 517 dynarrin = []*big.Int{big.NewInt(1), big.NewInt(2)} 518 fixedarrin2 = [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)} 519 multipleMixedArrStrPack, err := abi.Pack("multipleMixedArrStr", strin, fixedarrin1, dynarrin, fixedarrin2) 520 if err != nil { 521 t.Error(err) 522 } 523 524 //生成预期输出 525 stroffset = make([]byte, 32) 526 stroffset[31] = 224 527 strlength = make([]byte, 32) 528 strlength[31] = byte(len(strin)) 529 strvalue = common.RightPadBytes([]byte(strin), 32) 530 fixedarrin1value1 = common.LeftPadBytes(fixedarrin1[0].Bytes(), 32) 531 fixedarrin1value2 = common.LeftPadBytes(fixedarrin1[1].Bytes(), 32) 532 dynarroffset = U256(big.NewInt(int64(256 + ((len(strin)/32)+1)*32))) 533 dynarrlength = make([]byte, 32) 534 dynarrlength[31] = byte(len(dynarrin)) 535 dynarrinvalue1 = common.LeftPadBytes(dynarrin[0].Bytes(), 32) 536 dynarrinvalue2 = common.LeftPadBytes(dynarrin[1].Bytes(), 32) 537 fixedarrin2value1 = common.LeftPadBytes(fixedarrin2[0].Bytes(), 32) 538 fixedarrin2value2 = common.LeftPadBytes(fixedarrin2[1].Bytes(), 32) 539 fixedarrin2value3 = common.LeftPadBytes(fixedarrin2[2].Bytes(), 32) 540 exp = append(stroffset, fixedarrin1value1...) 541 exp = append(exp, fixedarrin1value2...) 542 exp = append(exp, dynarroffset...) 543 exp = append(exp, fixedarrin2value1...) 544 exp = append(exp, fixedarrin2value2...) 545 exp = append(exp, fixedarrin2value3...) 546 exp = append(exp, append(strlength, strvalue...)...) 547 dynarrarg = append(dynarrlength, dynarrinvalue1...) 548 dynarrarg = append(dynarrarg, dynarrinvalue2...) 549 exp = append(exp, dynarrarg...) 550 551 //忽略输出的前4个字节。这是函数标识符 552 multipleMixedArrStrPack = multipleMixedArrStrPack[4:] 553 if !bytes.Equal(multipleMixedArrStrPack, exp) { 554 t.Errorf("expected %x, got %x\n", exp, multipleMixedArrStrPack) 555 } 556 } 557 558 func TestDefaultFunctionParsing(t *testing.T) { 559 const definition = `[{ "name" : "balance" }]` 560 561 abi, err := JSON(strings.NewReader(definition)) 562 if err != nil { 563 t.Fatal(err) 564 } 565 566 if _, ok := abi.Methods["balance"]; !ok { 567 t.Error("expected 'balance' to be present") 568 } 569 } 570 571 func TestBareEvents(t *testing.T) { 572 const definition = `[ 573 { "type" : "event", "name" : "balance" }, 574 { "type" : "event", "name" : "anon", "anonymous" : true}, 575 { "type" : "event", "name" : "args", "inputs" : [{ "indexed":false, "name":"arg0", "type":"uint256" }, { "indexed":true, "name":"arg1", "type":"address" }] } 576 ]` 577 578 arg0, _ := NewType("uint256") 579 arg1, _ := NewType("address") 580 581 expectedEvents := map[string]struct { 582 Anonymous bool 583 Args []Argument 584 }{ 585 "balance": {false, nil}, 586 "anon": {true, nil}, 587 "args": {false, []Argument{ 588 {Name: "arg0", Type: arg0, Indexed: false}, 589 {Name: "arg1", Type: arg1, Indexed: true}, 590 }}, 591 } 592 593 abi, err := JSON(strings.NewReader(definition)) 594 if err != nil { 595 t.Fatal(err) 596 } 597 598 if len(abi.Events) != len(expectedEvents) { 599 t.Fatalf("invalid number of events after parsing, want %d, got %d", len(expectedEvents), len(abi.Events)) 600 } 601 602 for name, exp := range expectedEvents { 603 got, ok := abi.Events[name] 604 if !ok { 605 t.Errorf("could not found event %s", name) 606 continue 607 } 608 if got.Anonymous != exp.Anonymous { 609 t.Errorf("invalid anonymous indication for event %s, want %v, got %v", name, exp.Anonymous, got.Anonymous) 610 } 611 if len(got.Inputs) != len(exp.Args) { 612 t.Errorf("invalid number of args, want %d, got %d", len(exp.Args), len(got.Inputs)) 613 continue 614 } 615 for i, arg := range exp.Args { 616 if arg.Name != got.Inputs[i].Name { 617 t.Errorf("events[%s].Input[%d] has an invalid name, want %s, got %s", name, i, arg.Name, got.Inputs[i].Name) 618 } 619 if arg.Indexed != got.Inputs[i].Indexed { 620 t.Errorf("events[%s].Input[%d] has an invalid indexed indication, want %v, got %v", name, i, arg.Indexed, got.Inputs[i].Indexed) 621 } 622 if arg.Type.T != got.Inputs[i].Type.T { 623 t.Errorf("events[%s].Input[%d] has an invalid type, want %x, got %x", name, i, arg.Type.T, got.Inputs[i].Type.T) 624 } 625 } 626 } 627 } 628 629 //TestUnpackEvent基于此合同: 630 //合同t{ 631 //接收到的事件(地址发送方、uint金额、字节备忘录); 632 //事件接收数据(地址发送者); 633 //功能接收(字节备忘录)外部应付款 634 //接收(msg.sender,msg.value,memo); 635 //接收数据(消息发送方); 636 //} 637 //} 638 //当使用发送方0x00调用Receive(“X”)时…以及值1,它生成此Tx收据: 639 //收据状态=1 cgas=23949 bloom=0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[日志:B6818C8064F645CD82D99B59A1267D61117EF[75FD880D39C1DAF53B6547AB6CB59451FC6452D27CAA90E5B6649DD8293B9EED]000000000000000376C47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f43425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c4323DE162CF00 0 } 640 func TestUnpackEvent(t *testing.T) { 641 const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` 642 abi, err := JSON(strings.NewReader(abiJSON)) 643 if err != nil { 644 t.Fatal(err) 645 } 646 647 const hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158` 648 data, err := hex.DecodeString(hexdata) 649 if err != nil { 650 t.Fatal(err) 651 } 652 if len(data)%32 == 0 { 653 t.Errorf("len(data) is %d, want a non-multiple of 32", len(data)) 654 } 655 656 type ReceivedEvent struct { 657 Address common.Address 658 Amount *big.Int 659 Memo []byte 660 } 661 var ev ReceivedEvent 662 663 err = abi.Unpack(&ev, "received", data) 664 if err != nil { 665 t.Error(err) 666 } else { 667 t.Logf("len(data): %d; received event: %+v", len(data), ev) 668 } 669 670 type ReceivedAddrEvent struct { 671 Address common.Address 672 } 673 var receivedAddrEv ReceivedAddrEvent 674 err = abi.Unpack(&receivedAddrEv, "receivedAddr", data) 675 if err != nil { 676 t.Error(err) 677 } else { 678 t.Logf("len(data): %d; received event: %+v", len(data), receivedAddrEv) 679 } 680 } 681 682 func TestABI_MethodById(t *testing.T) { 683 const abiJSON = `[ 684 {"type":"function","name":"receive","constant":false,"inputs":[{"name":"memo","type":"bytes"}],"outputs":[],"payable":true,"stateMutability":"payable"}, 685 {"type":"event","name":"received","anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}]}, 686 {"type":"function","name":"fixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr","type":"uint256[2]"}]}, 687 {"type":"function","name":"fixedArrBytes","constant":true,"inputs":[{"name":"str","type":"bytes"},{"name":"fixedArr","type":"uint256[2]"}]}, 688 {"type":"function","name":"mixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr","type":"uint256[2]"},{"name":"dynArr","type":"uint256[]"}]}, 689 {"type":"function","name":"doubleFixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr1","type":"uint256[2]"},{"name":"fixedArr2","type":"uint256[3]"}]}, 690 {"type":"function","name":"multipleMixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr1","type":"uint256[2]"},{"name":"dynArr","type":"uint256[]"},{"name":"fixedArr2","type":"uint256[3]"}]}, 691 {"type":"function","name":"balance","constant":true}, 692 {"type":"function","name":"send","constant":false,"inputs":[{"name":"amount","type":"uint256"}]}, 693 {"type":"function","name":"test","constant":false,"inputs":[{"name":"number","type":"uint32"}]}, 694 {"type":"function","name":"string","constant":false,"inputs":[{"name":"inputs","type":"string"}]}, 695 {"type":"function","name":"bool","constant":false,"inputs":[{"name":"inputs","type":"bool"}]}, 696 {"type":"function","name":"address","constant":false,"inputs":[{"name":"inputs","type":"address"}]}, 697 {"type":"function","name":"uint64[2]","constant":false,"inputs":[{"name":"inputs","type":"uint64[2]"}]}, 698 {"type":"function","name":"uint64[]","constant":false,"inputs":[{"name":"inputs","type":"uint64[]"}]}, 699 {"type":"function","name":"foo","constant":false,"inputs":[{"name":"inputs","type":"uint32"}]}, 700 {"type":"function","name":"bar","constant":false,"inputs":[{"name":"inputs","type":"uint32"},{"name":"string","type":"uint16"}]}, 701 {"type":"function","name":"_slice","constant":false,"inputs":[{"name":"inputs","type":"uint32[2]"}]}, 702 {"type":"function","name":"__slice256","constant":false,"inputs":[{"name":"inputs","type":"uint256[2]"}]}, 703 {"type":"function","name":"sliceAddress","constant":false,"inputs":[{"name":"inputs","type":"address[]"}]}, 704 {"type":"function","name":"sliceMultiAddress","constant":false,"inputs":[{"name":"a","type":"address[]"},{"name":"b","type":"address[]"}]} 705 ] 706 ` 707 abi, err := JSON(strings.NewReader(abiJSON)) 708 if err != nil { 709 t.Fatal(err) 710 } 711 for name, m := range abi.Methods { 712 a := fmt.Sprintf("%v", m) 713 m2, err := abi.MethodById(m.Id()) 714 if err != nil { 715 t.Fatalf("Failed to look up ABI method: %v", err) 716 } 717 b := fmt.Sprintf("%v", m2) 718 if a != b { 719 t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, common.ToHex(m.Id())) 720 } 721 } 722 723 }