9 "github.com/spf13/cobra"
10 jww "github.com/spf13/jwalterweatherman"
12 "github.com/bytom/vapor/api"
13 "github.com/bytom/vapor/blockchain/txbuilder"
14 chainjson "github.com/bytom/vapor/encoding/json"
15 "github.com/bytom/vapor/protocol/bc/types"
16 "github.com/bytom/vapor/util"
20 buildTransactionCmd.PersistentFlags().StringVarP(&buildType, "type", "t", "", "transaction type, valid types: 'issue', 'spend', 'address', 'retire', 'unlock'")
21 buildTransactionCmd.PersistentFlags().StringVarP(&receiverProgram, "receiver", "r", "", "program of receiver when type is spend")
22 buildTransactionCmd.PersistentFlags().StringVarP(&address, "address", "a", "", "address of receiver when type is address")
23 buildTransactionCmd.PersistentFlags().StringVarP(&program, "program", "p", "", "program of receiver when type is program")
24 buildTransactionCmd.PersistentFlags().StringVarP(&arbitrary, "arbitrary", "v", "", "additional arbitrary data when type is retire")
25 buildTransactionCmd.PersistentFlags().StringVarP(&btmGas, "gas", "g", "20000000", "gas of this transaction")
26 buildTransactionCmd.PersistentFlags().StringVarP(&contractName, "contract-name", "c", "",
27 "name of template contract, currently supported: 'LockWithPublicKey', 'LockWithMultiSig', 'LockWithPublicKeyHash',"+
28 "\n\t\t\t 'RevealPreimage', 'TradeOffer', 'Escrow', 'CallOption', 'LoanCollateral'")
29 buildTransactionCmd.PersistentFlags().BoolVar(&pretty, "pretty", false, "pretty print json result")
30 buildTransactionCmd.PersistentFlags().BoolVar(&alias, "alias", false, "use alias build transaction")
32 signTransactionCmd.PersistentFlags().StringVarP(&password, "password", "p", "", "password of the account which sign these transaction(s)")
33 signTransactionCmd.PersistentFlags().BoolVar(&pretty, "pretty", false, "pretty print json result")
35 listTransactionsCmd.PersistentFlags().StringVar(&txID, "id", "", "transaction id")
36 listTransactionsCmd.PersistentFlags().StringVar(&account, "account_id", "", "account id")
37 listTransactionsCmd.PersistentFlags().BoolVar(&detail, "detail", false, "list transactions details")
38 listTransactionsCmd.PersistentFlags().BoolVar(&unconfirmed, "unconfirmed", false, "list unconfirmed transactions")
58 var buildIssueReqFmt = `
60 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"},
61 {"type": "issue", "asset_id": "%s", "amount": %s},
62 {"type": "control_address", "asset_id": "%s", "amount": %s, "address": "%s"}
65 var buildIssueReqFmtByAlias = `
67 {"type": "spend_account", "asset_alias": "BTM", "amount":%s, "account_alias": "%s"},
68 {"type": "issue", "asset_alias": "%s", "amount": %s},
69 {"type": "control_address", "asset_alias": "%s", "amount": %s, "address": "%s"}
72 var buildSpendReqFmt = `
74 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"},
75 {"type": "spend_account", "asset_id": "%s","amount": %s,"account_id": "%s"},
76 {"type": "control_program", "asset_id": "%s", "amount": %s, "control_program": "%s"}
79 var buildSpendReqFmtByAlias = `
81 {"type": "spend_account", "asset_alias": "BTM", "amount":%s, "account_alias": "%s"},
82 {"type": "spend_account", "asset_alias": "%s","amount": %s,"account_alias": "%s"},
83 {"type": "control_program", "asset_alias": "%s", "amount": %s, "control_program": "%s"}
86 var buildRetireReqFmt = `
88 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"},
89 {"type": "spend_account", "asset_id": "%s", "amount": %s, "account_id": "%s"},
90 {"type": "retire", "asset_id": "%s", "amount": %s, "arbitrary": "%s"}
93 var buildRetireReqFmtByAlias = `
95 {"type": "spend_account", "asset_alias": "BTM", "amount":%s, "account_alias": "%s"},
96 {"type": "spend_account", "asset_alias": "%s", "amount": %s, "account_alias": "%s"},
97 {"type": "retire", "asset_alias": "%s", "amount": %s, "arbitrary": "%s"}
100 var buildControlAddressReqFmt = `
102 {"type": "spend_account", "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "amount":%s, "account_id": "%s"},
103 {"type": "spend_account", "asset_id": "%s","amount": %s,"account_id": "%s"},
104 {"type": "control_address", "asset_id": "%s", "amount": %s,"address": "%s"}
107 var buildControlAddressReqFmtByAlias = `
109 {"type": "spend_account", "asset_alias": "BTM", "amount":%s, "account_alias": "%s"},
110 {"type": "spend_account", "asset_alias": "%s","amount": %s, "account_alias": "%s"},
111 {"type": "control_address", "asset_alias": "%s", "amount": %s,"address": "%s"}
114 var buildTransactionCmd = &cobra.Command{
115 Use: "build-transaction <accountID|alias> <assetID|alias> <amount> [outputID]",
116 Short: "Build one transaction template,default use account id and asset id",
117 Args: cobra.RangeArgs(3, 20),
118 PreRun: func(cmd *cobra.Command, args []string) {
119 cmd.MarkFlagRequired("type")
120 if buildType == "spend" {
121 cmd.MarkFlagRequired("receiver")
124 Run: func(cmd *cobra.Command, args []string) {
125 var buildReqStr string
126 accountInfo := args[0]
132 buildReqStr = fmt.Sprintf(buildIssueReqFmtByAlias, btmGas, accountInfo, assetInfo, amount, assetInfo, amount, address)
135 buildReqStr = fmt.Sprintf(buildIssueReqFmt, btmGas, accountInfo, assetInfo, amount, assetInfo, amount, address)
138 buildReqStr = fmt.Sprintf(buildSpendReqFmtByAlias, btmGas, accountInfo, assetInfo, amount, accountInfo, assetInfo, amount, receiverProgram)
141 buildReqStr = fmt.Sprintf(buildSpendReqFmt, btmGas, accountInfo, assetInfo, amount, accountInfo, assetInfo, amount, receiverProgram)
144 buildReqStr = fmt.Sprintf(buildRetireReqFmtByAlias, btmGas, accountInfo, assetInfo, amount, accountInfo, assetInfo, amount, arbitrary)
147 buildReqStr = fmt.Sprintf(buildRetireReqFmt, btmGas, accountInfo, assetInfo, amount, accountInfo, assetInfo, amount, arbitrary)
150 buildReqStr = fmt.Sprintf(buildControlAddressReqFmtByAlias, btmGas, accountInfo, assetInfo, amount, accountInfo, assetInfo, amount, address)
153 buildReqStr = fmt.Sprintf(buildControlAddressReqFmt, btmGas, accountInfo, assetInfo, amount, accountInfo, assetInfo, amount, address)
156 usage := "Usage:\n vaporcli build-transaction <accountID|alias> <assetID|alias> <amount> <outputID> -c <contractName>"
158 if len(args) < baseCount {
159 jww.ERROR.Printf("%s <contract_argument> ... [flags]\n\n", usage)
160 os.Exit(util.ErrLocalExe)
163 baseArg := baseContractArg{
164 accountInfo: accountInfo,
165 assetInfo: assetInfo,
170 outputID: args[baseCount-1],
172 specArgs := args[baseCount:]
174 if buildReqStr, err = addContractArgs(contractName, baseArg, specArgs, usage); err != nil {
175 jww.ERROR.Println(err)
176 os.Exit(util.ErrLocalExe)
180 jww.ERROR.Println("Invalid transaction template type")
181 os.Exit(util.ErrLocalExe)
184 var buildReq api.BuildRequest
185 if err := json.Unmarshal([]byte(buildReqStr), &buildReq); err != nil {
186 jww.ERROR.Println(err)
187 os.Exit(util.ErrLocalExe)
190 data, exitCode := util.ClientCall("/build-transaction", &buildReq)
191 if exitCode != util.Success {
200 dataMap, ok := data.(map[string]interface{})
202 jww.ERROR.Println("invalid type assertion")
203 os.Exit(util.ErrLocalParse)
206 rawTemplate, err := json.Marshal(dataMap)
208 jww.ERROR.Println(err)
209 os.Exit(util.ErrLocalParse)
212 jww.FEEDBACK.Printf("Template Type: %s\n%s\n", buildType, string(rawTemplate))
216 var signTransactionCmd = &cobra.Command{
217 Use: "sign-transaction <json templates>",
218 Short: "Sign transaction templates with account password",
219 Args: cobra.ExactArgs(1),
220 PreRun: func(cmd *cobra.Command, args []string) {
221 cmd.MarkFlagRequired("password")
223 Run: func(cmd *cobra.Command, args []string) {
224 template := txbuilder.Template{}
226 err := json.Unmarshal([]byte(args[0]), &template)
228 jww.ERROR.Println(err)
229 os.Exit(util.ErrLocalExe)
233 Password string `json:"password"`
234 Txs txbuilder.Template `json:"transaction"`
235 }{Password: password, Txs: template}
237 jww.FEEDBACK.Printf("\n\n")
238 data, exitCode := util.ClientCall("/sign-transaction", &req)
239 if exitCode != util.Success {
248 dataMap, ok := data.(map[string]interface{})
250 jww.ERROR.Println("invalid type assertion")
251 os.Exit(util.ErrLocalParse)
254 rawSign, err := json.Marshal(dataMap)
256 jww.ERROR.Println(err)
257 os.Exit(util.ErrLocalParse)
259 jww.FEEDBACK.Printf("\nSign Template:\n%s\n", string(rawSign))
263 var submitTransactionCmd = &cobra.Command{
264 Use: "submit-transaction <signed json raw_transaction>",
265 Short: "Submit signed transaction",
266 Args: cobra.ExactArgs(1),
267 Run: func(cmd *cobra.Command, args []string) {
269 Tx types.Tx `json:"raw_transaction"`
272 err := json.Unmarshal([]byte(args[0]), &ins)
274 jww.ERROR.Println(err)
275 os.Exit(util.ErrLocalExe)
278 data, exitCode := util.ClientCall("/submit-transaction", &ins)
279 if exitCode != util.Success {
287 var estimateTransactionGasCmd = &cobra.Command{
288 Use: "estimate-transaction-gas <json templates>",
289 Short: "estimate gas for build transaction",
290 Args: cobra.ExactArgs(1),
291 Run: func(cmd *cobra.Command, args []string) {
292 template := txbuilder.Template{}
294 err := json.Unmarshal([]byte(args[0]), &template)
296 jww.ERROR.Println(err)
297 os.Exit(util.ErrLocalExe)
301 TxTemplate txbuilder.Template `json:"transaction_template"`
302 }{TxTemplate: template}
304 data, exitCode := util.ClientCall("/estimate-transaction-gas", &req)
305 if exitCode != util.Success {
313 var decodeRawTransactionCmd = &cobra.Command{
314 Use: "decode-raw-transaction <raw_transaction>",
315 Short: "decode the raw transaction",
316 Args: cobra.ExactArgs(1),
317 Run: func(cmd *cobra.Command, args []string) {
319 Tx types.Tx `json:"raw_transaction"`
322 err := ins.Tx.UnmarshalText([]byte(args[0]))
324 jww.ERROR.Println(err)
325 os.Exit(util.ErrLocalExe)
328 data, exitCode := util.ClientCall("/decode-raw-transaction", &ins)
329 if exitCode != util.Success {
337 var getTransactionCmd = &cobra.Command{
338 Use: "get-transaction <hash>",
339 Short: "get the transaction by matching the given transaction hash",
340 Args: cobra.ExactArgs(1),
341 Run: func(cmd *cobra.Command, args []string) {
343 TxID string `json:"tx_id"`
346 data, exitCode := util.ClientCall("/get-transaction", txInfo)
347 if exitCode != util.Success {
355 var listTransactionsCmd = &cobra.Command{
356 Use: "list-transactions",
357 Short: "List the transactions",
359 Run: func(cmd *cobra.Command, args []string) {
361 ID string `json:"id"`
362 AccountID string `json:"account_id"`
363 Detail bool `json:"detail"`
364 Unconfirmed bool `json:"unconfirmed"`
365 }{ID: txID, AccountID: account, Detail: detail, Unconfirmed: unconfirmed}
367 data, exitCode := util.ClientCall("/list-transactions", &filter)
368 if exitCode != util.Success {
376 var getUnconfirmedTransactionCmd = &cobra.Command{
377 Use: "get-unconfirmed-transaction <hash>",
378 Short: "get unconfirmed transaction by matching the given transaction hash",
379 Args: cobra.ExactArgs(1),
380 Run: func(cmd *cobra.Command, args []string) {
381 txID, err := hex.DecodeString(args[0])
383 jww.ERROR.Println(err)
384 os.Exit(util.ErrLocalExe)
388 TxID chainjson.HexBytes `json:"tx_id"`
391 data, exitCode := util.ClientCall("/get-unconfirmed-transaction", txInfo)
392 if exitCode != util.Success {
400 var listUnconfirmedTransactionsCmd = &cobra.Command{
401 Use: "list-unconfirmed-transactions",
402 Short: "list unconfirmed transactions hashes",
404 Run: func(cmd *cobra.Command, args []string) {
405 data, exitCode := util.ClientCall("/list-unconfirmed-transactions")
406 if exitCode != util.Success {
414 var gasRateCmd = &cobra.Command{
416 Short: "Print the current gas rate",
418 Run: func(cmd *cobra.Command, args []string) {
419 data, exitCode := util.ClientCall("/gas-rate")
420 if exitCode != util.Success {