github.com/onflow/flow-go@v0.33.17/fvm/evm/types/call.go (about)

     1  package types
     2  
     3  import (
     4  	"math/big"
     5  
     6  	gethCommon "github.com/ethereum/go-ethereum/common"
     7  	gethCore "github.com/ethereum/go-ethereum/core"
     8  	gethCrypto "github.com/ethereum/go-ethereum/crypto"
     9  	"github.com/ethereum/go-ethereum/rlp"
    10  )
    11  
    12  const (
    13  	// tx type 255 is used for direct calls from bridged accounts
    14  	DirectCallTxType = byte(255)
    15  
    16  	UnknownCallSubType  = byte(0)
    17  	DepositCallSubType  = byte(1)
    18  	WithdrawCallSubType = byte(2)
    19  	TransferCallSubType = byte(3)
    20  	DeployCallSubType   = byte(4)
    21  	ContractCallSubType = byte(5)
    22  
    23  	TransferGasUsage = 21_000
    24  )
    25  
    26  // DirectCall captures all the data related to a direct call to evm
    27  // direct calls are similar to transactions but they don't have
    28  // signatures and don't need sequence number checks
    29  type DirectCall struct {
    30  	Type     byte
    31  	SubType  byte
    32  	From     Address
    33  	To       Address
    34  	Data     []byte
    35  	Value    *big.Int
    36  	GasLimit uint64
    37  }
    38  
    39  // Encode encodes the direct call it also adds the type
    40  // as the very first byte, similar to how evm encodes types.
    41  func (dc *DirectCall) Encode() ([]byte, error) {
    42  	encoded, err := rlp.EncodeToBytes(dc)
    43  	return append([]byte{dc.Type}, encoded...), err
    44  }
    45  
    46  // Hash computes the hash of a direct call
    47  func (dc *DirectCall) Hash() (gethCommon.Hash, error) {
    48  	encoded, err := dc.Encode()
    49  	return gethCrypto.Keccak256Hash(encoded), err
    50  }
    51  
    52  // Message constructs a core.Message from the direct call
    53  func (dc *DirectCall) Message() *gethCore.Message {
    54  	var to *gethCommon.Address
    55  	if dc.To != EmptyAddress {
    56  		ct := dc.To.ToCommon()
    57  		to = &ct
    58  	}
    59  	return &gethCore.Message{
    60  		From:      dc.From.ToCommon(),
    61  		To:        to,
    62  		Value:     dc.Value,
    63  		Data:      dc.Data,
    64  		GasLimit:  dc.GasLimit,
    65  		GasPrice:  big.NewInt(0), // price is set to zero fo direct calls
    66  		GasTipCap: big.NewInt(1), // also known as maxPriorityFeePerGas
    67  		GasFeeCap: big.NewInt(2), // also known as maxFeePerGas
    68  		// AccessList:        tx.AccessList(), // TODO revisit this value, the cost matter but performance might
    69  		SkipAccountChecks: true, // this would let us not set the nonce
    70  	}
    71  }
    72  
    73  func NewDepositCall(address Address, amount *big.Int) *DirectCall {
    74  	return &DirectCall{
    75  		Type:     DirectCallTxType,
    76  		SubType:  DepositCallSubType,
    77  		From:     EmptyAddress,
    78  		To:       address,
    79  		Data:     nil,
    80  		Value:    amount,
    81  		GasLimit: TransferGasUsage,
    82  	}
    83  }
    84  
    85  func NewWithdrawCall(address Address, amount *big.Int) *DirectCall {
    86  	return &DirectCall{
    87  		Type:     DirectCallTxType,
    88  		SubType:  WithdrawCallSubType,
    89  		From:     address,
    90  		To:       EmptyAddress,
    91  		Data:     nil,
    92  		Value:    amount,
    93  		GasLimit: TransferGasUsage,
    94  	}
    95  }
    96  
    97  func NewTransferCall(from Address, to Address, amount *big.Int) *DirectCall {
    98  	return &DirectCall{
    99  		Type:     DirectCallTxType,
   100  		SubType:  TransferCallSubType,
   101  		From:     from,
   102  		To:       to,
   103  		Data:     nil,
   104  		Value:    amount,
   105  		GasLimit: TransferGasUsage,
   106  	}
   107  }
   108  
   109  func NewDeployCall(caller Address, code Code, gasLimit uint64, value *big.Int) *DirectCall {
   110  	return &DirectCall{
   111  		Type:     DirectCallTxType,
   112  		SubType:  DeployCallSubType,
   113  		From:     caller,
   114  		To:       EmptyAddress,
   115  		Data:     code,
   116  		Value:    value,
   117  		GasLimit: gasLimit,
   118  	}
   119  }
   120  
   121  func NewContractCall(caller Address, to Address, data Data, gasLimit uint64, value *big.Int) *DirectCall {
   122  	return &DirectCall{
   123  		Type:     DirectCallTxType,
   124  		SubType:  ContractCallSubType,
   125  		From:     caller,
   126  		To:       to,
   127  		Data:     data,
   128  		Value:    value,
   129  		GasLimit: gasLimit,
   130  	}
   131  }