github.com/annchain/OG@v0.0.9/client/cmd/tx.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package cmd
    15  
    16  import (
    17  	"encoding/json"
    18  	"fmt"
    19  	"github.com/annchain/OG/arefactor/common/httplib"
    20  	"github.com/annchain/OG/common"
    21  	"github.com/annchain/OG/common/crypto"
    22  	"github.com/annchain/OG/common/hexutil"
    23  	"github.com/annchain/OG/common/math"
    24  	"github.com/annchain/OG/og/types"
    25  	"github.com/spf13/cobra"
    26  )
    27  
    28  var (
    29  	txCmd = &cobra.Command{
    30  		Use:   "tx ",
    31  		Short: "send new transaction",
    32  		Run:   newTx,
    33  	}
    34  
    35  	payload string
    36  	to      string
    37  	nonce   uint64
    38  	value   int64
    39  )
    40  
    41  func txInit() {
    42  	txCmd.PersistentFlags().StringVarP(&payload, "payload", "p", "", "payload value")
    43  	txCmd.PersistentFlags().StringVarP(&to, "to", "t", "", "to 0x***")
    44  	txCmd.PersistentFlags().StringVarP(&priv_key, "priv_key", "k", "", "priv_key ***")
    45  	txCmd.PersistentFlags().Int64VarP(&value, "value", "v", 0, "value 1")
    46  	txCmd.PersistentFlags().Uint64VarP(&nonce, "nonce", "n", 0, "nonce 1")
    47  }
    48  
    49  //NewTxrequest for RPC request
    50  type NewTxRequest struct {
    51  	Nonce     string `json:"nonce"`
    52  	From      string `json:"from"`
    53  	To        string `json:"to"`
    54  	Data      string `json:"data"`
    55  	Value     string `json:"value"`
    56  	Signature string `json:"signature"`
    57  	Pubkey    string `json:"pubkey"`
    58  	//CryptoType string `json:"crypto_type"`
    59  }
    60  
    61  func newTx(cmd *cobra.Command, args []string) {
    62  	if to == "" || value < 1 || priv_key == "" {
    63  		cmd.HelpFunc()
    64  	}
    65  	toAddr := common.HexToAddress(to)
    66  	key, err := crypto.PrivateKeyFromString(priv_key)
    67  	if err != nil {
    68  		fmt.Println(err)
    69  		return
    70  	}
    71  	//todo smart contracts
    72  	//data := common.Hex2Bytes(payload)
    73  	// do sign work
    74  	signer := crypto.NewSigner(key.Type)
    75  	pub := signer.PubKey(key)
    76  	from := signer.Address(pub)
    77  	if nonce <= 0 {
    78  		nonce = getNonce(from)
    79  	}
    80  	tx := types.Tx{
    81  		Value: math.NewBigInt(value),
    82  		To:    toAddr,
    83  		From:  &from,
    84  		Data:  common.FromHex(payload),
    85  		TxBase: types.TxBase{
    86  			AccountNonce: nonce,
    87  			Type:         types.TxBaseTypeTx,
    88  		},
    89  	}
    90  	signature := signer.Sign(key, tx.SignatureTargets())
    91  	pubKey := signer.PubKey(key)
    92  	txReq := &NewTxRequest{
    93  		Nonce:     fmt.Sprintf("%d", tx.AccountNonce),
    94  		From:      tx.From.Hex(),
    95  		To:        to,
    96  		Data:      payload,
    97  		Value:     tx.Value.String(),
    98  		Signature: hexutil.Encode(signature.SignatureBytes),
    99  		Pubkey:    pubKey.String(),
   100  	}
   101  	req := httplib.Post(Host + "/new_transaction")
   102  	_, err = req.JSONBody(&txReq)
   103  	if err != nil {
   104  		panic(fmt.Errorf("encode tx errror %v", err))
   105  	}
   106  
   107  	d, _ := json.MarshalIndent(&txReq, "", "\t")
   108  	fmt.Println(string(d))
   109  
   110  	str, err := req.String()
   111  	if err != nil {
   112  		fmt.Println(err)
   113  		return
   114  	}
   115  	fmt.Println(str)
   116  }
   117  
   118  func getNonce(addr common.Address) (nonce uint64) {
   119  	uri := fmt.Sprintf("query_nonce?address=%s", addr.Hex())
   120  	req := httplib.Get(Host + "/" + uri)
   121  	var nonceResp struct {
   122  		Nonce uint64 `json:"nonce"`
   123  	}
   124  	_, err := req.JSONBody(&nonceResp)
   125  	if err != nil {
   126  		fmt.Println("encode nonce errror ", err)
   127  	}
   128  	return nonceResp.Nonce
   129  }