github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/signer/fourbyte/abi_test.go (about)

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