aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi/argument.go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-12-30 05:20:02 +0800
committerGitHub <noreply@github.com>2017-12-30 05:20:02 +0800
commitb9731767af634ff90ae9b387bd035d9bc4b128e3 (patch)
treeb9e05770b293a06310948f2f2261f918e8b7064d /accounts/abi/argument.go
parent36a10875c8c1a34aab851e3f65da48ccbb5367ce (diff)
downloadgo-tangerine-b9731767af634ff90ae9b387bd035d9bc4b128e3.tar
go-tangerine-b9731767af634ff90ae9b387bd035d9bc4b128e3.tar.gz
go-tangerine-b9731767af634ff90ae9b387bd035d9bc4b128e3.tar.bz2
go-tangerine-b9731767af634ff90ae9b387bd035d9bc4b128e3.tar.lz
go-tangerine-b9731767af634ff90ae9b387bd035d9bc4b128e3.tar.xz
go-tangerine-b9731767af634ff90ae9b387bd035d9bc4b128e3.tar.zst
go-tangerine-b9731767af634ff90ae9b387bd035d9bc4b128e3.zip
accounts/abi: handle named ouputs prefixed with underscores (#15766)
* accounts/abi: handle named ouputs prefixed with underscores * accounts/abi: handle collinding outputs for struct unpacks * accounts: handle purely underscore output names
Diffstat (limited to 'accounts/abi/argument.go')
-rw-r--r--accounts/abi/argument.go30
1 files changed, 28 insertions, 2 deletions
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go
index ad17fbf2b..4540c342f 100644
--- a/accounts/abi/argument.go
+++ b/accounts/abi/argument.go
@@ -96,6 +96,20 @@ func (arguments Arguments) unpackTuple(v interface{}, output []byte) error {
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 kind == reflect.Struct {
+ exists := make(map[string]bool)
+ for _, arg := range arguments {
+ field := capitalise(arg.Name)
+ if field == "" {
+ return fmt.Errorf("abi: purely underscored output cannot unpack to struct")
+ }
+ if exists[field] {
+ return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field)
+ }
+ exists[field] = true
+ }
+ }
// `i` counts the nonindexed arguments.
// `j` counts the number of complex types.
// both `i` and `j` are used to to correctly compute `data` offset.
@@ -123,10 +137,10 @@ func (arguments Arguments) unpackTuple(v interface{}, output []byte) error {
switch kind {
case reflect.Struct:
+ name := capitalise(arg.Name)
for j := 0; j < typ.NumField(); j++ {
- field := typ.Field(j)
// TODO read tags: `abi:"fieldName"`
- if field.Name == strings.ToUpper(arg.Name[:1])+arg.Name[1:] {
+ if typ.Field(j).Name == name {
if err := set(value.Field(j), reflectValue, arg); err != nil {
return err
}
@@ -222,3 +236,15 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) {
return ret, nil
}
+
+// capitalise makes the first character of a string upper case, also removing any
+// prefixing underscores from the variable names.
+func capitalise(input string) string {
+ for len(input) > 0 && input[0] == '_' {
+ input = input[1:]
+ }
+ if len(input) == 0 {
+ return ""
+ }
+ return strings.ToUpper(input[:1]) + input[1:]
+}