github.com/aergoio/aergo@v1.3.1/cmd/brick/exec/deployContract.go (about) 1 package exec 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "math/big" 7 "net/http" 8 "os" 9 "path/filepath" 10 "strings" 11 12 "github.com/aergoio/aergo/cmd/brick/context" 13 "github.com/aergoio/aergo/contract" 14 ) 15 16 func init() { 17 registerExec(&deployContract{}) 18 } 19 20 type deployContract struct{} 21 22 func (c *deployContract) Command() string { 23 return "deploy" 24 } 25 26 func (c *deployContract) Syntax() string { 27 return fmt.Sprintf("%s %s %s %s %s", context.AccountSymbol, context.AmountSymbol, 28 context.ContractSymbol, context.PathSymbol, context.ContractArgsSymbol) 29 } 30 31 func (c *deployContract) Usage() string { 32 return fmt.Sprintf("deploy <sender_name> <amount> <contract_name> `<definition_file_path>` `[contructor_json_arg]`") 33 } 34 35 func (c *deployContract) Describe() string { 36 return "deploy a smart contract" 37 } 38 39 func (c *deployContract) Validate(args string) error { 40 41 // check whether chain is loaded 42 if context.Get() == nil { 43 return fmt.Errorf("load chain first") 44 } 45 46 _, _, _, _, _, err := c.parse(args) 47 48 return err 49 } 50 51 func (c *deployContract) readDefFile(defPath string) ([]byte, error) { 52 if strings.HasPrefix(defPath, "http") { 53 // search in the web 54 req, err := http.NewRequest("GET", defPath, nil) 55 if err != nil { 56 return nil, err 57 } 58 client := &http.Client{} 59 resp, err := client.Do(req) 60 if err != nil { 61 return nil, err 62 } 63 defer resp.Body.Close() 64 defByte, _ := ioutil.ReadAll(resp.Body) 65 66 return defByte, nil 67 } 68 69 // search in a local file system 70 if _, err := os.Stat(defPath); os.IsNotExist(err) { 71 return nil, err 72 } 73 defByte, err := ioutil.ReadFile(defPath) 74 if err != nil { 75 return nil, err 76 } 77 78 return defByte, nil 79 80 } 81 82 func (c *deployContract) parse(args string) (string, *big.Int, string, string, string, error) { 83 splitArgs := context.SplitSpaceAndAccent(args, false) 84 if len(splitArgs) < 4 { 85 return "", nil, "", "", "", fmt.Errorf("need 4 arguments. usage: %s", c.Usage()) 86 } 87 88 amount, success := new(big.Int).SetString(splitArgs[1].Text, 10) 89 if success == false { 90 return "", nil, "", "", "", fmt.Errorf("fail to parse number %s", splitArgs[1].Text) 91 } 92 93 defPath := splitArgs[3].Text 94 if _, err := c.readDefFile(defPath); err != nil { 95 return "", nil, "", "", "", fmt.Errorf("fail to read a contrat def file %s: %s", splitArgs[3].Text, err.Error()) 96 } 97 98 constuctorArg := "[]" 99 if len(splitArgs) == 5 { 100 constuctorArg = splitArgs[4].Text 101 } else if len(splitArgs) > 5 { 102 return "", nil, "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) 103 } 104 105 return splitArgs[0].Text, //accountName 106 amount, // amount 107 splitArgs[2].Text, // contractName 108 defPath, // defPath 109 constuctorArg, 110 nil 111 } 112 113 func (c *deployContract) Run(args string) (string, error) { 114 accountName, amount, contractName, defPath, constuctorArg, _ := c.parse(args) 115 116 defByte, err := c.readDefFile(defPath) 117 if err != nil { 118 return "", err 119 } 120 121 updateContractInfoInterface(contractName, defPath) 122 123 err = context.Get().ConnectBlock( 124 contract.NewRawLuaTxDefBig(accountName, contractName, amount, string(defByte)).Constructor(constuctorArg), 125 ) 126 127 if enableWatch && !strings.HasPrefix(defPath, "http") { 128 absPath, _ := filepath.Abs(defPath) 129 watcher.Add(absPath) 130 } 131 132 if err != nil { 133 return "", err 134 } 135 136 Index(context.ContractSymbol, contractName) 137 Index(context.AccountSymbol, contractName) 138 139 return "deploy a smart contract successfully", nil 140 }