@@ -18,63 +18,129 @@ package main
18
18
19
19
import (
20
20
"encoding/json"
21
- "flag"
22
21
"fmt"
23
22
"io/ioutil"
24
23
"os"
25
24
"strings"
26
25
27
26
"github.com/ethereum/go-ethereum/accounts/abi/bind"
27
+ "github.com/ethereum/go-ethereum/cmd/utils"
28
28
"github.com/ethereum/go-ethereum/common/compiler"
29
29
"github.com/ethereum/go-ethereum/crypto"
30
+ "github.com/ethereum/go-ethereum/log"
31
+ "gopkg.in/urfave/cli.v1"
30
32
)
31
33
32
- var (
33
- abiFlag = flag .String ("abi" , "" , "Path to the Ethereum contract ABI json to bind, - for STDIN" )
34
- binFlag = flag .String ("bin" , "" , "Path to the Ethereum contract bytecode (generate deploy method)" )
35
- typFlag = flag .String ("type" , "" , "Struct name for the binding (default = package name)" )
34
+ const (
35
+ commandHelperTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} [arguments...]
36
+ {{if .Description}}{{.Description}}
37
+ {{end}}{{if .Subcommands}}
38
+ SUBCOMMANDS:
39
+ {{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
40
+ {{end}}{{end}}{{if .Flags}}
41
+ OPTIONS:
42
+ {{range $.Flags}}{{"\t"}}{{.}}
43
+ {{end}}
44
+ {{end}}`
45
+ )
36
46
37
- solFlag = flag .String ("sol" , "" , "Path to the Ethereum contract Solidity source to build and bind" )
38
- solcFlag = flag .String ("solc" , "solc" , "Solidity compiler to use if source builds are requested" )
39
- excFlag = flag .String ("exc" , "" , "Comma separated types to exclude from binding" )
47
+ var (
48
+ // Git SHA1 commit hash of the release (set via linker flags)
49
+ gitCommit = ""
50
+ gitDate = ""
40
51
41
- vyFlag = flag .String ("vy" , "" , "Path to the Ethereum contract Vyper source to build and bind" )
42
- vyperFlag = flag .String ("vyper" , "vyper" , "Vyper compiler to use if source builds are requested" )
52
+ app * cli.App
43
53
44
- pkgFlag = flag .String ("pkg" , "" , "Package name to generate the binding into" )
45
- outFlag = flag .String ("out" , "" , "Output file for the generated binding (default = stdout)" )
46
- langFlag = flag .String ("lang" , "go" , "Destination language for the bindings (go, java, objc)" )
54
+ // Flags needed by abigen
55
+ abiFlag = cli.StringFlag {
56
+ Name : "abi" ,
57
+ Usage : "Path to the Ethereum contract ABI json to bind, - for STDIN" ,
58
+ }
59
+ binFlag = cli.StringFlag {
60
+ Name : "bin" ,
61
+ Usage : "Path to the Ethereum contract bytecode (generate deploy method)" ,
62
+ }
63
+ typeFlag = cli.StringFlag {
64
+ Name : "type" ,
65
+ Usage : "Struct name for the binding (default = package name)" ,
66
+ }
67
+ jsonFlag = cli.StringFlag {
68
+ Name : "combined-json" ,
69
+ Usage : "Path to the combined-json file generated by compiler" ,
70
+ }
71
+ solFlag = cli.StringFlag {
72
+ Name : "sol" ,
73
+ Usage : "Path to the Ethereum contract Solidity source to build and bind" ,
74
+ }
75
+ solcFlag = cli.StringFlag {
76
+ Name : "solc" ,
77
+ Usage : "Solidity compiler to use if source builds are requested" ,
78
+ Value : "solc" ,
79
+ }
80
+ vyFlag = cli.StringFlag {
81
+ Name : "vy" ,
82
+ Usage : "Path to the Ethereum contract Vyper source to build and bind" ,
83
+ }
84
+ vyperFlag = cli.StringFlag {
85
+ Name : "vyper" ,
86
+ Usage : "Vyper compiler to use if source builds are requested" ,
87
+ Value : "vyper" ,
88
+ }
89
+ excFlag = cli.StringFlag {
90
+ Name : "exc" ,
91
+ Usage : "Comma separated types to exclude from binding" ,
92
+ }
93
+ pkgFlag = cli.StringFlag {
94
+ Name : "pkg" ,
95
+ Usage : "Package name to generate the binding into" ,
96
+ }
97
+ outFlag = cli.StringFlag {
98
+ Name : "out" ,
99
+ Usage : "Output file for the generated binding (default = stdout)" ,
100
+ }
101
+ langFlag = cli.StringFlag {
102
+ Name : "lang" ,
103
+ Usage : "Destination language for the bindings (go, java, objc)" ,
104
+ Value : "go" ,
105
+ }
47
106
)
48
107
49
- func main () {
50
- // Parse and ensure all needed inputs are specified
51
- flag .Parse ()
108
+ func init () {
109
+ app = utils .NewApp (gitCommit , gitDate , "ethereum checkpoint helper tool" )
110
+ app .Flags = []cli.Flag {
111
+ abiFlag ,
112
+ binFlag ,
113
+ typeFlag ,
114
+ jsonFlag ,
115
+ solFlag ,
116
+ solcFlag ,
117
+ vyFlag ,
118
+ vyperFlag ,
119
+ excFlag ,
120
+ pkgFlag ,
121
+ outFlag ,
122
+ langFlag ,
123
+ }
124
+ app .Action = utils .MigrateFlags (abigen )
125
+ cli .CommandHelpTemplate = commandHelperTemplate
126
+ }
52
127
53
- if * abiFlag == "" && * solFlag == "" && * vyFlag == "" {
54
- fmt .Printf ("No contract ABI (--abi), Solidity source (--sol), or Vyper source (--vy) specified\n " )
55
- os .Exit (- 1 )
56
- } else if (* abiFlag != "" || * binFlag != "" || * typFlag != "" ) && (* solFlag != "" || * vyFlag != "" ) {
57
- fmt .Printf ("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity (--sol) and Vyper (--vy) flags\n " )
58
- os .Exit (- 1 )
59
- } else if * solFlag != "" && * vyFlag != "" {
60
- fmt .Printf ("Solidity (--sol) and Vyper (--vy) flags are mutually exclusive\n " )
61
- os .Exit (- 1 )
62
- }
63
- if * pkgFlag == "" {
64
- fmt .Printf ("No destination package specified (--pkg)\n " )
65
- os .Exit (- 1 )
128
+ func abigen (c * cli.Context ) error {
129
+ utils .CheckExclusive (c , abiFlag , jsonFlag , solFlag , vyFlag ) // Only one source can be selected.
130
+ if c .GlobalString (pkgFlag .Name ) == "" {
131
+ utils .Fatalf ("No destination package specified (--pkg)" )
66
132
}
67
133
var lang bind.Lang
68
- switch * langFlag {
134
+ switch c . GlobalString ( langFlag . Name ) {
69
135
case "go" :
70
136
lang = bind .LangGo
71
137
case "java" :
72
138
lang = bind .LangJava
73
139
case "objc" :
74
140
lang = bind .LangObjC
141
+ utils .Fatalf ("Objc binding generation is uncompleted" )
75
142
default :
76
- fmt .Printf ("Unsupported destination language \" %s\" (--lang)\n " , * langFlag )
77
- os .Exit (- 1 )
143
+ utils .Fatalf ("Unsupported destination language \" %s\" (--lang)" , c .GlobalString (langFlag .Name ))
78
144
}
79
145
// If the entire solidity code was specified, build and bind based on that
80
146
var (
@@ -84,34 +150,67 @@ func main() {
84
150
sigs []map [string ]string
85
151
libs = make (map [string ]string )
86
152
)
87
- if * solFlag != "" || * vyFlag != "" || * abiFlag == "-" {
153
+ if c .GlobalString (abiFlag .Name ) != "" {
154
+ // Load up the ABI, optional bytecode and type name from the parameters
155
+ var (
156
+ abi []byte
157
+ err error
158
+ )
159
+ input := c .GlobalString (abiFlag .Name )
160
+ if input == "-" {
161
+ abi , err = ioutil .ReadAll (os .Stdin )
162
+ } else {
163
+ abi , err = ioutil .ReadFile (input )
164
+ }
165
+ if err != nil {
166
+ utils .Fatalf ("Failed to read input ABI: %v" , err )
167
+ }
168
+ abis = append (abis , string (abi ))
169
+
170
+ var bin []byte
171
+ if binFile := c .GlobalString (binFlag .Name ); binFile != "" {
172
+ if bin , err = ioutil .ReadFile (binFile ); err != nil {
173
+ utils .Fatalf ("Failed to read input bytecode: %v" , err )
174
+ }
175
+ if strings .Contains (string (bin ), "//" ) {
176
+ utils .Fatalf ("Contract has additional library references, please use other mode(e.g. --combined-json) to catch library infos" )
177
+ }
178
+ }
179
+ bins = append (bins , string (bin ))
180
+
181
+ kind := c .GlobalString (typeFlag .Name )
182
+ if kind == "" {
183
+ kind = c .GlobalString (pkgFlag .Name )
184
+ }
185
+ types = append (types , kind )
186
+ } else {
88
187
// Generate the list of types to exclude from binding
89
188
exclude := make (map [string ]bool )
90
- for _ , kind := range strings .Split (* excFlag , "," ) {
189
+ for _ , kind := range strings .Split (c . GlobalString ( excFlag . Name ) , "," ) {
91
190
exclude [strings .ToLower (kind )] = true
92
191
}
93
-
94
- var contracts map [string ]* compiler.Contract
95
192
var err error
193
+ var contracts map [string ]* compiler.Contract
96
194
97
195
switch {
98
- case * solFlag != "" :
99
- contracts , err = compiler .CompileSolidity (* solcFlag , * solFlag )
196
+ case c .GlobalIsSet (solFlag .Name ):
197
+ contracts , err = compiler .CompileSolidity (c .GlobalString (solcFlag .Name ), c .GlobalString (solFlag .Name ))
198
+ if err != nil {
199
+ utils .Fatalf ("Failed to build Solidity contract: %v" , err )
200
+ }
201
+ case c .GlobalIsSet (vyFlag .Name ):
202
+ contracts , err = compiler .CompileVyper (c .GlobalString (vyperFlag .Name ), c .GlobalString (vyFlag .Name ))
100
203
if err != nil {
101
- fmt .Printf ("Failed to build Solidity contract: %v\n " , err )
102
- os .Exit (- 1 )
204
+ utils .Fatalf ("Failed to build Vyper contract: %v" , err )
103
205
}
104
- case * vyFlag != "" :
105
- contracts , err = compiler . CompileVyper ( * vyperFlag , * vyFlag )
206
+ case c . GlobalIsSet ( jsonFlag . Name ) :
207
+ jsonOutput , err := ioutil . ReadFile ( c . GlobalString ( jsonFlag . Name ) )
106
208
if err != nil {
107
- fmt .Printf ("Failed to build Vyper contract: %v\n " , err )
108
- os .Exit (- 1 )
209
+ utils .Fatalf ("Failed to read combined-json from compiler: %v" , err )
109
210
}
110
- default :
111
- contracts , err = contractsFromStdin ()
211
+ contracts , err = compiler .ParseCombinedJSON (jsonOutput , "" , "" , "" , "" )
112
212
if err != nil {
113
- fmt .Printf ("Failed to read input ABIs from STDIN: %v\n " , err )
114
- os .Exit (- 1 )
213
+ utils .Fatalf ("Failed to read contract information from json output: %v" , err )
115
214
}
116
215
}
117
216
// Gather all non-excluded contract for binding
@@ -121,65 +220,39 @@ func main() {
121
220
}
122
221
abi , err := json .Marshal (contract .Info .AbiDefinition ) // Flatten the compiler parse
123
222
if err != nil {
124
- fmt .Printf ("Failed to parse ABIs from compiler output: %v\n " , err )
125
- os .Exit (- 1 )
223
+ utils .Fatalf ("Failed to parse ABIs from compiler output: %v" , err )
126
224
}
127
225
abis = append (abis , string (abi ))
128
226
bins = append (bins , contract .Code )
129
227
sigs = append (sigs , contract .Hashes )
130
-
131
228
nameParts := strings .Split (name , ":" )
132
229
types = append (types , nameParts [len (nameParts )- 1 ])
133
230
134
231
libPattern := crypto .Keccak256Hash ([]byte (name )).String ()[2 :36 ]
135
232
libs [libPattern ] = nameParts [len (nameParts )- 1 ]
136
233
}
137
- } else {
138
- // Otherwise load up the ABI, optional bytecode and type name from the parameters
139
- abi , err := ioutil .ReadFile (* abiFlag )
140
-
141
- if err != nil {
142
- fmt .Printf ("Failed to read input ABI: %v\n " , err )
143
- os .Exit (- 1 )
144
- }
145
- abis = append (abis , string (abi ))
146
-
147
- var bin []byte
148
- if * binFlag != "" {
149
- if bin , err = ioutil .ReadFile (* binFlag ); err != nil {
150
- fmt .Printf ("Failed to read input bytecode: %v\n " , err )
151
- os .Exit (- 1 )
152
- }
153
- }
154
- bins = append (bins , string (bin ))
155
-
156
- kind := * typFlag
157
- if kind == "" {
158
- kind = * pkgFlag
159
- }
160
- types = append (types , kind )
161
234
}
162
235
// Generate the contract binding
163
- code , err := bind .Bind (types , abis , bins , sigs , * pkgFlag , lang , libs )
236
+ code , err := bind .Bind (types , abis , bins , sigs , c . GlobalString ( pkgFlag . Name ) , lang , libs )
164
237
if err != nil {
165
- fmt .Printf ("Failed to generate ABI binding: %v\n " , err )
166
- os .Exit (- 1 )
238
+ utils .Fatalf ("Failed to generate ABI binding: %v" , err )
167
239
}
168
240
// Either flush it out to a file or display on the standard output
169
- if * outFlag == "" {
241
+ if ! c . GlobalIsSet ( outFlag . Name ) {
170
242
fmt .Printf ("%s\n " , code )
171
- return
243
+ return nil
172
244
}
173
- if err := ioutil .WriteFile (* outFlag , []byte (code ), 0600 ); err != nil {
174
- fmt .Printf ("Failed to write ABI binding: %v\n " , err )
175
- os .Exit (- 1 )
245
+ if err := ioutil .WriteFile (c .GlobalString (outFlag .Name ), []byte (code ), 0600 ); err != nil {
246
+ utils .Fatalf ("Failed to write ABI binding: %v" , err )
176
247
}
248
+ return nil
177
249
}
178
250
179
- func contractsFromStdin () (map [string ]* compiler.Contract , error ) {
180
- bytes , err := ioutil .ReadAll (os .Stdin )
181
- if err != nil {
182
- return nil , err
251
+ func main () {
252
+ log .Root ().SetHandler (log .LvlFilterHandler (log .LvlInfo , log .StreamHandler (os .Stderr , log .TerminalFormat (true ))))
253
+
254
+ if err := app .Run (os .Args ); err != nil {
255
+ fmt .Fprintln (os .Stderr , err )
256
+ os .Exit (1 )
183
257
}
184
- return compiler .ParseCombinedJSON (bytes , "" , "" , "" , "" )
185
258
}
0 commit comments