diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index ba1774c647..e92970556a 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -21,6 +21,8 @@ import ( "encoding/json" "fmt" "io" + + "github.com/ethereum/go-ethereum/common" ) // The ABI holds information about a contract's context and available @@ -145,3 +147,14 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { } return nil, fmt.Errorf("no method with id: %#x", sigdata[:4]) } + +// EventById looks up a event by the topic hash +// returns nil if none found +func (abi *ABI) EventById(topic common.Hash) (*Event, error) { + for _, event := range abi.Events { + if event.Id() == topic { + return &event, nil + } + } + return nil, fmt.Errorf("no event with topic: %#x", topic.Hex()) +} diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index b9444f9f0d..f3c0808833 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -745,3 +745,30 @@ func TestABI_MethodById(t *testing.T) { t.Errorf("Expected error, nil is short to decode data") } } + +func TestABI_EventById(t *testing.T) { + const abiJSON = `[ + {"type":"event","name":"received","anonymous":false,"inputs":[ + {"indexed":false,"name":"sender","type":"address"}, + {"indexed":false,"name":"amount","type":"uint256"}, + {"indexed":false,"name":"memo","type":"bytes"} + ] + }]` + + abi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + + topic := "received(address,uint256,bytes)" + topicID := crypto.Keccak256Hash([]byte(topic)) + + event, err := abi.EventById(topicID) + if err != nil { + t.Fatalf("Failed to look up ABI event: %v", err) + } + + if event.Id() != topicID { + t.Errorf("topic %v (id %v) not 'findable' by id in ABI", topic, topicID) + } +}