github.com/ava-labs/subnet-evm@v0.6.4/accounts/abi/abi_extra_test.go (about) 1 // (c) 2023, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package abi 5 6 import ( 7 "bytes" 8 "math/big" 9 "strings" 10 "testing" 11 12 "github.com/ethereum/go-ethereum/common" 13 "github.com/stretchr/testify/require" 14 ) 15 16 // Note: This file contains tests in addition to those found in go-ethereum. 17 18 const TEST_ABI = `[{"type":"function","name":"receive","inputs":[{"name":"sender","type":"address"},{"name":"amount","type":"uint256"},{"name":"memo","type":"bytes"}],"outputs":[{"internalType":"bool","name":"isAllowed","type":"bool"}]}]` 19 20 func TestUnpackInputIntoInterface(t *testing.T) { 21 abi, err := JSON(strings.NewReader(TEST_ABI)) 22 require.NoError(t, err) 23 24 type inputType struct { 25 Sender common.Address 26 Amount *big.Int 27 Memo []byte 28 } 29 input := inputType{ 30 Sender: common.HexToAddress("0x02"), 31 Amount: big.NewInt(100), 32 Memo: []byte("hello"), 33 } 34 35 rawData, err := abi.Pack("receive", input.Sender, input.Amount, input.Memo) 36 require.NoError(t, err) 37 38 abi, err = JSON(strings.NewReader(TEST_ABI)) 39 require.NoError(t, err) 40 41 for _, test := range []struct { 42 name string 43 extraPaddingBytes int 44 strictMode bool 45 expectedErrorSubstring string 46 }{ 47 { 48 name: "No extra padding to input data", 49 strictMode: true, 50 }, 51 { 52 name: "Valid input data with 32 extra padding(%32) ", 53 extraPaddingBytes: 32, 54 strictMode: true, 55 }, 56 { 57 name: "Valid input data with 64 extra padding(%32)", 58 extraPaddingBytes: 64, 59 strictMode: true, 60 }, 61 { 62 name: "Valid input data with extra padding indivisible by 32", 63 extraPaddingBytes: 33, 64 strictMode: true, 65 expectedErrorSubstring: "abi: improperly formatted input:", 66 }, 67 { 68 name: "Valid input data with extra padding indivisible by 32, no strict mode", 69 extraPaddingBytes: 33, 70 strictMode: false, 71 }, 72 } { 73 { 74 t.Run(test.name, func(t *testing.T) { 75 // skip 4 byte selector 76 data := rawData[4:] 77 // Add extra padding to data 78 data = append(data, make([]byte, test.extraPaddingBytes)...) 79 80 // Unpack into interface 81 var v inputType 82 err = abi.UnpackInputIntoInterface(&v, "receive", data, test.strictMode) // skips 4 byte selector 83 84 if test.expectedErrorSubstring != "" { 85 require.Error(t, err) 86 require.ErrorContains(t, err, test.expectedErrorSubstring) 87 } else { 88 require.NoError(t, err) 89 // Verify unpacked values match input 90 require.Equal(t, v.Amount, input.Amount) 91 require.EqualValues(t, v.Amount, input.Amount) 92 require.True(t, bytes.Equal(v.Memo, input.Memo)) 93 } 94 }) 95 } 96 } 97 } 98 99 func TestPackOutput(t *testing.T) { 100 abi, err := JSON(strings.NewReader(TEST_ABI)) 101 require.NoError(t, err) 102 103 bytes, err := abi.PackOutput("receive", true) 104 require.NoError(t, err) 105 106 vals, err := abi.Methods["receive"].Outputs.Unpack(bytes) 107 require.NoError(t, err) 108 109 require.Len(t, vals, 1) 110 require.True(t, vals[0].(bool)) 111 }