EIP-7819: SETDELEGATE 指令
引入一条新的指令,允许合约使用 EIP-7702 委托指定来创建克隆
Authors | Hadrien Croubois (@amxx), Danno Ferrin (@shemnon) |
---|---|
Created | 2024-11-18 |
Discussion Link | https://ethereum-magicians.org/t/eip-7819-create-delegate/21763 |
Requires | EIP-7702 |
摘要
引入一条新的指令,允许智能合约创建(和更新)与 EIP-7702 设计相匹配的委托账户。这些账户可以像 ERC-1167 克隆一样使用,但具有显著的优势。
动机
许多链上应用涉及到在不同位置创建相同代码的多个实例。这些应用通常依赖于克隆或代理来降低部署成本。
克隆,例如 ERC-1167 中描述的克隆,是包含目标地址直接在代码中的最小代码片段。这使得它们非常轻量,但也阻止了任何形式的重新配置(可升级性)。
可升级代理与克隆的不同之处在于,它们从存储中读取实现的地址。这使得它们用途更广泛,但使用起来也更昂贵。
在这两种情况下,使用 EVM 代码将接收到的调用委托给实现都存在一些缺点:
- 在执行委托调用之前,必须将 Calldata 复制到内存中
- 如果启用了 EOF,则用 EOF 编写的克隆和代理不支持委托给用传统 EVM 代码编写的实现,因此受到限制或可能存在危险。这鼓励了传统 EVM 代码的持续使用。
EIP-7702 引入了一种新型对象,它具有预期的行为:指示器。这些对象旨在在 EOA 的地址上实例化,但相同的行为可以被重用以在协议级别实现克隆。如果调用 SETDELEGATE
的合约允许,则使用指示器用于此用例可以在不需要存储查找的情况下提供可升级性。它还消除了与代码版本不兼容相关的任何问题。
规范
在 0xf6
处添加了一个新的指令 (SETDELEGATE
)。
行为
执行此指令会执行以下操作:
- 扣除
EMPTY_ACCOUNT_COST
gas - 如果当前帧处于
static-mode
,则停止 - 从操作数堆栈中弹出
salt
、target
- 将
location
计算为keccak256(MAGIC ++ address ++ salt)[12:]
- 如果
location
处的代码不为空且不以0xEF0100
开头(非空且不是指示器),则停止 - 如果
location
存在于 trie 中,则将EMPTY_ACCOUNT_COST - BASE_COST
gas 添加到全局退款计数器。 - 将
location
的代码设置为MAGIC || target
,与 EIP-7702 中定义的委托过程相匹配。- 与 EIP-7702 类似,如果
target
是0x0000000000000000000000000000000000000000
,则不要写入指定。清除location
处的代码,并将location
的代码哈希重置为空哈希0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
。
- 与 EIP-7702 类似,如果
- 将
location
推送到堆栈上
在 location
创建的指示器的行为与 EIP-7702 创建的指示器的行为相同。
注意:委托在操作完成后立即生效。在下一个操作执行后立即调用该地址将执行新委托的代码。
参数
Constant | Value |
---|---|
MAGIC |
0xef0100 |
EMPTY_ACCOUNT_COST |
25000 |
BASE_COST |
12500 |
理由
Gas 成本
SETDELEGATE
指令的执行涉及的活动部件比 EIP-7702 gas 成本考虑的要少:
- 没有签名恢复
- 没有必须在交易级别已经支付的专用 calldata
- 没有 nonce 更新
因此,执行此指令的成本可能低于 EIP-7702。为简单起见,重用了 EIP-7702 中的数字。它们低于 CREATE
或 CREATE2
操作,使得此指令的使用对于预期用例具有竞争力。
向后兼容性
TODO
安全考虑
委托者升级和删除
重用 EIP-7702 的行为,包括如果目标为 0 则清除代码,从而可以升级甚至“删除”创建的指示器。此过程由工厂(调用 SETDELEGATE
的合约)控制(并且可以限制)。一些工厂会添加检查,以防止使用已使用的 salt 重新执行 SETDELEGATE
,从而使创建的指示器不可变。其他工厂可能允许访问受限的升级,但会阻止删除。在任何情况下,关于使用 SETDELEGATE
创建的指示器的生命周期的保证由调用它的合约提供,而不是由协议提供。
委托者链接
如 EIP-7702 中所述,指示器链或循环未解决。这意味着,与克隆不同,链接是一个问题。然而,这是开发人员已经习惯的事情,因为链接代理可能导致奇怪的行为,包括无限委托循环。
工厂可能希望通过验证 target
不包含指示器来防止这种风险。这可以使用可以访问 EXTCODEHASH
的传统合约助手来实现。也可以使用其他形式的自省,例如 ACCOUNT_TYPE
指令。
抢跑初始化
与 EIP-7702 签名不同,EIP-7702 签名可以包含在任何交易中,因此如果实现不检查初始化参数的真实性,则可能导致初始化抢跑,CREATE_DELEGATION
由智能合约执行,该智能合约可以在创建委托后立即原子地执行初始化逻辑。此过程对于在创建后立即初始化克隆和代理的开发人员来说是众所周知的。
在单个交易中进行多次委托更改。
如果合约在同一个交易中执行多个 SETDELEGATE
操作,但使用相同的 salt 但目标不同,同时执行与相应地址的调用,这将在同一个交易中,且没有回滚的情况下,使一个地址具有与之关联的多个不同的代码,其中两个或多个代码被执行。这包括在交易期间多次删除/重置委托。
这种行为使用更传统的、可升级的合约已经基本可以实现。
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Hadrien Croubois (@amxx), Danno Ferrin (@shemnon), "EIP-7819: SETDELEGATE 指令 [DRAFT]," Ethereum Improvement Proposals, no. 7819, November 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7819.