@@ -3,14 +3,15 @@ package bind
33import (
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.
3045type 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.
6359func (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.
6866type 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