github.com/klaytn/klaytn@v1.10.2/accounts/abi/pack_test.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2017 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from accounts/abi/pack_test.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package abi
    22  
    23  import (
    24  	"bytes"
    25  	"encoding/hex"
    26  	"fmt"
    27  	"math"
    28  	"math/big"
    29  	"reflect"
    30  	"strconv"
    31  	"strings"
    32  	"testing"
    33  
    34  	"github.com/klaytn/klaytn/common"
    35  )
    36  
    37  // TestPack tests the general pack/unpack tests in packing_test.go
    38  func TestPack(t *testing.T) {
    39  	for i, test := range packUnpackTests {
    40  		t.Run(strconv.Itoa(i), func(t *testing.T) {
    41  			encb, err := hex.DecodeString(test.packed)
    42  			if err != nil {
    43  				t.Fatalf("invalid hex %s: %v", test.packed, err)
    44  			}
    45  			inDef := fmt.Sprintf(`[{ "name" : "method", "type": "function", "inputs": %s}]`, test.def)
    46  			inAbi, err := JSON(strings.NewReader(inDef))
    47  			if err != nil {
    48  				t.Fatalf("invalid ABI definition %s, %v", inDef, err)
    49  			}
    50  			var packed []byte
    51  			if reflect.TypeOf(test.unpacked).Kind() != reflect.Struct {
    52  				packed, err = inAbi.Pack("method", test.unpacked)
    53  			} else {
    54  				// if want is a struct we need to use the components.
    55  				elem := reflect.ValueOf(test.unpacked)
    56  				var values []interface{}
    57  				for i := 0; i < elem.NumField(); i++ {
    58  					field := elem.Field(i)
    59  					values = append(values, field.Interface())
    60  				}
    61  				packed, err = inAbi.Pack("method", values...)
    62  			}
    63  
    64  			if err != nil {
    65  				t.Fatalf("test %d (%v) failed: %v", i, test.def, err)
    66  			}
    67  			if !reflect.DeepEqual(packed[4:], encb) {
    68  				t.Errorf("test %d (%v) failed: expected %x, got %x", i, test.def, encb, packed[4:])
    69  			}
    70  		})
    71  	}
    72  }
    73  
    74  func TestMethodPack(t *testing.T) {
    75  	abi, err := JSON(strings.NewReader(jsondata))
    76  	if err != nil {
    77  		t.Fatal(err)
    78  	}
    79  
    80  	sig := abi.Methods["slice"].ID
    81  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
    82  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
    83  
    84  	packed, err := abi.Pack("slice", []uint32{1, 2})
    85  	if err != nil {
    86  		t.Error(err)
    87  	}
    88  
    89  	if !bytes.Equal(packed, sig) {
    90  		t.Errorf("expected %x got %x", sig, packed)
    91  	}
    92  
    93  	addrA, addrB := common.Address{1}, common.Address{2}
    94  	sig = abi.Methods["sliceAddress"].ID
    95  	sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...)
    96  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
    97  	sig = append(sig, common.LeftPadBytes(addrA[:], 32)...)
    98  	sig = append(sig, common.LeftPadBytes(addrB[:], 32)...)
    99  
   100  	packed, err = abi.Pack("sliceAddress", []common.Address{addrA, addrB})
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  	if !bytes.Equal(packed, sig) {
   105  		t.Errorf("expected %x got %x", sig, packed)
   106  	}
   107  
   108  	addrC, addrD := common.Address{3}, common.Address{4}
   109  	sig = abi.Methods["sliceMultiAddress"].ID
   110  	sig = append(sig, common.LeftPadBytes([]byte{64}, 32)...)
   111  	sig = append(sig, common.LeftPadBytes([]byte{160}, 32)...)
   112  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   113  	sig = append(sig, common.LeftPadBytes(addrA[:], 32)...)
   114  	sig = append(sig, common.LeftPadBytes(addrB[:], 32)...)
   115  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   116  	sig = append(sig, common.LeftPadBytes(addrC[:], 32)...)
   117  	sig = append(sig, common.LeftPadBytes(addrD[:], 32)...)
   118  
   119  	packed, err = abi.Pack("sliceMultiAddress", []common.Address{addrA, addrB}, []common.Address{addrC, addrD})
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	if !bytes.Equal(packed, sig) {
   124  		t.Errorf("expected %x got %x", sig, packed)
   125  	}
   126  
   127  	sig = abi.Methods["slice256"].ID
   128  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   129  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   130  
   131  	packed, err = abi.Pack("slice256", []*big.Int{big.NewInt(1), big.NewInt(2)})
   132  	if err != nil {
   133  		t.Error(err)
   134  	}
   135  
   136  	if !bytes.Equal(packed, sig) {
   137  		t.Errorf("expected %x got %x", sig, packed)
   138  	}
   139  
   140  	a := [2][2]*big.Int{{big.NewInt(1), big.NewInt(1)}, {big.NewInt(2), big.NewInt(0)}}
   141  	sig = abi.Methods["nestedArray"].ID
   142  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   143  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   144  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   145  	sig = append(sig, common.LeftPadBytes([]byte{0}, 32)...)
   146  	sig = append(sig, common.LeftPadBytes([]byte{0xa0}, 32)...)
   147  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   148  	sig = append(sig, common.LeftPadBytes(addrC[:], 32)...)
   149  	sig = append(sig, common.LeftPadBytes(addrD[:], 32)...)
   150  	packed, err = abi.Pack("nestedArray", a, []common.Address{addrC, addrD})
   151  	if err != nil {
   152  		t.Fatal(err)
   153  	}
   154  	if !bytes.Equal(packed, sig) {
   155  		t.Errorf("expected %x got %x", sig, packed)
   156  	}
   157  
   158  	sig = abi.Methods["nestedArray2"].ID
   159  	sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...)
   160  	sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...)
   161  	sig = append(sig, common.LeftPadBytes([]byte{0x80}, 32)...)
   162  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   163  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   164  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   165  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   166  	packed, err = abi.Pack("nestedArray2", [2][]uint8{{1}, {1}})
   167  	if err != nil {
   168  		t.Fatal(err)
   169  	}
   170  	if !bytes.Equal(packed, sig) {
   171  		t.Errorf("expected %x got %x", sig, packed)
   172  	}
   173  
   174  	sig = abi.Methods["nestedSlice"].ID
   175  	sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...)
   176  	sig = append(sig, common.LeftPadBytes([]byte{0x02}, 32)...)
   177  	sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...)
   178  	sig = append(sig, common.LeftPadBytes([]byte{0xa0}, 32)...)
   179  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   180  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   181  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   182  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   183  	sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...)
   184  	sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...)
   185  	packed, err = abi.Pack("nestedSlice", [][]uint8{{1, 2}, {1, 2}})
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  	if !bytes.Equal(packed, sig) {
   190  		t.Errorf("expected %x got %x", sig, packed)
   191  	}
   192  }
   193  
   194  func TestPackNumber(t *testing.T) {
   195  	tests := []struct {
   196  		value  reflect.Value
   197  		packed []byte
   198  	}{
   199  		// Protocol limits
   200  		{reflect.ValueOf(0), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")},
   201  		{reflect.ValueOf(1), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")},
   202  		{reflect.ValueOf(-1), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")},
   203  
   204  		// Type corner cases
   205  		{reflect.ValueOf(uint8(math.MaxUint8)), common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000ff")},
   206  		{reflect.ValueOf(uint16(math.MaxUint16)), common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000ffff")},
   207  		{reflect.ValueOf(uint32(math.MaxUint32)), common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000ffffffff")},
   208  		{reflect.ValueOf(uint64(math.MaxUint64)), common.Hex2Bytes("000000000000000000000000000000000000000000000000ffffffffffffffff")},
   209  
   210  		{reflect.ValueOf(int8(math.MaxInt8)), common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000007f")},
   211  		{reflect.ValueOf(int16(math.MaxInt16)), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000007fff")},
   212  		{reflect.ValueOf(int32(math.MaxInt32)), common.Hex2Bytes("000000000000000000000000000000000000000000000000000000007fffffff")},
   213  		{reflect.ValueOf(int64(math.MaxInt64)), common.Hex2Bytes("0000000000000000000000000000000000000000000000007fffffffffffffff")},
   214  
   215  		{reflect.ValueOf(int8(math.MinInt8)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80")},
   216  		{reflect.ValueOf(int16(math.MinInt16)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000")},
   217  		{reflect.ValueOf(int32(math.MinInt32)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000")},
   218  		{reflect.ValueOf(int64(math.MinInt64)), common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000")},
   219  	}
   220  	for i, tt := range tests {
   221  		packed := packNum(tt.value)
   222  		if !bytes.Equal(packed, tt.packed) {
   223  			t.Errorf("test %d: pack mismatch: have %x, want %x", i, packed, tt.packed)
   224  		}
   225  	}
   226  }