这篇文章详细介绍了以太坊的账户抽象机制(ERC-4337),包括其在智能合约钱包中的应用、设计注意事项以及潜在的安全性挑战。文章强调了在实现智能账户时需要注意的各种安全问题和最佳实践,为开发者提供了重要的指导。
这一年对于以太坊的 账户抽象 来说令人激动。链上,使智能账户成为可能的关键 EntryPoint
合约终于完成了 审计 并 部署。链下,准备投产的捆绑器正在 主网及其他网络 上运行并中继 UserOperations
。在以太坊生态系统之外,新技术如 通行钥匙 在浏览器和移动设备中的采用,将与账户抽象结合起来 简化 密钥管理或 完全替代 种子短语签名器 一起。
关于账户抽象能够解锁的众多功能,我们很容易感到兴奋:社交恢复系统、赞助的Gas、定期付款、临时有限权限会话密钥、可编程消费限额、可替换的签名算法、灵活的多签政策、便宜的原子批量操作!这些功能以及更多的功能可能很快就会出现在你的钱包中。或者至少,将在你的钱包构建它们后。
ERC-4337 规范提供了智能账户的基础设施和抽象,但它启用的大多数新功能将是在应用层中构建的,特别是在智能合约钱包的实现中。
实际上,ERC-4337 在钱包层面上的要求出乎意料地简单。它仅要求账户实现简单的 IAccount
接口,并遵循一些规则:
interface IAccount {
function validateUserOp(
UserOperation
calldata userOp,
bytes32 userOpHash,
uint256 missingAccountFunds
) external returns (uint256 validationData);
}
智能账户必须确保对其 validateUserOp
函数的调用来自一个受信任的入口地址,支付他们的Gas,并验证操作的签名。其他一切则留给钱包实现,包括来自入口的调用的解析和执行。
这种灵活性使标准强大且可扩展,但这也意味着钱包实现对自己的正确性、安全性和保密性负责。ERC-4337 仓库中包含的参考 SmartAccount.sol
是一个简单单一所有者智能账户的很好例子,但它故意包含了一组有限的功能。构建真正有趣的功能需要更多的自定义代码,这留出了大量出错和漏洞的空间。如果你正在构建或审计智能账户,以下是一些常见的设计和安全关注点需要牢记。
智能账户是懒加载到反事实地址。ERC-4337 的这一非常酷的特性意味着,可以在已知的、确定的地址 现在 接收资产,并在 以后 部署钱包合约来管理它们。如果钱包不存在,入口在账户的第一次 UserOperation
时创建它,通过调用用户提供的工厂合约。
非常重要的是,账户工厂合约的设计必须确保它们部署的钱包只能由授权部署的用户控制。这通常意味着确保所有相关的部署参数(所有者地址、启用的模块、部署时初始化代码)会迫使反事实地址发生变化。但是,由于钱包合约通常是可升级代理,不同的部署时初始化参数可能不会改变合约生成的 CREATE2 地址,除非它们被显式传递作为构造函数参数或包含在盐中。
如果钱包需要执行后部署初始化,例如设置所有者地址或启用模块,确保这些参数的任何更改也会改变生成的地址。确保对手不能直接调用代理工厂,并操控【指定为他人](https://code4rena.com/reports/2023-01-biconomy#h-03-attacker-can-gain-control-of-counterfactual-wallet) 部署的钱包的配置。
4337 规范建议确保生成的合约地址依赖用户的初始签名。由于用户会对所有 UserOperation
参数进行签名,包括他们钱包的部署初始化代码,这是一种确保唯一反事实地址的简单方式。
跨链账户抢先交易也是潜在的关注点:如果部署不是完全确定的 且 工厂是有状态的(例如,存储特定的部署参数),对手可能能够在新的链上部署工厂,改变参数,部署被后门或操控的钱包。
理想的工厂是简单的、无主体的、无状态的和确定性的:任何人都应该能够在任何链的同一地址处部署它,并通过调用它在具有可验证的部署参数的确定性地址进行部署。
从 4337 规范的角度来看,钱包最重要的工作是验证 UserOperation
签名。为了防止跨链和入口实现的重放,有必要确保签名不仅包括 UserOperation
哈希,还包括链 ID 和入口地址。这是规范的一部分,并且 入口 提供的 userOpHash
包含这些值。不要偏离规范:对哈希中包含的所有参数进行签名是重要的。
虽然对 UserOperation
哈希的签名是验证操作的最常见方式,但也可以定义程序规则,以链上状态等条件来定义有效操作,而不是调用者提供的签名。在这些情况下,确保每个参数在 UserOperation
中都经过验证具有规则或已知良值是重要的。未能做到这一点可能导致Gas攻击、欺骗操作,或更糟的结果。
许多智能钱包提供了执行钱包操作的第二路径,通常由钱包所有者或授权账户调用。如果这些函数由签名授权(例如,多签智能钱包),请确保这些签名也没有脆弱性:它们应始终包含一个随机数,并对跨多个链 ID 的重放具有稳健性。
智能账户可能支持同时生成 EIP-1271 智能合约签名和验证来自其他合约的 EIP-1271 签名。这可能会出乎意料地复杂 达到 正确。如果一个调用者能够控制与 1271 签名相关的签名合约,或者在某种授权检查中没有使用签名合约的地址,请仔细检查你的实现逻辑。
一些事情 永远不会改变,selfdestruct
-able 模块和代理实现始终是任何基于代理的智能合约钱包的担忧。如果你的智能账户能够 delegatecall
,请确保没有办法接管并 销毁 实现 或 模块。
另外,由于智能账户通常使用 ECDSA 签名,请特别警惕签名上下文中的空地址:如果签名恢复直接使用 ecrecover
,则可能仍然能够使用 无效签名 篡改所有权,从而获取或销毁实现,即使其无法初始化。
尽管 selfdestruct
正在逐步淘汰 在以太坊主网,其他 EVM 链 需要时间 才能采用相同的语义。由于智能账户天生是多链的,因此这种攻击可能在一段时间内不会消失。
EIP-4337 是可编程账户的一大步,以太坊构建者和日常用户因这一标准而感到兴奋,这并非没有理由。但从外部拥有账户(EOA)转向账户抽象意味着将安全责任从个人管理密钥转移到智能合约管理账户。这是可能的,智能账户可以成为比 EOA 更好、更安全的替代品,但这只要我们负责构建、测试和审计智能钱包代码的人能正确实现。
感谢 horsefacts 这篇来宾文章。你可以在 Code4rena 上找到他 在这里 ,以及在 Twitter 在这里 。
要了解有关 Code4rena 的更多信息, 访问我们的网站 _。
- 原文链接: medium.com/code4rena/sma...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!