transfer、send、call区别

  • transfer() 函数是智能合约中最基本的发送 ETH 的方式, 从调用者的合约地址发送固定数量的 ETH 到目标地址
address payable recipient = payable(0xRecipientAddress);
uint256 amount = 1 ether;
recipient.transfer(amount);

transfer() 会自动限制 gas 费为 2300,防止重入攻击, 如果交易失败,它会自动回滚

  • send() 函数与 transfer() 类似,它返回一个布尔值,表示交易是否成功, 但是出现失败的情况下不会回滚,需要手动处理
bool success = recipient.send(amount); 
require(success, "Transfer failed.");
  • call() 是一种更底层、更灵活的发送 ETH 的方法, 它允许指定更高的 gas 费用和进行更复杂的调用, 但需要小心处理以防止重入攻击
(bool success, ) = recipient.call{value: amount}("");
require(success, "Transfer failed.");

以太坊的几种主要的交易类型:

传统交易(Legacy Transaction)

又以 EIP-155 作为时间点,EIP-155 在签名中增加了链 ID, 通过引入链 ID (v = chainId * 2 + 35 or 36) 避免了跨链重放攻击的风险

{
  "nonce": 1,
  "gasPrice": "0x09184e72a000",
  "gasLimit": "0x2710",
  "to": "0xRecipientAddress",
  "value": "0x10",
  "data": "0x",
  "v": "0x26",  // v = 1 (mainnet) * 2 + 35 引入 chainId 
  "r": "0x5e1d3a76fbf824220e3e3b7d75e53fdd5e287e046a8dba03e2cb1e7c78d0d11d",
  "s": "0x5e1d3a76fbf824220e3e3b7d75e53fdd5e287e046a8dba03e2cb1e7c78d0d11d"
}

EIP-2930 交易(访问列表交易 / Access List Transaction)

随以太坊 Berlin 硬分叉上线, 增加了 accessList 字段,用于在交易开始前加载相关的存储槽和合约代码,优化了 EVM 的 gas 消耗 特点

  • type = 1 表示这是一个 EIP-2930 交易。
  • accessList 用于在交易开始前加载相关的存储槽和合约代码,减少交易执行中的 gas 消耗
{
  "type": "0x1",
  "chainId": "0x1",
  "nonce": "0x0",
  "gasPrice": "0x09184e72a000",
  "gasLimit": "0x2710",
  "to": "0xRecipientAddress",
  "value": "0x10",
  "data": "0x",
  "accessList": [
    {
      "address": "0xContractAddress",
      "storageKeys": ["0xStorageKey1", "0xStorageKey2"]
    }
  ],
  "v": "0x26",
  "r": "0x5e1d3a76fbf824220e3e3b7d75e53fdd5e287e046a8dba03e2cb1e7c78d0d11d",
  "s": "0x5e1d3a76fbf824220e3e3b7d75e53fdd5e287e046a8dba03e2cb1e7c78d0d11d"
}

EIP-1559 交易(动态费用交易 / Dynamic Fee Transaction)

引入了 maxFeePerGasmaxPriorityFeePerGas 字段,改变了以太坊的交易费用模型,随以太坊 London 硬分叉上线 特点

  • type = 2 表示这是一个 EIP-1559 交易。
  • maxFeePerGas 定义了用户愿意支付的最高 gas 费用。
  • maxPriorityFeePerGas 是用户愿意支付给矿工的额外小费,用于加速交易。
  • baseFee 由网络动态调整,是所有交易支付的最低费用
{
  "type": "0x2",
  "chainId": "0x1",
  "nonce": "0x0",
  "maxPriorityFeePerGas": "0x01",
  "maxFeePerGas": "0x09184e72a000",
  "gasLimit": "0x2710",
  "to": "0xRecipientAddress",
  "value": "0x10",
  "data": "0x",
  "accessList": [],
  "v": "0x26",
  "r": "0x5e1d3a76fbf824220e3e3b7d75e53fdd5e287e046a8dba03e2cb1e7c78d0d11d",
  "s": "0x5e1d3a76fbf824220e3e3b7d75e53fdd5e287e046a8dba03e2cb1e7c78d0d11d"
}

EIP4844 (Proto-Danksharding)

引入 **Blob-carrying Transactions**,这是一种可以携带 “blobs”(大块数据)的交易类型。这些 blobs 数据是外部无法直接访问的,但它们被验证并存储在以太坊网络中,以支持以后的分片架构