github.com/turingchain2020/turingchain@v1.1.21/cmd/write/write.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 main
     6  
     7  import (
     8  	"encoding/hex"
     9  	"flag"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"math/rand"
    13  	"os"
    14  	"strconv"
    15  	"strings"
    16  	"time"
    17  
    18  	"github.com/turingchain2020/turingchain/common"
    19  	"github.com/turingchain2020/turingchain/common/address"
    20  	"github.com/turingchain2020/turingchain/common/log"
    21  	"github.com/turingchain2020/turingchain/rpc/jsonclient"
    22  	rpctypes "github.com/turingchain2020/turingchain/rpc/types"
    23  	coinstypes "github.com/turingchain2020/turingchain/system/dapp/coins/types"
    24  	"github.com/turingchain2020/turingchain/types"
    25  	"github.com/BurntSushi/toml"
    26  )
    27  
    28  var (
    29  	configPath    = flag.String("f", "write.toml", "configfile")
    30  	receiveAddr   = "1MHkgR4uUg1ksssR5NFzU6zkzyCqxqjg2Z"
    31  	rpcAddr       = "http://localhost:9671"
    32  	currentHeight int64
    33  	currentIndex  int64
    34  	heightFile    = "height.txt"
    35  )
    36  
    37  //Config 配置
    38  type Config struct {
    39  	UserWriteConf *UserWriteConf
    40  }
    41  
    42  //UserWriteConf 用户配置
    43  type UserWriteConf struct {
    44  	ReceiveAddr   string
    45  	CurrentHeight int64
    46  	CurrentIndex  int64
    47  	HeightFile    string
    48  }
    49  
    50  func initWrite() *Config {
    51  	var cfg Config
    52  	if _, err := toml.DecodeFile(*configPath, &cfg); err != nil {
    53  		fmt.Println(err)
    54  		os.Exit(0)
    55  	}
    56  	return &cfg
    57  }
    58  
    59  func main() {
    60  	turingchainCfg := types.NewTuringchainConfig(types.GetDefaultCfgstring())
    61  	cfg := initWrite()
    62  	receiveAddr = cfg.UserWriteConf.ReceiveAddr
    63  	currentHeight = cfg.UserWriteConf.CurrentHeight
    64  	currentIndex = cfg.UserWriteConf.CurrentIndex
    65  	heightFile = cfg.UserWriteConf.HeightFile
    66  	log.SetLogLevel("error")
    67  	err := ioHeightAndIndex()
    68  	if err != nil {
    69  		fmt.Println("file err")
    70  		return
    71  	}
    72  	fmt.Println("starting scaning.............")
    73  	scanWrite(turingchainCfg)
    74  }
    75  
    76  func ioHeightAndIndex() error {
    77  	if _, err := os.Stat(heightFile); os.IsNotExist(err) {
    78  		f, innerErr := os.Create(heightFile)
    79  		if innerErr != nil {
    80  			return innerErr
    81  		}
    82  		height := strconv.FormatInt(currentHeight, 10)
    83  		index := strconv.FormatInt(currentIndex, 10)
    84  		f.WriteString(height + " " + index)
    85  		f.Close()
    86  	}
    87  	f, err := os.OpenFile(heightFile, os.O_RDWR, 0666)
    88  	if err != nil {
    89  		return err
    90  	}
    91  	defer f.Close()
    92  	fileContent, err := ioutil.ReadFile(heightFile)
    93  	if err != nil {
    94  		fmt.Print(err)
    95  		return err
    96  	}
    97  	str := string(fileContent)
    98  	heights := strings.Split(str, " ")
    99  	if len(heights) == 2 {
   100  		currentHeight, _ = strconv.ParseInt(heights[0], 10, 64)
   101  		currentIndex, _ = strconv.ParseInt(heights[1], 10, 64)
   102  	} else {
   103  		height := strconv.FormatInt(currentHeight, 10)
   104  		index := strconv.FormatInt(currentIndex, 10)
   105  		f.WriteString(height + " " + index)
   106  	}
   107  	return nil
   108  }
   109  
   110  func scanWrite(cfg *types.TuringchainConfig) {
   111  	for {
   112  		time.Sleep(time.Second * 5)
   113  		rpc, err := jsonclient.NewJSONClient(rpcAddr)
   114  		if err != nil {
   115  			fmt.Fprintln(os.Stderr, err)
   116  			return
   117  		}
   118  		paramsReqAddr := types.ReqAddr{
   119  			Addr:      receiveAddr,
   120  			Flag:      2,
   121  			Count:     0,
   122  			Direction: 1,
   123  			Height:    currentHeight,
   124  		}
   125  		if currentIndex != 0 {
   126  			paramsReqAddr.Index = currentIndex
   127  		}
   128  
   129  		var replyTxInfos rpctypes.ReplyTxInfos
   130  		err = rpc.Call("Turingchain.GetTxByAddr", paramsReqAddr, &replyTxInfos)
   131  		if err != nil {
   132  			fmt.Fprintln(os.Stderr, err)
   133  			continue
   134  		}
   135  		last := &rpctypes.ReplyTxInfo{
   136  			Height: currentHeight,
   137  			Index:  currentIndex,
   138  		}
   139  		var txHashes []string
   140  		for _, tx := range replyTxInfos.TxInfos {
   141  			txHashes = append(txHashes, tx.Hash)
   142  			last = tx
   143  		}
   144  		currentHeight = last.Height
   145  		currentIndex = last.Index
   146  		for _, hash := range txHashes {
   147  			paramsQuery := rpctypes.QueryParm{Hash: hash}
   148  			var transactionDetail rpctypes.TransactionDetail
   149  			err = rpc.Call("Turingchain.QueryTransaction", paramsQuery, &transactionDetail)
   150  			if err != nil {
   151  				fmt.Fprintln(os.Stderr, err)
   152  				continue
   153  			}
   154  			if len(transactionDetail.Tx.Payload) == 0 {
   155  				fmt.Fprintln(os.Stderr, "not a coin action")
   156  				continue
   157  			}
   158  			action := &coinstypes.CoinsAction{}
   159  			if err = types.Decode(transactionDetail.Tx.Payload, action); err != nil {
   160  				fmt.Fprintln(os.Stderr, err.Error())
   161  				continue
   162  			}
   163  			if action.Ty != coinstypes.CoinsActionTransfer {
   164  				fmt.Fprintln(os.Stderr, "not a transfer action")
   165  				continue
   166  			}
   167  			var noteTx types.Transaction
   168  			txBytes, err := common.FromHex(string(action.GetTransfer().Note))
   169  			if err != nil {
   170  				fmt.Fprintln(os.Stderr, "not a user data tx")
   171  				continue
   172  			}
   173  			err = types.Decode(txBytes, &noteTx)
   174  			if err != nil {
   175  				fmt.Fprintln(os.Stderr, err)
   176  				continue
   177  			}
   178  			amount := transactionDetail.Amount
   179  			if amount < types.Coin {
   180  				fmt.Fprintln(os.Stderr, "not enough fee")
   181  				continue
   182  			}
   183  			if !strings.HasPrefix(string(noteTx.Execer), "user.") {
   184  				fmt.Fprintln(os.Stderr, "not a user defined executor")
   185  				continue
   186  			}
   187  			userTx := &types.Transaction{
   188  				Execer:  noteTx.Execer,
   189  				Payload: noteTx.Payload,
   190  			}
   191  			userTx.To = address.ExecAddress(string(noteTx.Execer))
   192  			userTx.Fee, err = userTx.GetRealFee(cfg.GetMinTxFeeRate())
   193  			if err != nil {
   194  				fmt.Fprintln(os.Stderr, err)
   195  				continue
   196  			}
   197  			userTx.Nonce = rand.New(rand.NewSource(time.Now().UnixNano())).Int63()
   198  			userTx.ChainID = cfg.GetChainID()
   199  
   200  			txHex := types.Encode(userTx)
   201  			paramsReqSignRawTx := types.ReqSignRawTx{
   202  				Addr:   receiveAddr,
   203  				TxHex:  hex.EncodeToString(txHex),
   204  				Expire: "0",
   205  			}
   206  			var signed string
   207  			rpc.Call("Turingchain.SignRawTx", paramsReqSignRawTx, &signed)
   208  			paramsRaw := rpctypes.RawParm{
   209  				Data: signed,
   210  			}
   211  			var sent string
   212  			rpc.Call("Turingchain.SendTransaction", paramsRaw, &sent)
   213  			f, err := os.OpenFile(heightFile, os.O_RDWR, 0666)
   214  			if err != nil {
   215  				fmt.Fprintln(os.Stderr, err)
   216  				continue
   217  			}
   218  			height := strconv.FormatInt(currentHeight, 10)
   219  			index := strconv.FormatInt(currentIndex, 10)
   220  			f.WriteString(height + " " + index)
   221  			f.Close()
   222  			fmt.Println(sent)
   223  		}
   224  	}
   225  }