aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi/argument.go
diff options
context:
space:
mode:
authorGuillaume Ballet <gballet@gmail.com>2018-05-14 20:47:31 +0800
committerGitHub <noreply@github.com>2018-05-14 20:47:31 +0800
commit247b5f03690b47fdcb862c9a1173365cbdd9d279 (patch)
tree582b47762aa978c12caa63e55ae9dc8cc9136aa1 /accounts/abi/argument.go
parent49ec4f0cd1f4d4c84c13ccd8d920d56112d7268a (diff)
downloadgo-tangerine-247b5f03690b47fdcb862c9a1173365cbdd9d279.tar
go-tangerine-247b5f03690b47fdcb862c9a1173365cbdd9d279.tar.gz
go-tangerine-247b5f03690b47fdcb862c9a1173365cbdd9d279.tar.bz2
go-tangerine-247b5f03690b47fdcb862c9a1173365cbdd9d279.tar.lz
go-tangerine-247b5f03690b47fdcb862c9a1173365cbdd9d279.tar.xz
go-tangerine-247b5f03690b47fdcb862c9a1173365cbdd9d279.tar.zst
go-tangerine-247b5f03690b47fdcb862c9a1173365cbdd9d279.zip
accounts/abi: allow abi: tags when unpacking structs
Go code users can now tag event struct members with `abi:` to specify in what fields the event will be de-serialized. See PR #16648 for details.
Diffstat (limited to 'accounts/abi/argument.go')
-rw-r--r--accounts/abi/argument.go44
1 files changed, 20 insertions, 24 deletions
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go
index 512d8fdfa..93b513c34 100644
--- a/accounts/abi/argument.go
+++ b/accounts/abi/argument.go
@@ -111,9 +111,14 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
if err := requireUnpackKind(value, typ, kind, arguments); err != nil {
return err
}
- // If the output interface is a struct, make sure names don't collide
+
+ // If the interface is a struct, get of abi->struct_field mapping
+
+ var abi2struct map[string]string
if kind == reflect.Struct {
- if err := requireUniqueStructFieldNames(arguments); err != nil {
+ var err error
+ abi2struct, err = mapAbiToStructFields(arguments, value)
+ if err != nil {
return err
}
}
@@ -123,9 +128,10 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
switch kind {
case reflect.Struct:
- err := unpackStruct(value, reflectValue, arg)
- if err != nil {
- return err
+ if structField, ok := abi2struct[arg.Name]; ok {
+ if err := set(value.FieldByName(structField), reflectValue, arg); err != nil {
+ return err
+ }
}
case reflect.Slice, reflect.Array:
if value.Len() < i {
@@ -151,17 +157,22 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf
if len(marshalledValues) != 1 {
return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues))
}
+
elem := reflect.ValueOf(v).Elem()
kind := elem.Kind()
reflectValue := reflect.ValueOf(marshalledValues[0])
+ var abi2struct map[string]string
if kind == reflect.Struct {
- //make sure names don't collide
- if err := requireUniqueStructFieldNames(arguments); err != nil {
+ var err error
+ if abi2struct, err = mapAbiToStructFields(arguments, elem); err != nil {
return err
}
-
- return unpackStruct(elem, reflectValue, arguments[0])
+ arg := arguments.NonIndexed()[0]
+ if structField, ok := abi2struct[arg.Name]; ok {
+ return set(elem.FieldByName(structField), reflectValue, arg)
+ }
+ return nil
}
return set(elem, reflectValue, arguments.NonIndexed()[0])
@@ -277,18 +288,3 @@ func capitalise(input string) string {
}
return strings.ToUpper(input[:1]) + input[1:]
}
-
-//unpackStruct extracts each argument into its corresponding struct field
-func unpackStruct(value, reflectValue reflect.Value, arg Argument) error {
- name := capitalise(arg.Name)
- typ := value.Type()
- for j := 0; j < typ.NumField(); j++ {
- // TODO read tags: `abi:"fieldName"`
- if typ.Field(j).Name == name {
- if err := set(value.Field(j), reflectValue, arg); err != nil {
- return err
- }
- }
- }
- return nil
-}