// Copyright 2016 The go-ethereum Authors // This file is part of go-ethereum. // // go-ethereum is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // go-ethereum is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with go-ethereum. If not, see . package main import ( "encoding/json" "fmt" "os" "strings" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/common/compiler" "github.com/XinFinOrg/XDPoSChain/internal/flags" "github.com/XinFinOrg/XDPoSChain/log" "github.com/urfave/cli/v2" ) var ( // Git SHA1 commit hash of the release (set via linker flags) gitCommit = "" app *cli.App ) var ( // Flags needed by abigen abiFlag = &cli.StringFlag{ Name: "abi", Usage: "Path to the Ethereum contract ABI json to bind", } binFlag = &cli.StringFlag{ Name: "bin", Usage: "Path to the Ethereum contract bytecode (generate deploy method)", } typeFlag = &cli.StringFlag{ Name: "type", Usage: "Struct name for the binding (default = package name)", } solFlag = &cli.StringFlag{ Name: "sol", Usage: "Path to the Ethereum contract Solidity source to build and bind", } solcFlag = &cli.StringFlag{ Name: "solc", Usage: "Solidity compiler to use if source builds are requested", Value: "solc", } excFlag = &cli.StringFlag{ Name: "exc", Usage: "Comma separated types to exclude from binding", } pkgFlag = &cli.StringFlag{ Name: "pkg", Usage: "Package name to generate the binding into", } outFlag = &cli.StringFlag{ Name: "out", Usage: "Output file for the generated binding (default = stdout)", } langFlag = &cli.StringFlag{ Name: "lang", Usage: "Destination language for the bindings (go)", Value: "go", } ) func init() { app = flags.NewApp(gitCommit, "ethereum checkpoint helper tool") app.Name = "abigen" app.Flags = []cli.Flag{ abiFlag, binFlag, typeFlag, solFlag, solcFlag, excFlag, pkgFlag, outFlag, langFlag, } app.Action = abigen } func abigen(c *cli.Context) error { if c.String(abiFlag.Name) == "" && c.String(solFlag.Name) == "" { fmt.Printf("No contract ABI (--abi) or Solidity source (--sol) specified\n") os.Exit(-1) } else if (c.String(abiFlag.Name) != "" || c.String(binFlag.Name) != "" || c.String(typeFlag.Name) != "") && c.String(solFlag.Name) != "" { fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag\n") os.Exit(-1) } 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) } // If the entire solidity code was specified, build and bind based on that var ( abis []string bins []string types []string ) if c.String(solFlag.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 } 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) } // Gather all non-excluded contract for binding for name, contract := range contracts { if exclude[strings.ToLower(name)] { continue } abi, _ := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse abis = append(abis, string(abi)) bins = append(bins, contract.Code) nameParts := strings.Split(name, ":") types = append(types, 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) } abis = append(abis, string(abi)) 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) } } bins = append(bins, string(bin)) kind := c.String(typeFlag.Name) if kind == "" { kind = c.String(pkgFlag.Name) } types = append(types, kind) } // Generate the contract binding code, err := bind.Bind(types, abis, bins, c.String(pkgFlag.Name), lang) if err != nil { fmt.Printf("Failed to generate ABI binding: %v\n", err) os.Exit(-1) } // Either flush it out to a file or display on the standard output if c.String(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) } return nil } func main() { log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true))) if err := app.Run(os.Args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } }