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 }