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