@@ -82,6 +82,100 @@ func isKeyWord(arg string) bool {
8282// enforces compile time type safety and naming convention opposed to having to
8383// manually maintain hard coded strings that break on runtime.
8484func Bind (types []string , abis []string , bytecodes []string , fsigs []map [string ]string , pkg string , lang Lang , libs map [string ]string , aliases map [string ]string ) (string , error ) {
85+ data , err := bind (types , abis , bytecodes , fsigs , pkg , lang , libs , aliases )
86+ if err != nil {
87+ return "" , err
88+ }
89+ buffer := new (bytes.Buffer )
90+
91+ funcs := map [string ]interface {}{
92+ "bindtype" : bindType [lang ],
93+ "bindtopictype" : bindTopicType [lang ],
94+ "namedtype" : namedType [lang ],
95+ "capitalise" : capitalise ,
96+ "decapitalise" : decapitalise ,
97+ }
98+ tmpl := template .Must (template .New ("" ).Funcs (funcs ).Parse (tmplSource [lang ]))
99+ if err := tmpl .Execute (buffer , data ); err != nil {
100+ return "" , err
101+ }
102+ // For Go bindings pass the code through gofmt to clean it up
103+ if lang == LangGo {
104+ code , err := format .Source (buffer .Bytes ())
105+ if err != nil {
106+ return "" , fmt .Errorf ("%v\n %s" , err , buffer )
107+ }
108+ return string (code ), nil
109+ }
110+ // For all others just return as is for now
111+ return buffer .String (), nil
112+ }
113+
114+ func BindV2 (types []string , abis []string , bytecodes []string , fsigs []map [string ]string , pkg string , lang Lang , libs map [string ]string , aliases map [string ]string ) (string , error ) {
115+ data , err := bind (types , abis , bytecodes , fsigs , pkg , lang , libs , aliases )
116+ if err != nil {
117+ return "" , err
118+ }
119+ for _ , c := range data .Contracts {
120+ // We want pack/unpack methods for all existing methods.
121+ for name , t := range c .Transacts {
122+ c .Calls [name ] = t
123+ }
124+ c .Transacts = nil
125+
126+ // Make sure we return one argument. If multiple exist
127+ // merge them into a struct.
128+ for _ , call := range c .Calls {
129+ if call .Structured {
130+ continue
131+ }
132+ if len (call .Normalized .Outputs ) == 1 {
133+ continue
134+ }
135+ // Build up dictionary of existing arg names.
136+ keys := make (map [string ]struct {})
137+ for _ , o := range call .Normalized .Outputs {
138+ if o .Name != "" {
139+ keys [strings .ToLower (o .Name )] = struct {}{}
140+ }
141+ }
142+ // Assign names to anonymous fields.
143+ for i , o := range call .Normalized .Outputs {
144+ if o .Name != "" {
145+ continue
146+ }
147+ o .Name = capitalise (abi .ResolveNameConflict ("arg" , func (name string ) bool { _ , ok := keys [name ]; return ok }))
148+ call .Normalized .Outputs [i ] = o
149+ keys [strings .ToLower (o .Name )] = struct {}{}
150+ }
151+ call .Structured = true
152+ }
153+ }
154+ buffer := new (bytes.Buffer )
155+ funcs := map [string ]interface {}{
156+ "bindtype" : bindType [lang ],
157+ "bindtopictype" : bindTopicType [lang ],
158+ "namedtype" : namedType [lang ],
159+ "capitalise" : capitalise ,
160+ "decapitalise" : decapitalise ,
161+ }
162+ tmpl := template .Must (template .New ("" ).Funcs (funcs ).Parse (tmplSourceV2 [lang ]))
163+ if err := tmpl .Execute (buffer , data ); err != nil {
164+ return "" , err
165+ }
166+ // For Go bindings pass the code through gofmt to clean it up
167+ if lang == LangGo {
168+ code , err := format .Source (buffer .Bytes ())
169+ if err != nil {
170+ return "" , fmt .Errorf ("%v\n %s" , err , buffer )
171+ }
172+ return string (code ), nil
173+ }
174+ // For all others just return as is for now
175+ return buffer .String (), nil
176+ }
177+
178+ func bind (types []string , abis []string , bytecodes []string , fsigs []map [string ]string , pkg string , lang Lang , libs map [string ]string , aliases map [string ]string ) (* tmplData , error ) {
85179 var (
86180 // contracts is the map of each individual contract requested binding
87181 contracts = make (map [string ]* tmplContract )
@@ -96,7 +190,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
96190 // Parse the actual ABI to generate the binding for
97191 evmABI , err := abi .JSON (strings .NewReader (abis [i ]))
98192 if err != nil {
99- return "" , err
193+ return nil , err
100194 }
101195 // Strip any whitespace from the JSON ABI
102196 strippedABI := strings .Map (func (r rune ) rune {
@@ -140,7 +234,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
140234 identifiers = transactIdentifiers
141235 }
142236 if identifiers [normalizedName ] {
143- return "" , fmt .Errorf ("duplicated identifier \" %s\" (normalized \" %s\" ), use --alias for renaming" , original .Name , normalizedName )
237+ return nil , fmt .Errorf ("duplicated identifier \" %s\" (normalized \" %s\" ), use --alias for renaming" , original .Name , normalizedName )
144238 }
145239 identifiers [normalizedName ] = true
146240
@@ -183,7 +277,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
183277 // Ensure there is no duplicated identifier
184278 normalizedName := methodNormalizer [lang ](alias (aliases , original .Name ))
185279 if eventIdentifiers [normalizedName ] {
186- return "" , fmt .Errorf ("duplicated identifier \" %s\" (normalized \" %s\" ), use --alias for renaming" , original .Name , normalizedName )
280+ return nil , fmt .Errorf ("duplicated identifier \" %s\" (normalized \" %s\" ), use --alias for renaming" , original .Name , normalizedName )
187281 }
188282 eventIdentifiers [normalizedName ] = true
189283 normalized .Name = normalizedName
@@ -218,6 +312,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
218312 if evmABI .HasReceive () {
219313 receive = & tmplMethod {Original : evmABI .Receive }
220314 }
315+
221316 contracts [types [i ]] = & tmplContract {
222317 Type : capitalise (types [i ]),
223318 InputABI : strings .ReplaceAll (strippedABI , "\" " , "\\ \" " ),
@@ -262,29 +357,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
262357 Libraries : libs ,
263358 Structs : structs ,
264359 }
265- buffer := new (bytes.Buffer )
266-
267- funcs := map [string ]interface {}{
268- "bindtype" : bindType [lang ],
269- "bindtopictype" : bindTopicType [lang ],
270- "namedtype" : namedType [lang ],
271- "capitalise" : capitalise ,
272- "decapitalise" : decapitalise ,
273- }
274- tmpl := template .Must (template .New ("" ).Funcs (funcs ).Parse (tmplSource [lang ]))
275- if err := tmpl .Execute (buffer , data ); err != nil {
276- return "" , err
277- }
278- // For Go bindings pass the code through gofmt to clean it up
279- if lang == LangGo {
280- code , err := format .Source (buffer .Bytes ())
281- if err != nil {
282- return "" , fmt .Errorf ("%v\n %s" , err , buffer )
283- }
284- return string (code ), nil
285- }
286- // For all others just return as is for now
287- return buffer .String (), nil
360+ return data , nil
288361}
289362
290363// bindType is a set of type binders that convert Solidity types to some supported
0 commit comments