mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
accounts, abigen: link dependent libs in deploy
This commit is contained in:
parent
5f5de49cd9
commit
4f04fc89bb
3 changed files with 27 additions and 3 deletions
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/format"
|
"go/format"
|
||||||
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
@ -46,7 +47,7 @@ const (
|
||||||
// to be used as is in client code, but rather as an intermediate struct which
|
// to be used as is in client code, but rather as an intermediate struct which
|
||||||
// enforces compile time type safety and naming convention opposed to having to
|
// enforces compile time type safety and naming convention opposed to having to
|
||||||
// manually maintain hard coded strings that break on runtime.
|
// manually maintain hard coded strings that break on runtime.
|
||||||
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang) (string, error) {
|
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string) (string, error) {
|
||||||
// Process each individual contract requested binding
|
// Process each individual contract requested binding
|
||||||
contracts := make(map[string]*tmplContract)
|
contracts := make(map[string]*tmplContract)
|
||||||
|
|
||||||
|
|
@ -142,16 +143,28 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
|
||||||
Calls: calls,
|
Calls: calls,
|
||||||
Transacts: transacts,
|
Transacts: transacts,
|
||||||
Events: events,
|
Events: events,
|
||||||
|
Libraries: make(map[string]string),
|
||||||
Structs: structs,
|
Structs: structs,
|
||||||
}
|
}
|
||||||
if len(fsigs) > i {
|
if len(fsigs) > i {
|
||||||
contracts[types[i]].FuncSigs = fsigs[i]
|
contracts[types[i]].FuncSigs = fsigs[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for pattern, name := range libs {
|
||||||
|
matched, err := regexp.Match("__\\$"+pattern+"\\$__", []byte(contracts[types[i]].InputBin))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Could not search for pattern %v in %v: %v", pattern, contracts[types[i]], err)
|
||||||
|
}
|
||||||
|
if matched {
|
||||||
|
contracts[types[i]].Libraries[pattern] = name
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Generate the contract template data content and render it
|
// Generate the contract template data content and render it
|
||||||
data := &tmplData{
|
data := &tmplData{
|
||||||
Package: pkg,
|
Package: pkg,
|
||||||
Contracts: contracts,
|
Contracts: contracts,
|
||||||
|
Libraries: libs,
|
||||||
}
|
}
|
||||||
buffer := new(bytes.Buffer)
|
buffer := new(bytes.Buffer)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import "github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
type tmplData struct {
|
type tmplData struct {
|
||||||
Package string // Name of the package to place the generated file in
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// tmplContract contains the data needed to generate an individual contract binding.
|
// tmplContract contains the data needed to generate an individual contract binding.
|
||||||
|
|
@ -34,6 +35,7 @@ type tmplContract struct {
|
||||||
Calls map[string]*tmplMethod // Contract calls that only read state data
|
Calls map[string]*tmplMethod // Contract calls that only read state data
|
||||||
Transacts map[string]*tmplMethod // Contract calls that write state data
|
Transacts map[string]*tmplMethod // Contract calls that write state data
|
||||||
Events map[string]*tmplEvent // Contract events accessors
|
Events map[string]*tmplEvent // Contract events accessors
|
||||||
|
Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs
|
||||||
Structs map[string]*tmplStruct // Contract struct type definitions
|
Structs map[string]*tmplStruct // Contract struct type definitions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,7 +123,7 @@ var (
|
||||||
|
|
||||||
{{if .InputBin}}
|
{{if .InputBin}}
|
||||||
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
|
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
|
||||||
const {{.Type}}Bin = ` + "`" + `{{.InputBin}}` + "`" + `
|
var {{.Type}}Bin = ` + "`" + `{{.InputBin}}` + "`" + `
|
||||||
|
|
||||||
// Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
|
// Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
|
||||||
func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
|
func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
|
||||||
|
|
@ -129,6 +131,10 @@ var (
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, nil, nil, err
|
return common.Address{}, nil, nil, err
|
||||||
}
|
}
|
||||||
|
{{range $pattern, $name := .Libraries}}
|
||||||
|
{{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend)
|
||||||
|
{{$contract.Type}}Bin = strings.Replace({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:])
|
||||||
|
{{end}}
|
||||||
address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
|
address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, nil, nil, err
|
return common.Address{}, nil, nil, err
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common/compiler"
|
"github.com/ethereum/go-ethereum/common/compiler"
|
||||||
)
|
)
|
||||||
|
|
@ -81,6 +82,7 @@ func main() {
|
||||||
bins []string
|
bins []string
|
||||||
types []string
|
types []string
|
||||||
sigs []map[string]string
|
sigs []map[string]string
|
||||||
|
libs map[string]string
|
||||||
)
|
)
|
||||||
if *solFlag != "" || *vyFlag != "" || *abiFlag == "-" {
|
if *solFlag != "" || *vyFlag != "" || *abiFlag == "-" {
|
||||||
// Generate the list of types to exclude from binding
|
// Generate the list of types to exclude from binding
|
||||||
|
|
@ -128,6 +130,9 @@ func main() {
|
||||||
|
|
||||||
nameParts := strings.Split(name, ":")
|
nameParts := strings.Split(name, ":")
|
||||||
types = append(types, nameParts[len(nameParts)-1])
|
types = append(types, nameParts[len(nameParts)-1])
|
||||||
|
|
||||||
|
libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36]
|
||||||
|
libs[libPattern] = nameParts[len(nameParts)-1]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise load up the ABI, optional bytecode and type name from the parameters
|
// Otherwise load up the ABI, optional bytecode and type name from the parameters
|
||||||
|
|
@ -155,7 +160,7 @@ func main() {
|
||||||
types = append(types, kind)
|
types = append(types, kind)
|
||||||
}
|
}
|
||||||
// Generate the contract binding
|
// Generate the contract binding
|
||||||
code, err := bind.Bind(types, abis, bins, sigs, *pkgFlag, lang)
|
code, err := bind.Bind(types, abis, bins, sigs, *pkgFlag, lang, libs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to generate ABI binding: %v\n", err)
|
fmt.Printf("Failed to generate ABI binding: %v\n", err)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue