Skip to content

Commit fb26a58

Browse files
jwasingerfjl
authored andcommitted
address some recent feedback. add docs about what the binder and contractBinder structs are used for.
1 parent c7ff648 commit fb26a58

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

accounts/abi/bind/bindv2.go

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ package bind
33
import (
44
"bytes"
55
"fmt"
6-
"github.com/ethereum/go-ethereum/accounts/abi"
76
"go/format"
87
"reflect"
98
"regexp"
109
"slices"
1110
"strings"
1211
"text/template"
1312
"unicode"
13+
14+
"github.com/ethereum/go-ethereum/accounts/abi"
1415
)
1516

1617
// underlyingBindType returns the underlying Go type represented by the given type, panicking if it is not a pointer type.
@@ -27,8 +28,23 @@ func isPointerType(typ abi.Type) bool {
2728
return typ.GetType().Kind() == reflect.Pointer
2829
}
2930

31+
// binder is used during the conversion of an ABI definition into Go bindings (as part of the execution of BindV2)
32+
// in contrast to contractBinder, binder contains binding-generation-state that is shared between contracts:
33+
//
34+
// a global struct map of structs emitted by all contracts is tracked and expanded. Structs generated in the bindings
35+
// are not prefixed with the contract name that uses them (to keep the generated bindings less verbose).
36+
//
37+
// This contrasts to other per-contract
38+
// state (constructor/method/event/error pack/unpack methods) which are guaranteed to be unique because of their association
39+
// with the uniquely-named owning contract (whether prefixed in the generated symbol name, or as a member method on a
40+
// contract struct).
41+
//
42+
// In addition, binder contains the input alias map.
43+
// In BindV2, a binder is instantiated to produce a set of tmplContractV2 and tmplStruct objects from the provided ABI
44+
// definition. These are used as part of the input to rendering the binding template.
3045
type binder struct {
31-
// contracts is the map of each individual contract requested binding
46+
// contracts is the map of each individual contract requested binding.
47+
// It is keyed by the contract name provided in the ABI definition.
3248
contracts map[string]*tmplContractV2
3349

3450
// structs is the map of all redeclared structs shared by passed contracts.
@@ -38,33 +54,15 @@ type binder struct {
3854
aliases map[string]string
3955
}
4056

41-
// registerIdentifier applies alias renaming, name normalization (conversion to camel case), and registers the normalized
42-
// name in the specified identifier map. It returns an error if the normalized name already exists in the map.
43-
func (b *contractBinder) registerIdentifier(identifiers map[string]bool, original string) (normalized string, err error) {
44-
normalized = abi.ToCamelCase(alias(b.binder.aliases, original))
45-
// Name shouldn't start with a digit. It will make the generated code invalid.
46-
if len(normalized) > 0 && unicode.IsDigit(rune(normalized[0])) {
47-
normalized = fmt.Sprintf("E%s", normalized)
48-
normalized = abi.ResolveNameConflict(normalized, func(name string) bool {
49-
_, ok := identifiers[name]
50-
return ok
51-
})
52-
}
53-
54-
if _, ok := identifiers[normalized]; ok {
55-
return "", fmt.Errorf("duplicate symbol '%s'", normalized)
56-
}
57-
identifiers[normalized] = true
58-
return normalized, nil
59-
}
60-
6157
// BindStructType register the type to be emitted as a struct in the
6258
// bindings.
6359
func (b *binder) BindStructType(typ abi.Type) {
6460
bindStructType(typ, b.structs)
6561
}
6662

67-
// contractBinder holds state for binding of a single contract
63+
// contractBinder holds state for binding of a single contract.
64+
// It is a type registry for compiling maps of identifiers that will be emitted in generated bindings.
65+
// It also sanitizes/converts information contained in the ABI definition into a data-format that is amenable for rendering the templates.
6866
type contractBinder struct {
6967
binder *binder
7068
calls map[string]*tmplMethod
@@ -88,6 +86,26 @@ func newContractBinder(binder *binder) *contractBinder {
8886
}
8987
}
9088

89+
// registerIdentifier applies alias renaming, name normalization (conversion to camel case), and registers the normalized
90+
// name in the specified identifier map. It returns an error if the normalized name already exists in the map.
91+
func (b *contractBinder) registerIdentifier(identifiers map[string]bool, original string) (normalized string, err error) {
92+
normalized = abi.ToCamelCase(alias(b.binder.aliases, original))
93+
// Name shouldn't start with a digit. It will make the generated code invalid.
94+
if len(normalized) > 0 && unicode.IsDigit(rune(normalized[0])) {
95+
normalized = fmt.Sprintf("E%s", normalized)
96+
normalized = abi.ResolveNameConflict(normalized, func(name string) bool {
97+
_, ok := identifiers[name]
98+
return ok
99+
})
100+
}
101+
102+
if _, ok := identifiers[normalized]; ok {
103+
return "", fmt.Errorf("duplicate symbol '%s'", normalized)
104+
}
105+
identifiers[normalized] = true
106+
return normalized, nil
107+
}
108+
91109
// bindMethod registers a method to be emitted in the bindings.
92110
// The name, inputs and outputs are normalized. If any inputs are
93111
// struct-type their structs are registered to be emitted in the bindings.

0 commit comments

Comments
 (0)