github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/cmd/abigen/main.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:27</date> 10 //</624342588459061248> 11 12 13 package main 14 15 import ( 16 "encoding/json" 17 "flag" 18 "fmt" 19 "io/ioutil" 20 "os" 21 "strings" 22 23 "github.com/ethereum/go-ethereum/accounts/abi/bind" 24 "github.com/ethereum/go-ethereum/common/compiler" 25 ) 26 27 var ( 28 abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind, - for STDIN") 29 binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") 30 typFlag = flag.String("type", "", "Struct name for the binding (default = package name)") 31 32 solFlag = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") 33 solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") 34 excFlag = flag.String("exc", "", "Comma separated types to exclude from binding") 35 36 pkgFlag = flag.String("pkg", "", "Package name to generate the binding into") 37 outFlag = flag.String("out", "", "Output file for the generated binding (default = stdout)") 38 langFlag = flag.String("lang", "go", "Destination language for the bindings (go, java, objc)") 39 ) 40 41 func main() { 42 //分析并确保指定了所有需要的输入 43 flag.Parse() 44 45 if *abiFlag == "" && *solFlag == "" { 46 fmt.Printf("No contract ABI (--abi) or Solidity source (--sol) specified\n") 47 os.Exit(-1) 48 } else if (*abiFlag != "" || *binFlag != "" || *typFlag != "") && *solFlag != "" { 49 fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag\n") 50 os.Exit(-1) 51 } 52 if *pkgFlag == "" { 53 fmt.Printf("No destination package specified (--pkg)\n") 54 os.Exit(-1) 55 } 56 var lang bind.Lang 57 switch *langFlag { 58 case "go": 59 lang = bind.LangGo 60 case "java": 61 lang = bind.LangJava 62 case "objc": 63 lang = bind.LangObjC 64 default: 65 fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", *langFlag) 66 os.Exit(-1) 67 } 68 //如果指定了整个solidity代码,则基于该代码构建和绑定 69 var ( 70 abis []string 71 bins []string 72 types []string 73 ) 74 if *solFlag != "" || *abiFlag == "-" { 75 //生成要从绑定中排除的类型列表 76 exclude := make(map[string]bool) 77 for _, kind := range strings.Split(*excFlag, ",") { 78 exclude[strings.ToLower(kind)] = true 79 } 80 81 var contracts map[string]*compiler.Contract 82 var err error 83 if *solFlag != "" { 84 contracts, err = compiler.CompileSolidity(*solcFlag, *solFlag) 85 if err != nil { 86 fmt.Printf("Failed to build Solidity contract: %v\n", err) 87 os.Exit(-1) 88 } 89 } else { 90 contracts, err = contractsFromStdin() 91 if err != nil { 92 fmt.Printf("Failed to read input ABIs from STDIN: %v\n", err) 93 os.Exit(-1) 94 } 95 } 96 //收集所有未排除的合同进行约束 97 for name, contract := range contracts { 98 if exclude[strings.ToLower(name)] { 99 continue 100 } 101 abi, _ := json.Marshal(contract.Info.AbiDefinition) //扁平化编译器分析 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 //否则,从参数中加载abi、可选字节码和类型名。 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 //生成合同绑定 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 //将其刷新为文件或显示在标准输出上 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 } 148 149 func contractsFromStdin() (map[string]*compiler.Contract, error) { 150 bytes, err := ioutil.ReadAll(os.Stdin) 151 if err != nil { 152 return nil, err 153 } 154 155 return compiler.ParseCombinedJSON(bytes, "", "", "", "") 156 } 157