github.com/turingchain2020/turingchain@v1.1.21/system/dapp/commands/account.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package commands 6 7 import ( 8 "fmt" 9 "os" 10 "strconv" 11 12 "github.com/turingchain2020/turingchain/common/address" 13 "github.com/turingchain2020/turingchain/rpc/jsonclient" 14 rpctypes "github.com/turingchain2020/turingchain/rpc/types" 15 commandtypes "github.com/turingchain2020/turingchain/system/dapp/commands/types" 16 "github.com/turingchain2020/turingchain/types" 17 "github.com/spf13/cobra" 18 ) 19 20 // AccountCmd account command 21 func AccountCmd() *cobra.Command { 22 cmd := &cobra.Command{ 23 Use: "account", 24 Short: "Account management", 25 Args: cobra.MinimumNArgs(1), 26 } 27 28 cmd.AddCommand( 29 DumpKeyCmd(), 30 GetAccountListCmd(), 31 GetBalanceCmd(), 32 ImportKeyCmd(), 33 NewAccountCmd(), 34 SetLabelCmd(), 35 DumpKeysFileCmd(), 36 ImportKeysFileCmd(), 37 GetAccountCmd(), 38 ) 39 40 return cmd 41 } 42 43 // DumpKeyCmd dump private key 44 func DumpKeyCmd() *cobra.Command { 45 cmd := &cobra.Command{ 46 Use: "dump_key", 47 Short: "Dump private key for account address", 48 Run: dumpKey, 49 } 50 addDumpKeyFlags(cmd) 51 return cmd 52 } 53 54 func addDumpKeyFlags(cmd *cobra.Command) { 55 cmd.Flags().StringP("addr", "a", "", "address of account") 56 cmd.MarkFlagRequired("addr") 57 } 58 59 func dumpKey(cmd *cobra.Command, args []string) { 60 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 61 addr, _ := cmd.Flags().GetString("addr") 62 params := types.ReqString{ 63 Data: addr, 64 } 65 var res types.ReplyString 66 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.DumpPrivkey", params, &res) 67 ctx.Run() 68 } 69 70 // GetAccountListCmd get accounts of the wallet 71 func GetAccountListCmd() *cobra.Command { 72 cmd := &cobra.Command{ 73 Use: "list", 74 Short: "Get account list", 75 Run: listAccount, 76 } 77 return cmd 78 } 79 80 func listAccount(cmd *cobra.Command, args []string) { 81 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 82 var res rpctypes.WalletAccounts 83 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetAccounts", nil, &res) 84 ctx.SetResultCb(parseListAccountRes) 85 ctx.Run() 86 } 87 88 func parseListAccountRes(arg interface{}) (interface{}, error) { 89 res := arg.(*rpctypes.WalletAccounts) 90 var result commandtypes.AccountsResult 91 for _, r := range res.Wallets { 92 balanceResult := strconv.FormatFloat(float64(r.Acc.Balance/types.Int1E4)/types.Float1E4, 'f', 4, 64) 93 frozenResult := strconv.FormatFloat(float64(r.Acc.Frozen/types.Int1E4)/types.Float1E4, 'f', 4, 64) 94 accResult := &commandtypes.AccountResult{ 95 Currency: r.Acc.Currency, 96 Addr: r.Acc.Addr, 97 Balance: balanceResult, 98 Frozen: frozenResult, 99 } 100 result.Wallets = append(result.Wallets, &commandtypes.WalletResult{Acc: accResult, Label: r.Label}) 101 } 102 return result, nil 103 } 104 105 // GetBalanceCmd get balance of an execer 106 func GetBalanceCmd() *cobra.Command { 107 cmd := &cobra.Command{ 108 Use: "balance", 109 Short: "Get balance of a account address", 110 Run: balance, 111 } 112 addBalanceFlags(cmd) 113 return cmd 114 } 115 116 func addBalanceFlags(cmd *cobra.Command) { 117 cmd.Flags().StringP("addr", "a", "", "account addr") 118 cmd.MarkFlagRequired("addr") 119 cmd.Flags().StringP("exec", "e", "", getExecuterNameString()) 120 cmd.Flags().IntP("height", "", -1, "block height") 121 } 122 123 func getExecuterNameString() string { 124 str := "executer name (only " 125 allowExeName := types.AllowUserExec 126 nameLen := len(allowExeName) 127 for i := 0; i < nameLen; i++ { 128 if i > 0 { 129 str += ", " 130 } 131 str += fmt.Sprintf("\"%s\"", string(allowExeName[i])) 132 } 133 str += " and user-defined type supported)" 134 return str 135 } 136 137 func balance(cmd *cobra.Command, args []string) { 138 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 139 addr, _ := cmd.Flags().GetString("addr") 140 execer, _ := cmd.Flags().GetString("exec") 141 height, _ := cmd.Flags().GetInt("height") 142 err := address.CheckAddress(addr) 143 if err != nil { 144 if err = address.CheckMultiSignAddress(addr); err != nil { 145 fmt.Fprintln(os.Stderr, types.ErrInvalidAddress) 146 return 147 } 148 } 149 if execer == "" && height == -1 { 150 req := types.ReqAllExecBalance{Addr: addr} 151 var res rpctypes.AllExecBalance 152 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetAllExecBalance", req, &res) 153 ctx.SetResultCb(parseGetAllBalanceRes) 154 ctx.Run() 155 return 156 } 157 158 stateHash := "" 159 if height >= 0 { 160 params := types.ReqBlocks{ 161 Start: int64(height), 162 End: int64(height), 163 IsDetail: false, 164 } 165 var res rpctypes.Headers 166 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetHeaders", params, &res) 167 _, err := ctx.RunResult() 168 if err != nil { 169 fmt.Fprintln(os.Stderr, err) 170 return 171 } 172 h := res.Items[0] 173 stateHash = h.StateHash 174 } 175 176 if execer == "" { 177 req := types.ReqAllExecBalance{Addr: addr, StateHash: stateHash} 178 var res rpctypes.AllExecBalance 179 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetAllExecBalance", req, &res) 180 ctx.SetResultCb(parseGetAllBalanceRes) 181 ctx.Run() 182 return 183 } 184 185 if ok := types.IsAllowExecName([]byte(execer), []byte(execer)); !ok { 186 fmt.Fprintln(os.Stderr, types.ErrExecNameNotAllow) 187 return 188 } 189 190 var addrs []string 191 addrs = append(addrs, addr) 192 params := types.ReqBalance{ 193 Addresses: addrs, 194 Execer: execer, 195 StateHash: stateHash, 196 } 197 var res []*rpctypes.Account 198 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetBalance", params, &res) 199 ctx.SetResultCb(parseGetBalanceRes) 200 ctx.Run() 201 } 202 203 func parseGetBalanceRes(arg interface{}) (interface{}, error) { 204 res := *arg.(*[]*rpctypes.Account) 205 balanceResult := strconv.FormatFloat(float64(res[0].Balance/types.Int1E4)/types.Float1E4, 'f', 4, 64) 206 frozenResult := strconv.FormatFloat(float64(res[0].Frozen/types.Int1E4)/types.Float1E4, 'f', 4, 64) 207 result := &commandtypes.AccountResult{ 208 Addr: res[0].Addr, 209 Currency: res[0].Currency, 210 Balance: balanceResult, 211 Frozen: frozenResult, 212 } 213 return result, nil 214 } 215 216 func parseGetAllBalanceRes(arg interface{}) (interface{}, error) { 217 res := *arg.(*rpctypes.AllExecBalance) 218 accs := res.ExecAccount 219 result := commandtypes.AllExecBalance{Addr: res.Addr} 220 for _, acc := range accs { 221 balanceResult := strconv.FormatFloat(float64(acc.Account.Balance/types.Int1E4)/types.Float1E4, 'f', 4, 64) 222 frozenResult := strconv.FormatFloat(float64(acc.Account.Frozen/types.Int1E4)/types.Float1E4, 'f', 4, 64) 223 ar := &commandtypes.AccountResult{ 224 Currency: acc.Account.Currency, 225 Balance: balanceResult, 226 Frozen: frozenResult, 227 } 228 result.ExecAccount = append(result.ExecAccount, &commandtypes.ExecAccount{Execer: acc.Execer, Account: ar}) 229 } 230 return result, nil 231 } 232 233 // ImportKeyCmd import private key 234 func ImportKeyCmd() *cobra.Command { 235 cmd := &cobra.Command{ 236 Use: "import_key", 237 Short: "Import private key with label", 238 Run: importKey, 239 } 240 addImportKeyFlags(cmd) 241 return cmd 242 } 243 244 func addImportKeyFlags(cmd *cobra.Command) { 245 cmd.Flags().StringP("key", "k", "", "private key") 246 cmd.MarkFlagRequired("key") 247 248 cmd.Flags().StringP("label", "l", "", "label for private key") 249 cmd.MarkFlagRequired("label") 250 } 251 252 func importKey(cmd *cobra.Command, args []string) { 253 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 254 key, _ := cmd.Flags().GetString("key") 255 label, _ := cmd.Flags().GetString("label") 256 params := types.ReqWalletImportPrivkey{ 257 Privkey: key, 258 Label: label, 259 } 260 var res types.WalletAccount 261 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.ImportPrivkey", params, &res) 262 ctx.SetResultCb(parseImportKeyRes) 263 ctx.Run() 264 } 265 266 func parseImportKeyRes(arg interface{}) (interface{}, error) { 267 res := arg.(*types.WalletAccount) 268 accResult := commandtypes.DecodeAccount(res.GetAcc(), types.Coin) 269 result := commandtypes.WalletResult{ 270 Acc: accResult, 271 Label: res.GetLabel(), 272 } 273 return result, nil 274 } 275 276 // NewAccountCmd create an account 277 func NewAccountCmd() *cobra.Command { 278 cmd := &cobra.Command{ 279 Use: "create", 280 Short: "Create a new account with label", 281 Run: createAccount, 282 } 283 addCreateAccountFlags(cmd) 284 return cmd 285 } 286 287 func addCreateAccountFlags(cmd *cobra.Command) { 288 cmd.Flags().StringP("label", "l", "", "account label") 289 cmd.MarkFlagRequired("label") 290 } 291 292 func createAccount(cmd *cobra.Command, args []string) { 293 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 294 label, _ := cmd.Flags().GetString("label") 295 params := types.ReqNewAccount{ 296 Label: label, 297 } 298 var res types.WalletAccount 299 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.NewAccount", params, &res) 300 ctx.SetResultCb(parseCreateAccountRes) 301 ctx.Run() 302 } 303 304 func parseCreateAccountRes(arg interface{}) (interface{}, error) { 305 res := arg.(*types.WalletAccount) 306 accResult := commandtypes.DecodeAccount(res.GetAcc(), types.Coin) 307 result := commandtypes.WalletResult{ 308 Acc: accResult, 309 Label: res.GetLabel(), 310 } 311 return result, nil 312 } 313 314 //GetAccountCmd get account by label 315 func GetAccountCmd() *cobra.Command { 316 cmd := &cobra.Command{ 317 Use: "get", 318 Short: "Get account by label", 319 Run: getAccount, 320 } 321 addGetAccountFlags(cmd) 322 return cmd 323 } 324 325 // SetLabelCmd set label of an account 326 func SetLabelCmd() *cobra.Command { 327 cmd := &cobra.Command{ 328 Use: "set_label", 329 Short: "Set label for account address", 330 Run: setLabel, 331 } 332 addSetLabelFlags(cmd) 333 return cmd 334 } 335 func addGetAccountFlags(cmd *cobra.Command) { 336 cmd.Flags().StringP("label", "l", "", "account label") 337 cmd.MarkFlagRequired("label") 338 } 339 func addSetLabelFlags(cmd *cobra.Command) { 340 cmd.Flags().StringP("addr", "a", "", "account address") 341 cmd.MarkFlagRequired("addr") 342 343 cmd.Flags().StringP("label", "l", "", "account label") 344 cmd.MarkFlagRequired("label") 345 } 346 347 func getAccount(cmd *cobra.Command, args []string) { 348 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 349 label, _ := cmd.Flags().GetString("label") 350 params := types.ReqGetAccount{ 351 Label: label, 352 } 353 var res types.WalletAccount 354 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetAccount", params, &res) 355 ctx.SetResultCb(parseSetLabelRes) 356 ctx.Run() 357 } 358 359 func setLabel(cmd *cobra.Command, args []string) { 360 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 361 addr, _ := cmd.Flags().GetString("addr") 362 label, _ := cmd.Flags().GetString("label") 363 params := types.ReqWalletSetLabel{ 364 Addr: addr, 365 Label: label, 366 } 367 var res types.WalletAccount 368 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.SetLabl", params, &res) 369 ctx.SetResultCb(parseSetLabelRes) 370 ctx.Run() 371 } 372 373 func parseSetLabelRes(arg interface{}) (interface{}, error) { 374 res := arg.(*types.WalletAccount) 375 accResult := commandtypes.DecodeAccount(res.GetAcc(), types.Coin) 376 result := commandtypes.WalletResult{ 377 Acc: accResult, 378 Label: res.GetLabel(), 379 } 380 return result, nil 381 } 382 383 //DumpKeysFileCmd dump file 384 func DumpKeysFileCmd() *cobra.Command { 385 cmd := &cobra.Command{ 386 Use: "dump_keys", 387 Short: "Dump private keys to file", 388 Run: dumpKeys, 389 } 390 cmd.Flags().StringP("file", "f", "", "file name") 391 cmd.MarkFlagRequired("file") 392 cmd.Flags().StringP("pwd", "p", "", "password needed to encrypt") 393 cmd.MarkFlagRequired("pwd") 394 return cmd 395 } 396 397 //ImportKeysFileCmd import key 398 func ImportKeysFileCmd() *cobra.Command { 399 cmd := &cobra.Command{ 400 Use: "import_keys", 401 Short: "Import private keys from file", 402 Run: importKeys, 403 } 404 cmd.Flags().StringP("file", "f", "", "file name") 405 cmd.MarkFlagRequired("file") 406 cmd.Flags().StringP("pwd", "p", "", "password needed to decode") 407 cmd.MarkFlagRequired("pwd") 408 return cmd 409 } 410 411 func dumpKeys(cmd *cobra.Command, args []string) { 412 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 413 file, _ := cmd.Flags().GetString("file") 414 pwd, _ := cmd.Flags().GetString("pwd") 415 params := types.ReqPrivkeysFile{ 416 FileName: file, 417 Passwd: pwd, 418 } 419 var res types.Reply 420 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.DumpPrivkeysFile", params, &res) 421 ctx.Run() 422 } 423 424 func importKeys(cmd *cobra.Command, args []string) { 425 rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") 426 file, _ := cmd.Flags().GetString("file") 427 pwd, _ := cmd.Flags().GetString("pwd") 428 params := types.ReqPrivkeysFile{ 429 FileName: file, 430 Passwd: pwd, 431 } 432 var res types.Reply 433 ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.ImportPrivkeysFile", params, &res) 434 ctx.Run() 435 }