本文档主要讨论了 EIP-7702 引入的新交易类型及其安全考量,重点关注使用 EIP-7702 在现有 EOA 上实现账户抽象功能。内容涵盖了多个 7702 授权、公共 EIP-7702 签名、多态账户等安全隐患,并针对合约和签名参数提出了指导方针,包括合约应支持撤销、存储命名空间,以及钱包应限制对未知合约地址和空 nonce 的签名等。
null
的 nonce,会与长期授权的其中一个特性冲突
EIP-7702 引入了一种新的交易类型,允许在 EOA 的上下文中执行代码。在当前的提案下,为了使 EOA 授权应该执行的代码,它必须签署包含要执行代码的帐户的 address
,以及可选的当前 nonce
和 chainId
。重要的是要理解每个这些参数的语义,以及不签署 nonce
或 chainId
的安全含义。本文档包含有关此方面的建议和指南。
本文档主要关注的用例是使用 EIP-7702 引入的新功能,作为在现有 EOA 上实现帐户抽象功能的一种手段。
一个 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 签名被使用一次,就必须假定任何其他人,包括恶意行为者,都可以重放该签名,以便执行他们自己的交易,其中 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 一起使用,但我们提出了一些合约指南,以最大限度地提高跨合约的互操作性。
CREATE2
部署,以便对特定地址处的代码有一些保证,这对于不签署特定链的 EIP-7702 授权更为重要。
CREATE2
,也不能 100% 保证特定地址处的代码始终相同(例如,请参阅 create3)。有关旨在与 EIP-7702 一起使用的代理的参考实现,请参见:https://gist.github.com/lightclient/7742e84fde4962f32928c6177eda7523
默认情况下,钱包应仅允许签署已知遵循指南的合约地址,并且仅允许所有合约作为选择加入功能。
有关 EIP-7702 的参考代理实现,请参见上文。
帐户或 null
的当前交易计数。签名 null
值将使 EIP-7702 授权永远有效,并提供撤销签名的协议内机制。因此,建议钱包不允许签名 nonce null
。
签名链 id 可确保代码授权无法跨链重用。这很重要,因为不能始终保证相同的代码存在于多个链上的相同地址。
也就是说,有一些用例可以从跨链重放授权的可能性中受益。
例子:
在要求用户签名时,重要的是他们了解跨链可重放性的风险。因此,建议的默认设置是不允许使用链 id 0
的交易,并且仅将其作为选择加入功能。
钱包应始终确保他们显示为哪个链签署了代码授权,并在可能的情况下检查它是否与连接的网络相对应。
- 原文链接: hackmd.io/@rimeissner/ei...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!