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 }