github.com/AlohaMobile/go-ethereum@v1.9.7/core/types/transaction.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package types
    18  
    19  import (
    20  	"container/heap"
    21  	"errors"
    22  	"io"
    23  	"math/big"
    24  	"sync/atomic"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/common/hexutil"
    28  	"github.com/ethereum/go-ethereum/crypto"
    29  	"github.com/ethereum/go-ethereum/rlp"
    30  )
    31  
    32  //go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
    33  
    34  var (
    35  	ErrInvalidSig = errors.New("invalid transaction v, r, s values")
    36  )
    37  
    38  type Transaction struct {
    39  	data txdata
    40  	// caches
    41  	hash atomic.Value
    42  	size atomic.Value
    43  	from atomic.Value
    44  }
    45  
    46  type txdata struct {
    47  	AccountNonce uint64          `json:"nonce"    gencodec:"required"`
    48  	Price        *big.Int        `json:"gasPrice" gencodec:"required"`
    49  	GasLimit     uint64          `json:"gas"      gencodec:"required"`
    50  	Recipient    *common.Address `json:"to"       rlp:"nil"` // nil means contract creation
    51  	Amount       *big.Int        `json:"value"    gencodec:"required"`
    52  	Payload      []byte          `json:"input"    gencodec:"required"`
    53  
    54  	// Signature values
    55  	V *big.Int `json:"v" gencodec:"required"`
    56  	R *big.Int `json:"r" gencodec:"required"`
    57  	S *big.Int `json:"s" gencodec:"required"`
    58  
    59  	// This is only used when marshaling to JSON.
    60  	Hash *common.Hash `json:"hash" rlp:"-"`
    61  }
    62  
    63  type txdataMarshaling struct {
    64  	AccountNonce hexutil.Uint64
    65  	Price        *hexutil.Big
    66  	GasLimit     hexutil.Uint64
    67  	Amount       *hexutil.Big
    68  	Payload      hexutil.Bytes
    69  	V            *hexutil.Big
    70  	R            *hexutil.Big
    71  	S            *hexutil.Big
    72  }
    73  
    74  func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
    75  	return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data)
    76  }
    77  
    78  func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
    79  	return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data)
    80  }
    81  
    82  func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
    83  	if len(data) > 0 {
    84  		data = common.CopyBytes(data)
    85  	}
    86  	d := txdata{
    87  		AccountNonce: nonce,
    88  		Recipient:    to,
    89  		Payload:      data,
    90  		Amount:       new(big.Int),
    91  		GasLimit:     gasLimit,
    92  		Price:        new(big.Int),
    93  		V:            new(big.Int),
    94  		R:            new(big.Int),
    95  		S:            new(big.Int),
    96  	}
    97  	if amount != nil {
    98  		d.Amount.Set(amount)
    99  	}
   100  	if gasPrice != nil {
   101  		d.Price.Set(gasPrice)
   102  	}
   103  
   104  	return &Transaction{data: d}
   105  }
   106  
   107  // ChainId returns which chain id this transaction was signed for (if at all)
   108  func (tx *Transaction) ChainId() *big.Int {
   109  	return deriveChainId(tx.data.V)
   110  }
   111  
   112  // Protected returns whether the transaction is protected from replay protection.
   113  func (tx *Transaction) Protected() bool {
   114  	return isProtectedV(tx.data.V)
   115  }
   116  
   117  func isProtectedV(V *big.Int) bool {
   118  	if V.BitLen() <= 8 {
   119  		v := V.Uint64()
   120  		return v != 27 && v != 28
   121  	}
   122  	// anything not 27 or 28 is considered protected
   123  	return true
   124  }
   125  
   126  // EncodeRLP implements rlp.Encoder
   127  func (tx *Transaction) EncodeRLP(w io.Writer) error {
   128  	return rlp.Encode(w, &tx.data)
   129  }
   130  
   131  // DecodeRLP implements rlp.Decoder
   132  func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
   133  	_, size, _ := s.Kind()
   134  	err := s.Decode(&tx.data)
   135  	if err == nil {
   136  		tx.size.Store(common.StorageSize(rlp.ListSize(size)))
   137  	}
   138  
   139  	return err
   140  }
   141  
   142  // MarshalJSON encodes the web3 RPC transaction format.
   143  func (tx *Transaction) MarshalJSON() ([]byte, error) {
   144  	hash := tx.Hash()
   145  	data := tx.data
   146  	data.Hash = &hash
   147  	return data.MarshalJSON()
   148  }
   149  
   150  // UnmarshalJSON decodes the web3 RPC transaction format.
   151  func (tx *Transaction) UnmarshalJSON(input []byte) error {
   152  	var dec txdata
   153  	if err := dec.UnmarshalJSON(input); err != nil {
   154  		return err
   155  	}
   156  
   157  	withSignature := dec.V.Sign() != 0 || dec.R.Sign() != 0 || dec.S.Sign() != 0
   158  	if withSignature {
   159  		var V byte
   160  		if isProtectedV(dec.V) {
   161  			chainID := deriveChainId(dec.V).Uint64()
   162  			V = byte(dec.V.Uint64() - 35 - 2*chainID)
   163  		} else {
   164  			V = byte(dec.V.Uint64() - 27)
   165  		}
   166  		if !crypto.ValidateSignatureValues(V, dec.R, dec.S, false) {
   167  			return ErrInvalidSig
   168  		}
   169  	}
   170  
   171  	*tx = Transaction{data: dec}
   172  	return nil
   173  }
   174  
   175  func (tx *Transaction) Data() []byte       { return common.CopyBytes(tx.data.Payload) }
   176  func (tx *Transaction) Gas() uint64        { return tx.data.GasLimit }
   177  func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) }
   178  func (tx *Transaction) Value() *big.Int    { return new(big.Int).Set(tx.data.Amount) }
   179  func (tx *Transaction) Nonce() uint64      { return tx.data.AccountNonce }
   180  func (tx *Transaction) CheckNonce() bool   { return true }
   181  
   182  // To returns the recipient address of the transaction.
   183  // It returns nil if the transaction is a contract creation.
   184  func (tx *Transaction) To() *common.Address {
   185  	if tx.data.Recipient == nil {
   186  		return nil
   187  	}
   188  	to := *tx.data.Recipient
   189  	return &to
   190  }
   191  
   192  // Hash hashes the RLP encoding of tx.
   193  // It uniquely identifies the transaction.
   194  func (tx *Transaction) Hash() common.Hash {
   195  	if hash := tx.hash.Load(); hash != nil {
   196  		return hash.(common.Hash)
   197  	}
   198  	v := rlpHash(tx)
   199  	tx.hash.Store(v)
   200  	return v
   201  }
   202  
   203  // Size returns the true RLP encoded storage size of the transaction, either by
   204  // encoding and returning it, or returning a previsouly cached value.
   205  func (tx *Transaction) Size() common.StorageSize {
   206  	if size := tx.size.Load(); size != nil {
   207  		return size.(common.StorageSize)
   208  	}
   209  	c := writeCounter(0)
   210  	rlp.Encode(&c, &tx.data)
   211  	tx.size.Store(common.StorageSize(c))
   212  	return common.StorageSize(c)
   213  }
   214  
   215  // AsMessage returns the transaction as a core.Message.
   216  //
   217  // AsMessage requires a signer to derive the sender.
   218  //
   219  // XXX Rename message to something less arbitrary?
   220  func (tx *Transaction) AsMessage(s Signer) (Message, error) {
   221  	msg := Message{
   222  		nonce:      tx.data.AccountNonce,
   223  		gasLimit:   tx.data.GasLimit,
   224  		gasPrice:   new(big.Int).Set(tx.data.Price),
   225  		to:         tx.data.Recipient,
   226  		amount:     tx.data.Amount,
   227  		data:       tx.data.Payload,
   228  		checkNonce: true,
   229  	}
   230  
   231  	var err error
   232  	msg.from, err = Sender(s, tx)
   233  	return msg, err
   234  }
   235  
   236  // WithSignature returns a new transaction with the given signature.
   237  // This signature needs to be in the [R || S || V] format where V is 0 or 1.
   238  func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) {
   239  	r, s, v, err := signer.SignatureValues(tx, sig)
   240  	if err != nil {
   241  		return nil, err
   242  	}
   243  	cpy := &Transaction{data: tx.data}
   244  	cpy.data.R, cpy.data.S, cpy.data.V = r, s, v
   245  	return cpy, nil
   246  }
   247  
   248  // Cost returns amount + gasprice * gaslimit.
   249  func (tx *Transaction) Cost() *big.Int {
   250  	total := new(big.Int).Mul(tx.data.Price, new(big.Int).SetUint64(tx.data.GasLimit))
   251  	total.Add(total, tx.data.Amount)
   252  	return total
   253  }
   254  
   255  // RawSignatureValues returns the V, R, S signature values of the transaction.
   256  // The return values should not be modified by the caller.
   257  func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) {
   258  	return tx.data.V, tx.data.R, tx.data.S
   259  }
   260  
   261  // Transactions is a Transaction slice type for basic sorting.
   262  type Transactions []*Transaction
   263  
   264  // Len returns the length of s.
   265  func (s Transactions) Len() int { return len(s) }
   266  
   267  // Swap swaps the i'th and the j'th element in s.
   268  func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
   269  
   270  // GetRlp implements Rlpable and returns the i'th element of s in rlp.
   271  func (s Transactions) GetRlp(i int) []byte {
   272  	enc, _ := rlp.EncodeToBytes(s[i])
   273  	return enc
   274  }
   275  
   276  // TxDifference returns a new set which is the difference between a and b.
   277  func TxDifference(a, b Transactions) Transactions {
   278  	keep := make(Transactions, 0, len(a))
   279  
   280  	remove := make(map[common.Hash]struct{})
   281  	for _, tx := range b {
   282  		remove[tx.Hash()] = struct{}{}
   283  	}
   284  
   285  	for _, tx := range a {
   286  		if _, ok := remove[tx.Hash()]; !ok {
   287  			keep = append(keep, tx)
   288  		}
   289  	}
   290  
   291  	return keep
   292  }
   293  
   294  // TxByNonce implements the sort interface to allow sorting a list of transactions
   295  // by their nonces. This is usually only useful for sorting transactions from a
   296  // single account, otherwise a nonce comparison doesn't make much sense.
   297  type TxByNonce Transactions
   298  
   299  func (s TxByNonce) Len() int           { return len(s) }
   300  func (s TxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce }
   301  func (s TxByNonce) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   302  
   303  // TxByPrice implements both the sort and the heap interface, making it useful
   304  // for all at once sorting as well as individually adding and removing elements.
   305  type TxByPrice Transactions
   306  
   307  func (s TxByPrice) Len() int           { return len(s) }
   308  func (s TxByPrice) Less(i, j int) bool { return s[i].data.Price.Cmp(s[j].data.Price) > 0 }
   309  func (s TxByPrice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   310  
   311  func (s *TxByPrice) Push(x interface{}) {
   312  	*s = append(*s, x.(*Transaction))
   313  }
   314  
   315  func (s *TxByPrice) Pop() interface{} {
   316  	old := *s
   317  	n := len(old)
   318  	x := old[n-1]
   319  	*s = old[0 : n-1]
   320  	return x
   321  }
   322  
   323  // TransactionsByPriceAndNonce represents a set of transactions that can return
   324  // transactions in a profit-maximizing sorted order, while supporting removing
   325  // entire batches of transactions for non-executable accounts.
   326  type TransactionsByPriceAndNonce struct {
   327  	txs    map[common.Address]Transactions // Per account nonce-sorted list of transactions
   328  	heads  TxByPrice                       // Next transaction for each unique account (price heap)
   329  	signer Signer                          // Signer for the set of transactions
   330  }
   331  
   332  // NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
   333  // price sorted transactions in a nonce-honouring way.
   334  //
   335  // Note, the input map is reowned so the caller should not interact any more with
   336  // if after providing it to the constructor.
   337  func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions) *TransactionsByPriceAndNonce {
   338  	// Initialize a price based heap with the head transactions
   339  	heads := make(TxByPrice, 0, len(txs))
   340  	for from, accTxs := range txs {
   341  		heads = append(heads, accTxs[0])
   342  		// Ensure the sender address is from the signer
   343  		acc, _ := Sender(signer, accTxs[0])
   344  		txs[acc] = accTxs[1:]
   345  		if from != acc {
   346  			delete(txs, from)
   347  		}
   348  	}
   349  	heap.Init(&heads)
   350  
   351  	// Assemble and return the transaction set
   352  	return &TransactionsByPriceAndNonce{
   353  		txs:    txs,
   354  		heads:  heads,
   355  		signer: signer,
   356  	}
   357  }
   358  
   359  // Peek returns the next transaction by price.
   360  func (t *TransactionsByPriceAndNonce) Peek() *Transaction {
   361  	if len(t.heads) == 0 {
   362  		return nil
   363  	}
   364  	return t.heads[0]
   365  }
   366  
   367  // Shift replaces the current best head with the next one from the same account.
   368  func (t *TransactionsByPriceAndNonce) Shift() {
   369  	acc, _ := Sender(t.signer, t.heads[0])
   370  	if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
   371  		t.heads[0], t.txs[acc] = txs[0], txs[1:]
   372  		heap.Fix(&t.heads, 0)
   373  	} else {
   374  		heap.Pop(&t.heads)
   375  	}
   376  }
   377  
   378  // Pop removes the best transaction, *not* replacing it with the next one from
   379  // the same account. This should be used when a transaction cannot be executed
   380  // and hence all subsequent ones should be discarded from the same account.
   381  func (t *TransactionsByPriceAndNonce) Pop() {
   382  	heap.Pop(&t.heads)
   383  }
   384  
   385  // Message is a fully derived transaction and implements core.Message
   386  //
   387  // NOTE: In a future PR this will be removed.
   388  type Message struct {
   389  	to         *common.Address
   390  	from       common.Address
   391  	nonce      uint64
   392  	amount     *big.Int
   393  	gasLimit   uint64
   394  	gasPrice   *big.Int
   395  	data       []byte
   396  	checkNonce bool
   397  }
   398  
   399  func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message {
   400  	return Message{
   401  		from:       from,
   402  		to:         to,
   403  		nonce:      nonce,
   404  		amount:     amount,
   405  		gasLimit:   gasLimit,
   406  		gasPrice:   gasPrice,
   407  		data:       data,
   408  		checkNonce: checkNonce,
   409  	}
   410  }
   411  
   412  func (m Message) From() common.Address { return m.from }
   413  func (m Message) To() *common.Address  { return m.to }
   414  func (m Message) GasPrice() *big.Int   { return m.gasPrice }
   415  func (m Message) Value() *big.Int      { return m.amount }
   416  func (m Message) Gas() uint64          { return m.gasLimit }
   417  func (m Message) Nonce() uint64        { return m.nonce }
   418  func (m Message) Data() []byte         { return m.data }
   419  func (m Message) CheckNonce() bool     { return m.checkNonce }