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