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  }