Skip to content

Commit

Permalink
accounts/abi: change unpacking of abi fields w/ underscores (ethereum…
Browse files Browse the repository at this point in the history
…#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.
  • Loading branch information
mkrump authored and cryptomental committed Jan 9, 2019
1 parent 9c2296d commit 040e1e6
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 47 deletions.
17 changes: 8 additions & 9 deletions accounts/abi/argument.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, "")
}
41 changes: 4 additions & 37 deletions accounts/abi/bind/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion accounts/abi/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
47 changes: 47 additions & 0 deletions accounts/abi/unpack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,53 @@ var unpackTests = []unpackTest{
Int2 *big.Int
}{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",
Expand Down

0 comments on commit 040e1e6

Please sign in to comment.