diff options
author | Matt K <1036969+mkrump@users.noreply.github.com> | 2018-12-29 18:32:58 +0800 |
---|---|---|
committer | Guillaume Ballet <gballet@gmail.com> | 2018-12-29 18:32:58 +0800 |
commit | a4af734328d50b9ea89405c7e5050065a8087946 (patch) | |
tree | 5741ded89a84cef4ca38faf10b5cc9094a1c7529 | |
parent | 735343430dec74a340f5c9a18822537e18165caa (diff) | |
download | dexon-a4af734328d50b9ea89405c7e5050065a8087946.tar.gz dexon-a4af734328d50b9ea89405c7e5050065a8087946.tar.zst dexon-a4af734328d50b9ea89405c7e5050065a8087946.zip |
accounts/abi: change unpacking of abi fields w/ underscores (#16513)
* accounts/abi: fix name styling when unpacking abi fields w/ underscores
ABI fields with underscores that are being unpacked
into structs expect structs with following form:
int_one -> Int_one
whereas in abigen the generated structs are camelcased
int_one -> IntOne
so updated the unpack method to expect camelcased structs as well.
-rw-r--r-- | accounts/abi/argument.go | 17 | ||||
-rw-r--r-- | accounts/abi/bind/bind.go | 41 | ||||
-rw-r--r-- | accounts/abi/reflect.go | 2 | ||||
-rw-r--r-- | accounts/abi/unpack_test.go | 47 |
4 files changed, 60 insertions, 47 deletions
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 90fd9d05f..fdc6ff164 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -272,14 +272,13 @@ 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 "" +// ToCamelCase converts an under-score string to a camel-case string +func ToCamelCase(input string) string { + parts := strings.Split(input, "_") + for i, s := range parts { + if len(s) > 0 { + parts[i] = strings.ToUpper(s[:1]) + s[1:] + } } - return strings.ToUpper(input[:1]) + input[1:] + return strings.Join(parts, "") } diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 4dca4b4ea..21e16060c 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -387,48 +387,15 @@ var methodNormalizer = map[Lang]func(string) string{ // capitalise makes a camel-case string which starts with an upper case character. func capitalise(input string) string { - for len(input) > 0 && input[0] == '_' { - input = input[1:] - } - if len(input) == 0 { - return "" - } - return toCamelCase(strings.ToUpper(input[:1]) + input[1:]) + return abi.ToCamelCase(input) } // decapitalise makes a camel-case string which starts with a lower case character. func decapitalise(input string) string { - for len(input) > 0 && input[0] == '_' { - input = input[1:] - } - if len(input) == 0 { - return "" - } - return toCamelCase(strings.ToLower(input[:1]) + input[1:]) -} - -// toCamelCase converts an under-score string to a camel-case string -func toCamelCase(input string) string { - toupper := false + // NOTE: This is the current behavior, it doesn't match the comment + // above and needs to be investigated. + return abi.ToCamelCase(input) - result := "" - for k, v := range input { - switch { - case k == 0: - result = strings.ToUpper(string(input[0])) - - case toupper: - result += strings.ToUpper(string(v)) - toupper = false - - case v == '_': - toupper = true - - default: - result += string(v) - } - } - return result } // structured checks whether a list of ABI data types has enough information to diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 6ec79a12f..f541cf3bf 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -186,7 +186,7 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin for _, arg := range args { abiFieldName := arg.Name - structFieldName := capitalise(abiFieldName) + structFieldName := ToCamelCase(abiFieldName) if structFieldName == "" { return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct") diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 22aa1a857..3873414c9 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -311,6 +311,53 @@ var unpackTests = []unpackTest{ }{big.NewInt(1), big.NewInt(2)}, }, { + def: `[{"name":"int_one","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int__one","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int_one_","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int_one","type":"int256"}, {"name":"intone","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + Intone *big.Int + }{big.NewInt(1), big.NewInt(2)}, + }, + { + def: `[{"name":"___","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + Intone *big.Int + }{}, + err: "abi: purely underscored output cannot unpack to struct", + }, + { + def: `[{"name":"int_one","type":"int256"},{"name":"IntOne","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + Int1 *big.Int + Int2 *big.Int + }{}, + err: "abi: multiple outputs mapping to the same struct field 'IntOne'", + }, + { def: `[{"name":"int","type":"int256"},{"name":"Int","type":"int256"}]`, enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", want: struct { |