Bläddra i källkod

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

bas-vk 9 år sedan
förälder
incheckning
6d15d00ac4
4 ändrade filer med 61 tillägg och 20 borttagningar
  1. 10 8
      accounts/abi/abi.go
  2. 44 9
      accounts/abi/abi_test.go
  3. 2 0
      accounts/abi/argument.go
  4. 5 3
      accounts/abi/event.go

+ 10 - 8
accounts/abi/abi.go

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

+ 44 - 9
accounts/abi/abi_test.go

@@ -752,23 +752,58 @@ func TestDefaultFunctionParsing(t *testing.T) {
 func TestBareEvents(t *testing.T) {
 	const definition = `[
 	{ "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))
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if len(abi.Events) != 2 {
-		t.Error("expected 2 events")
-	}
-
-	if _, ok := abi.Events["balance"]; !ok {
-		t.Error("expected 'balance' event to be present")
+	if len(abi.Events) != len(expectedEvents) {
+		t.Fatalf("invalid number of events after parsing, want %d, got %d", len(expectedEvents), len(abi.Events))
 	}
 
-	if _, ok := abi.Events["name"]; !ok {
-		t.Error("expected 'name' event to be present")
+	for name, exp := range expectedEvents {
+		got, ok := abi.Events[name]
+		if !ok {
+			t.Errorf("could not found event %s", name)
+			continue
+		}
+		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)
+			}
+		}
 	}
 }
 

+ 2 - 0
accounts/abi/argument.go

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

+ 5 - 3
accounts/abi/event.go

@@ -25,10 +25,12 @@ import (
 )
 
 // 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 {
-	Name   string
-	Inputs []Argument
+	Name      string
+	Anonymous bool
+	Inputs    []Argument
 }
 
 // Id returns the canonical representation of the event's signature used by the