From 04bdfa060572b370055b53943a9d659081d63e70 Mon Sep 17 00:00:00 2001 From: Ken Matsushima Date: Sat, 4 Jun 2016 16:15:25 +0900 Subject: [PATCH] add functionality for unpacking transaction log to event parameters --- accounts/abi/abi.go | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 1b07b2f68e..8fe79fba1e 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -232,7 +232,8 @@ var ( // Unpack output in v according to the abi specification func (abi ABI) Unpack(v interface{}, name string, output []byte) error { - var method = abi.Methods[name] + var method, ok = abi.Methods[name] + var args []Argument if len(output) == 0 { return fmt.Errorf("abi: unmarshalling empty output") @@ -244,18 +245,27 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error { return fmt.Errorf("abi: Unpack(non-pointer %T)", v) } + if ok { + args = method.Outputs + } else { + var event, ok = abi.Events[name] + if ok { + args = event.Inputs + } + } + var ( value = valueOf.Elem() typ = value.Type() ) - if len(method.Outputs) > 1 { + if len(args) > 1 { switch value.Kind() { // struct will match named return values to the struct's field // names case reflect.Struct: - for i := 0; i < len(method.Outputs); i++ { - marshalledValue, err := toGoType(i, method.Outputs[i], output) + for i := 0; i < len(args); i++ { + marshalledValue, err := toGoType(i, args[i], output) if err != nil { return err } @@ -264,8 +274,8 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error { for j := 0; j < typ.NumField(); j++ { field := typ.Field(j) // TODO read tags: `abi:"fieldName"` - if field.Name == strings.ToUpper(method.Outputs[i].Name[:1])+method.Outputs[i].Name[1:] { - if err := set(value.Field(j), reflectValue, method.Outputs[i]); err != nil { + if field.Name == strings.ToUpper(args[i].Name[:1])+args[i].Name[1:] { + if err := set(value.Field(j), reflectValue, args[i]); err != nil { return err } } @@ -278,17 +288,17 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error { // if the slice already contains values, set those instead of the interface slice itself. if value.Len() > 0 { - if len(method.Outputs) > value.Len() { - return fmt.Errorf("abi: cannot marshal in to slices of unequal size (require: %v, got: %v)", len(method.Outputs), value.Len()) + if len(args) > value.Len() { + return fmt.Errorf("abi: cannot marshal in to slices of unequal size (require: %v, got: %v)", len(args), value.Len()) } - for i := 0; i < len(method.Outputs); i++ { - marshalledValue, err := toGoType(i, method.Outputs[i], output) + for i := 0; i < len(args); i++ { + marshalledValue, err := toGoType(i, args[i], output) if err != nil { return err } reflectValue := reflect.ValueOf(marshalledValue) - if err := set(value.Index(i).Elem(), reflectValue, method.Outputs[i]); err != nil { + if err := set(value.Index(i).Elem(), reflectValue, args[i]); err != nil { return err } } @@ -297,9 +307,9 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error { // create a new slice and start appending the unmarshalled // values to the new interface slice. - z := reflect.MakeSlice(typ, 0, len(method.Outputs)) - for i := 0; i < len(method.Outputs); i++ { - marshalledValue, err := toGoType(i, method.Outputs[i], output) + z := reflect.MakeSlice(typ, 0, len(args)) + for i := 0; i < len(args); i++ { + marshalledValue, err := toGoType(i, args[i], output) if err != nil { return err } @@ -311,11 +321,11 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error { } } else { - marshalledValue, err := toGoType(0, method.Outputs[0], output) + marshalledValue, err := toGoType(0, args[0], output) if err != nil { return err } - if err := set(value, reflect.ValueOf(marshalledValue), method.Outputs[0]); err != nil { + if err := set(value, reflect.ValueOf(marshalledValue), args[0]); err != nil { return err } }