github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/cmd/ctool/core/transactioncmd.go (about)

     1  package core
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"encoding/json"
     6  	"fmt"
     7  	"github.com/PlatONnetwork/PlatON-Go/cmd/utils"
     8  	"github.com/PlatONnetwork/PlatON-Go/common"
     9  	"github.com/PlatONnetwork/PlatON-Go/common/hexutil"
    10  	"github.com/PlatONnetwork/PlatON-Go/core/types"
    11  	"github.com/PlatONnetwork/PlatON-Go/rlp"
    12  	"gopkg.in/urfave/cli.v1"
    13  	"math/big"
    14  	"strconv"
    15  	"strings"
    16  )
    17  
    18  var (
    19  	SendTransactionCmd = cli.Command{
    20  		Name:   "sendTransaction",
    21  		Usage:  "send a transaction",
    22  		Action: sendTransactionCmd,
    23  		Flags:  sendTransactionCmdFlags,
    24  	}
    25  	SendRawTransactionCmd = cli.Command{
    26  		Name:   "sendRawTransaction",
    27  		Usage:  "send a raw transaction",
    28  		Action: sendRawTransactionCmd,
    29  		Flags:  sendRawTransactionCmdFlags,
    30  	}
    31  	GetTxReceiptCmd = cli.Command{
    32  		Name:   "getTxReceipt",
    33  		Usage:  "get transaction receipt by hash",
    34  		Action: getTxReceiptCmd,
    35  		Flags:  getTxReceiptCmdFlags,
    36  	}
    37  )
    38  
    39  func getTxReceiptCmd(c *cli.Context) {
    40  	hash := c.String(TransactionHashFlag.Name)
    41  	parseConfigJson(c.String(ConfigPathFlag.Name))
    42  	GetTxReceipt(hash)
    43  }
    44  
    45  func GetTxReceipt(txHash string) (Receipt, error) {
    46  	var receipt = Receipt{}
    47  	res, _ := Send([]string{txHash}, "eth_getTransactionReceipt")
    48  	e := json.Unmarshal([]byte(res), &receipt)
    49  	if e != nil {
    50  		panic(fmt.Sprintf("parse get receipt result error ! \n %s", e.Error()))
    51  	}
    52  
    53  	if receipt.Result.BlockHash == "" {
    54  		panic("no receipt found")
    55  	}
    56  	out, _ := json.MarshalIndent(receipt, "", "  ")
    57  	fmt.Println(string(out))
    58  	return receipt, nil
    59  }
    60  
    61  func sendTransactionCmd(c *cli.Context) error {
    62  	from := c.String(TxFromFlag.Name)
    63  	to := c.String(TxToFlag.Name)
    64  	value := c.String(TransferValueFlag.Name)
    65  	parseConfigJson(c.String(ConfigPathFlag.Name))
    66  
    67  	hash, err := SendTransaction(from, to, value)
    68  	if err != nil {
    69  		utils.Fatalf("Send transaction error: %v", err)
    70  	}
    71  
    72  	fmt.Printf("tx hash: %s", hash)
    73  	return nil
    74  }
    75  
    76  func sendRawTransactionCmd(c *cli.Context) error {
    77  	from := c.String(TxFromFlag.Name)
    78  	to := c.String(TxToFlag.Name)
    79  	value := c.String(TransferValueFlag.Name)
    80  	pkFile := c.String(PKFilePathFlag.Name)
    81  
    82  	parseConfigJson(c.String(ConfigPathFlag.Name))
    83  
    84  	hash, err := SendRawTransaction(from, to, value, pkFile)
    85  	if err != nil {
    86  		utils.Fatalf("Send transaction error: %v", err)
    87  	}
    88  
    89  	fmt.Printf("tx hash: %s", hash)
    90  	return nil
    91  }
    92  
    93  func SendTransaction(from, to, value string) (string, error) {
    94  	var tx TxParams
    95  	if from == "" {
    96  		from = config.From
    97  	}
    98  	tx.From = from
    99  	tx.To = to
   100  	tx.Gas = config.Gas
   101  	tx.GasPrice = config.GasPrice
   102  
   103  	if !strings.HasPrefix(value, "0x") {
   104  		intValue, _ := strconv.ParseInt(value, 10, 64)
   105  		value = hexutil.EncodeBig(big.NewInt(intValue))
   106  	}
   107  	tx.Value = value
   108  
   109  	params := make([]TxParams, 1)
   110  	params[0] = tx
   111  
   112  	res, _ := Send(params, "eth_sendTransaction")
   113  	response := parseResponse(res)
   114  
   115  	return response.Result, nil
   116  }
   117  
   118  func SendRawTransaction(from, to, value string, pkFile string) (string, error) {
   119  	if len(accountPool) == 0 {
   120  		parsePkFile(pkFile)
   121  	}
   122  	var v int64
   123  	if strings.HasPrefix(value, "0x") {
   124  		bigValue, _ := hexutil.DecodeBig(value)
   125  		v = bigValue.Int64()
   126  	} else {
   127  		v, _ = strconv.ParseInt(value, 10, 64)
   128  	}
   129  
   130  	acc, ok := accountPool[from]
   131  	if !ok {
   132  		return "", fmt.Errorf("private key not found in private key file,addr:%s", from)
   133  	}
   134  	nonce := getNonce(from)
   135  	nonce++
   136  	newTx := getSignedTransaction(from, to, v, acc.Priv, nonce)
   137  
   138  	hash, err := sendRawTransaction(newTx)
   139  	if err != nil {
   140  		panic(err)
   141  	}
   142  	return hash, nil
   143  }
   144  
   145  func sendRawTransaction(transaction *types.Transaction) (string, error) {
   146  	bytes, _ := rlp.EncodeToBytes(transaction)
   147  	res, err := Send([]string{hexutil.Encode(bytes)}, "eth_sendRawTransaction")
   148  	if err != nil {
   149  		panic(err)
   150  	}
   151  	response := parseResponse(res)
   152  
   153  	return response.Result, nil
   154  }
   155  
   156  func getSignedTransaction(from, to string, value int64, priv *ecdsa.PrivateKey, nonce uint64) *types.Transaction {
   157  	newTx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress(to), big.NewInt(value), 100000, big.NewInt(90000), []byte{}), types.HomesteadSigner{}, priv)
   158  	if err != nil {
   159  		panic(fmt.Errorf("sign error,%s", err.Error()))
   160  	}
   161  	return newTx
   162  }
   163  
   164  func getNonce(addr string) uint64 {
   165  	res, _ := Send([]string{addr, "latest"}, "eth_getTransactionCount")
   166  	response := parseResponse(res)
   167  	nonce, _ := hexutil.DecodeBig(response.Result)
   168  	fmt.Println(addr, nonce)
   169  	return nonce.Uint64()
   170  }
   171  
   172  //func getCoinbase() (error) {
   173  //	res, _ := Send([]string{}, "eth_coinbase")
   174  //	response := parseResponse(res)
   175  //	coinBase = response.Result
   176  //	return nil
   177  //}