github.com/amazechain/amc@v0.1.3/common/transaction/transaction.go (about)

     1  // Copyright 2022 The AmazeChain Authors
     2  // This file is part of the AmazeChain library.
     3  //
     4  // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package transaction
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"github.com/amazechain/amc/utils"
    23  	"github.com/holiman/uint256"
    24  	"google.golang.org/protobuf/proto"
    25  	"math/big"
    26  	"sync/atomic"
    27  	"time"
    28  
    29  	"github.com/amazechain/amc/api/protocol/types_pb"
    30  	"github.com/amazechain/amc/common/types"
    31  )
    32  
    33  var (
    34  	ErrGasFeeCapTooLow = fmt.Errorf("fee cap less than base fee")
    35  	ErrUnmarshalHash   = fmt.Errorf("hash verify falied")
    36  )
    37  
    38  // Transaction types.
    39  const (
    40  	LegacyTxType = iota
    41  	AccessListTxType
    42  	DynamicFeeTxType
    43  )
    44  
    45  type TxData interface {
    46  	txType() byte // returns the type ID
    47  	copy() TxData // creates a deep copy and initializes all fields
    48  
    49  	chainID() *uint256.Int
    50  	accessList() AccessList
    51  	data() []byte
    52  	gas() uint64
    53  	gasPrice() *uint256.Int
    54  	gasTipCap() *uint256.Int
    55  	gasFeeCap() *uint256.Int
    56  	value() *uint256.Int
    57  	nonce() uint64
    58  	to() *types.Address
    59  	from() *types.Address
    60  	sign() []byte
    61  	hash() types.Hash
    62  
    63  	rawSignatureValues() (v, r, s *uint256.Int)
    64  	setSignatureValues(chainID, v, r, s *uint256.Int)
    65  
    66  	//Marshal() ([]byte, error)
    67  	//MarshalTo(data []byte) (n int, err error)
    68  	//Unmarshal(data []byte) error
    69  	//Size() int
    70  }
    71  
    72  // Transactions implements DerivableList for transactions.
    73  type Transactions []*Transaction
    74  
    75  // Len returns the length of s.
    76  func (s Transactions) Len() int { return len(s) }
    77  
    78  // EncodeIndex encodes the i'th transaction to w. Note that this does not check for errors
    79  // because we assume that *Transaction will only ever contain valid txs that were either
    80  // constructed by decoding or via public API in this package.
    81  func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) {
    82  	tx := s[i]
    83  	proto, _ := tx.Marshal()
    84  	w.Write(proto)
    85  }
    86  
    87  type Transaction struct {
    88  	inner TxData    // Consensus contents of a transaction
    89  	time  time.Time // Time first seen locally (spam avoidance)
    90  
    91  	// caches
    92  	hash atomic.Value
    93  	size atomic.Value
    94  	from atomic.Value
    95  }
    96  
    97  // NewTx creates a new transaction.
    98  func NewTx(inner TxData) *Transaction {
    99  	tx := new(Transaction)
   100  	tx.setDecoded(inner.copy(), 0)
   101  	return tx
   102  }
   103  
   104  func txDataFromProtoMessage(message proto.Message) (TxData, error) {
   105  	var (
   106  		pbTx  *types_pb.Transaction
   107  		ok    bool
   108  		inner TxData
   109  	)
   110  
   111  	if pbTx, ok = message.(*types_pb.Transaction); !ok {
   112  		return nil, fmt.Errorf("aa")
   113  	}
   114  
   115  	switch pbTx.Type {
   116  	case LegacyTxType:
   117  		var itx LegacyTx
   118  		if nil != pbTx.To {
   119  			itx.To = utils.ConvertH160ToPAddress(pbTx.To)
   120  			if *itx.To == (types.Address{}) {
   121  				itx.To = nil
   122  			}
   123  		}
   124  		itx.From = utils.ConvertH160ToPAddress(pbTx.From)
   125  		itx.Sign = pbTx.Sign
   126  		itx.Nonce = pbTx.Nonce
   127  		itx.Gas = pbTx.Gas
   128  		itx.GasPrice = utils.ConvertH256ToUint256Int(pbTx.GasPrice)
   129  		itx.Value = utils.ConvertH256ToUint256Int(pbTx.Value)
   130  		if nil != pbTx.V {
   131  			itx.V = utils.ConvertH256ToUint256Int(pbTx.V)
   132  		}
   133  		if nil != pbTx.R {
   134  			itx.R = utils.ConvertH256ToUint256Int(pbTx.R)
   135  		}
   136  		if nil != pbTx.S {
   137  			itx.S = utils.ConvertH256ToUint256Int(pbTx.S)
   138  		}
   139  		itx.Data = pbTx.Data
   140  		inner = &itx
   141  	case AccessListTxType:
   142  		var altt AccessListTx
   143  		altt.ChainID = uint256.NewInt(pbTx.ChainID)
   144  		altt.Nonce = pbTx.Nonce
   145  		altt.Gas = pbTx.Gas
   146  		altt.GasPrice = utils.ConvertH256ToUint256Int(pbTx.GasPrice)
   147  		altt.Value = utils.ConvertH256ToUint256Int(pbTx.Value)
   148  		if nil != pbTx.V {
   149  			altt.V = utils.ConvertH256ToUint256Int(pbTx.V)
   150  		}
   151  		if nil != pbTx.R {
   152  			altt.R = utils.ConvertH256ToUint256Int(pbTx.R)
   153  		}
   154  		if nil != pbTx.S {
   155  			altt.S = utils.ConvertH256ToUint256Int(pbTx.S)
   156  		}
   157  		altt.Data = pbTx.Data
   158  		if nil != pbTx.To {
   159  			altt.To = utils.ConvertH160ToPAddress(pbTx.To)
   160  			if *altt.To == (types.Address{}) {
   161  				altt.To = nil
   162  			}
   163  		}
   164  		//altt.To = utils.ConvertH160ToPAddress(pbTx.To)
   165  		altt.From = utils.ConvertH160ToPAddress(pbTx.From)
   166  		altt.Sign = pbTx.Sign
   167  		inner = &altt
   168  	case DynamicFeeTxType:
   169  		var dftt DynamicFeeTx
   170  		dftt.ChainID = uint256.NewInt(pbTx.ChainID)
   171  		dftt.Nonce = pbTx.Nonce
   172  		dftt.Gas = pbTx.Gas
   173  		dftt.GasFeeCap = utils.ConvertH256ToUint256Int(pbTx.FeePerGas)
   174  		dftt.GasTipCap = utils.ConvertH256ToUint256Int(pbTx.PriorityFeePerGas)
   175  		dftt.Value = utils.ConvertH256ToUint256Int(pbTx.Value)
   176  		if nil != pbTx.V {
   177  			dftt.V = utils.ConvertH256ToUint256Int(pbTx.V)
   178  		}
   179  		if nil != pbTx.R {
   180  			dftt.R = utils.ConvertH256ToUint256Int(pbTx.R)
   181  		}
   182  		if nil != pbTx.S {
   183  			dftt.S = utils.ConvertH256ToUint256Int(pbTx.S)
   184  		}
   185  		dftt.Data = pbTx.Data
   186  		if nil != pbTx.To {
   187  			dftt.To = utils.ConvertH160ToPAddress(pbTx.To)
   188  			if *dftt.To == (types.Address{}) {
   189  				dftt.To = nil
   190  			}
   191  		}
   192  
   193  		//dftt.To = utils.ConvertH160ToPAddress(pbTx.To)
   194  		dftt.From = utils.ConvertH160ToPAddress(pbTx.From)
   195  		dftt.Sign = pbTx.Sign
   196  		inner = &dftt
   197  	}
   198  
   199  	// todo
   200  	protoHash := utils.ConvertH256ToHash(pbTx.Hash)
   201  	innerHash := inner.hash()
   202  	if bytes.Compare(protoHash[:], innerHash[:]) != 0 {
   203  		//return nil, ErrUnmarshalHash
   204  	}
   205  
   206  	return inner, nil
   207  }
   208  
   209  func FromProtoMessage(message proto.Message) (*Transaction, error) {
   210  	inner, err := txDataFromProtoMessage(message)
   211  	if err != nil {
   212  		return nil, err
   213  	}
   214  	return NewTx(inner), nil
   215  }
   216  
   217  func (tx *Transaction) ToProtoMessage() proto.Message {
   218  	var pbTx types_pb.Transaction
   219  	pbTx.Type = uint64(tx.inner.txType())
   220  
   221  	switch t := tx.inner.(type) {
   222  	case *AccessListTx:
   223  		pbTx.ChainID = t.ChainID.Uint64()
   224  		pbTx.Nonce = tx.Nonce()
   225  		pbTx.Gas = tx.Gas()
   226  		pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice())
   227  		pbTx.Value = utils.ConvertUint256IntToH256(tx.Value())
   228  		pbTx.Data = tx.Data()
   229  		pbTx.From = utils.ConvertAddressToH160(*tx.From())
   230  		pbTx.Sign = t.Sign
   231  	case *LegacyTx:
   232  		pbTx.Nonce = tx.Nonce()
   233  		pbTx.Gas = tx.Gas()
   234  		pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice())
   235  		pbTx.Value = utils.ConvertUint256IntToH256(tx.Value())
   236  		pbTx.Data = tx.Data()
   237  		//pbTx.To = utils.ConvertAddressToH160(*tx.To())
   238  		pbTx.From = utils.ConvertAddressToH160(*tx.From())
   239  		pbTx.Sign = t.Sign
   240  	case *DynamicFeeTx:
   241  		pbTx.ChainID = t.ChainID.Uint64()
   242  		pbTx.Nonce = tx.Nonce()
   243  		pbTx.Gas = tx.Gas()
   244  		pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice())
   245  		pbTx.Value = utils.ConvertUint256IntToH256(tx.Value())
   246  		pbTx.Data = tx.Data()
   247  		//pbTx.To = utils.ConvertAddressToH160(*tx.To())
   248  		pbTx.From = utils.ConvertAddressToH160(*tx.From())
   249  		pbTx.Sign = t.Sign
   250  		pbTx.FeePerGas = utils.ConvertUint256IntToH256(t.GasFeeCap)
   251  		pbTx.PriorityFeePerGas = utils.ConvertUint256IntToH256(t.GasTipCap)
   252  	}
   253  	if tx.To() != nil {
   254  		pbTx.To = utils.ConvertAddressToH160(*tx.To())
   255  	}
   256  
   257  	pbTx.Hash = utils.ConvertHashToH256(tx.Hash())
   258  
   259  	v, r, s := tx.RawSignatureValues()
   260  	if nil != v {
   261  		pbTx.V = utils.ConvertUint256IntToH256(v)
   262  	}
   263  	if nil != r {
   264  		pbTx.R = utils.ConvertUint256IntToH256(r)
   265  	}
   266  	if nil != s {
   267  		pbTx.S = utils.ConvertUint256IntToH256(s)
   268  	}
   269  
   270  	return &pbTx
   271  }
   272  
   273  func (tx *Transaction) setDecoded(inner TxData, size int) {
   274  	tx.inner = inner
   275  	tx.time = time.Now()
   276  	//if size > 0 {
   277  	//	tx.size.Store(common.StorageSize(size))
   278  	//}
   279  }
   280  
   281  func (tx *Transaction) RawSignatureValues() (v, r, s *uint256.Int) {
   282  	return tx.inner.rawSignatureValues()
   283  }
   284  
   285  // WithSignature todo
   286  func (tx *Transaction) WithSignatureValues(v, r, s *uint256.Int) (*Transaction, error) {
   287  	//todo
   288  	tx.inner.setSignatureValues(uint256.NewInt(100100100), v, r, s)
   289  	return tx, nil
   290  }
   291  
   292  func (tx Transaction) Marshal() ([]byte, error) {
   293  	var pbTx types_pb.Transaction
   294  	pbTx.Type = uint64(tx.inner.txType())
   295  
   296  	switch t := tx.inner.(type) {
   297  	case *AccessListTx:
   298  		pbTx.ChainID = t.ChainID.Uint64()
   299  		pbTx.Nonce = tx.Nonce()
   300  		pbTx.Gas = tx.Gas()
   301  		pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice())
   302  		pbTx.Value = utils.ConvertUint256IntToH256(tx.Value())
   303  		pbTx.Data = tx.Data()
   304  		pbTx.From = utils.ConvertAddressToH160(*tx.From())
   305  		pbTx.Sign = t.Sign
   306  	case *LegacyTx:
   307  		pbTx.Nonce = tx.Nonce()
   308  		pbTx.Gas = tx.Gas()
   309  		pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice())
   310  		pbTx.Value = utils.ConvertUint256IntToH256(tx.Value())
   311  		pbTx.Data = tx.Data()
   312  		//pbTx.To = utils.ConvertAddressToH160(*tx.To())
   313  		pbTx.From = utils.ConvertAddressToH160(*tx.From())
   314  		pbTx.Sign = t.Sign
   315  	case *DynamicFeeTx:
   316  		pbTx.ChainID = t.ChainID.Uint64()
   317  		pbTx.Nonce = tx.Nonce()
   318  		pbTx.Gas = tx.Gas()
   319  		pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice())
   320  		pbTx.Value = utils.ConvertUint256IntToH256(tx.Value())
   321  		pbTx.Data = tx.Data()
   322  		//pbTx.To = utils.ConvertAddressToH160(*tx.To())
   323  		pbTx.From = utils.ConvertAddressToH160(*tx.From())
   324  		pbTx.Sign = t.Sign
   325  		pbTx.FeePerGas = utils.ConvertUint256IntToH256(t.GasFeeCap)
   326  		pbTx.PriorityFeePerGas = utils.ConvertUint256IntToH256(t.GasTipCap)
   327  	}
   328  	if tx.To() != nil {
   329  		pbTx.To = utils.ConvertAddressToH160(*tx.To())
   330  	}
   331  	v, r, s := tx.RawSignatureValues()
   332  	if nil != v {
   333  		pbTx.V = utils.ConvertUint256IntToH256(v)
   334  	}
   335  	if nil != r {
   336  		pbTx.R = utils.ConvertUint256IntToH256(r)
   337  	}
   338  	if nil != s {
   339  		pbTx.S = utils.ConvertUint256IntToH256(s)
   340  	}
   341  	return proto.Marshal(&pbTx)
   342  }
   343  
   344  func (tx *Transaction) MarshalTo(data []byte) (n int, err error) {
   345  	b, err := tx.Marshal()
   346  	if err != nil {
   347  		return 0, err
   348  	}
   349  
   350  	copy(data, b)
   351  	return len(b), nil
   352  }
   353  
   354  func (tx *Transaction) Unmarshal(data []byte) error {
   355  	var pbTx types_pb.Transaction
   356  	var err error
   357  	var inner TxData
   358  	err = proto.Unmarshal(data, &pbTx)
   359  	if err != nil {
   360  		return err
   361  	}
   362  
   363  	inner, err = txDataFromProtoMessage(&pbTx)
   364  	if err != nil {
   365  		return err
   366  	}
   367  
   368  	tx.setDecoded(inner, 0)
   369  	return err
   370  }
   371  
   372  func (tx *Transaction) Type() uint8 {
   373  	return tx.inner.txType()
   374  }
   375  
   376  func (tx *Transaction) ChainId() *uint256.Int {
   377  	return tx.inner.chainID()
   378  }
   379  
   380  func (tx *Transaction) Data() []byte {
   381  	return tx.inner.data()
   382  }
   383  
   384  func (tx *Transaction) AccessList() AccessList {
   385  	return tx.inner.accessList()
   386  }
   387  
   388  func (tx *Transaction) Gas() uint64 {
   389  	return tx.inner.gas()
   390  }
   391  
   392  func (tx *Transaction) GasPrice() *uint256.Int {
   393  	return tx.inner.gasPrice()
   394  }
   395  
   396  func (tx *Transaction) GasTipCap() *uint256.Int {
   397  	return tx.inner.gasTipCap()
   398  }
   399  
   400  func (tx *Transaction) GasFeeCap() *uint256.Int {
   401  	return tx.inner.gasFeeCap()
   402  }
   403  
   404  func (tx *Transaction) Value() *uint256.Int {
   405  	return tx.inner.value()
   406  }
   407  
   408  func (tx *Transaction) Nonce() uint64 {
   409  	return tx.inner.nonce()
   410  }
   411  
   412  func (tx *Transaction) To() *types.Address {
   413  	return copyAddressPtr(tx.inner.to())
   414  }
   415  
   416  func (tx *Transaction) From() *types.Address {
   417  	return tx.inner.from()
   418  }
   419  
   420  func (tx *Transaction) SetFrom(addr types.Address) {
   421  	switch t := tx.inner.(type) {
   422  	case *AccessListTx:
   423  		t.From = &addr
   424  	case *LegacyTx:
   425  		t.From = &addr
   426  	case *DynamicFeeTx:
   427  		t.From = &addr
   428  	}
   429  }
   430  
   431  func (tx *Transaction) SetNonce(nonce uint64) {
   432  	switch t := tx.inner.(type) {
   433  	case *AccessListTx:
   434  		t.Nonce = nonce
   435  	case *LegacyTx:
   436  		t.Nonce = nonce
   437  	case *DynamicFeeTx:
   438  		t.Nonce = nonce
   439  	}
   440  }
   441  
   442  func (tx *Transaction) Sign() []byte {
   443  	return tx.inner.sign()
   444  }
   445  
   446  func (tx *Transaction) Cost() *uint256.Int {
   447  	price := tx.inner.gasPrice()
   448  	gas := uint256.NewInt(tx.inner.gas())
   449  	total := new(uint256.Int).Mul(price, gas)
   450  	total = total.Add(total, tx.Value())
   451  	return total
   452  }
   453  
   454  func (tx *Transaction) Hash() types.Hash {
   455  	if hash := tx.hash.Load(); hash != nil {
   456  		return hash.(types.Hash)
   457  	}
   458  	h := tx.inner.hash()
   459  	tx.hash.Store(h)
   460  	return h
   461  }
   462  
   463  // GasFeeCapCmp compares the fee cap of two transactions.
   464  func (tx *Transaction) GasFeeCapCmp(other *Transaction) int {
   465  	return tx.inner.gasFeeCap().Cmp(other.inner.gasFeeCap())
   466  }
   467  
   468  // EffectiveGasTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap.
   469  func (tx *Transaction) EffectiveGasTipIntCmp(other *uint256.Int, baseFee *uint256.Int) int {
   470  	if baseFee == nil {
   471  		return tx.GasTipCapIntCmp(other)
   472  	}
   473  	return tx.EffectiveGasTipValue(baseFee).Cmp(other)
   474  }
   475  
   476  // GasTipCapCmp compares the gasTipCap of two transactions.
   477  func (tx *Transaction) GasTipCapCmp(other *Transaction) int {
   478  	return tx.inner.gasTipCap().Cmp(other.inner.gasTipCap())
   479  }
   480  
   481  // GasFeeCapIntCmp compares the fee cap of the transaction against the given fee cap.
   482  func (tx *Transaction) GasFeeCapIntCmp(other *uint256.Int) int {
   483  	return tx.inner.gasFeeCap().Cmp(other)
   484  }
   485  
   486  // GasTipCapIntCmp compares the gasTipCap of the transaction against the given gasTipCap.
   487  func (tx *Transaction) GasTipCapIntCmp(other *uint256.Int) int {
   488  	return tx.inner.gasTipCap().Cmp(other)
   489  }
   490  
   491  // EffectiveGasTipValue is identical to EffectiveGasTip, but does not return an
   492  // error in case the effective gasTipCap is negative
   493  func (tx *Transaction) EffectiveGasTipValue(baseFee *uint256.Int) *uint256.Int {
   494  	effectiveTip, _ := tx.EffectiveGasTip(baseFee)
   495  	return effectiveTip
   496  }
   497  
   498  // EffectiveGasTipCmp compares the effective gasTipCap of two transactions assuming the given base fee.
   499  func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *uint256.Int) int {
   500  	if baseFee == nil {
   501  		return tx.GasTipCapCmp(other)
   502  	}
   503  	return tx.EffectiveGasTipValue(baseFee).Cmp(other.EffectiveGasTipValue(baseFee))
   504  }
   505  
   506  // EffectiveGasTip returns the effective miner gasTipCap for the given base fee.
   507  // Note: if the effective gasTipCap is negative, this method returns both error
   508  // the actual negative value, _and_ ErrGasFeeCapTooLow
   509  func (tx *Transaction) EffectiveGasTip(baseFee *uint256.Int) (*uint256.Int, error) {
   510  	if baseFee == nil {
   511  		return tx.GasTipCap(), nil
   512  	}
   513  	var err error
   514  	gasFeeCap := tx.GasFeeCap()
   515  	if gasFeeCap.Cmp(baseFee) == -1 {
   516  		err = ErrGasFeeCapTooLow
   517  	}
   518  	return uint256Min(tx.GasTipCap(), new(uint256.Int).Sub(gasFeeCap, baseFee)), err
   519  }
   520  
   521  func uint256Min(x, y *uint256.Int) *uint256.Int {
   522  	if x.Cmp(y) == 1 {
   523  		return x
   524  	}
   525  	return y
   526  }
   527  
   528  func isProtectedV(V *big.Int) bool {
   529  	if V.BitLen() <= 8 {
   530  		v := V.Uint64()
   531  		return v != 27 && v != 28 && v != 1 && v != 0
   532  	}
   533  	// anything not 27 or 28 is considered protected
   534  	return true
   535  }
   536  
   537  // Protected says whether the transaction is replay-protected.
   538  func (tx *Transaction) Protected() bool {
   539  	switch tx := tx.inner.(type) {
   540  	case *LegacyTx:
   541  		return tx.V.ToBig() != nil && isProtectedV(tx.V.ToBig())
   542  	default:
   543  		return true
   544  	}
   545  }
   546  
   547  // WithSignature returns a new transaction with the given signature.
   548  // This signature needs to be in the [R || S || V] format where V is 0 or 1.
   549  func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) {
   550  	r, s, v, err := signer.SignatureValues(tx, sig)
   551  	if err != nil {
   552  		return nil, err
   553  	}
   554  	cpy := tx.inner.copy()
   555  	var chainID *uint256.Int
   556  	if signer.ChainID() == nil {
   557  		chainID = nil
   558  	} else {
   559  		chainID, _ = uint256.FromBig(signer.ChainID())
   560  	}
   561  
   562  	v1, _ := uint256.FromBig(v)
   563  	r1, _ := uint256.FromBig(r)
   564  	s1, _ := uint256.FromBig(s)
   565  	cpy.setSignatureValues(chainID, v1, r1, s1)
   566  	return &Transaction{inner: cpy, time: tx.time}, nil
   567  }
   568  
   569  //type Transaction struct {
   570  //	to        types.Address
   571  //	from      types.Address
   572  //	nonce     uint64
   573  //	amount    uint256.Int
   574  //	gasLimit  uint64
   575  //	gasPrice  uint256.Int
   576  //	gasFeeCap uint256.Int
   577  //	payload   []byte
   578  //}
   579  
   580  //func (t *Transaction) ToProtoMessage() proto.Message {
   581  //	pbTx := types_pb.Transaction{
   582  //		From:  types.Address(t.from),
   583  //		To:    types.Address(t.to),
   584  //		Value: t.amount,
   585  //		Data:  t.payload,
   586  //		Nonce: t.nonce,
   587  //		S:     nil,
   588  //		V:     nil,
   589  //		R:     nil,
   590  //	}
   591  //
   592  //	return &pbTx
   593  //}
   594  
   595  func copyAddressPtr(a *types.Address) *types.Address {
   596  	if a == nil {
   597  		return nil
   598  	}
   599  	cpy := *a
   600  	return &cpy
   601  }
   602  
   603  // Message is a fully derived transaction and implements core.Message
   604  type Message struct {
   605  	to         *types.Address
   606  	from       types.Address
   607  	nonce      uint64
   608  	amount     uint256.Int
   609  	gasLimit   uint64
   610  	gasPrice   uint256.Int
   611  	feeCap     uint256.Int
   612  	tip        uint256.Int
   613  	data       []byte
   614  	accessList AccessList
   615  	checkNonce bool
   616  	isFree     bool
   617  }
   618  
   619  func NewMessage(from types.Address, to *types.Address, nonce uint64, amount *uint256.Int, gasLimit uint64, gasPrice *uint256.Int, feeCap, tip *uint256.Int, data []byte, accessList AccessList, checkNonce bool, isFree bool) Message {
   620  	m := Message{
   621  		from:       from,
   622  		to:         to,
   623  		nonce:      nonce,
   624  		amount:     *amount,
   625  		gasLimit:   gasLimit,
   626  		data:       data,
   627  		accessList: accessList,
   628  		checkNonce: checkNonce,
   629  		isFree:     isFree,
   630  	}
   631  	if gasPrice != nil {
   632  		m.gasPrice.Set(gasPrice)
   633  	}
   634  	if tip != nil {
   635  		m.tip.Set(tip)
   636  	}
   637  	if feeCap != nil {
   638  		m.feeCap.Set(feeCap)
   639  	}
   640  	return m
   641  }
   642  
   643  // AsMessage returns the transaction as a core.Message.
   644  func (tx *Transaction) AsMessage(s Signer, baseFee *uint256.Int) (Message, error) {
   645  	msg := Message{
   646  		nonce:    tx.Nonce(),
   647  		gasLimit: tx.Gas(),
   648  		gasPrice: *new(uint256.Int).Set(tx.GasPrice()),
   649  		feeCap:   *new(uint256.Int).Set(tx.GasFeeCap()),
   650  		tip:      *new(uint256.Int).Set(tx.GasTipCap()),
   651  		//gasFeeCap:  new(big.Int).Set(tx.GasFeeCap()),
   652  		//gasTipCap:  new(big.Int).Set(tx.GasTipCap()),
   653  		to:         tx.To(),
   654  		amount:     *tx.Value(),
   655  		data:       tx.Data(),
   656  		accessList: tx.AccessList(),
   657  		checkNonce: false,
   658  		//isFake:     false,
   659  	}
   660  
   661  	// If baseFee provided, set gasPrice to effectiveGasPrice.
   662  	if baseFee != nil {
   663  		msg.gasPrice.Add(&msg.tip, baseFee)
   664  
   665  		if msg.gasPrice.Gt(&msg.feeCap) {
   666  			msg.gasPrice = msg.feeCap
   667  		}
   668  	}
   669  	//var err error
   670  	//msg.from, err = Sender(s, tx)
   671  	//if nil != err {
   672  	//	return msg, err
   673  	//}
   674  	msg.from = *tx.From()
   675  
   676  	return msg, nil
   677  }
   678  func (m Message) From() types.Address    { return m.from }
   679  func (m Message) To() *types.Address     { return m.to }
   680  func (m Message) GasPrice() *uint256.Int { return &m.gasPrice }
   681  func (m Message) FeeCap() *uint256.Int   { return &m.feeCap }
   682  func (m Message) Tip() *uint256.Int      { return &m.tip }
   683  func (m Message) Value() *uint256.Int    { return &m.amount }
   684  func (m Message) Gas() uint64            { return m.gasLimit }
   685  func (m Message) Nonce() uint64          { return m.nonce }
   686  func (m Message) Data() []byte           { return m.data }
   687  func (m Message) AccessList() AccessList { return m.accessList }
   688  func (m Message) CheckNonce() bool       { return m.checkNonce }
   689  func (m *Message) SetCheckNonce(checkNonce bool) {
   690  	m.checkNonce = checkNonce
   691  }
   692  func (m Message) IsFree() bool { return m.isFree }
   693  func (m *Message) SetIsFree(isFree bool) {
   694  	m.isFree = isFree
   695  }