github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/cmd/contract/contractdeploysol.go (about) 1 // Copyright (c) 2022 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package contract 7 8 import ( 9 "encoding/json" 10 "fmt" 11 "os" 12 "strings" 13 14 "github.com/spf13/cobra" 15 16 "github.com/iotexproject/iotex-core/ioctl/cmd/action" 17 "github.com/iotexproject/iotex-core/ioctl/config" 18 "github.com/iotexproject/iotex-core/ioctl/flag" 19 "github.com/iotexproject/iotex-core/ioctl/output" 20 "github.com/iotexproject/iotex-core/ioctl/util" 21 ) 22 23 // Multi-language support 24 var ( 25 _deploySolCmdUses = map[config.Language]string{ 26 config.English: "sol [FILE_NAME:]CONTRACT_NAME [CODE_FILES...] [--with-arguments INIT_INPUT] [--init-amount IOTX数量]", 27 config.Chinese: "sol [文件名:]合约名 [代码文件...] [--with-arguments 初始化输入] [--init-amount IOTX数量]", 28 } 29 _deploySolCmdShorts = map[config.Language]string{ 30 config.English: "deploy smart contract with sol files on IoTeX blockchain", 31 config.Chinese: "使用sol文件在IoTex区块链上部署智能合约", 32 } 33 ) 34 35 // _contractDeploySolCmd represents the contract deploy sol command 36 var _contractDeploySolCmd = &cobra.Command{ 37 Use: config.TranslateInLang(_deploySolCmdUses, config.UILanguage), 38 Short: config.TranslateInLang(_deploySolCmdShorts, config.UILanguage), 39 Args: cobra.MinimumNArgs(1), 40 RunE: func(cmd *cobra.Command, args []string) error { 41 cmd.SilenceUsage = true 42 err := contractDeploySol(args) 43 return output.PrintError(err) 44 }, 45 } 46 47 func init() { 48 _initialAmountFlag.RegisterCommand(_contractDeploySolCmd) 49 } 50 51 func contractDeploySol(args []string) error { 52 contractName := args[0] 53 54 files := args[1:] 55 if len(files) == 0 { 56 dirInfo, err := os.ReadDir("./") 57 if err != nil { 58 return output.NewError(output.ReadFileError, "failed to get current directory", err) 59 } 60 61 for _, fileInfo := range dirInfo { 62 if !fileInfo.IsDir() && strings.HasSuffix(fileInfo.Name(), ".sol") { 63 files = append(files, fileInfo.Name()) 64 } 65 } 66 67 if len(files) == 0 { 68 return output.NewError(output.InputError, "failed to get source file(s)", nil) 69 } 70 } 71 72 contracts, err := Compile(files...) 73 if err != nil { 74 return output.NewError(0, "failed to compile", err) 75 } 76 77 for name := range contracts { 78 if strings.HasSuffix(name, contractName) { 79 if contractName != args[0] { 80 return output.NewError(output.CompilerError, 81 fmt.Sprintf("there are more than one %s contract", args[0]), nil) 82 } 83 contractName = name 84 } 85 } 86 87 contract, ok := contracts[contractName] 88 if !ok { 89 return output.NewError(output.CompilerError, fmt.Sprintf("failed to find out contract %s", contractName), nil) 90 } 91 92 bytecode, err := decodeBytecode(contract.Code) 93 if err != nil { 94 return output.NewError(output.ConvertError, "failed to decode bytecode", err) 95 } 96 97 if flag.WithArgumentsFlag.Value().(string) != "" { 98 abiByte, err := json.Marshal(contract.Info.AbiDefinition) 99 if err != nil { 100 return output.NewError(output.SerializationError, "failed to marshal abi", err) 101 } 102 103 abi, err := parseAbi(abiByte) 104 if err != nil { 105 return err 106 } 107 108 // Constructor's method name is "" (empty string) 109 packedArg, err := packArguments(abi, "", flag.WithArgumentsFlag.Value().(string)) 110 if err != nil { 111 return output.NewError(output.ConvertError, "failed to pack given arguments", err) 112 } 113 114 bytecode = append(bytecode, packedArg...) 115 } 116 117 amount, err := util.StringToRau(_initialAmountFlag.Value().(string), util.IotxDecimalNum) 118 if err != nil { 119 return output.NewError(output.FlagError, "invalid amount", err) 120 } 121 122 return action.Execute("", amount, bytecode) 123 }