github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/cmd/abigen/main.go (about)

     1  // Copyright 2016 The Spectrum Authors
     2  // This file is part of Spectrum.
     3  //
     4  // Spectrum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // Spectrum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with Spectrum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"encoding/json"
    21  	"flag"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"os"
    25  	"strings"
    26  
    27  	"github.com/SmartMeshFoundation/Spectrum/accounts/abi/bind"
    28  	"github.com/SmartMeshFoundation/Spectrum/common/compiler"
    29  )
    30  
    31  const VSN = "0.0.2"
    32  
    33  var (
    34  	abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind")
    35  	binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)")
    36  	typFlag = flag.String("type", "", "Struct name for the binding (default = package name)")
    37  
    38  	solFlag  = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind")
    39  	solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested")
    40  	excFlag  = flag.String("exc", "", "Comma separated types to exclude from binding")
    41  
    42  	pkgFlag     = flag.String("pkg", "", "Package name to generate the binding into")
    43  	outFlag     = flag.String("out", "", "Output file for the generated binding (default = stdout)")
    44  	langFlag    = flag.String("lang", "go", "Destination language for the bindings (go, java, objc)")
    45  	versionFlag = flag.Bool("version", false, "show version")
    46  )
    47  
    48  func main() {
    49  	// Parse and ensure all needed inputs are specified
    50  	flag.Parse()
    51  	if *versionFlag {
    52  		fmt.Println("Version :", VSN)
    53  		fmt.Println("Copyright 2017-2018 The Spectrum Author (Ethereum-based)")
    54  		os.Exit(-1)
    55  	}
    56  	if *abiFlag == "" && *solFlag == "" {
    57  		fmt.Printf("No contract ABI (--abi) or Solidity source (--sol) specified\n")
    58  		os.Exit(-1)
    59  	} else if (*abiFlag != "" || *binFlag != "" || *typFlag != "") && *solFlag != "" {
    60  		fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag\n")
    61  		os.Exit(-1)
    62  	}
    63  	if *pkgFlag == "" {
    64  		fmt.Printf("No destination package specified (--pkg)\n")
    65  		os.Exit(-1)
    66  	}
    67  	var lang bind.Lang
    68  	switch *langFlag {
    69  	case "go":
    70  		lang = bind.LangGo
    71  	case "java":
    72  		lang = bind.LangJava
    73  	case "objc":
    74  		lang = bind.LangObjC
    75  	default:
    76  		fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", *langFlag)
    77  		os.Exit(-1)
    78  	}
    79  	// If the entire solidity code was specified, build and bind based on that
    80  	var (
    81  		abis  []string
    82  		bins  []string
    83  		types []string
    84  	)
    85  	if *solFlag != "" {
    86  		// Generate the list of types to exclude from binding
    87  		exclude := make(map[string]bool)
    88  		for _, kind := range strings.Split(*excFlag, ",") {
    89  			exclude[strings.ToLower(kind)] = true
    90  		}
    91  		contracts, err := compiler.CompileSolidity(*solcFlag, *solFlag)
    92  		if err != nil {
    93  			fmt.Printf("Failed to build Solidity contract: %v\n", err)
    94  			os.Exit(-1)
    95  		}
    96  		// Gather all non-excluded contract for binding
    97  		for name, contract := range contracts {
    98  			if exclude[strings.ToLower(name)] {
    99  				continue
   100  			}
   101  			abi, _ := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse
   102  			abis = append(abis, string(abi))
   103  			bins = append(bins, contract.Code)
   104  
   105  			nameParts := strings.Split(name, ":")
   106  			types = append(types, nameParts[len(nameParts)-1])
   107  		}
   108  	} else {
   109  		// Otherwise load up the ABI, optional bytecode and type name from the parameters
   110  		abi, err := ioutil.ReadFile(*abiFlag)
   111  		if err != nil {
   112  			fmt.Printf("Failed to read input ABI: %v\n", err)
   113  			os.Exit(-1)
   114  		}
   115  		abis = append(abis, string(abi))
   116  
   117  		bin := []byte{}
   118  		if *binFlag != "" {
   119  			if bin, err = ioutil.ReadFile(*binFlag); err != nil {
   120  				fmt.Printf("Failed to read input bytecode: %v\n", err)
   121  				os.Exit(-1)
   122  			}
   123  		}
   124  		bins = append(bins, string(bin))
   125  
   126  		kind := *typFlag
   127  		if kind == "" {
   128  			kind = *pkgFlag
   129  		}
   130  		types = append(types, kind)
   131  	}
   132  	// Generate the contract binding
   133  	code, err := bind.Bind(types, abis, bins, *pkgFlag, lang)
   134  	if err != nil {
   135  		fmt.Printf("Failed to generate ABI binding: %v\n", err)
   136  		os.Exit(-1)
   137  	}
   138  	// Either flush it out to a file or display on the standard output
   139  	if *outFlag == "" {
   140  		fmt.Printf("%s\n", code)
   141  		return
   142  	}
   143  	if err := ioutil.WriteFile(*outFlag, []byte(code), 0600); err != nil {
   144  		fmt.Printf("Failed to write ABI binding: %v\n", err)
   145  		os.Exit(-1)
   146  	}
   147  }