github.com/ethereum/go-ethereum@v1.16.1/accounts/abi/pack_test.go (about)

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