github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/signer/core/abihelper_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  //版权所有2018 Go Ethereum作者
    10  //此文件是Go以太坊的一部分。
    11  //
    12  //Go以太坊是免费软件:您可以重新发布和/或修改它
    13  //根据GNU通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊的分布希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU通用公共许可证了解更多详细信息。
    21  //
    22  //你应该已经收到一份GNU通用公共许可证的副本
    23  //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package core
    26  
    27  import (
    28  	"fmt"
    29  	"strings"
    30  	"testing"
    31  
    32  	"io/ioutil"
    33  	"math/big"
    34  	"reflect"
    35  
    36  	"github.com/ethereum/go-ethereum/accounts/abi"
    37  	"github.com/ethereum/go-ethereum/common"
    38  )
    39  
    40  func verify(t *testing.T, jsondata, calldata string, exp []interface{}) {
    41  
    42  	abispec, err := abi.JSON(strings.NewReader(jsondata))
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	cd := common.Hex2Bytes(calldata)
    47  	sigdata, argdata := cd[:4], cd[4:]
    48  	method, err := abispec.MethodById(sigdata)
    49  
    50  	if err != nil {
    51  		t.Fatal(err)
    52  	}
    53  
    54  	data, err := method.Inputs.UnpackValues(argdata)
    55  
    56  	if len(data) != len(exp) {
    57  		t.Fatalf("Mismatched length, expected %d, got %d", len(exp), len(data))
    58  	}
    59  	for i, elem := range data {
    60  		if !reflect.DeepEqual(elem, exp[i]) {
    61  			t.Fatalf("Unpack error, arg %d, got %v, want %v", i, elem, exp[i])
    62  		}
    63  	}
    64  }
    65  func TestNewUnpacker(t *testing.T) {
    66  	type unpackTest struct {
    67  		jsondata string
    68  		calldata string
    69  		exp      []interface{}
    70  	}
    71  	testcases := []unpackTest{
    72  { //https://solidity.readthedocs.io/en/develop/abi-spec.html使用动态类型
    73  			`[{"type":"function","name":"f", "inputs":[{"type":"uint256"},{"type":"uint32[]"},{"type":"bytes10"},{"type":"bytes"}]}]`,
    74  //0x123,[0x456,0x789],“1234567890”,“你好,世界!”
    75  			"8be65246" + "00000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000",
    76  			[]interface{}{
    77  				big.NewInt(0x123),
    78  				[]uint32{0x456, 0x789},
    79  				[10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48},
    80  				common.Hex2Bytes("48656c6c6f2c20776f726c6421"),
    81  			},
    82  }, { //https://github.com/ethereum/wiki/wiki/ethereum contract abi示例
    83  			`[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`,
    84  //“Dave”,真的和[1,2,3]
    85  			"a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
    86  			[]interface{}{
    87  				[]byte{0x64, 0x61, 0x76, 0x65},
    88  				true,
    89  				[]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
    90  			},
    91  		}, {
    92  			`[{"type":"function","name":"send","inputs":[{"type":"uint256"}]}]`,
    93  			"a52c101e0000000000000000000000000000000000000000000000000000000000000012",
    94  			[]interface{}{big.NewInt(0x12)},
    95  		}, {
    96  			`[{"type":"function","name":"compareAndApprove","inputs":[{"type":"address"},{"type":"uint256"},{"type":"uint256"}]}]`,
    97  			"751e107900000000000000000000000000000133700000deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
    98  			[]interface{}{
    99  				common.HexToAddress("0x00000133700000deadbeef000000000000000000"),
   100  				new(big.Int).SetBytes([]byte{0x00}),
   101  				big.NewInt(0x1),
   102  			},
   103  		},
   104  	}
   105  	for _, c := range testcases {
   106  		verify(t, c.jsondata, c.calldata, c.exp)
   107  	}
   108  
   109  }
   110  
   111  /*
   112  func测试反射(t*testing.t)
   113   A:=big.newint(0)
   114   b:=new(big.int).setbytes([]字节0x00)
   115   如果!反射。深度(A,B)
   116    t.fatalf(“不,%v!= %V“,A,B”
   117   }
   118  }
   119  **/
   120  
   121  
   122  func TestCalldataDecoding(t *testing.T) {
   123  
   124  //发送(uint256):a52c101e
   125  //比较数据证明(地址,uint256,uint256):751E1079
   126  //问题(地址[],uint256):42958b54
   127  	jsondata := `
   128  [
   129  	{"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]},
   130  	{"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]},
   131  	{"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]},
   132  	{"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]}
   133  ]`
   134  //预期故障
   135  	for _, hexdata := range []string{
   136  		"a52c101e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
   137  		"a52c101e000000000000000000000000000000000000000000000000000000000000001200",
   138  		"a52c101e00000000000000000000000000000000000000000000000000000000000000",
   139  		"a52c101e",
   140  		"a52c10",
   141  		"",
   142  //太短
   143  		"751e10790000000000000000000000000000000000000000000000000000000000000012",
   144  		"751e1079FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
   145  //不是32的有效倍数
   146  		"deadbeef00000000000000000000000000000000000000000000000000000000000000",
   147  //
   148  		"42958b5400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
   149  //比较过短,不适用
   150  		"a52c101e00ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
   151  //来自https://github.com/ethereum/wiki/wiki/ethereum-contract-abi
   152  //包含具有非法值的bool
   153  		"a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
   154  	} {
   155  		_, err := parseCallData(common.Hex2Bytes(hexdata), jsondata)
   156  		if err == nil {
   157  			t.Errorf("Expected decoding to fail: %s", hexdata)
   158  		}
   159  	}
   160  
   161  //预期成功
   162  	for _, hexdata := range []string{
   163  //来自https://github.com/ethereum/wiki/wiki/ethereum-contract-abi
   164  		"a5643bf20000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
   165  		"a52c101e0000000000000000000000000000000000000000000000000000000000000012",
   166  		"a52c101eFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
   167  		"751e1079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   168  		"42958b54" +
   169  //动态类型的开始
   170  			"0000000000000000000000000000000000000000000000000000000000000040" +
   171  //UIT2525
   172  			"0000000000000000000000000000000000000000000000000000000000000001" +
   173  //阵列长度
   174  			"0000000000000000000000000000000000000000000000000000000000000002" +
   175  //数组值
   176  			"000000000000000000000000000000000000000000000000000000000000dead" +
   177  			"000000000000000000000000000000000000000000000000000000000000beef",
   178  	} {
   179  		_, err := parseCallData(common.Hex2Bytes(hexdata), jsondata)
   180  		if err != nil {
   181  			t.Errorf("Unexpected failure on input %s:\n %v (%d bytes) ", hexdata, err, len(common.Hex2Bytes(hexdata)))
   182  		}
   183  	}
   184  }
   185  
   186  func TestSelectorUnmarshalling(t *testing.T) {
   187  	var (
   188  		db        *AbiDb
   189  		err       error
   190  		abistring []byte
   191  		abistruct abi.ABI
   192  	)
   193  
   194  	db, err = NewAbiDBFromFile("../../cmd/clef/4byte.json")
   195  	if err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	fmt.Printf("DB size %v\n", db.Size())
   199  	for id, selector := range db.db {
   200  
   201  		abistring, err = MethodSelectorToAbi(selector)
   202  		if err != nil {
   203  			t.Error(err)
   204  			return
   205  		}
   206  		abistruct, err = abi.JSON(strings.NewReader(string(abistring)))
   207  		if err != nil {
   208  			t.Error(err)
   209  			return
   210  		}
   211  		m, err := abistruct.MethodById(common.Hex2Bytes(id[2:]))
   212  		if err != nil {
   213  			t.Error(err)
   214  			return
   215  		}
   216  		if m.Sig() != selector {
   217  			t.Errorf("Expected equality: %v != %v", m.Sig(), selector)
   218  		}
   219  	}
   220  
   221  }
   222  
   223  func TestCustomABI(t *testing.T) {
   224  	d, err := ioutil.TempDir("", "signer-4byte-test")
   225  	if err != nil {
   226  		t.Fatal(err)
   227  	}
   228  	filename := fmt.Sprintf("%s/4byte_custom.json", d)
   229  	abidb, err := NewAbiDBFromFiles("../../cmd/clef/4byte.json", filename)
   230  	if err != nil {
   231  		t.Fatal(err)
   232  	}
   233  //现在我们将删除所有现有签名
   234  	abidb.db = make(map[string]string)
   235  	calldata := common.Hex2Bytes("a52c101edeadbeef")
   236  	_, err = abidb.LookupMethodSelector(calldata)
   237  	if err == nil {
   238  		t.Fatalf("Should not find a match on empty db")
   239  	}
   240  	if err = abidb.AddSignature("send(uint256)", calldata); err != nil {
   241  		t.Fatalf("Failed to save file: %v", err)
   242  	}
   243  	_, err = abidb.LookupMethodSelector(calldata)
   244  	if err != nil {
   245  		t.Fatalf("Should find a match for abi signature, got: %v", err)
   246  	}
   247  //检查它是否写入文件
   248  	abidb2, err := NewAbiDBFromFile(filename)
   249  	if err != nil {
   250  		t.Fatalf("Failed to create new abidb: %v", err)
   251  	}
   252  	_, err = abidb2.LookupMethodSelector(calldata)
   253  	if err != nil {
   254  		t.Fatalf("Save failed: should find a match for abi signature after loading from disk")
   255  	}
   256  }