github.com/turingchain2020/turingchain@v1.1.21/system/dapp/commands/wallet.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  	"time"
    12  
    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  // WalletCmd wallet command
    21  func WalletCmd() *cobra.Command {
    22  	cmd := &cobra.Command{
    23  		Use:   "wallet",
    24  		Short: "Wallet management",
    25  		Args:  cobra.MinimumNArgs(1),
    26  	}
    27  
    28  	cmd.AddCommand(
    29  		LockCmd(),
    30  		UnlockCmd(),
    31  		WalletStatusCmd(),
    32  		SetPwdCmd(),
    33  		WalletListTxsCmd(),
    34  		MergeBalanceCmd(),
    35  		AutoMineCmd(),
    36  		SignRawTxCmd(),
    37  		NoBalanceCmd(),
    38  		SetFeeCmd(),
    39  		SendTxCmd(),
    40  	)
    41  
    42  	return cmd
    43  }
    44  
    45  // LockCmd lock the wallet
    46  func LockCmd() *cobra.Command {
    47  	cmd := &cobra.Command{
    48  		Use:   "lock",
    49  		Short: "Lock wallet",
    50  		Run:   lock,
    51  	}
    52  	return cmd
    53  }
    54  
    55  func lock(cmd *cobra.Command, args []string) {
    56  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
    57  	var res rpctypes.Reply
    58  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.Lock", nil, &res)
    59  	ctx.Run()
    60  }
    61  
    62  // UnlockCmd unlock the wallet
    63  func UnlockCmd() *cobra.Command {
    64  	cmd := &cobra.Command{
    65  		Use:   "unlock",
    66  		Short: "Unlock wallet",
    67  		Run:   unLock,
    68  	}
    69  	addUnlockFlags(cmd)
    70  	return cmd
    71  }
    72  
    73  func addUnlockFlags(cmd *cobra.Command) {
    74  	cmd.Flags().StringP("pwd", "p", "", "password needed to unlock")
    75  	cmd.MarkFlagRequired("pwd")
    76  
    77  	cmd.Flags().Int64P("time_out", "t", 0, "time out for unlock operation(0 for unlimited)")
    78  	cmd.Flags().StringP("scope", "s", "wallet", "unlock scope(wallet/ticket)")
    79  }
    80  
    81  func unLock(cmd *cobra.Command, args []string) {
    82  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
    83  	pwd, _ := cmd.Flags().GetString("pwd")
    84  	timeOut, _ := cmd.Flags().GetInt64("time_out")
    85  	scope, _ := cmd.Flags().GetString("scope")
    86  	var walletOrTicket bool
    87  	switch scope {
    88  	case "wallet":
    89  		walletOrTicket = false
    90  	case "ticket":
    91  		walletOrTicket = true
    92  	default:
    93  		fmt.Println("unlock scope code wrong: wallet or ticket")
    94  		return
    95  	}
    96  
    97  	params := types.WalletUnLock{
    98  		Passwd:         pwd,
    99  		Timeout:        timeOut,
   100  		WalletOrTicket: walletOrTicket,
   101  	}
   102  	var res rpctypes.Reply
   103  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.UnLock", params, &res)
   104  	ctx.Run()
   105  }
   106  
   107  // WalletStatusCmd get wallet status
   108  func WalletStatusCmd() *cobra.Command {
   109  	cmd := &cobra.Command{
   110  		Use:   "status",
   111  		Short: "Get wallet status",
   112  		Run:   walletStatus,
   113  	}
   114  	return cmd
   115  }
   116  
   117  func walletStatus(cmd *cobra.Command, args []string) {
   118  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   119  	var res rpctypes.WalletStatus
   120  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetWalletStatus", nil, &res)
   121  	ctx.Run()
   122  }
   123  
   124  // SetPwdCmd set password
   125  func SetPwdCmd() *cobra.Command {
   126  	cmd := &cobra.Command{
   127  		Use:   "set_pwd",
   128  		Short: "Set password",
   129  		Run:   setPwd,
   130  	}
   131  	addSetPwdFlags(cmd)
   132  	return cmd
   133  }
   134  
   135  func addSetPwdFlags(cmd *cobra.Command) {
   136  	cmd.Flags().StringP("old", "o", "", "old password")
   137  	cmd.MarkFlagRequired("old")
   138  
   139  	cmd.Flags().StringP("new", "n", "", "new password,[8-30]letter and digit")
   140  	cmd.MarkFlagRequired("new")
   141  }
   142  
   143  func setPwd(cmd *cobra.Command, args []string) {
   144  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   145  	oldPwd, _ := cmd.Flags().GetString("old")
   146  	newPwd, _ := cmd.Flags().GetString("new")
   147  	params := types.ReqWalletSetPasswd{
   148  		OldPass: oldPwd,
   149  		NewPass: newPwd,
   150  	}
   151  	var res rpctypes.Reply
   152  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.SetPasswd", params, &res)
   153  	ctx.Run()
   154  }
   155  
   156  // WalletListTxsCmd  get wallet transactions
   157  func WalletListTxsCmd() *cobra.Command {
   158  	cmd := &cobra.Command{
   159  		Use:   "list_txs",
   160  		Short: "List transactions in wallet",
   161  		Run:   walletListTxs,
   162  	}
   163  	addWalletListTxsFlags(cmd)
   164  	return cmd
   165  }
   166  
   167  func addWalletListTxsFlags(cmd *cobra.Command) {
   168  	cmd.Flags().StringP("from", "f", "", "from which transaction begin")
   169  	cmd.MarkFlagRequired("from")
   170  
   171  	cmd.Flags().Int32P("count", "c", 0, "number of transactions")
   172  	cmd.MarkFlagRequired("count")
   173  
   174  	cmd.Flags().Int32P("direction", "d", 0, "query direction (0: pre page, 1: next page)")
   175  }
   176  
   177  func walletListTxs(cmd *cobra.Command, args []string) {
   178  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   179  	txHash, _ := cmd.Flags().GetString("from")
   180  	count, _ := cmd.Flags().GetInt32("count")
   181  	direction, _ := cmd.Flags().GetInt32("direction")
   182  	params := rpctypes.ReqWalletTransactionList{
   183  		FromTx:    txHash,
   184  		Count:     count,
   185  		Direction: direction,
   186  	}
   187  	var res rpctypes.WalletTxDetails
   188  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.WalletTxList", params, &res)
   189  	ctx.SetResultCb(parseWalletTxListRes)
   190  	ctx.Run()
   191  }
   192  
   193  func parseWalletTxListRes(arg interface{}) (interface{}, error) {
   194  	res := arg.(*rpctypes.WalletTxDetails)
   195  	var result commandtypes.WalletTxDetailsResult
   196  	for _, v := range res.TxDetails {
   197  		amountResult := strconv.FormatFloat(float64(v.Amount)/float64(types.Coin), 'f', 4, 64)
   198  		wtxd := &commandtypes.WalletTxDetailResult{
   199  			Tx:         commandtypes.DecodeTransaction(v.Tx),
   200  			Receipt:    v.Receipt,
   201  			Height:     v.Height,
   202  			Index:      v.Index,
   203  			Blocktime:  v.BlockTime,
   204  			Amount:     amountResult,
   205  			Fromaddr:   v.FromAddr,
   206  			Txhash:     v.TxHash,
   207  			ActionName: v.ActionName,
   208  		}
   209  		result.TxDetails = append(result.TxDetails, wtxd)
   210  	}
   211  	return result, nil
   212  }
   213  
   214  // MergeBalanceCmd  merge all balance to an account
   215  func MergeBalanceCmd() *cobra.Command {
   216  	cmd := &cobra.Command{
   217  		Use:   "merge",
   218  		Short: "Merge accounts' balance into address",
   219  		Run:   mergeBalance,
   220  	}
   221  	addMergeBalanceFlags(cmd)
   222  	return cmd
   223  }
   224  
   225  func addMergeBalanceFlags(cmd *cobra.Command) {
   226  	cmd.Flags().StringP("to", "t", "", "destination account address")
   227  	cmd.MarkFlagRequired("to")
   228  }
   229  
   230  func mergeBalance(cmd *cobra.Command, args []string) {
   231  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   232  	toAddr, _ := cmd.Flags().GetString("to")
   233  	params := types.ReqWalletMergeBalance{
   234  		To: toAddr,
   235  	}
   236  	var res rpctypes.ReplyHashes
   237  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.MergeBalance", params, &res)
   238  	ctx.Run()
   239  }
   240  
   241  // AutoMineCmd  set auto mining: 为了兼容现在的命令行, 这个命令就放到wallet,实际上依赖 ticket
   242  func AutoMineCmd() *cobra.Command {
   243  	cmd := &cobra.Command{
   244  		Use:   "auto_mine",
   245  		Short: "Set auto mine on/off. Deprecated",
   246  		Run:   autoMine,
   247  	}
   248  	addAutoMineFlags(cmd)
   249  	return cmd
   250  }
   251  
   252  func addAutoMineFlags(cmd *cobra.Command) {
   253  	cmd.Flags().Int32P("flag", "f", 0, `auto mine(0: off, 1: on)`)
   254  	cmd.MarkFlagRequired("flag")
   255  }
   256  
   257  func autoMine(cmd *cobra.Command, args []string) {
   258  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   259  	flag, _ := cmd.Flags().GetInt32("flag")
   260  	if flag != 0 && flag != 1 {
   261  		err := cmd.UsageFunc()(cmd)
   262  		if err != nil {
   263  			fmt.Fprintln(os.Stderr, err)
   264  		}
   265  		return
   266  	}
   267  	params := struct {
   268  		Flag int32
   269  	}{
   270  		Flag: flag,
   271  	}
   272  	var res rpctypes.Reply
   273  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "ticket.SetAutoMining", params, &res)
   274  	ctx.Run()
   275  }
   276  
   277  // NoBalanceCmd sign raw tx
   278  func NoBalanceCmd() *cobra.Command {
   279  	cmd := &cobra.Command{
   280  		Use:   "nobalance",
   281  		Short: "Create nobalance transaction",
   282  		Run:   noBalanceTx,
   283  	}
   284  	addNoBalanceFlags(cmd)
   285  	return cmd
   286  }
   287  
   288  func addNoBalanceFlags(cmd *cobra.Command) {
   289  	cmd.Flags().StringP("data", "d", "", "raw transaction data")
   290  	cmd.MarkFlagRequired("data")
   291  	cmd.Flags().StringP("key", "k", "", "private key of pay fee account (optional)")
   292  	cmd.Flags().StringP("payaddr", "a", "", "account address of pay fee (optional)")
   293  	cmd.Flags().StringP("expire", "e", "120s", "transaction expire time")
   294  }
   295  
   296  // SignRawTxCmd sign raw tx
   297  func SignRawTxCmd() *cobra.Command {
   298  	cmd := &cobra.Command{
   299  		Use:   "sign",
   300  		Short: "Sign transaction",
   301  		Run:   signRawTx,
   302  	}
   303  	addSignRawTxFlags(cmd)
   304  	return cmd
   305  }
   306  
   307  func addSignRawTxFlags(cmd *cobra.Command) {
   308  	cmd.Flags().StringP("data", "d", "", "raw transaction data")
   309  	cmd.MarkFlagRequired("data")
   310  
   311  	cmd.Flags().Int32P("index", "i", 0, "transaction index to be signed")
   312  	cmd.Flags().StringP("key", "k", "", "private key (optional)")
   313  	cmd.Flags().StringP("addr", "a", "", "account address (optional)")
   314  	cmd.Flags().StringP("expire", "e", "120s", "transaction expire time")
   315  	cmd.Flags().Float64P("fee", "f", 0, "transaction fee (optional), auto set proper fee if not set or zero fee")
   316  	cmd.Flags().StringP("to", "t", "", "new to addr (optional)")
   317  
   318  	// A duration string is a possibly signed sequence of
   319  	// decimal numbers, each with optional fraction and a unit suffix,
   320  	// such as "300ms", "-1.5h" or "2h45m".
   321  	// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
   322  }
   323  
   324  func noBalanceTx(cmd *cobra.Command, args []string) {
   325  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   326  	data, _ := cmd.Flags().GetString("data")
   327  	addr, _ := cmd.Flags().GetString("payaddr")
   328  	privkey, _ := cmd.Flags().GetString("key")
   329  	expire, _ := cmd.Flags().GetString("expire")
   330  	expireTime, err := time.ParseDuration(expire)
   331  	if err != nil {
   332  		fmt.Fprintln(os.Stderr, err)
   333  		return
   334  	}
   335  	if expireTime < time.Minute*2 && expireTime != time.Second*0 {
   336  		expire = "120s"
   337  		fmt.Println("expire time must longer than 2 minutes, changed expire time into 2 minutes")
   338  	}
   339  	params := types.NoBalanceTx{
   340  		PayAddr: addr,
   341  		TxHex:   data,
   342  		Expire:  expire,
   343  		Privkey: privkey,
   344  	}
   345  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.CreateNoBalanceTransaction", params, nil)
   346  	ctx.RunWithoutMarshal()
   347  }
   348  
   349  func signRawTx(cmd *cobra.Command, args []string) {
   350  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   351  	data, _ := cmd.Flags().GetString("data")
   352  	key, _ := cmd.Flags().GetString("key")
   353  	addr, _ := cmd.Flags().GetString("addr")
   354  	index, _ := cmd.Flags().GetInt32("index")
   355  	to, _ := cmd.Flags().GetString("to")
   356  	fee, _ := cmd.Flags().GetFloat64("fee")
   357  	expire, _ := cmd.Flags().GetString("expire")
   358  	expire, err := commandtypes.CheckExpireOpt(expire)
   359  	if err != nil {
   360  		fmt.Fprintln(os.Stderr, err)
   361  		return
   362  	}
   363  	feeInt64 := int64(fee * 1e4)
   364  	params := types.ReqSignRawTx{
   365  		Addr:      addr,
   366  		Privkey:   key,
   367  		TxHex:     data,
   368  		Expire:    expire,
   369  		Index:     index,
   370  		Fee:       feeInt64 * 1e4,
   371  		NewToAddr: to,
   372  	}
   373  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.SignRawTx", params, nil)
   374  	ctx.RunWithoutMarshal()
   375  }
   376  
   377  // SetFeeCmd set tx fee
   378  func SetFeeCmd() *cobra.Command {
   379  	cmd := &cobra.Command{
   380  		Use:   "set_fee",
   381  		Short: "Set transaction fee",
   382  		Run:   setFee,
   383  	}
   384  	addSetFeeFlags(cmd)
   385  	return cmd
   386  }
   387  
   388  func addSetFeeFlags(cmd *cobra.Command) {
   389  	cmd.Flags().Float64P("amount", "a", 0, "tx fee amount")
   390  	cmd.MarkFlagRequired("amount")
   391  }
   392  
   393  func setFee(cmd *cobra.Command, args []string) {
   394  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   395  	amount, _ := cmd.Flags().GetFloat64("amount")
   396  	amountInt64 := int64(amount * 1e4)
   397  	params := types.ReqWalletSetFee{
   398  		Amount: amountInt64 * 1e4,
   399  	}
   400  	var res rpctypes.Reply
   401  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.SetTxFee", params, &res)
   402  	ctx.Run()
   403  }
   404  
   405  // SendTxCmd  send raw tx
   406  func SendTxCmd() *cobra.Command {
   407  	cmd := &cobra.Command{
   408  		Use:   "send",
   409  		Short: "Send a transaction",
   410  		Run:   sendTx,
   411  	}
   412  	addSendTxFlags(cmd)
   413  	return cmd
   414  }
   415  
   416  func addSendTxFlags(cmd *cobra.Command) {
   417  	cmd.Flags().StringP("data", "d", "", "transaction content")
   418  	cmd.MarkFlagRequired("data")
   419  
   420  	cmd.Flags().StringP("token", "t", types.TRC, "token name. (TRC supported)")
   421  }
   422  
   423  func sendTx(cmd *cobra.Command, args []string) {
   424  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   425  	data, _ := cmd.Flags().GetString("data")
   426  	token, _ := cmd.Flags().GetString("token")
   427  	params := rpctypes.RawParm{
   428  		Token: token,
   429  		Data:  data,
   430  	}
   431  
   432  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.SendTransaction", params, nil)
   433  	ctx.RunWithoutMarshal()
   434  }