encode nested tuple error
Closed this issue · 1 comments
0xfaceDEFI commented
code
import (
"fmt"
"github.com/umbracle/ethgo"
"github.com/umbracle/ethgo/abi"
"github.com/umbracle/ethgo/contract"
"github.com/umbracle/ethgo/jsonrpc"
"github.com/umbracle/ethgo/wallet"
"math/big"
"testing"
)
type SwapParams struct {
PoolID [32]byte
Kind *big.Int
AssertIn string
AssertOut string
Amount *big.Int
UserData []byte
}
type FunderParams struct {
Sender string
FromInternalBalance bool
Recipient string
ToInternalBalance bool
}
func MethodEncode(function string, args ...interface{}) ([]byte, error) {
method, err := abi.NewMethod(function)
if err != nil {
return nil, err
}
data, err := method.Encode(args)
if err != nil {
return nil, err
}
return data, nil
}
func TestEncodeNestedTuple(t *testing.T) {
poolID := [32]byte{}
copy(poolID[:], "0xf3946a0e5368f716b1f40586272c9066b419035c000200000000000000000424")
swapParams := SwapParams{
PoolID: poolID,
Kind: big.NewInt(0),
AssertIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
AssertOut: "0xfd0205066521550D7d7AB19DA8F72bb004b4C341",
Amount: big.NewInt(500000000),
UserData: []byte("0x"),
}
funderParams := FunderParams{
Sender: "0x8EbEC7277a5c0C43ac708BC641CBF9756E7938f4",
FromInternalBalance: false,
Recipient: "0x8EbEC7277a5c0C43ac708BC641CBF9756E7938f4",
ToInternalBalance: false,
}
encodeData, err := MethodEncode("swap((bytes32,uint8,address,address,uint256,bytes),(address,bool,address,bool),uint256,uint256)", swapParams, funderParams, 1, 1)
if err != nil {
panic(err)
}
fmt.Println(encodeData)
}
result
--- FAIL: TestEncodeNestedTuple (0.00s)
panic: cannot get key [recovered]
panic: cannot get key
ferranbt commented
Apologize for the late response.
The error is that the abi
encoder does not know how to match the inputs in the function signature with the struct. If it were a list instead, it matches by index (i.e. input at index 1 is item at index 1) but it needs a name when working with structs.
To fix it, you have to assign a name to the input and a tag to the fields in the struct:
type SwapParams struct {
PoolID [32]byte `abi:"a"`
Kind *big.Int `abi:"b"`
AssertIn string `abi:"c"`
AssertOut string `abi:"d"`
Amount *big.Int `abi:"e"`
UserData []byte `abi:"f"`
}
type FunderParams struct {
Sender string `abi:"a"`
FromInternalBalance bool `abi:"b"`
Recipient string `abi:"c"`
ToInternalBalance bool `abi:"d"`
}
...
encodeData, err := MethodEncode("swap((bytes32 a,uint8 b,address c,address d,uint256 e,bytes f),(address a,bool b,address c,bool d),uint256,uint256)", swapParams, funderParams, 1, 1)
if err != nil {
panic(err)
}