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)
引入了 maxFeePerGas
和 maxPriorityFeePerGas
字段,改变了以太坊的交易费用模型,随以太坊 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 数据是外部无法直接访问的,但它们被验证并存储在以太坊网络中,以支持以后的分片架构