Skip to content

Commit

Permalink
accounts/abi: events can't be overloaded
Browse files Browse the repository at this point in the history
  • Loading branch information
MariusVanDerWijden committed Oct 12, 2021
1 parent f50d40e commit 46e872a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 22 deletions.
3 changes: 1 addition & 2 deletions accounts/abi/abi.go
Expand Up @@ -187,8 +187,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
name := overloadedName(field.Name, func(s string) bool { _, ok := abi.Events[s]; return ok })
abi.Events[name] = NewEvent(name, field.Name, field.Anonymous, field.Inputs)
case "error":
name := overloadedName(field.Name, func(s string) bool { _, ok := abi.Errors[s]; return ok })
abi.Errors[name] = NewError(name, field.Name, field.Inputs)
abi.Errors[field.Name] = NewError(field.Name, field.Inputs)
default:
return fmt.Errorf("abi: could not recognize type %v of field %v", field.Type, field.Name)
}
Expand Down
16 changes: 12 additions & 4 deletions accounts/abi/bind/bind_test.go
Expand Up @@ -1862,15 +1862,18 @@ var bindTests = []struct {
`
pragma solidity >0.8.4;
contract Test {
contract NewErrors {
error MyError(uint256);
error MyError1(uint256);
error MyError2(uint256, uint256);
error MyError3(uint256 a, uint256 b, uint256 c);
function Error() public pure {
revert MyError3(1,2,3);
}
}
`,
[]string{"0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220313fc94775b67962460298a5e968a46aed3683e1162a713923677e23373efa6364736f6c63430008060033"},
[]string{`[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError1","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError2","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"MyError3","type":"error"}]`},
[]string{"0x6080604052348015600f57600080fd5b5060998061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063726c638214602d575b600080fd5b60336035565b005b60405163024876cd60e61b815260016004820152600260248201526003604482015260640160405180910390fdfea264697066735822122093f786a1bc60216540cd999fbb4a6109e0fef20abcff6e9107fb2817ca968f3c64736f6c63430008070033"},
[]string{`[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError1","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError2","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"MyError3","type":"error"},{"inputs":[],"name":"Error","outputs":[],"stateMutability":"pure","type":"function"}]`},
`
"math/big"
Expand All @@ -1888,7 +1891,7 @@ var bindTests = []struct {
)
defer sim.Close()
_, tx, _, err := DeployNewErrors(user, sim)
_, tx, contract, err := DeployNewErrors(user, sim)
if err != nil {
t.Fatal(err)
}
Expand All @@ -1897,6 +1900,11 @@ var bindTests = []struct {
if err != nil {
t.Error(err)
}
if err := contract.Error(new(bind.CallOpts)); err == nil {
t.Fatalf("expected contract to throw error")
}
// TODO (MariusVanDerWijden unpack error using abigen
// once that is implemented
`,
nil,
nil,
Expand Down
41 changes: 25 additions & 16 deletions accounts/abi/error.go
Expand Up @@ -17,6 +17,8 @@
package abi

import (
"bytes"
"errors"
"fmt"
"strings"

Expand All @@ -25,11 +27,9 @@ import (
)

type Error struct {
Name string
// RawName might be overloaded
RawName string
Inputs Arguments
str string
Name string
Inputs Arguments
str string
// Sig contains the string signature according to the ABI spec.
// e.g. event foo(uint32 a, int b) = "foo(uint32,int256)"
// Please note that "int" is substitute for its canonical representation "int256"
Expand All @@ -39,7 +39,7 @@ type Error struct {
ID common.Hash
}

func NewError(name, rawName string, inputs Arguments) Error {
func NewError(name string, inputs Arguments) Error {
// sanitize inputs to remove inputs without names
// and precompute string and sig representation.
names := make([]string, len(inputs))
Expand All @@ -63,20 +63,29 @@ func NewError(name, rawName string, inputs Arguments) Error {
types[i] = input.Type.String()
}

str := fmt.Sprintf("event %v(%v)", rawName, strings.Join(names, ", "))
sig := fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ","))
str := fmt.Sprintf("error %v(%v)", name, strings.Join(names, ", "))
sig := fmt.Sprintf("%v(%v)", name, strings.Join(types, ","))
id := common.BytesToHash(crypto.Keccak256([]byte(sig)))

return Error{
Name: name,
RawName: rawName,
Inputs: inputs,
str: str,
Sig: sig,
ID: id,
Name: name,
Inputs: inputs,
str: str,
Sig: sig,
ID: id,
}
}

func (err *Error) String() string {
return err.str
func (e *Error) String() string {
return e.str
}

func (e *Error) Unpack(data []byte) (interface{}, error) {
if len(data) < 4 {
return "", errors.New("invalid data for unpacking")
}
if !bytes.Equal(data[:4], e.ID[:4]) {
return "", errors.New("invalid data for unpacking")
}
return e.Inputs.Unpack(data[4:])
}

0 comments on commit 46e872a

Please sign in to comment.