mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +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"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
"github.com/XinFinOrg/XDPoSChain/cmd/utils"
|
||||
"github.com/XinFinOrg/XDPoSChain/common/compiler"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/XinFinOrg/XDPoSChain/internal/flags"
|
||||
|
|
@ -52,6 +53,10 @@ var (
|
|||
Name: "type",
|
||||
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{
|
||||
Name: "sol",
|
||||
Usage: "Path to the Ethereum contract Solidity source to build and bind",
|
||||
|
|
@ -96,6 +101,7 @@ func init() {
|
|||
abiFlag,
|
||||
binFlag,
|
||||
typeFlag,
|
||||
jsonFlag,
|
||||
solFlag,
|
||||
solcFlag,
|
||||
vyFlag,
|
||||
|
|
@ -109,28 +115,11 @@ func init() {
|
|||
}
|
||||
|
||||
func abigen(c *cli.Context) error {
|
||||
if c.String(abiFlag.Name) == "" && c.String(solFlag.Name) == "" && c.String(vyFlag.Name) == "" {
|
||||
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)
|
||||
}
|
||||
utils.CheckExclusive(c, abiFlag, jsonFlag, solFlag, vyFlag) // Only one source can be selected.
|
||||
if c.String(pkgFlag.Name) == "" {
|
||||
fmt.Printf("No destination package specified (--pkg)\n")
|
||||
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)
|
||||
utils.Fatalf("No destination package specified (--pkg)")
|
||||
}
|
||||
lang := bind.LangGo
|
||||
// If the entire solidity code was specified, build and bind based on that
|
||||
var (
|
||||
abis []string
|
||||
|
|
@ -139,72 +128,30 @@ func abigen(c *cli.Context) error {
|
|||
sigs []map[string]string
|
||||
libs = make(map[string]string)
|
||||
)
|
||||
if c.String(solFlag.Name) != "" || c.String(vyFlag.Name) != "" || c.String(abiFlag.Name) == "-" {
|
||||
// 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
|
||||
if c.String(abiFlag.Name) != "" {
|
||||
// Load up the ABI, optional bytecode and type name from the parameters
|
||||
var (
|
||||
abi []byte
|
||||
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 {
|
||||
fmt.Printf("Failed to read input ABI: %v\n", err)
|
||||
os.Exit(-1)
|
||||
utils.Fatalf("Failed to read input ABI: %v", err)
|
||||
}
|
||||
abis = append(abis, string(abi))
|
||||
|
||||
var bin []byte
|
||||
if c.String(binFlag.Name) != "" {
|
||||
if bin, err = os.ReadFile(c.String(binFlag.Name)); err != nil {
|
||||
fmt.Printf("Failed to read input bytecode: %v\n", err)
|
||||
os.Exit(-1)
|
||||
if binFile := c.String(binFlag.Name); binFile != "" {
|
||||
if bin, err = os.ReadFile(binFile); err != nil {
|
||||
utils.Fatalf("Failed to read input bytecode: %v", err)
|
||||
}
|
||||
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))
|
||||
|
|
@ -214,21 +161,67 @@ func abigen(c *cli.Context) error {
|
|||
kind = c.String(pkgFlag.Name)
|
||||
}
|
||||
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
|
||||
code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to generate ABI binding: %v\n", err)
|
||||
os.Exit(-1)
|
||||
utils.Fatalf("Failed to generate ABI binding: %v", err)
|
||||
}
|
||||
// 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)
|
||||
return nil
|
||||
}
|
||||
if err := os.WriteFile(c.String(outFlag.Name), []byte(code), 0600); err != nil {
|
||||
fmt.Printf("Failed to write ABI binding: %v\n", err)
|
||||
os.Exit(-1)
|
||||
utils.Fatalf("Failed to write ABI binding: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -241,11 +234,3 @@ func main() {
|
|||
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,
|
||||
// returning an empty string if IPC was explicitly disabled, or the set path.
|
||||
func setIPC(ctx *cli.Context, cfg *node.Config) {
|
||||
checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
|
||||
CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
|
||||
switch {
|
||||
case ctx.Bool(IPCDisabledFlag.Name):
|
||||
cfg.IPCPath = ""
|
||||
|
|
@ -1034,7 +1034,7 @@ func setIPC(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
|
||||
|
|
@ -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
|
||||
// specialize it further.
|
||||
func checkExclusive(ctx *cli.Context, args ...interface{}) {
|
||||
func CheckExclusive(ctx *cli.Context, args ...interface{}) {
|
||||
set := make([]string, 0, 1)
|
||||
for i := 0; i < len(args); i++ {
|
||||
// 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.
|
||||
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||
// Avoid conflicting network flags
|
||||
checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag)
|
||||
checkExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag)
|
||||
checkExclusive(ctx, LightServFlag, LightModeFlag)
|
||||
checkExclusive(ctx, LightServFlag, SyncModeFlag, "light")
|
||||
CheckExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag)
|
||||
CheckExclusive(ctx, FastSyncFlag, LightModeFlag, SyncModeFlag)
|
||||
CheckExclusive(ctx, LightServFlag, LightModeFlag)
|
||||
CheckExclusive(ctx, LightServFlag, SyncModeFlag, "light")
|
||||
|
||||
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
|
||||
setEtherbase(ctx, ks, cfg)
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin
|
|||
if err := json.Unmarshal(combinedJSON, &output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compilation succeeded, assemble and return the contracts.
|
||||
contracts := make(map[string]*Contract)
|
||||
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 {
|
||||
return nil, fmt.Errorf("solc: error reading abi definition (%v)", err)
|
||||
}
|
||||
var userdoc interface{}
|
||||
if err := json.Unmarshal([]byte(info.Userdoc), &userdoc); err != nil {
|
||||
return nil, fmt.Errorf("solc: error reading user doc: %v", err)
|
||||
}
|
||||
var devdoc interface{}
|
||||
if err := json.Unmarshal([]byte(info.Devdoc), &devdoc); err != nil {
|
||||
return nil, fmt.Errorf("solc: error reading dev doc: %v", err)
|
||||
}
|
||||
var userdoc, devdoc interface{}
|
||||
json.Unmarshal([]byte(info.Userdoc), &userdoc)
|
||||
json.Unmarshal([]byte(info.Devdoc), &devdoc)
|
||||
|
||||
contracts[name] = &Contract{
|
||||
Code: "0x" + info.Bin,
|
||||
RuntimeCode: "0x" + info.BinRuntime,
|
||||
|
|
|
|||
Loading…
Reference in a new issue