github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/cmd/abigen/main.go (about) 1 2 package main 3 4 import ( 5 "encoding/json" 6 "flag" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "strings" 11 12 "github.com/quickchainproject/quickchain/accounts/abi/bind" 13 "github.com/quickchainproject/quickchain/common/compiler" 14 ) 15 16 var ( 17 abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind") 18 binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") 19 typFlag = flag.String("type", "", "Struct name for the binding (default = package name)") 20 21 solFlag = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") 22 solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") 23 excFlag = flag.String("exc", "", "Comma separated types to exclude from binding") 24 25 pkgFlag = flag.String("pkg", "", "Package name to generate the binding into") 26 outFlag = flag.String("out", "", "Output file for the generated binding (default = stdout)") 27 langFlag = flag.String("lang", "go", "Destination language for the bindings (go, java, objc)") 28 ) 29 30 func main() { 31 // Parse and ensure all needed inputs are specified 32 flag.Parse() 33 34 if *abiFlag == "" && *solFlag == "" { 35 fmt.Printf("No contract ABI (--abi) or Solidity source (--sol) specified\n") 36 os.Exit(-1) 37 } else if (*abiFlag != "" || *binFlag != "" || *typFlag != "") && *solFlag != "" { 38 fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag\n") 39 os.Exit(-1) 40 } 41 if *pkgFlag == "" { 42 fmt.Printf("No destination package specified (--pkg)\n") 43 os.Exit(-1) 44 } 45 var lang bind.Lang 46 switch *langFlag { 47 case "go": 48 lang = bind.LangGo 49 case "java": 50 lang = bind.LangJava 51 case "objc": 52 lang = bind.LangObjC 53 default: 54 fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", *langFlag) 55 os.Exit(-1) 56 } 57 // If the entire solidity code was specified, build and bind based on that 58 var ( 59 abis []string 60 bins []string 61 types []string 62 ) 63 if *solFlag != "" { 64 // Generate the list of types to exclude from binding 65 exclude := make(map[string]bool) 66 for _, kind := range strings.Split(*excFlag, ",") { 67 exclude[strings.ToLower(kind)] = true 68 } 69 contracts, err := compiler.CompileSolidity(*solcFlag, *solFlag) 70 if err != nil { 71 fmt.Printf("Failed to build Solidity contract: %v\n", err) 72 os.Exit(-1) 73 } 74 // Gather all non-excluded contract for binding 75 for name, contract := range contracts { 76 if exclude[strings.ToLower(name)] { 77 continue 78 } 79 abi, _ := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse 80 abis = append(abis, string(abi)) 81 bins = append(bins, contract.Code) 82 83 nameParts := strings.Split(name, ":") 84 types = append(types, nameParts[len(nameParts)-1]) 85 } 86 } else { 87 // Otherwise load up the ABI, optional bytecode and type name from the parameters 88 abi, err := ioutil.ReadFile(*abiFlag) 89 if err != nil { 90 fmt.Printf("Failed to read input ABI: %v\n", err) 91 os.Exit(-1) 92 } 93 abis = append(abis, string(abi)) 94 95 bin := []byte{} 96 if *binFlag != "" { 97 if bin, err = ioutil.ReadFile(*binFlag); err != nil { 98 fmt.Printf("Failed to read input bytecode: %v\n", err) 99 os.Exit(-1) 100 } 101 } 102 bins = append(bins, string(bin)) 103 104 kind := *typFlag 105 if kind == "" { 106 kind = *pkgFlag 107 } 108 types = append(types, kind) 109 } 110 // Generate the contract binding 111 code, err := bind.Bind(types, abis, bins, *pkgFlag, lang) 112 if err != nil { 113 fmt.Printf("Failed to generate ABI binding: %v\n", err) 114 os.Exit(-1) 115 } 116 // Either flush it out to a file or display on the standard output 117 if *outFlag == "" { 118 fmt.Printf("%s\n", code) 119 return 120 } 121 if err := ioutil.WriteFile(*outFlag, []byte(code), 0600); err != nil { 122 fmt.Printf("Failed to write ABI binding: %v\n", err) 123 os.Exit(-1) 124 } 125 }