From dc378a562de6abcd87f4b0fc5bbcb2f5c0bd2d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 27 Dec 2017 23:00:11 +0200 Subject: [PATCH] accounts/abi: handle named ouputs prefixed with underscores --- accounts/abi/argument.go | 3 ++- accounts/abi/bind/bind.go | 6 +++++- accounts/abi/bind/bind_test.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index ad17fbf2b1..4a5d03186e 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -126,7 +126,8 @@ func (arguments Arguments) unpackTuple(v interface{}, output []byte) error { 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:] { + trimmed := strings.TrimLeft(arg.Name, "_") + if field.Name == strings.ToUpper(trimmed[:1])+trimmed[1:] { if err := set(value.Field(j), reflectValue, arg); err != nil { return err } diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 4dce79b779..5d2b61b870 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -304,8 +304,12 @@ var methodNormalizer = map[Lang]func(string) string{ LangJava: decapitalise, } -// capitalise makes the first character of a string upper case. +// 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:] + } return strings.ToUpper(input[:1]) + input[1:] } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 43ed53b922..b1b2b22c17 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -447,6 +447,36 @@ var bindTests = []struct { } `, }, + { + `Underscorer`, + ` + contract Underscorer { + function UnderscoredOutput() constant returns (int _int, string _string) { + return (314, "pi"); + } + } + `, `6060604052341561000f57600080fd5b6101698061001e6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806367e6633d14610046575b600080fd5b341561005157600080fd5b6100596100db565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561009f578082015181840152602081019050610084565b50505050905090810190601f1680156100cc5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b60006100e5610129565b61013a8090506040805190810160405280600281526020017f7069000000000000000000000000000000000000000000000000000000000000815250915091509091565b6020604051908101604052806000815250905600a165627a7a72305820b38a996760144524e16187fefa4a8ec24520361614be164ab10a4676a5f196340029`, + `[{"constant": true,"inputs": [],"name": "UnderscoredOutput","outputs": [{"name": "_int","type": "int256"},{"name": "_string","type": "string"}],"payable": false,"stateMutability": "view","type": "function"}]`, + ` + // Generate a new random account and a funded simulator + key, _ := crypto.GenerateKey() + auth := bind.NewKeyedTransactor(key) + sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}) + + // Deploy a underscorer tester contract and execute a structured call on it + _, _, underscorer, err := DeployUnderscorer(auth, sim) + if err != nil { + t.Fatalf("Failed to deploy underscorer contract: %v", err) + } + sim.Commit() + + if res, err := underscorer.UnderscoredOutput(nil); err != nil { + t.Errorf("Failed to call constant function: %v", err) + } else if res.Int.Cmp(big.NewInt(314)) != 0 || res.String != "pi" { + t.Errorf("Invalid result, want: {314, \"pi\"}, got: %+v", res) + } + `, + }, } // Tests that packages generated by the binder can be successfully compiled and