7702 最佳实践

本文档主要讨论了 EIP-7702 引入的新交易类型及其安全考量,重点关注使用 EIP-7702 在现有 EOA 上实现账户抽象功能。内容涵盖了多个 7702 授权、公共 EIP-7702 签名、多态账户等安全隐患,并针对合约和签名参数提出了指导方针,包括合约应支持撤销、存储命名空间,以及钱包应限制对未知合约地址和空 nonce 的签名等。

未决问题/TODO

  • 如何称呼一个 7702 授权?
  • 7702 授权应该如何展示?
    • 应该被认为类似于暴露你的私钥!
  • 不允许签名 null 的 nonce,会与长期授权的其中一个特性冲突
    • 应该更改为清楚地表明这一点,而不是阻止它
  • 添加一个关于合理的 nonce 是什么的章节
    • 签名一个过高的 nonce 也可能有安全隐患

介绍

EIP-7702 引入了一种新的交易类型,允许在 EOA 的上下文中执行代码。在当前的提案下,为了使 EOA 授权应该执行的代码,它必须签署包含要执行代码的帐户的 address,以及可选的当前 noncechainId。重要的是要理解每个这些参数的语义,以及不签署 noncechainId 的安全含义。本文档包含有关此方面的建议和指南。

本文档主要关注的用例是使用 EIP-7702 引入的新功能,作为在现有 EOA 上实现帐户抽象功能的一种手段。

安全考虑

多个 7702 授权

一个 EOA 能够签署多个 EIP-7702 授权,授权不同的代码在其上下文中执行。如果存在多个有效的签名,则无法保证在交易中实际使用哪一个(如果有的话)。交易签名者(不是 EOA)最终决定在交易中包含哪些签名。如果用户有多个有效的 EIP-7702 签名,这可能会导致意外的行为。

虽然这与代理有类似的安全考虑,但它还有一个额外的含义,即在有多个 EIP-7702 授权的情况下,不可能在“更改实现”地址时强制执行逻辑;只需使用不同的 EIP-7702 授权,就可以在 EOA 上使用不同的代码执行新的交易,而旧的实现无法实现任何控制更新过程的逻辑,也无法保证在该帐户上下文中没有执行过其他代码。

一个具体的例子是,如果用户签署 EIP-7702 授权,将其帐户升级到具有冲突存储使用的 SCA,这可能会成为一个问题。这意味着 SCA 实现对其存储或对其他合约的 CALL 维护的某些不变量可能不再可靠,因为另一个实现可能会破坏它们。当前的 Safe 实现依赖于 mapping(address => address),使其成为一个结构良好的所有者链表,如果 EOA 将自己升级到 Safe,那么一个并行的 EIP-7702 授权很容易破坏链表不变量,并无意中向帐户添加影子所有者。其中一些可以通过存储命名空间来解决,这在下面的合约指南部分中描述。

公开的 EIP-7702 签名

一旦 EIP-7702 签名在区块链上包含的交易中使用,它就会变成公开的。一旦 EIP-7702 签名被使用一次,就必须假定任何其他人,包括恶意行为者,都可以重放该签名,以便执行他们自己的交易,其中 EOA 有代码。这意味着合同应实施额外的授权机制,以便与 EIP-7702 一起使用,除非它们被设计为本质上是无需许可的。

另一个由签名公开引起的潜在问题的例子是,将 ERC-721 转移到 EOA 的交易,恶意行为者可能会通过提交相同的交易来 DoS 该交易,但使用了一个已签名的 EIP-7702 授权,该授权在 EOA 上设置了未正确实现 Token 回调函数的代码,导致转移回滚。请注意,这对此类交易的行为有一些假设(它必须是一个具有某种重放保护的合约,该合约在转移回滚时不会回滚 - 一个具体的例子是 Safe 将 ERC-721 转移到 EOA,并使用 Safe 交易配置为如果交易本身回滚则不回滚)。

为了避免签名公开可能引起的问题,建议 EOA 仅使用 nonce 签名 EIP-7702 授权,以便在协议级别上撤销签名,如果签名开始出现问题。

多态帐户

使用 EIP-7702,帐户是多态的,因为它们可以在交易中表现为合约或 EOA(具有零 EXTCODESIZE ),以及作为 ORIGIN (tx.origin 在 Solidity 中),或者通常能够计算恢复到包含代码的帐户的 ECDSA 签名。协议不能对其安全性的核心假设 EXTCODESIZE 对于 EOA 为零。

合约指南

虽然理论上任何合约都可以与 EIP-7702 一起使用,但我们提出了一些合约指南,以最大限度地提高跨合约的互操作性。

  • 构建撤销功能以使 7702 授权无效
    • 例如,参见参考代理实现,该实现依赖于可以通过 EOA 调用的外部合约的无效机制。
    • 另一种可能的策略是在特定区块或时间戳之后始终恢复,以此来实现有时间限制的 EIP-7702 授权方法。
  • 为了更容易地支持 EOA 从一个合约迁移到另一个合约,计划与 EIP-7702 一起使用的合约应实施存储命名空间(https://github.com/ethereum/solidity/issues/597#issuecomment-1537533170
    • 或者,他们可以使用存储持有者模式
  • 合约应使用 CREATE2 部署,以便对特定地址处的代码有一些保证,这对于不签署特定链的 EIP-7702 授权更为重要。
    • 请注意,即使使用 CREATE2 ,也不能 100% 保证特定地址处的代码始终相同(例如,请参阅 create3)。

有关旨在与 EIP-7702 一起使用的代理的参考实现,请参见:https://gist.github.com/lightclient/7742e84fde4962f32928c6177eda7523

签名参数

代码地址

默认情况下,钱包应仅允许签署已知遵循指南的合约地址,并且仅允许所有合约作为选择加入功能。

有关 EIP-7702 的参考代理实现,请参见上文。

Nonce

帐户或 null 的当前交易计数。签名 null 值将使 EIP-7702 授权永远有效,并提供撤销签名的协议内机制。因此,建议钱包不允许签名 nonce null

链 Id

签名链 id 可确保代码授权无法跨链重用。这很重要,因为不能始终保证相同的代码存在于多个链上的相同地址。

也就是说,有一些用例可以从跨链重放授权的可能性中受益。

例子:

  • 跨链“升级式”体验。该流程将允许用户为所有链签名一个消息并丢弃密钥(或者密钥一开始就是以非信任方式生成的,即 Nicks 方法)。

在要求用户签名时,重要的是他们了解跨链可重放性的风险。因此,建议的默认设置是不允许使用链 id 0的交易,并且仅将其作为选择加入功能。

钱包应始终确保他们显示为哪个链签署了代码授权,并在可能的情况下检查它是否与连接的网络相对应。

  • 原文链接: hackmd.io/@rimeissner/ei...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
rimeissner
rimeissner
江湖只有他的大名,没有他的介绍。