github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/cmd/abigen/main.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum 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 // go-ethereum 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 go-ethereum. 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/ethereumproject/go-ethereum/accounts/abi/bind" 28 "github.com/ethereumproject/go-ethereum/common/compiler" 29 ) 30 31 // Version is the application revision identifier. It can be set with the linker 32 // as in: go build -ldflags "-X main.Version="`git describe --tags` 33 var Version = "unknown" 34 35 var ( 36 abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind") 37 binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") 38 typFlag = flag.String("type", "", "Go struct name for the binding (default = package name)") 39 40 solFlag = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") 41 solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") 42 excFlag = flag.String("exc", "", "Comma separated types to exclude from binding") 43 44 pkgFlag = flag.String("pkg", "", "Go package name to generate the binding into") 45 outFlag = flag.String("out", "", "Output file for the generated binding (default = stdout)") 46 versionFlag = flag.Bool("version", false, "Prints the revision identifier and exit immediatily.") 47 ) 48 49 func main() { 50 // Parse and ensure all needed inputs are specified 51 flag.Parse() 52 53 if *versionFlag { 54 fmt.Println("abigen version", Version) 55 os.Exit(0) 56 } 57 58 if *abiFlag == "" && *solFlag == "" { 59 fmt.Printf("No contract ABI (--abi) or Solidity source (--sol) specified\n") 60 os.Exit(-1) 61 } else if (*abiFlag != "" || *binFlag != "" || *typFlag != "") && *solFlag != "" { 62 fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag\n") 63 os.Exit(-1) 64 } 65 if *pkgFlag == "" { 66 fmt.Printf("No destination Go package specified (--pkg)\n") 67 os.Exit(-1) 68 } 69 // If the entire solidity code was specified, build and bind based on that 70 var ( 71 abis []string 72 bins []string 73 types []string 74 ) 75 if *solFlag != "" { 76 // Generate the list of types to exclude from binding 77 exclude := make(map[string]bool) 78 for _, kind := range strings.Split(*excFlag, ",") { 79 exclude[strings.ToLower(kind)] = true 80 } 81 // Build the Solidity source into bindable components 82 solc, err := compiler.New(*solcFlag) 83 if err != nil { 84 fmt.Printf("Failed to locate Solidity compiler: %v\n", err) 85 os.Exit(-1) 86 } 87 source, err := ioutil.ReadFile(*solFlag) 88 if err != nil { 89 fmt.Printf("Failed to read Soldity source code: %v\n", err) 90 os.Exit(-1) 91 } 92 contracts, err := solc.Compile(string(source)) 93 if err != nil { 94 fmt.Printf("Failed to build Solidity contract: %v\n", err) 95 os.Exit(-1) 96 } 97 // Gather all non-excluded contract for binding 98 for name, contract := range contracts { 99 if exclude[strings.ToLower(name)] { 100 continue 101 } 102 abi, _ := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse 103 abis = append(abis, string(abi)) 104 bins = append(bins, contract.Code) 105 types = append(types, name) 106 } 107 } else { 108 // Otherwise load up the ABI, optional bytecode and type name from the parameters 109 abi, err := ioutil.ReadFile(*abiFlag) 110 if err != nil { 111 fmt.Printf("Failed to read input ABI: %v\n", err) 112 os.Exit(-1) 113 } 114 abis = append(abis, string(abi)) 115 116 bin := []byte{} 117 if *binFlag != "" { 118 if bin, err = ioutil.ReadFile(*binFlag); err != nil { 119 fmt.Printf("Failed to read input bytecode: %v\n", err) 120 os.Exit(-1) 121 } 122 } 123 bins = append(bins, string(bin)) 124 125 kind := *typFlag 126 if kind == "" { 127 kind = *pkgFlag 128 } 129 types = append(types, kind) 130 } 131 // Generate the contract binding 132 code, err := bind.Bind(types, abis, bins, *pkgFlag) 133 if err != nil { 134 fmt.Printf("Failed to generate ABI binding: %v\n", err) 135 os.Exit(-1) 136 } 137 // Either flush it out to a file or display on the standard output 138 if *outFlag == "" { 139 fmt.Printf("%s\n", code) 140 return 141 } 142 if err := ioutil.WriteFile(*outFlag, []byte(code), 0600); err != nil { 143 fmt.Printf("Failed to write ABI binding: %v\n", err) 144 os.Exit(-1) 145 } 146 }