github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/tests/transaction_test_util.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:45</date>
    10  //</624450122595438592>
    11  
    12  
    13  package tests
    14  
    15  import (
    16  	"bytes"
    17  	"errors"
    18  	"fmt"
    19  	"math/big"
    20  
    21  	"github.com/ethereum/go-ethereum/common"
    22  	"github.com/ethereum/go-ethereum/common/hexutil"
    23  	"github.com/ethereum/go-ethereum/common/math"
    24  	"github.com/ethereum/go-ethereum/core/types"
    25  	"github.com/ethereum/go-ethereum/params"
    26  	"github.com/ethereum/go-ethereum/rlp"
    27  )
    28  
    29  //TransactionTest检查事务的rlp解码和发送方派生。
    30  type TransactionTest struct {
    31  	json ttJSON
    32  }
    33  
    34  type ttJSON struct {
    35  	BlockNumber math.HexOrDecimal64 `json:"blockNumber"`
    36  	RLP         hexutil.Bytes       `json:"rlp"`
    37  	Sender      hexutil.Bytes       `json:"sender"`
    38  	Transaction *ttTransaction      `json:"transaction"`
    39  }
    40  
    41  //go:生成gencodec-type tttransaction-field override tttransactionmarshaling-out gen_tttransaction.go
    42  
    43  type ttTransaction struct {
    44  	Data     []byte         `gencodec:"required"`
    45  	GasLimit uint64         `gencodec:"required"`
    46  	GasPrice *big.Int       `gencodec:"required"`
    47  	Nonce    uint64         `gencodec:"required"`
    48  	Value    *big.Int       `gencodec:"required"`
    49  	R        *big.Int       `gencodec:"required"`
    50  	S        *big.Int       `gencodec:"required"`
    51  	V        *big.Int       `gencodec:"required"`
    52  	To       common.Address `gencodec:"required"`
    53  }
    54  
    55  type ttTransactionMarshaling struct {
    56  	Data     hexutil.Bytes
    57  	GasLimit math.HexOrDecimal64
    58  	GasPrice *math.HexOrDecimal256
    59  	Nonce    math.HexOrDecimal64
    60  	Value    *math.HexOrDecimal256
    61  	R        *math.HexOrDecimal256
    62  	S        *math.HexOrDecimal256
    63  	V        *math.HexOrDecimal256
    64  }
    65  
    66  func (tt *TransactionTest) Run(config *params.ChainConfig) error {
    67  	tx := new(types.Transaction)
    68  	if err := rlp.DecodeBytes(tt.json.RLP, tx); err != nil {
    69  		if tt.json.Transaction == nil {
    70  			return nil
    71  		}
    72  		return fmt.Errorf("RLP decoding failed: %v", err)
    73  	}
    74  //检查发送方派生。
    75  	signer := types.MakeSigner(config, new(big.Int).SetUint64(uint64(tt.json.BlockNumber)))
    76  	sender, err := types.Sender(signer, tx)
    77  	if err != nil {
    78  		return err
    79  	}
    80  	if sender != common.BytesToAddress(tt.json.Sender) {
    81  		return fmt.Errorf("Sender mismatch: got %x, want %x", sender, tt.json.Sender)
    82  	}
    83  //检查解码字段。
    84  	err = tt.json.Transaction.verify(signer, tx)
    85  	if tt.json.Sender == nil && err == nil {
    86  		return errors.New("field validations succeeded but should fail")
    87  	}
    88  	if tt.json.Sender != nil && err != nil {
    89  		return fmt.Errorf("field validations failed after RLP decoding: %s", err)
    90  	}
    91  	return nil
    92  }
    93  
    94  func (tt *ttTransaction) verify(signer types.Signer, tx *types.Transaction) error {
    95  	if !bytes.Equal(tx.Data(), tt.Data) {
    96  		return fmt.Errorf("Tx input data mismatch: got %x want %x", tx.Data(), tt.Data)
    97  	}
    98  	if tx.Gas() != tt.GasLimit {
    99  		return fmt.Errorf("GasLimit mismatch: got %d, want %d", tx.Gas(), tt.GasLimit)
   100  	}
   101  	if tx.GasPrice().Cmp(tt.GasPrice) != 0 {
   102  		return fmt.Errorf("GasPrice mismatch: got %v, want %v", tx.GasPrice(), tt.GasPrice)
   103  	}
   104  	if tx.Nonce() != tt.Nonce {
   105  		return fmt.Errorf("Nonce mismatch: got %v, want %v", tx.Nonce(), tt.Nonce)
   106  	}
   107  	v, r, s := tx.RawSignatureValues()
   108  	if r.Cmp(tt.R) != 0 {
   109  		return fmt.Errorf("R mismatch: got %v, want %v", r, tt.R)
   110  	}
   111  	if s.Cmp(tt.S) != 0 {
   112  		return fmt.Errorf("S mismatch: got %v, want %v", s, tt.S)
   113  	}
   114  	if v.Cmp(tt.V) != 0 {
   115  		return fmt.Errorf("V mismatch: got %v, want %v", v, tt.V)
   116  	}
   117  	if tx.To() == nil {
   118  		if tt.To != (common.Address{}) {
   119  			return fmt.Errorf("To mismatch when recipient is nil (contract creation): %x", tt.To)
   120  		}
   121  	} else if *tx.To() != tt.To {
   122  		return fmt.Errorf("To mismatch: got %x, want %x", *tx.To(), tt.To)
   123  	}
   124  	if tx.Value().Cmp(tt.Value) != 0 {
   125  		return fmt.Errorf("Value mismatch: got %x, want %x", tx.Value(), tt.Value)
   126  	}
   127  	return nil
   128  }
   129