github.com/core-coin/go-core/v2@v2.1.9/signer/fourbyte/abi_test.go (about)

     1  // Copyright 2019 by the Authors
     2  // This file is part of the go-core library.
     3  //
     4  // The go-core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-core library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package fourbyte
    18  
    19  import (
    20  	"math/big"
    21  	"reflect"
    22  	"strings"
    23  	"testing"
    24  
    25  	"github.com/core-coin/go-core/v2/accounts/abi"
    26  	"github.com/core-coin/go-core/v2/common"
    27  )
    28  
    29  func verify(t *testing.T, jsondata, calldata string, exp []interface{}) {
    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  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	data, err := method.Inputs.UnpackValues(argdata)
    41  	if err != nil {
    42  		t.Fatal(err)
    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  
    54  func TestNewUnpacker(t *testing.T) {
    55  	type unpackTest struct {
    56  		jsondata string
    57  		calldata string
    58  		exp      []interface{}
    59  	}
    60  	addr, err := common.HexToAddress("cb4900000133700000deadbeef000000000000000000")
    61  	if err != nil {
    62  		t.Error(err)
    63  	}
    64  	testcases := []unpackTest{
    65  		{ // https://ylem.readthedocs.io/en/develop/abi-spec.html#use-of-dynamic-types
    66  			`[{"type":"function","name":"f", "inputs":[{"type":"uint256"},{"type":"uint32[]"},{"type":"bytes10"},{"type":"bytes"}]}]`,
    67  			// 0x123, [0x456, 0x789], "1234567890", "Hello, world!"
    68  			"41cc790900000000000000000000000000000000000000000000000000000000000001230000000000000000000000000000000000000000000000000000000000000080313233343536373839300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004560000000000000000000000000000000000000000000000000000000000000789000000000000000000000000000000000000000000000000000000000000000d48656c6c6f2c20776f726c642100000000000000000000000000000000000000",
    69  			[]interface{}{
    70  				big.NewInt(0x123),
    71  				[]uint32{0x456, 0x789},
    72  				[10]byte{49, 50, 51, 52, 53, 54, 55, 56, 57, 48},
    73  				common.Hex2Bytes("48656c6c6f2c20776f726c6421"),
    74  			},
    75  		},
    76  		{ // https://github.com/core/wiki/wiki/Core-Contract-ABI#examples
    77  			`[{"type":"function","name":"sam","inputs":[{"type":"bytes"},{"type":"bool"},{"type":"uint256[]"}]}]`,
    78  			//  "dave", true and [1,2,3]
    79  			"cf3d9ff50000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000464617665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
    80  			[]interface{}{
    81  				[]byte{0x64, 0x61, 0x76, 0x65},
    82  				true,
    83  				[]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
    84  			},
    85  		},
    86  		{
    87  			`[{"type":"function","name":"send","inputs":[{"type":"uint256"}]}]`,
    88  			"e10c92510000000000000000000000000000000000000000000000000000000000000012",
    89  			[]interface{}{big.NewInt(0x12)},
    90  		},
    91  		{
    92  			`[{"type":"function","name":"compareAndApprove","inputs":[{"type":"address"},{"type":"uint256"},{"type":"uint256"}]}]`,
    93  			"db33183a00000000000000000000cb4900000133700000deadbeef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
    94  			[]interface{}{
    95  				addr,
    96  				new(big.Int).SetBytes([]byte{0x00}),
    97  				big.NewInt(0x1),
    98  			},
    99  		},
   100  	}
   101  	for _, c := range testcases {
   102  		verify(t, c.jsondata, c.calldata, c.exp)
   103  	}
   104  }
   105  
   106  func TestCalldataDecoding(t *testing.T) {
   107  	// send(uint256)                              : e10c9251
   108  	// compareAndApprove(address,uint256,uint256) : db33183a
   109  	// issue(address[],uint256)                   : 649cfa14
   110  	jsondata := `
   111  [
   112  	{"type":"function","name":"send","inputs":[{"name":"a","type":"uint256"}]},
   113  	{"type":"function","name":"compareAndApprove","inputs":[{"name":"a","type":"address"},{"name":"a","type":"uint256"},{"name":"a","type":"uint256"}]},
   114  	{"type":"function","name":"issue","inputs":[{"name":"a","type":"address[]"},{"name":"a","type":"uint256"}]},
   115  	{"type":"function","name":"sam","inputs":[{"name":"a","type":"bytes"},{"name":"a","type":"bool"},{"name":"a","type":"uint256[]"}]}
   116  ]`
   117  	// Expected failures
   118  	for i, hexdata := range []string{
   119  		"e10c925100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
   120  		"e10c9251000000000000000000000000000000000000000000000000000000000000001200",
   121  		"e10c925100000000000000000000000000000000000000000000000000000000000000",
   122  		"e10c9251",
   123  		"a52c10",
   124  		"",
   125  		// Too short
   126  		"db33183a0000000000000000000000000000000000000000000000000000000000000012",
   127  		"db33183aFFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
   128  		// Not valid multiple of 32
   129  		"deadbeef00000000000000000000000000000000000000000000000000000000000000",
   130  		// Too short 'issue'
   131  		"649cfa1400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
   132  		// Too short compareAndApprove
   133  		"e10c925100ff0000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000042",
   134  	} {
   135  		_, err := parseCallData(common.Hex2Bytes(hexdata), jsondata)
   136  		if err == nil {
   137  			t.Errorf("test %d: expected decoding to fail: %s", i, hexdata)
   138  		}
   139  	}
   140  	// Expected success
   141  	for i, hexdata := range []string{
   142  		// From https://github.com/core/wiki/wiki/Core-Contract-ABI
   143  		"e10c92510000000000000000000000000000000000000000000000000000000000000012",
   144  		"e10c9251FFffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
   145  		"db33183a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   146  		"649cfa14" +
   147  			// start of dynamic type
   148  			"0000000000000000000000000000000000000000000000000000000000000040" +
   149  			// uint256
   150  			"0000000000000000000000000000000000000000000000000000000000000001" +
   151  			// length of  array
   152  			"0000000000000000000000000000000000000000000000000000000000000002" +
   153  			// array values
   154  			"000000000000000000000000000000000000000000000000000000000000dead" +
   155  			"000000000000000000000000000000000000000000000000000000000000beef",
   156  	} {
   157  		_, err := parseCallData(common.Hex2Bytes(hexdata), jsondata)
   158  		if err != nil {
   159  			t.Errorf("test %d: unexpected failure on input %s:\n %v (%d bytes) ", i, hexdata, err, len(common.Hex2Bytes(hexdata)))
   160  		}
   161  	}
   162  }
   163  
   164  func TestMaliciousABIStrings(t *testing.T) {
   165  	tests := []string{
   166  		"func(uint256,uint256,[]uint256)",
   167  		"func(uint256,uint256,uint256,)",
   168  		"func(,uint256,uint256,uint256)",
   169  	}
   170  	data := common.Hex2Bytes("4401a6e40000000000000000000000000000000000000000000000000000000000000012")
   171  	for i, tt := range tests {
   172  		_, err := verifySelector(tt, data)
   173  		if err == nil {
   174  			t.Errorf("test %d: expected error for selector '%v'", i, tt)
   175  		}
   176  	}
   177  }