github.com/ChainSafe/chainbridge-core@v1.4.2/chains/evm/calls/evmtransaction/evm-tx.go (about)

     1  package evmtransaction
     2  
     3  import (
     4  	"context"
     5  	"math/big"
     6  
     7  	"github.com/ChainSafe/chainbridge-core/chains/evm/calls/evmclient"
     8  
     9  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethereum/go-ethereum/core/types"
    12  )
    13  
    14  type TX struct {
    15  	tx *types.Transaction
    16  }
    17  
    18  // RawWithSignature mostly copies WithSignature interface of type.Transaction from go-ethereum,
    19  // but return raw byte representation of transaction to be compatible and interchangeable between different go-ethereum forks
    20  // WithSignature returns a new transaction with the given signature.
    21  // This signature needs to be in the [R || S || V] format where V is 0 or 1.
    22  func (a *TX) RawWithSignature(signer evmclient.Signer, domainID *big.Int) ([]byte, error) {
    23  	opts, err := newTransactorWithChainID(signer, domainID)
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  	tx, err := opts.Signer(signer.CommonAddress(), a.tx)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  	a.tx = tx
    32  
    33  	data, err := tx.MarshalBinary()
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  
    38  	return data, nil
    39  }
    40  
    41  // NewTransaction is the ethereum transaction constructor
    42  func NewTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrices []*big.Int, data []byte) (evmclient.CommonTransaction, error) {
    43  	// If there is more than one gas price returned we are sending with DynamicFeeTx's
    44  	if len(gasPrices) > 1 {
    45  		return newDynamicFeeTransaction(nonce, to, amount, gasLimit, gasPrices[0], gasPrices[1], data), nil
    46  	} else {
    47  		return newTransaction(nonce, to, amount, gasLimit, gasPrices[0], data), nil
    48  	}
    49  }
    50  
    51  func newDynamicFeeTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasTipCap *big.Int, gasFeeCap *big.Int, data []byte) *TX {
    52  	tx := types.NewTx(&types.DynamicFeeTx{
    53  		Nonce:     nonce,
    54  		To:        to,
    55  		GasFeeCap: gasFeeCap,
    56  		GasTipCap: gasTipCap,
    57  		Gas:       gasLimit,
    58  		Value:     amount,
    59  		Data:      data,
    60  	})
    61  	return &TX{tx: tx}
    62  }
    63  
    64  func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *TX {
    65  	tx := types.NewTx(&types.LegacyTx{
    66  		Nonce:    nonce,
    67  		To:       to,
    68  		Value:    amount,
    69  		Gas:      gasLimit,
    70  		GasPrice: gasPrice,
    71  		Data:     data,
    72  	})
    73  	return &TX{tx: tx}
    74  }
    75  
    76  func (a *TX) Hash() common.Hash {
    77  	return a.tx.Hash()
    78  }
    79  
    80  // newTransactorWithChainID is a utility method to easily create a transaction signer
    81  // for an evmclient.Signer.
    82  // Mostly copies bind.NewKeyedTransactorWithChainID but sings with the provided signer
    83  // instead of a privateKey
    84  func newTransactorWithChainID(s evmclient.Signer, chainID *big.Int) (*bind.TransactOpts, error) {
    85  	keyAddr := s.CommonAddress()
    86  	if chainID == nil {
    87  		return nil, bind.ErrNoChainID
    88  	}
    89  	signer := types.LatestSignerForChainID(chainID)
    90  	return &bind.TransactOpts{
    91  		From: keyAddr,
    92  		Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
    93  			if address != keyAddr {
    94  				return nil, bind.ErrNotAuthorized
    95  			}
    96  			signature, err := s.Sign(signer.Hash(tx).Bytes())
    97  			if err != nil {
    98  				return nil, err
    99  			}
   100  			return tx.WithSignature(signer, signature)
   101  		},
   102  		Context: context.Background(),
   103  	}, nil
   104  }