abi: adding the method EventByID and its test (#19359)
This function searches for an event+parameters in the ABI and returns it if found. Co-authored-by: Victor Tran <vu.tran54@gmail.com> Co-authored-by: Guillaume Ballet <gballet@gmail.com>
This commit is contained in:
parent
98099d6fa7
commit
e4a1488b2f
|
@ -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
|
||||
|
@ -165,3 +167,14 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
|
|||
}
|
||||
return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
|
||||
}
|
||||
|
||||
// EventByID looks an event up by its topic hash in the
|
||||
// ABI and returns nil if none found.
|
||||
func (abi *ABI) EventByID(topic common.Hash) (*Event, error) {
|
||||
for _, event := range abi.Events {
|
||||
if bytes.Equal(event.Id().Bytes(), topic.Bytes()) {
|
||||
return &event, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("no event with id: %#x", topic.Hex())
|
||||
}
|
||||
|
|
|
@ -931,3 +931,71 @@ func TestABI_MethodById(t *testing.T) {
|
|||
t.Errorf("Expected error, nil is short to decode data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestABI_EventById(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
json string
|
||||
event string
|
||||
}{
|
||||
{
|
||||
name: "",
|
||||
json: `[
|
||||
{"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"}
|
||||
]
|
||||
}]`,
|
||||
event: "received(address,uint256,bytes)",
|
||||
}, {
|
||||
name: "",
|
||||
json: `[
|
||||
{ "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" },
|
||||
{ "constant": false, "inputs": [ { "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" },
|
||||
{ "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" },
|
||||
{ "constant": false, "inputs": [ { "name": "_from", "type": "address" }, { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" },
|
||||
{ "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" },
|
||||
{ "constant": true, "inputs": [ { "name": "_owner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "balance", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" },
|
||||
{ "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" },
|
||||
{ "constant": false, "inputs": [ { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" },
|
||||
{ "constant": true, "inputs": [ { "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" },
|
||||
{ "payable": true, "stateMutability": "payable", "type": "fallback" },
|
||||
{ "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" },
|
||||
{ "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }
|
||||
]`,
|
||||
event: "Transfer(address,address,uint256)",
|
||||
},
|
||||
}
|
||||
|
||||
for testnum, test := range tests {
|
||||
abi, err := JSON(strings.NewReader(test.json))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
topic := test.event
|
||||
topicID := crypto.Keccak256Hash([]byte(topic))
|
||||
|
||||
event, err := abi.EventByID(topicID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to look up ABI method: %v, test #%d", err, testnum)
|
||||
}
|
||||
if event == nil {
|
||||
t.Errorf("We should find a event for topic %s, test #%d", topicID.Hex(), testnum)
|
||||
}
|
||||
|
||||
if event.Id() != topicID {
|
||||
t.Errorf("Event id %s does not match topic %s, test #%d", event.Id().Hex(), topicID.Hex(), testnum)
|
||||
}
|
||||
|
||||
unknowntopicID := crypto.Keccak256Hash([]byte("unknownEvent"))
|
||||
unknownEvent, err := abi.EventByID(unknowntopicID)
|
||||
if err == nil {
|
||||
t.Errorf("EventByID should return an error if a topic is not found, test #%d", testnum)
|
||||
}
|
||||
if unknownEvent != nil {
|
||||
t.Errorf("We should not find any event for topic %s, test #%d", unknowntopicID.Hex(), testnum)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue