github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/cmd/account/accountimport.go (about) 1 // Copyright (c) 2019 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 account 7 8 import ( 9 "fmt" 10 "os" 11 12 "github.com/spf13/cobra" 13 "gopkg.in/yaml.v2" 14 15 "github.com/iotexproject/iotex-core/ioctl/config" 16 "github.com/iotexproject/iotex-core/ioctl/output" 17 "github.com/iotexproject/iotex-core/ioctl/util" 18 "github.com/iotexproject/iotex-core/ioctl/validator" 19 ) 20 21 // Multi-language support 22 var ( 23 _importCmdShorts = map[config.Language]string{ 24 config.English: "Import IoTeX private key or keystore into wallet", 25 config.Chinese: "将IoTeX的私钥或私钥库导入钱包", 26 } 27 _importKeyCmdShorts = map[config.Language]string{ 28 config.English: "Import IoTeX private key into wallet", 29 config.Chinese: "将IoTeX的私钥导入钱包", 30 } 31 _importKeyCmdUses = map[config.Language]string{ 32 config.English: "key ALIAS", 33 config.Chinese: "key 别名", 34 } 35 _importKeyStoreCmdShorts = map[config.Language]string{ 36 config.English: "Import IoTeX keystore into wallet", 37 config.Chinese: "将IoTeX的私钥库导入钱包", 38 } 39 _importKeyStoreCmdUses = map[config.Language]string{ 40 config.English: "keystore ALIAS FILEPATH", 41 config.Chinese: "keystore 别名 文件路径", 42 } 43 _importPemCmdShorts = map[config.Language]string{ 44 config.English: "Import IoTeX key from pem file into wallet", 45 config.Chinese: "将IoTeX私钥从pem文件导入钱包", 46 } 47 _importPemCmdUses = map[config.Language]string{ 48 config.English: "pem ALIAS FILEPATH", 49 config.Chinese: "pem 别名 文件路径", 50 } 51 ) 52 var ( 53 // _accountImportCmd represents the account import command 54 _accountImportCmd = &cobra.Command{ 55 Use: "import", 56 Short: config.TranslateInLang(_importCmdShorts, config.UILanguage), 57 } 58 // _accountImportKeyCmd represents the account import key command 59 _accountImportKeyCmd = &cobra.Command{ 60 Use: config.TranslateInLang(_importKeyCmdUses, config.UILanguage), 61 Short: config.TranslateInLang(_importKeyCmdShorts, config.UILanguage), 62 Args: cobra.ExactArgs(1), 63 RunE: func(cmd *cobra.Command, args []string) error { 64 cmd.SilenceUsage = true 65 err := accountImportKey(args) 66 return output.PrintError(err) 67 }, 68 } 69 // _accountImportKeyStoreCmd represents the account import keystore command 70 _accountImportKeyStoreCmd = &cobra.Command{ 71 Use: config.TranslateInLang(_importKeyStoreCmdUses, config.UILanguage), 72 Short: config.TranslateInLang(_importKeyStoreCmdShorts, config.UILanguage), 73 Args: cobra.ExactArgs(2), 74 RunE: func(cmd *cobra.Command, args []string) error { 75 cmd.SilenceUsage = true 76 err := accountImportKeyStore(args) 77 return output.PrintError(err) 78 }, 79 } 80 // _accountImportPemCmd represents the account import pem command 81 _accountImportPemCmd = &cobra.Command{ 82 Use: config.TranslateInLang(_importPemCmdUses, config.UILanguage), 83 Short: config.TranslateInLang(_importPemCmdShorts, config.UILanguage), 84 Args: cobra.ExactArgs(2), 85 RunE: func(cmd *cobra.Command, args []string) error { 86 cmd.SilenceUsage = true 87 err := accountImportPem(args) 88 return output.PrintError(err) 89 }, 90 } 91 ) 92 93 func init() { 94 _accountImportCmd.AddCommand(_accountImportKeyCmd) 95 _accountImportCmd.AddCommand(_accountImportKeyStoreCmd) 96 _accountImportCmd.AddCommand(_accountImportPemCmd) 97 } 98 func validateAlias(alias string) error { 99 if err := validator.ValidateAlias(alias); err != nil { 100 return err 101 } 102 if addr, ok := config.ReadConfig.Aliases[alias]; ok { 103 return fmt.Errorf("alias \"%s\" has already used for %s", alias, addr) 104 } 105 return nil 106 } 107 func writeToFile(alias, addr string) error { 108 config.ReadConfig.Aliases[alias] = addr 109 out, err := yaml.Marshal(&config.ReadConfig) 110 if err != nil { 111 return output.NewError(output.SerializationError, "failed to marshal config", err) 112 } 113 if err := os.WriteFile(config.DefaultConfigFile, out, 0600); err != nil { 114 return output.NewError(output.WriteFileError, 115 fmt.Sprintf("failed to write to config file %s", config.DefaultConfigFile), err) 116 } 117 output.PrintResult(fmt.Sprintf("New account #%s is created. Keep your password, "+ 118 "or you will lose your private key.", alias)) 119 return nil 120 } 121 func readPasswordFromStdin() (string, error) { 122 password, err := util.ReadSecretFromStdin() 123 if err != nil { 124 return "", fmt.Errorf("failed to get password") 125 } 126 return password, nil 127 } 128 func accountImportKey(args []string) error { 129 // Validate inputs 130 alias := args[0] 131 err := validateAlias(alias) 132 if err != nil { 133 return output.NewError(output.ValidationError, "invalid alias", err) 134 } 135 output.PrintQuery(fmt.Sprintf("#%s: Enter your private key, "+ 136 "which will not be exposed on the screen.", alias)) 137 privateKey, err := readPasswordFromStdin() 138 privateKey = util.TrimHexPrefix(privateKey) 139 if err != nil { 140 return output.NewError(output.InputError, "failed to get password", err) 141 } 142 addr, err := newAccountByKey(alias, privateKey, config.ReadConfig.Wallet) 143 if err != nil { 144 return output.NewError(0, "", err) 145 } 146 return writeToFile(alias, addr) 147 } 148 func accountImportKeyStore(args []string) error { 149 // Validate inputs 150 alias := args[0] 151 err := validateAlias(alias) 152 if err != nil { 153 return output.NewError(output.ValidationError, "invalid alias", err) 154 } 155 _, err = os.Stat(args[1]) 156 if err != nil { 157 return output.NewError(output.ReadFileError, "", err) 158 } 159 160 output.PrintQuery(fmt.Sprintf("#%s: Enter your password of keystore, "+ 161 "which will not be exposed on the screen.", alias)) 162 password, err := util.ReadSecretFromStdin() 163 if err != nil { 164 return output.NewError(output.InputError, "failed to get password", err) 165 } 166 addr, err := newAccountByKeyStore(alias, password, args[1], config.ReadConfig.Wallet) 167 if err != nil { 168 return output.NewError(0, "", err) 169 } 170 return writeToFile(alias, addr) 171 } 172 173 func accountImportPem(args []string) error { 174 // Validate inputs 175 alias := args[0] 176 err := validateAlias(alias) 177 if err != nil { 178 return output.NewError(output.ValidationError, "invalid alias", err) 179 } 180 _, err = os.Stat(args[1]) 181 if err != nil { 182 return output.NewError(output.ReadFileError, "", err) 183 } 184 185 output.PrintQuery(fmt.Sprintf("#%s: Enter your password of pem file, "+ 186 "which will not be exposed on the screen.", alias)) 187 password, err := util.ReadSecretFromStdin() 188 if err != nil { 189 return output.NewError(output.InputError, "failed to get password", err) 190 } 191 addr, err := newAccountByPem(alias, password, args[1], config.ReadConfig.Wallet) 192 if err != nil { 193 return output.NewError(0, "", err) 194 } 195 return writeToFile(alias, addr) 196 }