github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/cmd/contract/contract_test.go (about)

     1  // Copyright (c) 2020 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package contract
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"math/big"
    12  	"testing"
    13  
    14  	"github.com/ethereum/go-ethereum/accounts/abi"
    15  	"github.com/ethereum/go-ethereum/common"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestParseAbiFile(t *testing.T) {
    20  	r := require.New(t)
    21  	testAbiFile := "test.abi"
    22  	abi, err := readAbiFile(testAbiFile)
    23  	r.NoError(err)
    24  	r.Equal("", abi.Constructor.Name)
    25  	r.Equal(10, len(abi.Methods))
    26  	r.Equal("recipients", abi.Methods["multiSend"].Inputs[0].Name)
    27  }
    28  
    29  func TestParseInput(t *testing.T) {
    30  	r := require.New(t)
    31  
    32  	testAbiFile := "test.abi"
    33  	testAbi, err := readAbiFile(testAbiFile)
    34  	r.NoError(err)
    35  
    36  	tests := []struct {
    37  		expectCode string
    38  		method     string
    39  		inputs     string
    40  	}{
    41  		{
    42  			"0xe3b48f48000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b9c46db7b8464bad383a595fd7aa7845fbdd642b000000000000000000000000aa77fbf8596e0de5ce362dbd5ab29599a6c38ac4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000002fa7bc000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000009504c454153452121210000000000000000000000000000000000000000000000",
    43  			"multiSend",
    44  			`{"recipients":["io1h8zxmdacge966wp6t90a02ncghaa6eptnftfqr","io14fmlh7zedcx7tn3k9k744v54nxnv8zky86tjhj"],"amounts":["3123132","123"],"payload":"PLEASE!!!"}`,
    45  		}, {
    46  			"0xba025b7100000000000000000000000000000000000000011ade48e4922161024e211c62000000000000000000000000000000000000000000000000000000000001e0f30000000000000000000000000000000000000000000000000000000000000005fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf0d2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000",
    47  			"testArray",
    48  			// IntTy/UintTy larger than int64/uint64 should be passes by string, otherwise the precision losses
    49  			`{"a":["87543498528347976543703735394",123123,5,-12,-134958],"b":[1,2,0]}`,
    50  		}, {
    51  			"0x3ca8b1a70000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001007a675668798ab73482982748287842900000000000000000000000000000000",
    52  			"testBytes",
    53  			`{"t":"0x07a675668798ab734829827482878429"}`,
    54  		}, {
    55  			"0x901e5dda1221120000000000000000000000000000000000000000000000000000000000",
    56  			"testFixedBytes",
    57  			`{"t":"0x122112"}`,
    58  		}, {
    59  			"0x1bfc56c6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010496f54655820426c6f636b636861696e00000000000000000000000000000000",
    60  			"testBoolAndString",
    61  			`{"a":true,"s":"IoTeX Blockchain"}`,
    62  		},
    63  	}
    64  
    65  	for _, test := range tests {
    66  		expect, err := decodeBytecode(test.expectCode)
    67  		r.NoError(err)
    68  
    69  		bytecode, err := packArguments(testAbi, test.method, test.inputs)
    70  		r.NoError(err)
    71  
    72  		r.True(bytes.Equal(expect, bytecode))
    73  	}
    74  }
    75  
    76  func TestParseOutput(t *testing.T) {
    77  	r := require.New(t)
    78  
    79  	testAbiFile := "test.abi"
    80  	testAbi, err := readAbiFile(testAbiFile)
    81  	r.NoError(err)
    82  
    83  	tests := []struct {
    84  		expectResult string
    85  		method       string
    86  		outputs      string
    87  	}{
    88  		{
    89  			"0",
    90  			"minTips",
    91  			"0000000000000000000000000000000000000000000000000000000000000000",
    92  		},
    93  		{
    94  			"io1cl6rl2ev5dfa988qmgzg2x4hfazmp9vn2g66ng",
    95  			"owner",
    96  			"000000000000000000000000c7f43fab2ca353d29ce0da04851ab74f45b09593",
    97  		},
    98  		{
    99  			"Hello World",
   100  			"getMessage",
   101  			"0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b48656c6c6f20576f726c64000000000000000000000000000000000000000000",
   102  		},
   103  		{
   104  			"{i:17 abc:[io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqd39ym7 io1cl6rl2ev5dfa988qmgzg2x4hfazmp9vn2g66ng]}",
   105  			"testTuple",
   106  			"00000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7f43fab2ca353d29ce0da04851ab74f45b09593",
   107  		},
   108  	}
   109  
   110  	for _, test := range tests {
   111  		v, err := ParseOutput(testAbi, test.method, test.outputs)
   112  		r.NoError(err)
   113  		r.Equal(test.expectResult, fmt.Sprint(v))
   114  	}
   115  }
   116  
   117  func TestParseOutputArgument(t *testing.T) {
   118  	r := require.New(t)
   119  
   120  	bigInt, _ := new(big.Int).SetString("2346783498523230921101011", 10)
   121  	var bytes31 [31]byte
   122  	var bytes24 [24]byte
   123  	copy(bytes31[:], "test byte31313131313131313131")
   124  	copy(bytes24[:], "test function (=24-byte)")
   125  
   126  	tests := []struct {
   127  		v          interface{}
   128  		t          string
   129  		components []abi.ArgumentMarshaling
   130  		expect     string
   131  	}{
   132  		{
   133  			int16(-3),
   134  			"int16",
   135  			nil,
   136  			"-3",
   137  		},
   138  		{
   139  			uint64(98237478346),
   140  			"uint64",
   141  			nil,
   142  			"98237478346",
   143  		},
   144  		{
   145  			bigInt,
   146  			"uint233",
   147  			nil,
   148  			"2346783498523230921101011",
   149  		},
   150  		{
   151  			common.HexToAddress("c7F43FaB2ca353d29cE0DA04851aB74f45B09593"),
   152  			"address",
   153  			nil,
   154  			"io1cl6rl2ev5dfa988qmgzg2x4hfazmp9vn2g66ng",
   155  		},
   156  		{
   157  			[]byte("test bytes"),
   158  			"bytes",
   159  			nil,
   160  			"0x74657374206279746573",
   161  		},
   162  		{
   163  			bytes31,
   164  			"bytes31",
   165  			nil,
   166  			"0x74657374206279746533313331333133313331333133313331333133310000",
   167  		},
   168  		{
   169  			[5]string{"IoTeX blockchain", "Raullen", "MenloPark", "2020/06/13", "Frank-is-testing!"},
   170  			"string[5]",
   171  			nil,
   172  			"[IoTeX blockchain Raullen MenloPark 2020/06/13 Frank-is-testing!]",
   173  		},
   174  		{
   175  			[][31]byte{bytes31, bytes31},
   176  			"bytes31[]",
   177  			nil,
   178  			"[0x74657374206279746533313331333133313331333133313331333133310000 0x74657374206279746533313331333133313331333133313331333133310000]",
   179  		},
   180  		{
   181  			struct {
   182  				A string
   183  				B [24]byte
   184  				C []*big.Int
   185  			}{"tuple test!", bytes24, []*big.Int{big.NewInt(-123), bigInt, big.NewInt(0)}},
   186  			"tuple",
   187  			[]abi.ArgumentMarshaling{{Name: "a", Type: "string"}, {Name: "b", Type: "bytes24"}, {Name: "c", Type: "int256[]"}},
   188  			"{a:tuple test! b:0x746573742066756e6374696f6e20283d32342d6279746529 c:[-123 2346783498523230921101011 0]}",
   189  		},
   190  	}
   191  
   192  	for _, test := range tests {
   193  		t, err := abi.NewType(test.t, "", test.components)
   194  		r.NoError(err)
   195  		result, ok := parseOutputArgument(test.v, &t)
   196  		r.True(ok)
   197  		r.Equal(test.expect, result)
   198  	}
   199  }