diff options
Diffstat (limited to 'accounts/abi/bind/bind.go')
-rw-r--r-- | accounts/abi/bind/bind.go | 78 |
1 files changed, 65 insertions, 13 deletions
diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 8175e3cb9..e31b45481 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -63,10 +63,11 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La return r }, abis[i]) - // Extract the call and transact methods, and sort them alphabetically + // Extract the call and transact methods; events; and sort them alphabetically var ( calls = make(map[string]*tmplMethod) transacts = make(map[string]*tmplMethod) + events = make(map[string]*tmplEvent) ) for _, original := range evmABI.Methods { // Normalize the method for capital cases and non-anonymous inputs/outputs @@ -89,11 +90,33 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La } // Append the methods to the call or transact lists if original.Const { - calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)} + calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} } else { - transacts[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original)} + transacts[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} } } + for _, original := range evmABI.Events { + // Skip anonymous events as they don't support explicit filtering + if original.Anonymous { + continue + } + // Normalize the event for capital cases and non-anonymous outputs + normalized := original + normalized.Name = methodNormalizer[lang](original.Name) + + normalized.Inputs = make([]abi.Argument, len(original.Inputs)) + copy(normalized.Inputs, original.Inputs) + for j, input := range normalized.Inputs { + // Indexed fields are input, non-indexed ones are outputs + if input.Indexed { + if input.Name == "" { + normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) + } + } + } + // Append the event to the accumulator list + events[original.Name] = &tmplEvent{Original: original, Normalized: normalized} + } contracts[types[i]] = &tmplContract{ Type: capitalise(types[i]), InputABI: strings.Replace(strippedABI, "\"", "\\\"", -1), @@ -101,6 +124,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La Constructor: evmABI.Constructor, Calls: calls, Transacts: transacts, + Events: events, } } // Generate the contract template data content and render it @@ -111,10 +135,11 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La buffer := new(bytes.Buffer) funcs := map[string]interface{}{ - "bindtype": bindType[lang], - "namedtype": namedType[lang], - "capitalise": capitalise, - "decapitalise": decapitalise, + "bindtype": bindType[lang], + "bindtopictype": bindTopicType[lang], + "namedtype": namedType[lang], + "capitalise": capitalise, + "decapitalise": decapitalise, } tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSource[lang])) if err := tmpl.Execute(buffer, data); err != nil { @@ -133,7 +158,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La } // bindType is a set of type binders that convert Solidity types to some supported -// programming language. +// programming language types. var bindType = map[Lang]func(kind abi.Type) string{ LangGo: bindTypeGo, LangJava: bindTypeJava, @@ -254,6 +279,33 @@ func bindTypeJava(kind abi.Type) string { } } +// bindTopicType is a set of type binders that convert Solidity types to some +// supported programming language topic types. +var bindTopicType = map[Lang]func(kind abi.Type) string{ + LangGo: bindTopicTypeGo, + LangJava: bindTopicTypeJava, +} + +// bindTypeGo converts a Solidity topic type to a Go one. It is almost the same +// funcionality as for simple types, but dynamic types get converted to hashes. +func bindTopicTypeGo(kind abi.Type) string { + bound := bindTypeGo(kind) + if bound == "string" || bound == "[]byte" { + bound = "common.Hash" + } + return bound +} + +// bindTypeGo converts a Solidity topic type to a Java one. It is almost the same +// funcionality as for simple types, but dynamic types get converted to hashes. +func bindTopicTypeJava(kind abi.Type) string { + bound := bindTypeJava(kind) + if bound == "String" || bound == "Bytes" { + bound = "Hash" + } + return bound +} + // namedType is a set of functions that transform language specific types to // named versions that my be used inside method names. var namedType = map[Lang]func(string, abi.Type) string{ @@ -321,14 +373,14 @@ func decapitalise(input string) string { return strings.ToLower(input[:1]) + input[1:] } -// structured checks whether a method has enough information to return a proper -// Go struct or if flat returns are needed. -func structured(method abi.Method) bool { - if len(method.Outputs) < 2 { +// structured checks whether a list of ABI data types has enough information to +// operate through a proper Go struct or if flat returns are needed. +func structured(args abi.Arguments) bool { + if len(args) < 2 { return false } exists := make(map[string]bool) - for _, out := range method.Outputs { + for _, out := range args { // If the name is anonymous, we can't organize into a struct if out.Name == "" { return false |