From 14ad799a676759da65c8e240136ca1b79651f457 Mon Sep 17 00:00:00 2001 From: Darren Kelly Date: Wed, 6 Nov 2024 19:02:02 +0000 Subject: [PATCH] abi: unpack error into interface --- accounts/abi/abi.go | 5 ++++- accounts/abi/abi_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index c7bc2b4541..bee4fe40fd 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -95,8 +95,11 @@ func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { if event, ok := abi.Events[name]; ok { args = event.Inputs } + if err, ok := abi.Errors[name]; ok { + args = err.Inputs + } if args == nil { - return nil, fmt.Errorf("abi: could not locate named method or event: %s", name) + return nil, fmt.Errorf("abi: could not locate named method, event or error: %s", name) } return args, nil } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index fc290cfe84..e3a614688a 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -21,6 +21,7 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/ethereum/go-ethereum/internal/testrand" "math/big" "reflect" "strings" @@ -317,6 +318,38 @@ func TestCustomErrors(t *testing.T) { check("MyError", "MyError(uint256)") } +func TestCustomErrorUnpack(t *testing.T) { + t.Parallel() + errorName := "MyError" + json := fmt.Sprintf(`[{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"%s","type":"error"}]`, errorName) + abi, err := JSON(strings.NewReader(json)) + if err != nil { + t.Fatal(err) + } + type MyError struct { + Sender common.Address + Balance *big.Int + } + + sender := testrand.Address() + balance := new(big.Int).SetBytes(testrand.Bytes(8)) + encoded, err := abi.Errors[errorName].Inputs.Pack(sender, balance) + if err != nil { + t.Fatal(err) + } + result := MyError{} + err = abi.UnpackIntoInterface(&result, errorName, encoded) + if err != nil { + t.Fatal(err) + } + if result.Sender != sender { + t.Errorf("expected %x got %x", sender, result.Sender) + } + if result.Balance.Cmp(balance) != 0 { + t.Errorf("expected %v got %v", balance, result.Balance) + } +} + func TestMultiPack(t *testing.T) { t.Parallel() abi, err := JSON(strings.NewReader(jsondata))