accounts/abi: add support for "anonymous" and "indexed" for events (#3464)

This commit is contained in:
bas-vk 2016-12-22 01:51:20 +01:00 committed by Felix Lange
parent bdaa43510b
commit 6d15d00ac4
4 changed files with 61 additions and 20 deletions

@ -345,12 +345,13 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
func (abi *ABI) UnmarshalJSON(data []byte) error { func (abi *ABI) UnmarshalJSON(data []byte) error {
var fields []struct { var fields []struct {
Type string Type string
Name string Name string
Constant bool Constant bool
Indexed bool Indexed bool
Inputs []Argument Anonymous bool
Outputs []Argument Inputs []Argument
Outputs []Argument
} }
if err := json.Unmarshal(data, &fields); err != nil { if err := json.Unmarshal(data, &fields); err != nil {
@ -375,8 +376,9 @@ func (abi *ABI) UnmarshalJSON(data []byte) error {
} }
case "event": case "event":
abi.Events[field.Name] = Event{ abi.Events[field.Name] = Event{
Name: field.Name, Name: field.Name,
Inputs: field.Inputs, Anonymous: field.Anonymous,
Inputs: field.Inputs,
} }
} }
} }

@ -752,23 +752,58 @@ func TestDefaultFunctionParsing(t *testing.T) {
func TestBareEvents(t *testing.T) { func TestBareEvents(t *testing.T) {
const definition = `[ const definition = `[
{ "type" : "event", "name" : "balance" }, { "type" : "event", "name" : "balance" },
{ "type" : "event", "name" : "name" }]` { "type" : "event", "name" : "anon", "anonymous" : true},
{ "type" : "event", "name" : "args", "inputs" : [{ "indexed":false, "name":"arg0", "type":"uint256" }, { "indexed":true, "name":"arg1", "type":"address" }] }
]`
arg0, _ := NewType("uint256")
arg1, _ := NewType("address")
expectedEvents := map[string]struct {
Anonymous bool
Args []Argument
}{
"balance": {false, nil},
"anon": {true, nil},
"args": {false, []Argument{
Argument{Name: "arg0", Type: arg0, Indexed: false},
Argument{Name: "arg1", Type: arg1, Indexed: true},
}},
}
abi, err := JSON(strings.NewReader(definition)) abi, err := JSON(strings.NewReader(definition))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if len(abi.Events) != 2 { if len(abi.Events) != len(expectedEvents) {
t.Error("expected 2 events") t.Fatalf("invalid number of events after parsing, want %d, got %d", len(expectedEvents), len(abi.Events))
} }
if _, ok := abi.Events["balance"]; !ok { for name, exp := range expectedEvents {
t.Error("expected 'balance' event to be present") got, ok := abi.Events[name]
} if !ok {
t.Errorf("could not found event %s", name)
if _, ok := abi.Events["name"]; !ok { continue
t.Error("expected 'name' event to be present") }
if got.Anonymous != exp.Anonymous {
t.Errorf("invalid anonymous indication for event %s, want %v, got %v", name, exp.Anonymous, got.Anonymous)
}
if len(got.Inputs) != len(exp.Args) {
t.Errorf("invalid number of args, want %d, got %d", len(exp.Args), len(got.Inputs))
continue
}
for i, arg := range exp.Args {
if arg.Name != got.Inputs[i].Name {
t.Errorf("events[%s].Input[%d] has an invalid name, want %s, got %s", name, i, arg.Name, got.Inputs[i].Name)
}
if arg.Indexed != got.Inputs[i].Indexed {
t.Errorf("events[%s].Input[%d] has an invalid indexed indication, want %v, got %v", name, i, arg.Indexed, got.Inputs[i].Indexed)
}
if arg.Type.T != got.Inputs[i].Type.T {
t.Errorf("events[%s].Input[%d] has an invalid type, want %x, got %x", name, i, arg.Type.T, got.Inputs[i].Type.T)
}
}
} }
} }

@ -33,6 +33,7 @@ func (a *Argument) UnmarshalJSON(data []byte) error {
var extarg struct { var extarg struct {
Name string Name string
Type string Type string
Indexed bool
} }
err := json.Unmarshal(data, &extarg) err := json.Unmarshal(data, &extarg)
if err != nil { if err != nil {
@ -44,6 +45,7 @@ func (a *Argument) UnmarshalJSON(data []byte) error {
return err return err
} }
a.Name = extarg.Name a.Name = extarg.Name
a.Indexed = extarg.Indexed
return nil return nil
} }

@ -25,10 +25,12 @@ import (
) )
// Event is an event potentially triggered by the EVM's LOG mechanism. The Event // Event is an event potentially triggered by the EVM's LOG mechanism. The Event
// holds type information (inputs) about the yielded output // holds type information (inputs) about the yielded output. Anonymous events
// don't get the signature canonical representation as the first LOG topic.
type Event struct { type Event struct {
Name string Name string
Inputs []Argument Anonymous bool
Inputs []Argument
} }
// Id returns the canonical representation of the event's signature used by the // Id returns the canonical representation of the event's signature used by the