1// SPDX-License-Identifier: ISC 2// Copyright (c) 2014-2020 Bitmark Inc. 3// Use of this source code is governed by an ISC 4// license that can be found in the LICENSE file. 5 6package main 7 8import ( 9 "fmt" 10 "strings" 11 12 "github.com/urfave/cli" 13 14 "github.com/bitmark-inc/bitmarkd/command/bitmark-cli/rpccalls" 15) 16 17func runCreate(c *cli.Context) error { 18 19 m := c.App.Metadata["config"].(*metadata) 20 21 assetName := c.String("asset") 22 23 fingerprint, err := checkAssetFingerprint(c.String("fingerprint")) 24 if nil != err { 25 return err 26 } 27 28 metadata, err := checkAssetMetadata(c.String("metadata")) 29 if nil != err { 30 return err 31 } 32 33 quantity := c.Int("quantity") 34 if quantity <= 0 { 35 return fmt.Errorf("invalid quantity: %d", quantity) 36 } 37 38 zeroNonceOnly := c.Bool("zero") 39 if zeroNonceOnly && quantity != 1 { 40 return fmt.Errorf("invalid free-issue quantity: %d only 1 is allowed", quantity) 41 } 42 43 name, registrant, err := checkOwnerWithPasswordPrompt(c.GlobalString("identity"), m.config, c) 44 if nil != err { 45 return err 46 } 47 48 if m.verbose { 49 fmt.Fprintf(m.e, "issuer: %s\n", name) 50 fmt.Fprintf(m.e, "assetName: %q\n", assetName) 51 fmt.Fprintf(m.e, "fingerprint: %q\n", fingerprint) 52 fmt.Fprintf(m.e, "metadata:\n") 53 splitMeta := strings.Split(metadata, "\u0000") 54 for i := 0; i < len(splitMeta); i += 2 { 55 fmt.Fprintf(m.e, " %q: %q\n", splitMeta[i], splitMeta[i+1]) 56 } 57 fmt.Fprintf(m.e, "quantity: %d\n", quantity) 58 } 59 60 client, err := rpccalls.NewClient(m.testnet, m.config.Connections[m.connectionOffset], m.verbose, m.e) 61 if nil != err { 62 return err 63 } 64 defer client.Close() 65 66 assetConfig := &rpccalls.AssetData{ 67 Name: assetName, 68 Metadata: metadata, 69 Quantity: quantity, 70 Fingerprint: fingerprint, 71 Registrant: registrant, 72 } 73 74 assetResult, err := client.MakeAsset(assetConfig) 75 if nil != err { 76 return err 77 } 78 79 // make Issues 80 issueConfig := &rpccalls.IssueData{ 81 Issuer: assetConfig.Registrant, 82 AssetId: assetResult.AssetId, 83 Quantity: assetConfig.Quantity, 84 FreeIssue: 1 == assetConfig.Quantity, 85 } 86 87 response, err := client.Issue(issueConfig) 88 if issueConfig.FreeIssue && nil != err && strings.Contains(err.Error(), "transaction already exists") { 89 // if free issue was already done, try again asking for payment 90 if zeroNonceOnly { 91 return err 92 } 93 issueConfig.FreeIssue = false 94 response, err = client.Issue(issueConfig) 95 } 96 97 if nil != err { 98 return err 99 } 100 101 printJson(m.w, response) 102 return nil 103} 104