CYNIC

發布於 2023-07-11到 Mirror 閱讀

从EIP-101到EIP-4337,账户抽象的前世今生

2023年3月2日,以太坊声明ERC-4337合约已在主网部署,遂成此文。

Generated by DALL·E

当我们谈论账户,我们在谈论什么?

以太坊当前有两种账户类型:外部拥有账户(Externally Owned Accounts, EOA)和合约账户(Contract Account, CA)。

EOA是大家平常认知的钱包,通过密码学算法随机生成私钥和公钥密钥对,公钥用于他人验证,私钥用于账户签名。控制了私钥,也就控制了EOA。Not your keys, not your coins。这里的keys说的就是私钥。

CA是部署到网络上的智能合约,由代码控制,合约账户的地址通常在部署成功后给出,由创建人地址和nonce产生。

两种账户类型都能:

  • 接收、持有和发送 ETH 和 token

  • 与已部署的智能合约进行交互

两种账户类型的区别:

EOA

  • 创建帐户是免费的

  • 可以发起交易(主动发起

  • 外部所有的帐户之间只能进行以太币和代币交易

  • 由一对加密密钥组成:控制帐户活动的公钥和私钥

CA

  • 创建合约存在成本,因为需要使用网络存储空间

  • 只能在收到交易时发送交易(被动触发

  • 从外部帐户向合约帐户发起的交易能触发可执行多种操作的代码,例如转移代币甚至创建新合约

  • 合约帐户没有私钥。 相反,它们由智能合约代码逻辑控制

以太坊帐户有四个字段:

  • nonce – 显示从帐户发送的交易数量的计数器。 这将确保交易只处理一次。 在合约帐户中,这个数字代表该帐户创建的合约数量

  • balance – 这个地址拥有的 Wei 数量。 Wei 是以太币的计数单位,每个 ETH 有 1e+18 Wei。

  • codeHash - 该哈希表示以太坊虚拟机 (EVM) 上的帐户代码。 合约帐户具有编程的代码片段,可以执行不同的操作。 如果帐户收到消息调用,则执行此 EVM 代码。 与其他帐户字段不同,不能更改。 所有代码片段都被保存在状态数据库的相应哈希下,供后续检索。 此哈希值称为 codeHash。 对于外部所有的帐户,codeHash 字段是空字符串的哈希。

  • storageRoot – 有时被称为存储哈希。 Merkle Patricia trie 根节点的 256 位哈希已编码了帐户的存储内容(256 位整数值映射),并编码为 Trie,作为来自 256 的 Keccak 256 位哈希的映射位整数键,用于 RLP 编码的 256 位整数值。 此 Trie 对此帐户存储内容的哈希进行编码,默认情况下为空。

可以看出EOA和CA两者各有利弊,EOA能主动发起,但CA具有可编程性,账户抽象(Account Abstraction, AA)其实就是希望将两种账户的优势进行融合,让用户能够使用任意验证逻辑、可编程性地发起交易。

滚滚长江东逝水,浪花淘尽英雄

账户抽象的发展,经历了多种方案的讨论和改进。

幽暗的树林里分出两条路

经过社区近两年的讨论,关于账户抽象问题大致形成了两个解决思路:让EOA更像CA — — EIP-3074、让CA更像EOA — — EIP-4337。

与其将gas代付、批处理等能力庄严写入交易有效性的需求,EIP-3074允许用户将自己EOA的控制权委托给CA,这给了开发者灵活的框架来开发EOA的交易模式。简而言之,EIP-3074让EOA像CA一样运作而不需要部署合约。

使用EIP-3074,用户使用私钥签署消息。然后,该消息被包含在invoker的链上交易中。invoker将签名消息与AUTH操作码一起使用以获得对用户帐户的控制,并且使用AUTHCALL它可以代表用户执行操作。值得注意的是,包含用户签名消息的交易不一定要从该用户的账户发送,这使得用户不需要依赖ETH发送交易,而可以使用如ERC-20代币。

考虑安全性,用户依然是自己保管注记词和私钥,这方面的安全性不会减弱。但是invoker可能被授予了过高的权限,可能导致毁灭性的打击。

EIP-4337在不改变共识层协议的前提下,试图实现以下目标:

  • 允许用户使用包含任意验证逻辑的智能合约钱包而不是EOA作为主账户,完全移除对EOA的需求

  • 维持去中心化,bundler打包者作为uo的block builder,无需信任;直接和公开内存池通信,用户不需要知道任何参与者的地址;

  • 支持以下用例:隐私保护、原子多操作、ERC20支付gas、聚合签名(e.g. BLS)

EIP-4337工作逻辑如下:

  1. 用户使用私钥对UserOperation签名(自定义签名逻辑、不需要ECDSA),将签名后的UserOperation发送至UserOperation mempool

  2. bundler挑选、验证UserOperation后(调用entry point的simulateValidation函数来验证签名正确且支付了fees),将验证通过的打包进bundle transaction中,实际是通过调用entry point合约的handlerOps方法

  3. bundler由于负责发送bundle transaction,所以需要使用ETH支付gas fee,后续会从每个UserOperation的执行中得到补偿

  4. entry point是一个确保安全的智能合约,将部分本来由wallet合约实现的部分复杂逻辑放到了entry point中。如果账户未创建,entry point需要使用UserOperation中提供的initcode创建账户,否则调用失效。

  5. entry point需要调用wallet合约的validateUserOp来验证UserOperation的有效性,并且从wallet中获取gas的refund(如果wallet认为该UserOperation有效)。如果验证不通过,handleOps必须跳过执行,可能需要全部撤销。

  6. 对每个通过验证的UserOperation,handleOps会用UserOperation的calldata调用wallet

注意,simulateValidation模拟过程需要确保UserOperation是有效的,且用户或者paymaster有能力支付gas fee。此外,还需要确保UserOperation在链上执行的时候这些条件还是有效的。所以,UserOperation禁止获取任何可能在模拟和执行之间改变的状态。如果sender发起了一个状态变化,需要支付高昂的Gas,该机制用于抵御DoS攻击。

革命尚未成功,同志还须努力

为了避免核心层的改动导致硬分叉,EIP-4337最终赢得了这场账户抽象的比赛。

EIP-4337的优势如下:

  • 去中心化,无中心化角色(对比EIP-3074的invoker)

  • 验证逻辑可编程性

  • 执行逻辑可变,例如原子多操作

  • 执行层量子安全,可以根据情况改变验证逻辑

  • 钱包可升级性,可以更新wallet合约代码

  • DoS安全,除非sender状态改变(而这种攻击需要7500+的gas),不然UserOperation在模拟和执行时的一致性是相同的

  • 不需要复杂的用户端设置,由entry point负责处理wallet创建的事宜

  • 完全支持EIP-1559

  • 支持replace-by-fee,发送一个更高premium的UserOperation可以自动替换掉之前的,或者让其更快执行。

然而,EIP-4337同样具备不足:

  • Gas开销,由于钱包是智能合约形式,所以创建账户就需要gas来部署钱包合约,导致额外的gas开销。此外,智能合约的调用也比EOA的转账等操作gas更高。尤其是在当前ETH主网上,高昂的gas fee会劝退很多用户。

  • 每次只能单交易,由于UserOperation要求user的状态不能改变,所以没法排队送入多个交易到内存池中,不过由于可以支持原子多操作,这个问题显得不那么重要了。

目前最大的问题当然是高昂的gas开销,这也就是为什么在以太坊的路线图中,vitalik将EIP-4337纳入The Splurge阶段(目前规划的最后阶段)来实施。在可见的未来中,ZK Rollup的大规模使用应该能显著缓解gas开销问题,为EIP-4337的使用打开突破口。

参考文献:

https://camiinthisthang.substack.com/p/account-abstraction-for-everyone