diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 7ad368e5ad..a4dd0963d7 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -43,9 +43,6 @@ import ( "github.com/ethereum/go-ethereum/log" ) -// BindHook is a callback function that can be used to customize the binding. -type BindHook func(lang Lang, pkg string, types []string, contracts map[string]*TmplContract, structs map[string]*TmplStruct) (data interface{}, templateSource string, err error) - // Lang is a target programming language selector to generate bindings for. type Lang int @@ -53,7 +50,7 @@ const ( LangGo Lang = iota ) -func IsKeyWord(arg string) bool { +func isKeyWord(arg string) bool { switch arg { case "break": case "case": @@ -101,10 +98,10 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] func BindHelper(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string, bindHook BindHook) (string, error) { var ( // contracts is the map of each individual contract requested binding - contracts = make(map[string]*TmplContract) + contracts = make(map[string]*tmplContract) // structs is the map of all redeclared structs shared by passed contracts. - structs = make(map[string]*TmplStruct) + structs = make(map[string]*tmplStruct) // isLib is the map used to flag each encountered library as such isLib = make(map[string]struct{}) @@ -125,11 +122,11 @@ func BindHelper(types []string, abis []string, bytecodes []string, fsigs []map[s // Extract the call and transact methods; events, struct definitions; and sort them alphabetically var ( - calls = make(map[string]*TmplMethod) - transacts = make(map[string]*TmplMethod) + calls = make(map[string]*tmplMethod) + transacts = make(map[string]*tmplMethod) events = make(map[string]*tmplEvent) - fallback *TmplMethod - receive *TmplMethod + fallback *tmplMethod + receive *tmplMethod // identifiers are used to detect duplicated identifiers of functions // and events. For all calls, transacts and events, abigen will generate @@ -172,7 +169,7 @@ func BindHelper(types []string, abis []string, bytecodes []string, fsigs []map[s normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) for j, input := range normalized.Inputs { - if input.Name == "" || IsKeyWord(input.Name) { + if input.Name == "" || isKeyWord(input.Name) { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } if hasStruct(input.Type) { @@ -191,9 +188,9 @@ func BindHelper(types []string, abis []string, bytecodes []string, fsigs []map[s } // Append the methods to the call or transact lists if original.IsConstant() { - calls[original.Name] = &TmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} + calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} } else { - transacts[original.Name] = &TmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} + transacts[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} } } for _, original := range evmABI.Events { @@ -224,7 +221,7 @@ func BindHelper(types []string, abis []string, bytecodes []string, fsigs []map[s normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) for j, input := range normalized.Inputs { - if input.Name == "" || IsKeyWord(input.Name) { + if input.Name == "" || isKeyWord(input.Name) { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } // Event is a bit special, we need to define event struct in binding, @@ -245,12 +242,12 @@ func BindHelper(types []string, abis []string, bytecodes []string, fsigs []map[s } // Add two special fallback functions if they exist if evmABI.HasFallback() { - fallback = &TmplMethod{Original: evmABI.Fallback} + fallback = &tmplMethod{Original: evmABI.Fallback} } if evmABI.HasReceive() { - receive = &TmplMethod{Original: evmABI.Receive} + receive = &tmplMethod{Original: evmABI.Receive} } - contracts[types[i]] = &TmplContract{ + contracts[types[i]] = &tmplContract{ Type: capitalise(types[i]), InputABI: strings.ReplaceAll(strippedABI, "\"", "\\\""), InputBin: strings.TrimPrefix(strings.TrimSpace(bytecodes[i]), "0x"), @@ -341,14 +338,10 @@ func BindHelper(types []string, abis []string, bytecodes []string, fsigs []map[s // bindType is a set of type binders that convert Solidity types to some supported // programming language types. -var bindType = map[Lang]func(kind abi.Type, structs map[string]*TmplStruct) string{ +var bindType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ LangGo: bindTypeGo, } -var bindTypeNew = map[Lang]func(kind abi.Type, structs map[string]*TmplStruct) string{ - LangGo: bindTypeNewGo, -} - // bindBasicTypeGo converts basic solidity types(except array, slice and tuple) to Go ones. func bindBasicTypeGo(kind abi.Type) string { switch kind.T { @@ -373,43 +366,10 @@ func bindBasicTypeGo(kind abi.Type) string { } } -// bindTypeNewGo converts new types to Go ones. -func bindTypeNewGo(kind abi.Type, structs map[string]*TmplStruct) string { - switch kind.T { - case abi.TupleTy: - return structs[kind.TupleRawName+kind.String()].Name + "{}" - case abi.ArrayTy: - return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem, structs) + "{}" - case abi.SliceTy: - return "nil" - case abi.AddressTy: - return "common.Address{}" - case abi.IntTy, abi.UintTy: - parts := regexp.MustCompile(`(u)?int([0-9]*)`).FindStringSubmatch(kind.String()) - switch parts[2] { - case "8", "16", "32", "64": - return "0" - } - return "new(big.Int)" - case abi.FixedBytesTy: - return fmt.Sprintf("[%d]byte", kind.Size) + "{}" - case abi.BytesTy: - return "[]byte{}" - case abi.FunctionTy: - return "[24]byte{}" - case abi.BoolTy: - return "false" - case abi.StringTy: - return `""` - default: - return "nil" - } -} - // bindTypeGo converts solidity types to Go ones. Since there is no clear mapping // from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly // mapped will use an upscaled type (e.g. BigDecimal). -func bindTypeGo(kind abi.Type, structs map[string]*TmplStruct) string { +func bindTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { case abi.TupleTy: return structs[kind.TupleRawName+kind.String()].Name @@ -424,13 +384,13 @@ func bindTypeGo(kind abi.Type, structs map[string]*TmplStruct) 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, structs map[string]*TmplStruct) string{ +var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ LangGo: bindTopicTypeGo, } // bindTopicTypeGo converts a Solidity topic type to a Go one. It is almost the same // functionality as for simple types, but dynamic types get converted to hashes. -func bindTopicTypeGo(kind abi.Type, structs map[string]*TmplStruct) string { +func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { bound := bindTypeGo(kind, structs) // todo(rjl493456442) according solidity documentation, indexed event @@ -447,14 +407,14 @@ func bindTopicTypeGo(kind abi.Type, structs map[string]*TmplStruct) string { // bindStructType is a set of type binders that convert Solidity tuple types to some supported // programming language struct definition. -var bindStructType = map[Lang]func(kind abi.Type, structs map[string]*TmplStruct) string{ +var bindStructType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ LangGo: bindStructTypeGo, } // bindStructTypeGo converts a Solidity tuple type to a Go one and records the mapping // in the given map. // Notably, this function will resolve and record nested struct recursively. -func bindStructTypeGo(kind abi.Type, structs map[string]*TmplStruct) string { +func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { case abi.TupleTy: // We compose a raw struct name and a canonical parameter expression @@ -483,7 +443,7 @@ func bindStructTypeGo(kind abi.Type, structs map[string]*TmplStruct) string { } name = capitalise(name) - structs[id] = &TmplStruct{ + structs[id] = &tmplStruct{ Name: name, Fields: fields, } @@ -568,11 +528,3 @@ func hasStruct(t abi.Type) bool { return false } } - -func mkList(args ...interface{}) []interface{} { - return args -} - -func add(a, b int) int { - return a + b -} diff --git a/accounts/abi/bind/bind_extra.go b/accounts/abi/bind/bind_extra.go new file mode 100644 index 0000000000..a622058edc --- /dev/null +++ b/accounts/abi/bind/bind_extra.go @@ -0,0 +1,70 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bind + +import ( + "fmt" + "regexp" + + "github.com/ava-labs/subnet-evm/accounts/abi" +) + +type ( + // These types are exported for use in bind/precompilebind + TmplContract = tmplContract + TmplMethod = tmplMethod + TmplStruct = tmplStruct +) + +// BindHook is a callback function that can be used to customize the binding. +type BindHook func(lang Lang, pkg string, types []string, contracts map[string]*tmplContract, structs map[string]*tmplStruct) (data any, templateSource string, err error) + +func IsKeyWord(arg string) bool { + return isKeyWord(arg) +} + +var bindTypeNew = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ + LangGo: bindTypeNewGo, +} + +// bindTypeNewGo converts new types to Go ones. +func bindTypeNewGo(kind abi.Type, structs map[string]*tmplStruct) string { + switch kind.T { + case abi.TupleTy: + return structs[kind.TupleRawName+kind.String()].Name + "{}" + case abi.ArrayTy: + return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem, structs) + "{}" + case abi.SliceTy: + return "nil" + case abi.AddressTy: + return "common.Address{}" + case abi.IntTy, abi.UintTy: + parts := regexp.MustCompile(`(u)?int([0-9]*)`).FindStringSubmatch(kind.String()) + switch parts[2] { + case "8", "16", "32", "64": + return "0" + } + return "new(big.Int)" + case abi.FixedBytesTy: + return fmt.Sprintf("[%d]byte", kind.Size) + "{}" + case abi.BytesTy: + return "[]byte{}" + case abi.FunctionTy: + return "[24]byte{}" + case abi.BoolTy: + return "false" + case abi.StringTy: + return `""` + default: + return "nil" + } +} + +func mkList(args ...any) []any { + return args +} + +func add(a, b int) int { + return a + b +} diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index a39311d774..0ee3946569 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -31,30 +31,30 @@ import "github.com/ava-labs/subnet-evm/accounts/abi" // tmplData is the data structure required to fill the binding template. type tmplData struct { Package string // Name of the package to place the generated file in - Contracts map[string]*TmplContract // List of contracts to generate into this file + Contracts map[string]*tmplContract // List of contracts to generate into this file Libraries map[string]string // Map the bytecode's link pattern to the library name - Structs map[string]*TmplStruct // Contract struct type definitions + Structs map[string]*tmplStruct // Contract struct type definitions } -// TmplContract contains the data needed to generate an individual contract binding. -type TmplContract struct { +// tmplContract contains the data needed to generate an individual contract binding. +type tmplContract struct { Type string // Type name of the main contract binding InputABI string // JSON ABI used as the input to generate the binding from InputBin string // Optional EVM bytecode used to generate deploy code from FuncSigs map[string]string // Optional map: string signature -> 4-byte signature Constructor abi.Method // Contract constructor for deploy parametrization - Calls map[string]*TmplMethod // Contract calls that only read state data - Transacts map[string]*TmplMethod // Contract calls that write state data - Fallback *TmplMethod // Additional special fallback function - Receive *TmplMethod // Additional special receive function + Calls map[string]*tmplMethod // Contract calls that only read state data + Transacts map[string]*tmplMethod // Contract calls that write state data + Fallback *tmplMethod // Additional special fallback function + Receive *tmplMethod // Additional special receive function Events map[string]*tmplEvent // Contract events accessors Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs Library bool // Indicator whether the contract is a library } -// TmplMethod is a wrapper around an abi.Method that contains a few preprocessed +// tmplMethod is a wrapper around an abi.Method that contains a few preprocessed // and cached data fields. -type TmplMethod struct { +type tmplMethod struct { Original abi.Method // Original method as parsed by the abi package Normalized abi.Method // Normalized version of the parsed method (capitalized names, non-anonymous args/returns) Structured bool // Whether the returns should be accumulated into a struct @@ -75,9 +75,9 @@ type tmplField struct { SolKind abi.Type // Raw abi type information } -// TmplStruct is a wrapper around an abi.tuple and contains an auto-generated +// tmplStruct is a wrapper around an abi.tuple and contains an auto-generated // struct name. -type TmplStruct struct { +type tmplStruct struct { Name string // Auto-generated struct name(before solidity v0.5.11) or raw name. Fields []*tmplField // Struct fields definition depends on the binding language. } diff --git a/cmd/abigen/namefilter.go b/cmd/abigen/namefilter.go index e43cdf38e0..5fcf6e17a0 100644 --- a/cmd/abigen/namefilter.go +++ b/cmd/abigen/namefilter.go @@ -7,7 +7,6 @@ // original code from which it is derived. // // Much love to the original authors for their work. -// ********** package main import ( diff --git a/cmd/abigen/namefilter_test.go b/cmd/abigen/namefilter_test.go index 43dd28707e..d6c9a0a932 100644 --- a/cmd/abigen/namefilter_test.go +++ b/cmd/abigen/namefilter_test.go @@ -7,7 +7,6 @@ // original code from which it is derived. // // Much love to the original authors for their work. -// ********** package main import ( diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index 928041e02b..0d7ce2fd57 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -319,7 +319,7 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode return root, ctx.nodes, triestate.New(ctx.accountOrigin, ctx.storageOrigin, nil) } -// lastRoot returns the latest root hash, or empty if nothing is cached. +// lastHash returns the latest root hash, or empty if nothing is cached. func (t *tester) lastHash() common.Hash { if len(t.roots) == 0 { return common.Hash{}