EIP-7377: 迁移交易
允许 EOA 发送一次性交易,在其账户上部署代码。
Authors | lightclient (@lightclient), Sam Wilson (@samwilsn), Ansgar Dietrichs (@adietrichs) |
---|---|
Created | 2023-07-21 |
Discussion Link | https://ethereum-magicians.org/t/eip-xxxx-migration-transaction/15144 |
Requires | EIP-170, EIP-1559, EIP-2200, EIP-2718 |
Table of Contents
摘要
引入一个新的 EIP-2718 交易类型,格式为 0x04 || rlp([chainId, nonce, maxFeePerGas, maxPriorityFeePerGas, gasLimit, codeAddr, storage, data, value, accessList, yParity, r, s])
,它将发送账户的 code
字段在状态树中设置为 codeAddr
处的 code
值,并将存储元组应用于发送者的存储树。
动机
智能合约钱包长期以来一直被吹捧为解决以太坊用户体验困境的方案。早在 2015 年,就有人提议允许智能合约发起交易,希望新用户涌向智能合约钱包来存储他们的资产。到目前为止,只有一小部分用户选择这样做。
今天,账户抽象仍然是以太坊的一个重要目标,并且有许多尝试实现它的努力。我们越来越接近成功,但不幸的是,多年的失败导致许多用户仅仅依赖 EOA。
在用户在一个 EOA 中积累了足够的资产之后,将每个单独的资产迁移到一个新的地址是不可行的。这既是由于成本,也是由于需要手动签名和验证可能数百个交易。
这是这个问题中被忽视的一部分。有效地将 现有 用户转换为智能合约钱包将加速采用,并推动对智能合约钱包的更好支持和集成。它们将不再被视为小众用例。
因此,我们必须提供一种嵌入在协议中的机制,将 EOA 迁移到智能合约。这个 EIP 提出了这样的机制。
规范
在分叉区块 X
,引入迁移交易类型。
迁移交易
定义
field | type |
---|---|
chainId |
uint256 |
nonce |
uint64 |
maxFeePerGas |
uint256 |
maxPriorityFeePerGas |
uint256 |
gasLimit |
uint64 |
codeAddr |
address |
storage |
List[Tuple[uint256, uint256]] |
data |
bytes |
value |
uint256 |
accessList |
List[Tuple[address, List[uint256]]] |
yParity |
uint8 |
r |
uint256 |
s |
uint256 |
EIP-2718 TransactionType
为 0x04
,TransactionPayload
为 rlp([chainId, nonce, maxFeePerGas, maxPriorityFeePerGas, gasLimit, codeAddr, storage, data, value, accessList, yParity, r, s])
。
交易的签名哈希是 keccak256(0x04 || rlp([chainId, nonce, maxFeePerGas, maxPriorityFeePerGas, gasLimit, codeAddr, storage, data, value, accessList])
验证
如果以下属性成立,则迁移交易被认为是有效的:
从 EIP-1559 修改的内在 gas 计算为 21000 + 16 * non-zero calldata bytes + 4 * zero calldata bytes + 1900 * access list storage key count + 2400 * access list address count + 20000 * length of storage
。
处理
执行迁移交易有两个部分。
合约部署
与标准合约部署不同,迁移交易直接指定发送者账户应设置为什么 code
值。
作为处理交易的第一步,将发送者的 code
设置为 state[tx.codeAddr].code
。接下来,对于 tx.storage
中的每个元组和发送者的存储树,设置 storage[t.first] = t.second
。
交易执行
现在使用与 EIP-1559 相同的规则实例化一个 EVM 调用到发送者的账户中,并将交易的发起者设置为 keccak256(sender)[0..20]
。
理由
没有 to
地址字段
这个交易只适用于一次性使用,将 EOA 迁移到智能合约。它被设计为在部署后立即调用已部署的合约,该合约位于发送者的地址,以允许发送者进行任何进一步的处理。
用于部署的代码指针
天真地,人们可以设计迁移交易以具有 code
类型的 bytes
字段。但是,会有大量的代码 calldata 重复,因为许多用户会想要部署完全相同的东西(通常是钱包)。使用指针代替承认了这种交易类型的大量用例,并将其作为一种优化来利用。
更便宜的存储
由于存储保证为空,因此无需在写入之前读取。这意味着只需要 20,000 gas 就可以支付 EIP-2200 SSTORE_SET_GAS
值。这是对 22,100
的正常成本的一个小折扣,它是 SSTORE_SET_GAS
加上 EIP-2929 的 COLD_SLOAD_COST
的 2100
,因为没有发生加载。
内在因素不考虑合约部署
这利用了客户端倾向于存储代码的单个唯一副本的事实;无论部署数量如何。因此,这里的唯一操作是更改状态树中的指针到所需的代码。
此外,EOA 已经存在,因为它有足够的余额来使迁移交易被认为是有效的。因此,我们不需要为将新帐户添加到状态树中支付额外费用。
操作交易发起者
许多应用程序都有一个安全检查 caller == origin
,以验证调用者是否是 EOA。这样做是为了“保护”资产。虽然它通常更多的是一种权宜之计而不是实际的修复,但我们试图通过修改交易的发起者来安抚这些项目,以便检查将继续履行其职责。
一次性迁移
没有技术原因可以阻止我们允许 EOA 随时使用此交易类型更改其代码。目前唯一的抑制因素是 EIP-3607,如果迁移交易来自已部署代码的帐户,这将导致迁移交易被认为是无效的。但保留此行为的一个功能原因是,它可以更简单地推理合约及其可升级性。
向后兼容性
未发现向后兼容性问题。
安全考虑
盲签
与所有足够复杂的帐户设计一样,如果用户被说服签署任意消息,则该消息可能是由恶意参与者拥有而不是由用户拥有的迁移交易。如果钱包 极其 小心对待这些交易,并在完成签名之前创建尽可能多的摩擦和验证,则通常可以避免这种情况。
关于 ecrecover
ERC-2612: 许可扩展 等应用程序标准已经利用了 EOA 地址与其私钥之间的加密关系。今天许多 token 都支持这个扩展,允许 EOA 仅使用签名就批准从其帐户转移资金。虽然 EOA 和合约帐户之间的冲突被认为不太可能,并且鉴于今天的计算能力 可能是不可能的,但这个 EIP 将使私钥存在于合约帐户中变得司空见惯。这里有一些关于安全的考虑:
- 明显的攻击是 defi 协议使用这个 EIP 部署它们的一些合约,然后在签名一个 ERC-2612 消息来窃取合约中累积的资金。可以通过钱包简单地不允许用户与以这种方式部署的协议交互来避免这种情况。
- 同样值得一提的是,有人担心这个 EIP 将如何影响跨链体验。最终,用户的私钥可能仍然对帐户的资产有一些控制权,这取决于以太坊和其他链上使用的确切协议。真正完美地同时在所有链上迁移 EOA 是不可能的。最好做的是教育用户,仅仅因为他们的帐户已迁移并不意味着他们可以安全地公开他们的私钥。这似乎是一个合理的要求,特别是由于他们会想要保留私钥,以防他们想在任何其他类似 EVM 的链上使用该地址。
在某种程度上,缓解这些问题的方法是在 ecrecover
中添加一个 EXTCODEHASH
检查。如果恢复的帐户有代码,则预编译将恢复。这将禁止迁移的 EOA 使用 ERC-2612 等标准。
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
lightclient (@lightclient), Sam Wilson (@samwilsn), Ansgar Dietrichs (@adietrichs), "EIP-7377: 迁移交易 [DRAFT]," Ethereum Improvement Proposals, no. 7377, July 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7377.