本文提出了一种结合EIP-2938和ERC-4337的原生账户抽象提案,通过将以太坊交易拆分为验证、执行和后交易逻辑的多个步骤,实现了更好的兼容性和效率。文章详细阐述了新交易类型的定义、规则及其在现有协议中的应用,尤其关注了向后兼容性和安全性。
将 EIP-2938 和 ERC-4337 结合成一个全面的原生账户抽象提案。
我们提议将以太坊交易范围分为多个步骤:验证、执行和事务后逻辑。交易的有效性由交易的验证步骤的结果决定。
我们进一步为授权和Gas费用支付分开交易验证,允许合约 B 支付来自账户合约 A 的交易的Gas费。
这一提案的好处在于与新兴的 ERC-4337 生态系统的向后兼容,同时实现原生账户抽象的长期目标。
ERC-4337 作为一种纯自愿的 ERC 可以做很多事情。然而,与原生支持相比,任何非协议内的方法来实现账户抽象都面临几种缺点。在某些关键领域,它不如真正的协议内解决方案强大:
基本的 UserOperation
相比基本交易的额外Gas开销约为 42k,而基本交易约为 21k。
在协议内审查抵抗技术方面获得的收益较少,如 crLists,针对的是交易而会忽视 UserOperations
。
依赖于远小于参与节点集的的非标准 RPC 方法,如 eth_sendRawTransactionConditional
。
无法使用 tx.origin
或依赖于其的合约,因为它返回的是一个无意义的捆绑地址。
EIP-2938 定义了一种非常成熟的账户抽象替代方法。然而,它并没有很好地转换为在没有协议变化的情况下用于生产的 ERC-4337 的架构。因此,EIP-2938 的实现将无法从有使用 ERC-4337 所获得的生产经验中受益,也无法与之保持向后兼容。
未来在某个时刻,所有的 EOAs 在以太坊上可能会被预部署的智能合约所替代。然而,这在没有将原生账户抽象添加到协议中的情况下是不可能的。
名称 | 值 |
---|---|
FORK_BLOCK | TBD |
AA_TX_TYPE | TBD |
AA_ENTRY_POINT | address(7560) |
AA_SENDER_CREATOR | address(ffff7560) |
AA_BASE_GAS_COST | 15000 |
VERSION | 1 |
MAX_CONTEXT_SIZE | 65536 |
MAX_REVERT_REASON_SIZE | 1024 |
引入一种新的 EIP-2718 交易,其类型为 AA_TX_TYPE。此类型的交易称为 "AA 交易"。它们的负载应被解释为:
0x04 || 0x00 || rlp([
chainId,
nonceKey, nonceSequence,
sender, senderValidationData,
deployer, deployerData,
paymaster, paymasterData,
executionData,
builderFee,
maxPriorityFeePerGas, maxFeePerGas,
validationGasLimit, paymasterValidationGasLimit, paymasterPostOpGasLimit
callGasLimit,
accessList,
authorizationList
])
authorizationList = [[chain_id, address, nonce, y_parity, r, s], ...]
此交易的基本Gas费用设置为 AA_BASE_GAS_COST
而不是 21000,以反映 “内在” ECDSA 签名验证的缺乏。
authorizationList
参数的行为完全与 EIP-7702 中定义的相同。
下表表示 RIP-7560 交易字段的完整列表:
名称 | 类型 | 描述 |
---|---|---|
sender | DATA, 20 Bytes | 发起交易的智能合约账户地址 |
deployer | DATA, 20 Bytes | 部署者的地址 - 账户工厂合约(可选) |
deployerData | DATA | 提供给部署者合约的数据(如果设置了 deployer ) |
paymaster | DATA, 20 Bytes | 支付方合约的地址(可选) |
paymasterData | DATA | 提供给支付方合约的数据(如果设置了 paymaster ) |
executionData | DATA | 提供给账户合约进行执行的数据 |
nonceKey | QUANTITY | 一个 192 位的nonce键。使用 nonceKey != 0 在 RIP-7712 中定义。 |
nonceSequence | QUANTITY | 一个 64 位的nonce序列。使用 nonceKey != 0 在 RIP-7712 中定义。 |
builderFee | QUANTITY | 从发送者或支付方传递到 coinbase 的值 |
maxPriorityFeePerGas | QUANTITY | 包含的最大Gas价格作为对验证者的奖励 |
maxFeePerGas | QUANTITY | 每单位Gas的最大费用 |
validationGasLimit | QUANTITY | 提供给交易账户验证帧的Gas |
paymasterValidationGasLimit | QUANTITY | 提供给交易支付方验证帧的Gas(如果设置了 paymaster ) |
paymasterPostOpGasLimit | QUANTITY | 提供给交易支付方 postOp 帧的Gas(如果设置了 paymaster ) |
callGasLimit | QUANTITY | 提供给交易 RIP-7560 执行调用帧的Gas |
accessList | OBJECT | 与 EIP-2930 兼容的访问列表结构 |
EIP-7702 authorizations (WIP) | ARRAY | 与 EOAs 注入兼容的 EIP-7702 合约列表 |
authorizationData | DATA | 将用于账户验证交易的数据 |
交易收据对象的结构已修改,以支持 RIP-7560 交易收据。
名称 | 类型 | 描述 |
---|---|---|
sender | DATA, 20 Bytes | 此交易的发送者地址 |
paymaster | DATA, 20 Bytes | 如果它为该交易支付,支付方的地址,否则为 null |
deployer | DATA, 20 Bytes | 如果交易中包含,部署者的地址,否则为 null |
senderCreationGasUsed | QUANTITY | 发送者部署帧实际使用的Gas量,如果框架未执行则为零 |
senderValidationGasUsed | QUANTITY | 发送方验证帧实际使用的Gas量 |
paymasterValidationGasUsed | QUANTITY | 支付方验证帧实际使用的Gas量,如果框架未执行则为零 |
executionGasUsed | QUANTITY | RIP-7560 执行调用帧实际使用的Gas量 |
postOpGasUsed | QUANTITY | 支付方 postOp 帧实际使用的Gas量,如果框架未执行则为零 |
executionStatus | QUANTITY | 0(成功),1(执行回退),2(postOp 回退),3(执行和 postOp 均回退) |
validationLogs | ARRAY | 该交易的验证帧生成的日志对象数组 |
transactionHash | DATA, 32 Bytes | 交易的哈希 |
transactionIndex | QUANTITY | 交易在区块中的索引位置的整数 |
blockHash | DATA, 32 Bytes | 此交易所处区块的哈希 |
blockNumber | QUANTITY | 此交易所在区块的块号 |
cumulativeGasUsed | QUANTITY | 此交易在区块中执行时的Gas总消费量 |
effectiveGasPrice | QUANTITY | 每单位Gas支付的基本费用与小费的总和 |
gasUsed | QUANTITY | 此特定交易单独使用的Gas量 |
logs | ARRAY | 此交易的执行帧生成的日志对象数组 |
logsBloom | DATA, 256 Bytes | 用于轻客户端快速检索相关日志的布隆过滤器 |
type | QUANTITY | 交易类型的整数 |
AA_TX_TYPE
交易的最大Gas费用定义为:
maxPossibleGasCost = AA_BASE_GAS_COST +
validationGasLimit +
paymasterValidationGasLimit +
callGasLimit +
paymasterPostOpGasLimit
如果未指定 paymaster
,则 maxPossibleGasCost
在任何执行帧进行计算之前,从 sender
地址的余额中预先收取。
如果指定了 paymaster
,则Gas费用从其余额中收取。如果被预先收取的账户余额不足,无论是 sender
还是 paymaster
,交易都是无效的。
交易执行结束后,被预先收取的地址可能会获得Gas退款。
maxPriorityFeePerGas
和 maxFeePerGas
的含义与 EIP-1559 中定义的没有变化。
对于所有现有交易类型,关于 data
参数按字节收取 G_txdatazero (4 gas) 和 G_txdatanonzero (16 gas)。
交易类型 AA_TX_TYPE 引入以下动态长度输入:executionData
、paymasterData
、deployerData
、authorizationData
。这些参数的Gas费用将计入交易数据成本。该交易数据Gas成本称为 calldataGasUsed
,并在交易执行之前从 validationGasLimit
中减去。如果 validationGasLimit
小于 calldataGasUsed
,则交易将被视为无效。
由于需要考虑块构建者在将 AA_TX_TYPE
交易包含在其区块中时所需进行的额外离线工作,以及在 L2 rollups 上操作的构建者的潜在 L1 Gas费用,并且因为这些工作与验证所花费的Gas量无关,也不与Gas价格相关,因此 sender
可能决定支付额外的 builderFee
作为对块构建者的 “小费”。
该值以 wei 为单位,由 sender
或(如果指定)paymaster
传递到当前区块的 coinbase
中,作为Gas预收费的一部分。
所有现有交易类型仅具有隐式验证阶段,其中检查余额、nonce 和签名,以及具有
tx.origin == msg.sender
的单个顶级执行帧,而该地址由交易 ECDSA 签名确定。
然而,在处理类型为 AA_TX_TYPE
的交易时,将创建多个执行帧。可能的帧的完整列表尝试复刻 ERC-4337 流程:
sender
部署帧(每个账户一次)sender
验证帧(必需)paymaster
验证帧(可选)sender
执行帧(必需)paymaster
交易后帧(可选)“验证阶段”中的所有执行帧必须成功完成而不得回退,并且 sender
和 paymaster
验证帧必须包含对对应 AA_ENTRY_POINT
批准回调函数的调用,才能使交易在区块中的指定位置被视为有效。
在所有顶层帧中,全局变量具有以下含义:
操作码名称 | Solidity 等效 | 值 |
---|---|---|
CALLER |
msg.sender |
AA_ENTRY_POINT 地址。AA_SENDER_CREATOR 用于 “部署帧”。 |
ORIGIN |
tx.origin |
交易的 sender 地址 |
CALLDATA* |
msg.data |
交易数据设置为相应帧的输入 |
请注意 EVM 中某些行为取决于交易上下文。这些行为是:
这些功能不受将交易分成多个帧的影响。比如在一个帧中使用 TSTORE 设置的值将在下一帧中继续可用。
deployer
地址从 AA_SENDER_CREATOR
地址调用,使用 deployerData
作为调用数据输入。
此帧的 gas 限制设置为 validationGasLimit
。该帧使用的Gas量称为 senderCreationGasUsed
。
发送者部署帧必须导致 sender
地址被初始化为合约代码。
我们定义以下 Solidity 结构来表示链上的 AA 交易:
struct TransactionTypeRIP7560 {
address sender;
address paymaster;
address deployer;
uint256 nonceKey;
uint256 nonceSequence;
uint256 builderFee;
uint256 maxFeePerGas;
uint256 maxPriorityFeePerGas;
uint256 validationGasLimit;
uint256 paymasterValidationGasLimit;
uint256 paymasterPostOpGasLimit;
uint256 callGasLimit;
bytes senderValidationData;
bytes paymasterData;
bytes deployerData;
bytes executionData;
address[] authorizationList;
bool[] authorizationListStatus;
}
请注意,authorizationList
结构参数仅包含从每个 RLP 编码的交易负载元素中恢复的地址列表。
由于为 authorizationList
提供任何元素都与其有效性无关,并且在链上验证时避免重复执行 ecrecover
,因此引入 authorizationListStatus
结构参数。其元素为设置 EOAs 代码导致的条目返回 true
,否则返回 false
。
然后定义以下 Solidity 方法,sender
交易会使用相应的数据被调用:
function validateTransaction(uint256 version, bytes32 txHash, bytes transaction) external;
此帧的 gas 限制设置为 validationGasLimit - senderCreationGasUsed - calldataGasUsed
。transaction
参数被解释为 TransactionTypeRIP7560
的 ABI 编码。
txHash
参数表示 AA_TX_TYPE 交易的哈希,authorizationData
为空,如第 计算 AA_TX_TYPE 交易哈希 节中定义。version
参数被添加以在将来此结构修改时保持 Solidity 方法ID 的有效性。
该帧使用的Gas量称为 senderValidationGasUsed
。
接下来定义下列 Solidity 方法作为 AA_ENTRY_POINT
批准回调函数:
function acceptAccount(uint256 validAfter, uint256 validUntil) external;
function sigFailAccount(uint256 validAfter, uint256 validUntil) external;
对 AA_ENTRY_POINT
批准回调的调用具有以下含义:
acceptAccount
- 该回调在账户验证交易并同意支付执行费用后由账户调用。sigFailAccount
- 当交易在语法上有效,但 authorizationData
不正确时,账户会调用此回调。请注意,此回调在Gas估算时使用,并不表示交易有效。传递给回调函数的参数具有以下含义:
账户必须进行一次确切的调用到 AA_ENTRY_POINT
,才能被视为有效。任何其他结果,例如账户未调用 AA_ENTRY_POINT
回调,调用任何非 acceptAccount
的调用,多个调用 AA_ENTRY_POINT
,或导致执行回退,都将被视作验证失败,交易将被拒绝,不会被链上包含。
这些回调可以由账户直接调用,也可以在运行于账户上下文中的 DELEGATECALL
内部调用。如果在验证帧期间,从任何其他合约调用回调,交易将被拒绝,并不会被链上包含。
交易的 paymaster
,如果已指定,将使用以下数据调用:
function validatePaymasterTransaction(uint256 version, bytes32 txHash, bytes transaction) external;
此帧的 gas 限制设置为 paymasterValidationGasLimit
。
此帧使用的 gas 量称为 paymasterValidationGasUsed
。
version
参数为 VERSION
transaction
参数被解释为 TransactionTypeRIP7560
的 ABI 编码。\txHash
参数代表 AA_TX_TYPE 交易的哈希,authorizationData
为空,如第 计算 AA_TX_TYPE 交易哈希 节中定义。接下来定义下列 Solidity 方法作为 AA_ENTRY_POINT
批准回调函数:
function acceptPaymaster(uint256 validAfter, uint256 validUntil, bytes context);
function sigFailPaymaster(uint256 validAfter, uint256 validUntil, bytes context);
对 AA_ENTRY_POINT
批准回调的调用具有以下含义:
acceptPaymaster
- 支付方在验证交易后同意支付执行费用时调用该回调。sigFailPaymaster
- 如果支付方的 paymasterData
预计包含某种签名,但实际上并不包含有效的签名时,支付方会调用此回调。请注意,此回调在Gas估算时使用,并不表示交易有效。传递给回调函数的参数具有以下含义:
validAfter
、validUntil
- 同 acceptAccount
中的定义相同context
- 支付方合约提供的可选字节数组,该数组稍后传递给 postPaymasterTransaction
。此值的长度不得超过 MAX_CONTEXT_SIZE
字节。支付方必须进行一次确切的调用到 AA_ENTRY_POINT
,才能被视为有效。任何其他结果,例如支付方未调用 AA_ENTRY_POINT
回调,调用任何非 acceptPaymaster
的调用,多个调用 AA_ENTRY_POINT
,或使执行回退,都将被视作验证失败,交易将被拒绝,不会被链上包含。
这些回调可以由支付方直接调用,也可以在运行于支付方上下文中的 DELEGATECALL
内部调用。如果在验证帧期间,从任何其他合约调用回调,交易将被拒绝,并不会被链上包含。
sender
地址使用 executionData
输入调用。
此帧的 gas 限制设置为 callGasLimit
。\
calldataGasUsed
价值的计算在 交易输入的Gas费用收取 部分中定义。\
此帧使用的Gas量称为 gasUsedByExecution
。
验证帧不会回退,即使执行帧引发回退。此时,postPaymasterTransaction
仍然可以与 success: false
标志一起调用。
在发送方执行帧结束后,支付方可能需要执行某些事务后的逻辑,例如进行某种清理或记账。如果Gas支付验证帧在 acceptPaymaster
回调中提供了非零 context
,则支付方将再次被调用,输入如下:
function postPaymasterTransaction(bool success, uint256 actualGasCost, bytes context) external;
success
指示此交易的执行帧是否成功完成且无回退。actualGasCost
参数是截至这一点,支付方为此交易实际花费的Gas量。注意,它不包含 postPaymasterTransaction
函数自身的Gas成本。此帧的 gas 限制设置为 paymasterPostOpGasLimit
。
在 postPaymasterTransaction
帧中的回退也会导致交易执行帧的回退。支付方收取的Gas费用将包括验证帧以及回退的执行帧和 postPaymasterTransaction
帧的Gas成本。
我们定义以下系统级事件,它们作为 RIP-7560 交易的一部分被触发:
event RIP7560TransactionEvent(
address indexed sender,
address indexed paymaster,
address indexed deployer,
uint256 nonce,
uint256 executionStatus
);
event RIP7560TransactionRevertReason(
address indexed sender,
uint256 nonce,
bytes revertReason
);
event RIP7560TransactionPostOpRevertReason(
address indexed sender,
address indexed paymaster,
uint256 nonce,
bytes revertReason
);
RIP7560TransactionEvent
在每个 RIP-7560 交易结束时触发。
RIP7560TransactionRevertReason
在 RIP-7560 交易的执行帧因回退而产生非零长度返回数据的情况下触发。
RIP7560TransactionPostOpRevertReason
如果 RIP-7560 交易支付方的 “postOp” 调用因产生非零长度返回数据而引发回退,则触发。
返回的字节数组作为 revertReason
参数被截断为其最大长度 MAX_REVERT_REASON_SIZE
。超出该长度的数据将在交易收据中不可观察。
系统交易事件的Gas成本不单独收取,而是包含在交易的 AA_BASE_GAS_COST
中。
executionStatus
的值如下:
success
= 0executionFailure
= 1postOpFailure
= 2executionAndPostOpFailure
= 3由账户抽象交易确定的执行流程通过以下流程图可视化:
原生账户抽象交易的执行流程
在执行层,对区块的交易有效条件的扩展如下:
func validateAccountAbstractionTransaction(tx *Transaction) {
assert !(sender.code.length > 0 && deployer != address(0))
if (sender.code.length == 0 && deployer != address(0)) {
calldataGasUsed := calculateCallDataGasUsed(tx)
retDeployer, error := evm.Call(
from: AA_SENDER_CREATOR,
to: deployer,
input: deployerData,
gas: validationGasLimit - calldataGasUsed)
assert error == nil
assert sender.code.length > 0
}
senderInput := ABI.encodeWithSelector('validateTransaction', tx, tx.hash);
callbackParamsSender, error := evm.Call(
from: AA_ENTRY_POINT,
to: sender,
input: senderInput,
gas: validationGasLimit - retDeployer.gasUsed)
assert error == nil
assert callbackParamsSender != nil
assert Date.now() <= callbackParamsSender.validUntil
assert Date.now() >= callbackParamsSender.validAfter
assert callbackParamsSender.isValidAuthorizationData
if (paymaster != address(0)) {
paymasterInput := ABI.encodeWithSelector('validatePaymasterTransaction', tx, tx.hash)
callbackParamsPaymaster, error := evm.Call(
from: AA_ENTRY_POINT,
to: paymaster,
input: paymasterInput,
gas: paymasterValidationGasLimit)
assert error == nil
assert callbackParamsPaymaster != nil
assert Date.now() <= callbackParamsPaymaster.validUntil
assert Date.now() >= callbackParamsPaymaster.validAfter
assert callbackParamsPaymaster.isValidAuthorizationData
}
}
为了防御 DoS 攻击向量,区块构建者应考虑 ERC-7562 中描述的操作码禁止和存储访问规则。
块验证的工作量大致与没有 AA 交易时相同。在任何情况下,验证必须执行整个区块以验证状态更改。在执行过程中,当前会验证签名、nonce 和Gas支付。通过账户抽象,它也将验证所有验证帧是否成功。所需的内存仅略有增长,主要用于存储从支付方验证帧传递到其事务后帧的 context
值。
只要所有交易验证步骤成功执行并提供正确值到其 AA_ENTRY_POINT
回调,则该块被视为有效。愿意放宽对验证帧应用的规则的区块构建者可以这样做。
放大单个交易,AA 交易的验证部分可能包括多个执行帧:
在区块内的单个原生账户抽象交易中的帧
支付方验证帧
和 发送方验证帧
各自提供 validUntil
和 validAfter
的值。
这些值允许 sender
和 paymaster
合约指定该交易将在何时有效的区块时间范围。
交易不能被包含在超出此时间范围的区块中。如果被包含,该区块将被视为无效。
传递 validUntil = 0
和 validAfter = 0
将禁用检查。
keccak256(AA_TX_TYPE || 0x00 || rlp(transaction_payload)
请注意,chainId
、accessList
和 authorizationList
参数被包含在交易哈希计算中,但在链上并不可用,作为 TransactionTypeRIP7560
结构的一部分。
为了计算交易哈希,在签署交易和验证交易签名时,authorizationData
参数的值被视为一个空的字节数组。
与此账户抽象提案相关的合约,例如 sender
或 paymaster
,必须知道要执行哪些代码并理解提供给它们的 calldata,以便验证交易。
我们认为,最直接的实现是依赖 Solidity 的 4 字节方法选择器,因为这是公认的事实标准。
AA_SENDER_CREATOR
地址调用 deployer
重要的是,deployer
不是从 AA_ENTRY_POINT
调用,而是从 AA_SENDER_CREATOR
调用。这是必要的,以确保 AA_ENTRY_POINT
永远不会在未先完成成功验证的情况下调用 sender
执行函数。
没有这种保护,因为我们不控制 deployerData
字段,它可能会构造得看起来像是来自 AA_ENTRY_POINT
到 sender
的合法调用。
AA_ENTRY_POINT
批准回调在智能合约上下文中,成功的验证帧执行会导致交易的Gas支付。重要的是要防止任何不知情的合约被欺骗“接受” RIP-7560 交易验证,从而可能导致此合约被抽干。
为此,我们要求指定的调用到 AA_ENTRY_POINT
地址以表明 RIP-7560 交易的接受。
authorizationData
检查失败的使用 sigFailAccount
和 sigFailPaymaster
如果一个账户或支付方在各自的验证帧中可以验证交易的所有相关细节,但交易的 authorizationData
不正确,则会调用此回调。
此回调在Gas估算期间使用,有助于钱包和应用程序在生成任何真正的签名之前确定验证过程所用的Gas量。预计交易在用有效的 authorizationData
更新后将消耗相同数量的Gas。
这些事件是 ERC-4337 中由 EntryPoint.sol
合约发出的事件的等效物。它们提供了一组通过现有以太坊 API 通常无法获得的功能。
其中包括能够获取由给定的 sender
、paymaster
或 factory
发起的最新交易的能力,以及观察发生在已包含交易上的交易回退原因。
现有的 ERC-4337 基础设施很可能依赖这些事件以实现其基本功能,因此我们在 RIP-7560 中也保留这些事件。
该 EIP 保留了 ERC-4337 大部分设计元素。这允许在最低程度或没有修改的情况下在两个系统中使用相同的客户端代码和智能合约,同时提供显著的用户体验改进。
现有合约不受此变化的重大影响。假设 tx.origin
被保证为 EOA 的假设不再有效。假设 tx.origin
是支付当前交易的地址的假设也不再有效。
任何期望以太坊交易有单个顶级执行帧的代码都必须适应新的交易类型。
EIP-3607 引入了一项禁令,禁止从已部署代码的发送者那里进行交易。此限制不适用于 AA_TX_TYPE 交易。
ERC-4337 不是协议变化,可以与此 EIP 永久平行运行。由于与 ERC-4337 的相似性,相同的区块构建者可以轻松支持 ERC-4337 和 AA_TX_TYPE
交易。
EntryPoint
升级到适配器合约ERC-4337 背后的团队将提供一个参考实现,该合约将转换 paymaster
和 sender
合约的 ABI。此适配器可由 ERC-4337 合约设为受信任的 EntryPoint
地址。
在过渡期间,sender
合约可能支持 ERC-4337 和 AA_TX_TYPE
交易,只要某些链可能采用此 EIP,而另一些链则不采用。
此 EIP 创建了一种复杂和复杂的机制,旨在扩展智能合约账户的使用。所有这一切都带来了很多新的风险向量和攻击面。
以下是已知的原生账户抽象的一些非详尽的安全考虑列表。
此 EIP 增加了一种新的方式,智能合约可以通过有效的回调调用来简单地收费,只需使用符合 validateTransaction
、validatePaymasterTransaction
的方法 ID 的函数调用 AA_ENTRY_POINT
地址。
这给意外或恶意包含此类方法但未公开这些合约可用作 AA_TX_TYPE
交易中的 sender
或 paymaster
的合约带来了新的风险。
通过要求这些合约在 AA_ENTRY_POINT
地址上调用 acceptAccount
或 acceptPaymaster
回调来缓解此问题,使合约与 AA_ENTRY_POINT
地址的交互变得显式。
代码审查人员应了解 RIP-7560 交易的这一特性。
现有的交易类型会在回退时也包含在一个区块中,并提供回退原因供调试用途。薄弱错误通知的现象包括:
这不是发生在 AA_TX_TYPE
交易的验证阶段中的回退的情况。为此,开发人员应跟踪正在签署的这些交易的有效性,并鼓励依赖 validUntil
时间范围参数,确保未按预定时间包含的交易不会意外地再次变为有效。
重要的是要考虑区块构建者在规定时间内填充区块的能力。
就区块有效性而言,在区块中包含时,所有验证和 RIP-7560 执行调用帧都可以读取和写入任何状态。这意味着交易在技术上能够使彼此无效。
区块构建者可能面临因包含单个交易而使多个合格交易无效的风险,导致拒绝服务。顺序块构建者只要按接收顺序处理进入的交易,就不会有这样的风险。
作为缓解措施,AA 交易应受限于存储访问规则,以避免对区块构建者的 DoS。这些规则在 ERC-7562 中定义。
充分缓解可以通过将验证与分离到另一上下文中实现,具体参见 RIP-7711。
我们建议智能合约账户开发人员确保用户能够控制其账户,即使 AA_TX_TYPE
交易因任何原因变得不可用。
这可以通过提供一个公共函数来轻松实现,该函数包括对智能合约账户的验证和执行处理程序的调用。
通过 CC0 放弃版权和相关权利。
- 原文链接: github.com/ethereum/RIPs...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!