github.com/turingchain2020/turingchain@v1.1.21/system/dapp/commands/tx.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  	"strings"
    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  // TxCmd transaction command
    21  func TxCmd() *cobra.Command {
    22  	cmd := &cobra.Command{
    23  		Use:   "tx",
    24  		Short: "Transaction management",
    25  		Args:  cobra.MinimumNArgs(1),
    26  	}
    27  
    28  	cmd.AddCommand(
    29  		QueryTxCmd(),
    30  		QueryTxByAddrCmd(),
    31  		QueryTxsByHashesCmd(),
    32  		GetRawTxCmd(),
    33  		DecodeTxCmd(),
    34  		GetAddrOverviewCmd(),
    35  		ReWriteRawTxCmd(),
    36  	)
    37  
    38  	return cmd
    39  }
    40  
    41  // QueryTxByAddrCmd get tx by address
    42  func QueryTxByAddrCmd() *cobra.Command {
    43  	cmd := &cobra.Command{
    44  		Use:   "query_addr",
    45  		Short: "Query transaction by account address",
    46  		Run:   queryTxByAddr,
    47  	}
    48  	addQueryTxByAddrFlags(cmd)
    49  	return cmd
    50  }
    51  
    52  func addQueryTxByAddrFlags(cmd *cobra.Command) {
    53  	cmd.Flags().StringP("addr", "a", "", "account address")
    54  	cmd.MarkFlagRequired("addr")
    55  
    56  	cmd.Flags().Int32P("flag", "f", 0, "transaction type(0: all txs relevant to addr, 1: addr as sender, 2: addr as receiver) (default 0)")
    57  	cmd.Flags().Int32P("count", "c", 10, "maximum return number of transactions")
    58  	cmd.Flags().Int32P("direction", "d", 0, "query direction from height:index(0: positive order -1:negative order) (default 0)")
    59  	cmd.Flags().Int64P("height", "t", -1, "transaction's block height(-1: from latest txs, >=0: query from height)")
    60  	cmd.Flags().Int64P("index", "i", 0, "query from index of tx in block height[0-100000] (default 0)")
    61  }
    62  
    63  func queryTxByAddr(cmd *cobra.Command, args []string) {
    64  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
    65  	addr, _ := cmd.Flags().GetString("addr")
    66  	flag, _ := cmd.Flags().GetInt32("flag")
    67  	count, _ := cmd.Flags().GetInt32("count")
    68  	direction, _ := cmd.Flags().GetInt32("direction")
    69  	height, _ := cmd.Flags().GetInt64("height")
    70  	index, _ := cmd.Flags().GetInt64("index")
    71  	params := types.ReqAddr{
    72  		Addr:      addr,
    73  		Flag:      flag,
    74  		Count:     count,
    75  		Direction: direction,
    76  		Height:    height,
    77  		Index:     index,
    78  	}
    79  	var res rpctypes.ReplyTxInfos
    80  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetTxByAddr", params, &res)
    81  	ctx.Run()
    82  }
    83  
    84  // QueryTxCmd  query tx by hash
    85  func QueryTxCmd() *cobra.Command {
    86  	cmd := &cobra.Command{
    87  		Use:   "query",
    88  		Short: "Query transaction by hash",
    89  		Run:   queryTx,
    90  	}
    91  	addQueryTxFlags(cmd)
    92  	return cmd
    93  }
    94  
    95  func addQueryTxFlags(cmd *cobra.Command) {
    96  	cmd.Flags().StringP("hash", "s", "", "transaction hash")
    97  	cmd.MarkFlagRequired("hash")
    98  }
    99  
   100  func queryTx(cmd *cobra.Command, args []string) {
   101  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   102  	hash, _ := cmd.Flags().GetString("hash")
   103  	if len(hash) != 66 {
   104  		fmt.Print(types.ErrHashNotExist.Error())
   105  		return
   106  	}
   107  	params := rpctypes.QueryParm{
   108  		Hash: hash,
   109  	}
   110  	var res rpctypes.TransactionDetail
   111  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.QueryTransaction", params, &res)
   112  	ctx.SetResultCb(parseQueryTxRes)
   113  	ctx.Run()
   114  }
   115  
   116  func parseQueryTxRes(arg interface{}) (interface{}, error) {
   117  	res := arg.(*rpctypes.TransactionDetail)
   118  	amountResult := strconv.FormatFloat(float64(res.Amount)/float64(types.Coin), 'f', 4, 64)
   119  	result := commandtypes.TxDetailResult{
   120  		Tx:         commandtypes.DecodeTransaction(res.Tx),
   121  		Receipt:    res.Receipt,
   122  		Proofs:     res.Proofs,
   123  		Height:     res.Height,
   124  		Index:      res.Index,
   125  		Blocktime:  res.Blocktime,
   126  		Amount:     amountResult,
   127  		Fromaddr:   res.Fromaddr,
   128  		ActionName: res.ActionName,
   129  		Assets:     res.Assets,
   130  		TxProofs:   res.TxProofs,
   131  		FullHash:   res.FullHash,
   132  	}
   133  	return result, nil
   134  }
   135  
   136  // QueryTxsByHashesCmd  get transactions by hashes
   137  func QueryTxsByHashesCmd() *cobra.Command {
   138  	cmd := &cobra.Command{
   139  		Use:   "query_hash",
   140  		Short: "Get transactions by hashes",
   141  		Run:   getTxsByHashes,
   142  	}
   143  	addGetTxsByHashesFlags(cmd)
   144  	return cmd
   145  }
   146  
   147  func addGetTxsByHashesFlags(cmd *cobra.Command) {
   148  	cmd.Flags().StringP("hashes", "s", "", "transaction hash(es), separated by space")
   149  	cmd.MarkFlagRequired("hashes")
   150  }
   151  
   152  func getTxsByHashes(cmd *cobra.Command, args []string) {
   153  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   154  	hashes, _ := cmd.Flags().GetString("hashes")
   155  	hashesArr := strings.Split(hashes, " ")
   156  	params := rpctypes.ReqHashes{
   157  		Hashes: hashesArr,
   158  	}
   159  
   160  	var res rpctypes.TransactionDetails
   161  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetTxByHashes", params, &res)
   162  	ctx.SetResultCb(parseQueryTxsByHashesRes)
   163  	ctx.Run()
   164  }
   165  
   166  func parseQueryTxsByHashesRes(arg interface{}) (interface{}, error) {
   167  	var result commandtypes.TxDetailsResult
   168  	for _, v := range arg.(*rpctypes.TransactionDetails).Txs {
   169  		if v == nil {
   170  			result.Txs = append(result.Txs, nil)
   171  			continue
   172  		}
   173  		amountResult := strconv.FormatFloat(float64(v.Amount)/float64(types.Coin), 'f', 4, 64)
   174  		td := commandtypes.TxDetailResult{
   175  			Tx:         commandtypes.DecodeTransaction(v.Tx),
   176  			Receipt:    v.Receipt,
   177  			Proofs:     v.Proofs,
   178  			Height:     v.Height,
   179  			Index:      v.Index,
   180  			Blocktime:  v.Blocktime,
   181  			Amount:     amountResult,
   182  			Fromaddr:   v.Fromaddr,
   183  			ActionName: v.ActionName,
   184  			Assets:     v.Assets,
   185  		}
   186  		result.Txs = append(result.Txs, &td)
   187  	}
   188  	return result, nil
   189  }
   190  
   191  // GetRawTxCmd get raw transaction hex
   192  func GetRawTxCmd() *cobra.Command {
   193  	cmd := &cobra.Command{
   194  		Use:   "get_hex",
   195  		Short: "Get transaction hex by hash",
   196  		Run:   getTxHexByHash,
   197  	}
   198  	addGetRawTxFlags(cmd)
   199  	return cmd
   200  }
   201  
   202  func addGetRawTxFlags(cmd *cobra.Command) {
   203  	cmd.Flags().StringP("hash", "s", "", "transaction hash")
   204  	cmd.MarkFlagRequired("hash")
   205  }
   206  
   207  func getTxHexByHash(cmd *cobra.Command, args []string) {
   208  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   209  	txHash, _ := cmd.Flags().GetString("hash")
   210  	params := rpctypes.QueryParm{
   211  		Hash: txHash,
   212  	}
   213  
   214  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetHexTxByHash", params, nil)
   215  	ctx.RunWithoutMarshal()
   216  }
   217  
   218  // DecodeTxCmd decode raw hex to transaction
   219  func DecodeTxCmd() *cobra.Command {
   220  	cmd := &cobra.Command{
   221  		Use:   "decode",
   222  		Short: "Decode a hex format transaction",
   223  		Run:   decodeTx,
   224  	}
   225  	addDecodeTxFlags(cmd)
   226  	return cmd
   227  }
   228  
   229  func addDecodeTxFlags(cmd *cobra.Command) {
   230  	cmd.Flags().StringP("data", "d", "", "transaction content")
   231  	cmd.MarkFlagRequired("data")
   232  }
   233  
   234  func decodeTx(cmd *cobra.Command, args []string) {
   235  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   236  	data, _ := cmd.Flags().GetString("data")
   237  	params := types.ReqDecodeRawTransaction{
   238  		TxHex: data,
   239  	}
   240  
   241  	var res rpctypes.ReplyTxList
   242  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.DecodeRawTransaction", params, &res)
   243  	ctx.SetResultCb(parseReplyTxList)
   244  	ctx.Run()
   245  }
   246  
   247  func parseReplyTxList(view interface{}) (interface{}, error) {
   248  	replyTxList := view.(*rpctypes.ReplyTxList)
   249  	var commandtxs commandtypes.TxListResult
   250  	for _, cmdtx := range replyTxList.Txs {
   251  		txResult := commandtypes.DecodeTransaction(cmdtx)
   252  		commandtxs.Txs = append(commandtxs.Txs, txResult)
   253  	}
   254  	return &commandtxs, nil
   255  }
   256  
   257  // GetAddrOverviewCmd get overview of an address
   258  func GetAddrOverviewCmd() *cobra.Command {
   259  	cmd := &cobra.Command{
   260  		Use:   "addr_overview",
   261  		Short: "View transactions of address",
   262  		Run:   viewAddress,
   263  	}
   264  	addAddrViewFlags(cmd)
   265  	return cmd
   266  }
   267  
   268  func addAddrViewFlags(cmd *cobra.Command) {
   269  	cmd.Flags().StringP("addr", "a", "", "account address")
   270  	cmd.MarkFlagRequired("addr")
   271  }
   272  
   273  func viewAddress(cmd *cobra.Command, args []string) {
   274  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   275  	addr, _ := cmd.Flags().GetString("addr")
   276  	params := types.ReqAddr{
   277  		Addr: addr,
   278  	}
   279  
   280  	var res types.AddrOverview
   281  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.GetAddrOverview", params, &res)
   282  	ctx.SetResultCb(parseAddrOverview)
   283  	ctx.Run()
   284  }
   285  
   286  func parseAddrOverview(view interface{}) (interface{}, error) {
   287  	res := view.(*types.AddrOverview)
   288  	balance := strconv.FormatFloat(float64(res.GetBalance())/float64(types.Coin), 'f', 4, 64)
   289  	receiver := strconv.FormatFloat(float64(res.GetReciver())/float64(types.Coin), 'f', 4, 64)
   290  	addrOverview := &commandtypes.AddrOverviewResult{
   291  		Balance:  balance,
   292  		Receiver: receiver,
   293  		TxCount:  res.GetTxCount(),
   294  	}
   295  	return addrOverview, nil
   296  }
   297  
   298  // ReWriteRawTxCmd re-write raw transaction hex
   299  func ReWriteRawTxCmd() *cobra.Command {
   300  	cmd := &cobra.Command{
   301  		Use:   "rewrite",
   302  		Short: "rewrite transaction parameters",
   303  		Run:   reWriteRawTx,
   304  	}
   305  	addReWriteRawTxFlags(cmd)
   306  	return cmd
   307  }
   308  
   309  func addReWriteRawTxFlags(cmd *cobra.Command) {
   310  	cmd.Flags().StringP("tx", "s", "", "transaction hex")
   311  	cmd.MarkFlagRequired("tx")
   312  	cmd.Flags().StringP("to", "t", "", "to addr (optional)")
   313  	cmd.Flags().Float64P("fee", "f", 0, "transaction fee (optional)")
   314  	cmd.Flags().StringP("expire", "e", "", "expire time (optional)")
   315  	cmd.Flags().Int32P("index", "i", 0, "transaction index to be signed")
   316  }
   317  
   318  func reWriteRawTx(cmd *cobra.Command, args []string) {
   319  	rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
   320  	txHex, _ := cmd.Flags().GetString("tx")
   321  	to, _ := cmd.Flags().GetString("to")
   322  	fee, _ := cmd.Flags().GetFloat64("fee")
   323  	index, _ := cmd.Flags().GetInt32("index")
   324  	expire, _ := cmd.Flags().GetString("expire")
   325  
   326  	var err error
   327  	if expire != "" {
   328  		expire, err = commandtypes.CheckExpireOpt(expire)
   329  		if err != nil {
   330  			fmt.Fprintln(os.Stderr, err)
   331  			return
   332  		}
   333  	}
   334  
   335  	feeInt64 := int64(fee * 1e4)
   336  
   337  	params := rpctypes.ReWriteRawTx{
   338  		Tx:     txHex,
   339  		To:     to,
   340  		Fee:    feeInt64 * 1e4,
   341  		Expire: expire,
   342  		Index:  index,
   343  	}
   344  
   345  	ctx := jsonclient.NewRPCCtx(rpcLaddr, "Turingchain.ReWriteRawTx", params, nil)
   346  	ctx.RunWithoutMarshal()
   347  }