| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | // Copyright 2016 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2016-04-14 18:18:24 +02:00
										 |  |  | // This file is part of go-ethereum. | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2016-04-14 18:18:24 +02:00
										 |  |  | // 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 | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2016-04-14 18:18:24 +02:00
										 |  |  | // go-ethereum is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2016-04-14 18:18:24 +02:00
										 |  |  | // GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2016-04-14 18:18:24 +02:00
										 |  |  | // You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | 	"flag" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2016-03-26 11:43:09 +02:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/accounts/abi/bind" | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common/compiler" | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind") | 
					
						
							| 
									
										
										
										
											2016-03-17 19:27:37 +02:00
										 |  |  | 	binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") | 
					
						
							| 
									
										
										
										
											2016-09-05 19:07:57 +03:00
										 |  |  | 	typFlag = flag.String("type", "", "Struct name for the binding (default = package name)") | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	solFlag  = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") | 
					
						
							|  |  |  | 	solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") | 
					
						
							| 
									
										
										
										
											2016-03-26 11:43:09 +02:00
										 |  |  | 	excFlag  = flag.String("exc", "", "Comma separated types to exclude from binding") | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-05 19:07:57 +03:00
										 |  |  | 	pkgFlag  = flag.String("pkg", "", "Package name to generate the binding into") | 
					
						
							|  |  |  | 	outFlag  = flag.String("out", "", "Output file for the generated binding (default = stdout)") | 
					
						
							|  |  |  | 	langFlag = flag.String("lang", "go", "Destination language for the bindings (go, java, objc)") | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func main() { | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 	// Parse and ensure all needed inputs are specified | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | 	flag.Parse() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 	if *abiFlag == "" && *solFlag == "" { | 
					
						
							|  |  |  | 		fmt.Printf("No contract ABI (--abi) or Solidity source (--sol) specified\n") | 
					
						
							|  |  |  | 		os.Exit(-1) | 
					
						
							|  |  |  | 	} else if (*abiFlag != "" || *binFlag != "" || *typFlag != "") && *solFlag != "" { | 
					
						
							|  |  |  | 		fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag\n") | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | 		os.Exit(-1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if *pkgFlag == "" { | 
					
						
							| 
									
										
										
										
											2016-09-05 19:07:57 +03:00
										 |  |  | 		fmt.Printf("No destination package specified (--pkg)\n") | 
					
						
							|  |  |  | 		os.Exit(-1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var lang bind.Lang | 
					
						
							|  |  |  | 	switch *langFlag { | 
					
						
							|  |  |  | 	case "go": | 
					
						
							|  |  |  | 		lang = bind.LangGo | 
					
						
							|  |  |  | 	case "java": | 
					
						
							|  |  |  | 		lang = bind.LangJava | 
					
						
							|  |  |  | 	case "objc": | 
					
						
							|  |  |  | 		lang = bind.LangObjC | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", *langFlag) | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | 		os.Exit(-1) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 	// If the entire solidity code was specified, build and bind based on that | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		abis  []string | 
					
						
							|  |  |  | 		bins  []string | 
					
						
							|  |  |  | 		types []string | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	if *solFlag != "" { | 
					
						
							| 
									
										
										
										
											2016-03-26 11:43:09 +02:00
										 |  |  | 		// Generate the list of types to exclude from binding | 
					
						
							|  |  |  | 		exclude := make(map[string]bool) | 
					
						
							|  |  |  | 		for _, kind := range strings.Split(*excFlag, ",") { | 
					
						
							|  |  |  | 			exclude[strings.ToLower(kind)] = true | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-15 00:36:31 +02:00
										 |  |  | 		contracts, err := compiler.CompileSolidity(*solcFlag, *solFlag) | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			fmt.Printf("Failed to build Solidity contract: %v\n", err) | 
					
						
							|  |  |  | 			os.Exit(-1) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-26 11:43:09 +02:00
										 |  |  | 		// Gather all non-excluded contract for binding | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 		for name, contract := range contracts { | 
					
						
							| 
									
										
										
										
											2016-03-26 11:43:09 +02:00
										 |  |  | 			if exclude[strings.ToLower(name)] { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 			abi, _ := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse | 
					
						
							|  |  |  | 			abis = append(abis, string(abi)) | 
					
						
							|  |  |  | 			bins = append(bins, contract.Code) | 
					
						
							| 
									
										
										
										
											2017-02-06 18:16:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			nameParts := strings.Split(name, ":") | 
					
						
							|  |  |  | 			types = append(types, nameParts[len(nameParts)-1]) | 
					
						
							| 
									
										
										
										
											2016-03-21 14:34:49 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// Otherwise load up the ABI, optional bytecode and type name from the parameters | 
					
						
							|  |  |  | 		abi, err := ioutil.ReadFile(*abiFlag) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			fmt.Printf("Failed to read input ABI: %v\n", err) | 
					
						
							|  |  |  | 			os.Exit(-1) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		abis = append(abis, string(abi)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bin := []byte{} | 
					
						
							|  |  |  | 		if *binFlag != "" { | 
					
						
							|  |  |  | 			if bin, err = ioutil.ReadFile(*binFlag); err != nil { | 
					
						
							|  |  |  | 				fmt.Printf("Failed to read input bytecode: %v\n", err) | 
					
						
							|  |  |  | 				os.Exit(-1) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		bins = append(bins, string(bin)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		kind := *typFlag | 
					
						
							|  |  |  | 		if kind == "" { | 
					
						
							|  |  |  | 			kind = *pkgFlag | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		types = append(types, kind) | 
					
						
							| 
									
										
										
										
											2016-03-17 19:27:37 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Generate the contract binding | 
					
						
							| 
									
										
										
										
											2016-09-05 19:07:57 +03:00
										 |  |  | 	code, err := bind.Bind(types, abis, bins, *pkgFlag, lang) | 
					
						
							| 
									
										
										
										
											2016-03-16 12:48:33 +02:00
										 |  |  | 	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 *outFlag == "" { | 
					
						
							|  |  |  | 		fmt.Printf("%s\n", code) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := ioutil.WriteFile(*outFlag, []byte(code), 0600); err != nil { | 
					
						
							|  |  |  | 		fmt.Printf("Failed to write ABI binding: %v\n", err) | 
					
						
							|  |  |  | 		os.Exit(-1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |