mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-16 18:00:46 +00:00
cmd/abigen: refactor command line interface (#19797)
This commit is contained in:
parent
d6957d9283
commit
057a7dd780
3 changed files with 90 additions and 110 deletions
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/cmd/utils"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/compiler"
|
"github.com/XinFinOrg/XDPoSChain/common/compiler"
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
"github.com/XinFinOrg/XDPoSChain/internal/flags"
|
"github.com/XinFinOrg/XDPoSChain/internal/flags"
|
||||||
|
|
@ -52,6 +53,10 @@ var (
|
||||||
Name: "type",
|
Name: "type",
|
||||||
Usage: "Struct name for the binding (default = package name)",
|
Usage: "Struct name for the binding (default = package name)",
|
||||||
}
|
}
|
||||||
|
jsonFlag = &cli.StringFlag{
|
||||||
|
Name: "combined-json",
|
||||||
|
Usage: "Path to the combined-json file generated by compiler",
|
||||||
|
}
|
||||||
solFlag = &cli.StringFlag{
|
solFlag = &cli.StringFlag{
|
||||||
Name: "sol",
|
Name: "sol",
|
||||||
Usage: "Path to the Ethereum contract Solidity source to build and bind",
|
Usage: "Path to the Ethereum contract Solidity source to build and bind",
|
||||||
|
|
@ -96,6 +101,7 @@ func init() {
|
||||||
abiFlag,
|
abiFlag,
|
||||||
binFlag,
|
binFlag,
|
||||||
typeFlag,
|
typeFlag,
|
||||||
|
jsonFlag,
|
||||||
solFlag,
|
solFlag,
|
||||||
solcFlag,
|
solcFlag,
|
||||||
vyFlag,
|
vyFlag,
|
||||||
|
|
@ -109,28 +115,11 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func abigen(c *cli.Context) error {
|
func abigen(c *cli.Context) error {
|
||||||
if c.String(abiFlag.Name) == "" && c.String(solFlag.Name) == "" && c.String(vyFlag.Name) == "" {
|
utils.CheckExclusive(c, abiFlag, jsonFlag, solFlag, vyFlag) // Only one source can be selected.
|
||||||
fmt.Printf("No contract ABI (--abi), Solidity source (--sol), or Vyper source (--vy) specified\n")
|
|
||||||
os.Exit(-1)
|
|
||||||
} else if (c.String(abiFlag.Name) != "" || c.String(binFlag.Name) != "" || c.String(typeFlag.Name) != "") && (c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "") {
|
|
||||||
fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity (--sol) and Vyper (--vy) flags\n")
|
|
||||||
os.Exit(-1)
|
|
||||||
} else if c.String(solFlag.Name) != "" && c.String(vyFlag.Name) == "" {
|
|
||||||
fmt.Printf("Solidity (--sol) and Vyper (--vy) flags are mutually exclusive\n")
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
if c.String(pkgFlag.Name) == "" {
|
if c.String(pkgFlag.Name) == "" {
|
||||||
fmt.Printf("No destination package specified (--pkg)\n")
|
utils.Fatalf("No destination package specified (--pkg)")
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
var lang bind.Lang
|
|
||||||
switch c.String(langFlag.Name) {
|
|
||||||
case "go":
|
|
||||||
lang = bind.LangGo
|
|
||||||
default:
|
|
||||||
fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", c.String(langFlag.Name))
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
}
|
||||||
|
lang := bind.LangGo
|
||||||
// If the entire solidity code was specified, build and bind based on that
|
// If the entire solidity code was specified, build and bind based on that
|
||||||
var (
|
var (
|
||||||
abis []string
|
abis []string
|
||||||
|
|
@ -139,72 +128,30 @@ func abigen(c *cli.Context) error {
|
||||||
sigs []map[string]string
|
sigs []map[string]string
|
||||||
libs = make(map[string]string)
|
libs = make(map[string]string)
|
||||||
)
|
)
|
||||||
if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || c.String(abiFlag.Name) == "-" {
|
if c.String(abiFlag.Name) != "" {
|
||||||
// Generate the list of types to exclude from binding
|
// Load up the ABI, optional bytecode and type name from the parameters
|
||||||
exclude := make(map[string]bool)
|
var (
|
||||||
for _, kind := range strings.Split(c.String(excFlag.Name), ",") {
|
abi []byte
|
||||||
exclude[strings.ToLower(kind)] = true
|
err error
|
||||||
|
)
|
||||||
|
input := c.String(abiFlag.Name)
|
||||||
|
if input == "-" {
|
||||||
|
abi, err = io.ReadAll(os.Stdin)
|
||||||
|
} else {
|
||||||
|
abi, err = os.ReadFile(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
var contracts map[string]*compiler.Contract
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case c.String(solFlag.Name) != "":
|
|
||||||
contracts, err = compiler.CompileSolidity(c.String(solcFlag.Name), c.String(solFlag.Name))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to build Solidity contract: %v\n", err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
case c.String(vyFlag.Name) != "":
|
|
||||||
contracts, err = compiler.CompileVyper(c.String(vyperFlag.Name), c.String(vyFlag.Name))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to build Vyper contract: %v\n", err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
contracts, err = contractsFromStdin()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to read input ABIs from STDIN: %v\n", err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gather all non-excluded contract for binding
|
|
||||||
for name, contract := range contracts {
|
|
||||||
if exclude[strings.ToLower(name)] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to parse ABIs from compiler output: %v\n", err)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
abis = append(abis, string(abi))
|
|
||||||
bins = append(bins, contract.Code)
|
|
||||||
sigs = append(sigs, contract.Hashes)
|
|
||||||
|
|
||||||
nameParts := strings.Split(name, ":")
|
|
||||||
types = append(types, nameParts[len(nameParts)-1])
|
|
||||||
|
|
||||||
libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36]
|
|
||||||
libs[libPattern] = nameParts[len(nameParts)-1]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Otherwise load up the ABI, optional bytecode and type name from the parameters
|
|
||||||
abi, err := os.ReadFile(c.String(abiFlag.Name))
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to read input ABI: %v\n", err)
|
utils.Fatalf("Failed to read input ABI: %v", err)
|
||||||
os.Exit(-1)
|
|
||||||
}
|
}
|
||||||
abis = append(abis, string(abi))
|
abis = append(abis, string(abi))
|
||||||
|
|
||||||
var bin []byte
|
var bin []byte
|
||||||
if c.String(binFlag.Name) != "" {
|
if binFile := c.String(binFlag.Name); binFile != "" {
|
||||||
if bin, err = os.ReadFile(c.String(binFlag.Name)); err != nil {
|
if bin, err = os.ReadFile(binFile); err != nil {
|
||||||
fmt.Printf("Failed to read input bytecode: %v\n", err)
|
utils.Fatalf("Failed to read input bytecode: %v", err)
|
||||||
os.Exit(-1)
|
}
|
||||||
|
if strings.Contains(string(bin), "//") {
|
||||||
|
utils.Fatalf("Contract has additional library references, please use other mode(e.g. --combined-json) to catch library infos")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bins = append(bins, string(bin))
|
bins = append(bins, string(bin))
|
||||||
|
|
@ -214,21 +161,67 @@ func abigen(c *cli.Context) error {
|
||||||
kind = c.String(pkgFlag.Name)
|
kind = c.String(pkgFlag.Name)
|
||||||
}
|
}
|
||||||
types = append(types, kind)
|
types = append(types, kind)
|
||||||
|
} else {
|
||||||
|
// Generate the list of types to exclude from binding
|
||||||
|
exclude := make(map[string]bool)
|
||||||
|
for _, kind := range strings.Split(c.String(excFlag.Name), ",") {
|
||||||
|
exclude[strings.ToLower(kind)] = true
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
var contracts map[string]*compiler.Contract
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case c.IsSet(solFlag.Name):
|
||||||
|
contracts, err = compiler.CompileSolidity(c.String(solcFlag.Name), c.String(solFlag.Name))
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to build Solidity contract: %v", err)
|
||||||
|
}
|
||||||
|
case c.IsSet(vyFlag.Name):
|
||||||
|
contracts, err = compiler.CompileVyper(c.String(vyperFlag.Name), c.String(vyFlag.Name))
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to build Vyper contract: %v", err)
|
||||||
|
}
|
||||||
|
case c.IsSet(jsonFlag.Name):
|
||||||
|
jsonOutput, err := os.ReadFile(c.String(jsonFlag.Name))
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to read combined-json from compiler: %v", err)
|
||||||
|
}
|
||||||
|
contracts, err = compiler.ParseCombinedJSON(jsonOutput, "", "", "", "")
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to read contract information from json output: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Gather all non-excluded contract for binding
|
||||||
|
for name, contract := range contracts {
|
||||||
|
if exclude[strings.ToLower(name)] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to parse ABIs from compiler output: %v", err)
|
||||||
|
}
|
||||||
|
abis = append(abis, string(abi))
|
||||||
|
bins = append(bins, contract.Code)
|
||||||
|
sigs = append(sigs, contract.Hashes)
|
||||||
|
nameParts := strings.Split(name, ":")
|
||||||
|
types = append(types, nameParts[len(nameParts)-1])
|
||||||
|
|
||||||
|
libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36]
|
||||||
|
libs[libPattern] = nameParts[len(nameParts)-1]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Generate the contract binding
|
// Generate the contract binding
|
||||||
code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs)
|
code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to generate ABI binding: %v\n", err)
|
utils.Fatalf("Failed to generate ABI binding: %v", err)
|
||||||
os.Exit(-1)
|
|
||||||
}
|
}
|
||||||
// Either flush it out to a file or display on the standard output
|
// Either flush it out to a file or display on the standard output
|
||||||
if c.String(outFlag.Name) == "" {
|
if !c.IsSet(outFlag.Name) {
|
||||||
fmt.Printf("%s\n", code)
|
fmt.Printf("%s\n", code)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := os.WriteFile(c.String(outFlag.Name), []byte(code), 0600); err != nil {
|
if err := os.WriteFile(c.String(outFlag.Name), []byte(code), 0600); err != nil {
|
||||||
fmt.Printf("Failed to write ABI binding: %v\n", err)
|
utils.Fatalf("Failed to write ABI binding: %v", err)
|
||||||
os.Exit(-1)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -241,11 +234,3 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func contractsFromStdin() (map[string]*compiler.Contract, error) {
|
|
||||||
bytes, err := io.ReadAll(os.Stdin)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return compiler.ParseCombinedJSON(bytes, "", "", "", "")
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1024,7 +1024,7 @@ func setWS(ctx *cli.Context, cfg *node.Config) {
|
||||||
// setIPC creates an IPC path configuration from the set command line flags,
|
// setIPC creates an IPC path configuration from the set command line flags,
|
||||||
// returning an empty string if IPC was explicitly disabled, or the set path.
|
// returning an empty string if IPC was explicitly disabled, or the set path.
|
||||||
func setIPC(ctx *cli.Context, cfg *node.Config) {
|
func setIPC(ctx *cli.Context, cfg *node.Config) {
|
||||||
checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
|
CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
|
||||||
switch {
|
switch {
|
||||||
case ctx.Bool(IPCDisabledFlag.Name):
|
case ctx.Bool(IPCDisabledFlag.Name):
|
||||||
cfg.IPCPath = ""
|
cfg.IPCPath = ""
|
||||||
|
|
@ -1034,7 +1034,7 @@ func setIPC(ctx *cli.Context, cfg *node.Config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPrefix(ctx *cli.Context, cfg *node.Config) {
|
func setPrefix(ctx *cli.Context, cfg *node.Config) {
|
||||||
checkExclusive(ctx, Enable0xPrefixFlag, EnableXDCPrefixFlag)
|
CheckExclusive(ctx, Enable0xPrefixFlag, EnableXDCPrefixFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeDatabaseHandles raises out the number of allowed file handles per process
|
// MakeDatabaseHandles raises out the number of allowed file handles per process
|
||||||
|
|
@ -1301,10 +1301,10 @@ func setEthash(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkExclusive verifies that only a single isntance of the provided flags was
|
// CheckExclusive verifies that only a single isntance of the provided flags was
|
||||||
// set by the user. Each flag might optionally be followed by a string type to
|
// set by the user. Each flag might optionally be followed by a string type to
|
||||||
// specialize it further.
|
// specialize it further.
|
||||||
func checkExclusive(ctx *cli.Context, args ...interface{}) {
|
func CheckExclusive(ctx *cli.Context, args ...interface{}) {
|
||||||
set := make([]string, 0, 1)
|
set := make([]string, 0, 1)
|
||||||
for i := 0; i < len(args); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
// Make sure the next argument is a flag and skip if not set
|
// Make sure the next argument is a flag and skip if not set
|
||||||
|
|
@ -1381,10 +1381,10 @@ func SetXDCXConfig(ctx *cli.Context, cfg *XDCx.Config, XDCDataDir string) {
|
||||||
// SetEthConfig applies eth-related command line flags to the config.
|
// SetEthConfig applies eth-related command line flags to the config.
|
||||||
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
// Avoid conflicting network flags
|
// Avoid conflicting network flags
|
||||||
checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag)
|
CheckExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag)
|
||||||
checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag)
|
CheckExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag)
|
||||||
checkExclusive(ctx, LightServFlag, LightModeFlag)
|
CheckExclusive(ctx, LightServFlag, LightModeFlag)
|
||||||
checkExclusive(ctx, LightServFlag, SyncModeFlag, "light")
|
CheckExclusive(ctx, LightServFlag, SyncModeFlag, "light")
|
||||||
|
|
||||||
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
||||||
setEtherbase(ctx, ks, cfg)
|
setEtherbase(ctx, ks, cfg)
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,6 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin
|
||||||
if err := json.Unmarshal(combinedJSON, &output); err != nil {
|
if err := json.Unmarshal(combinedJSON, &output); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compilation succeeded, assemble and return the contracts.
|
// Compilation succeeded, assemble and return the contracts.
|
||||||
contracts := make(map[string]*Contract)
|
contracts := make(map[string]*Contract)
|
||||||
for name, info := range output.Contracts {
|
for name, info := range output.Contracts {
|
||||||
|
|
@ -151,14 +150,10 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin
|
||||||
if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil {
|
if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil {
|
||||||
return nil, fmt.Errorf("solc: error reading abi definition (%v)", err)
|
return nil, fmt.Errorf("solc: error reading abi definition (%v)", err)
|
||||||
}
|
}
|
||||||
var userdoc interface{}
|
var userdoc, devdoc interface{}
|
||||||
if err := json.Unmarshal([]byte(info.Userdoc), &userdoc); err != nil {
|
json.Unmarshal([]byte(info.Userdoc), &userdoc)
|
||||||
return nil, fmt.Errorf("solc: error reading user doc: %v", err)
|
json.Unmarshal([]byte(info.Devdoc), &devdoc)
|
||||||
}
|
|
||||||
var devdoc interface{}
|
|
||||||
if err := json.Unmarshal([]byte(info.Devdoc), &devdoc); err != nil {
|
|
||||||
return nil, fmt.Errorf("solc: error reading dev doc: %v", err)
|
|
||||||
}
|
|
||||||
contracts[name] = &Contract{
|
contracts[name] = &Contract{
|
||||||
Code: "0x" + info.Bin,
|
Code: "0x" + info.Bin,
|
||||||
RuntimeCode: "0x" + info.BinRuntime,
|
RuntimeCode: "0x" + info.BinRuntime,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue