🚀以太坊账户简介
一个以太坊帐户是一个具有以太币 (ETH) 余额的实体,可以在以太坊上发送交易。 帐户可以由用户控制,也可以作为智能合约部署。
目前以太坊上有两种账户:第一种地址是外部拥有账户(EOA),通常被称为钱包账户,由私钥和公钥组成,常用的 Metamask(小狐狸)钱包就是基于 EOA 设计的,它需要自己为每一笔交易授权并支付 gas。另一种是智能合约账户,各种部署在以太坊上的 DApp 就是以智能合约的方式运行着。
💰账户问题、账户抽象与合约钱包
但是这样的账户(地址)设计存在很多问题,一方面会阻碍 EOA 和 CA 相互实现对方能够实现的功能,组合了链上应用创新;另一方面,EOA 要求用户掌握私钥,造成了极大的用户进入门槛和安全隐患。
而账户抽象就是让 EOA(理解为metamask) 和 Contract Account(理解为dapp)可以做只有对方可以做的事,要么让 EOA 可以实现 CA 功能,要么反过来。
简而言之,账户抽象就是账户统一。
实现账户抽象(Account Abstract/AA)的钱包叫做智能合约钱包,目前可以实现如 ECDSA 以外的签名验证方式、多签管理、社会恢复、聚合签名、交易限制、隐私保护、gas 优化、gas 代付、异币 gas、应用聚合、自动收益等多种功能,长远来看有利于降低 Web3 进入门槛,并使得链上行为更加可编程。
长久以来有非常多基于 AA 的智能合约钱包的方案, Vitalik Buterin、Yoav Weiss、Kristof Gazso、Namra Patel 和 Dror Tirosh 在 2021 年通过入口点合约规范提出了 EIP-4337。
EIP-4337 是以太坊上基于 AA 的智能合约钱包最为先进的方案之一(或者没有之一),下面我将介绍 4337 的工作流、优点、缺点。
📃摘要
EIP-4337 完全避免共识层协议更改的帐户抽象提案。该提案没有添加新的协议特性和更改底层事务类型,而是引入了一个更高层的伪事务对象,称为 UserOperation
。用户将 UserOperation
对象发送到单独的内存池中。一类特殊的行为者被称为 Bundler(捆绑器)(要么是矿工,要么是可以通过捆绑市场向矿工发送交易的用户),他们将这些对象打包成一个交易,对一个特殊的合约进行 handleOps
调用,然后该交易就被纳入一个区块中。
做一个奇怪的比喻🎃,男孩子只能做男孩子能做的事,女孩子只能做女孩子能做的事,为了让男孩子和女孩子能做对方才能做的事,引入一个喇叭和中间人,喇叭传播信号,中间人协调执行。当男孩子需要做只能女孩子做的事,男孩子给自己的授权和具体的需求拜托中间人让女孩子来做。
🧐EIP-4337 钱包工作流
-
初始设定,在一个 4337 钱包中,该钱包由一个 Enternal Ownered Account(EOA) 和一个 Contract Account(CA)组成。
-
在钱包端,当 EOA 或者任何其他签名方案(在以太坊之外的公链)发起交易时,EOA 签名生成
UserOperation
(一种伪事务类型,提供所有交易信息,包括calldata、sender, gas, maxFeePerGas, maxPriorityFee,signature, nonce等)。 -
钱包将
UserOperation
传到专用的 UserOperation mempool,Bundler(矿工或可以通过bundle市场向矿工发送交易的用户)可以监听该 menpool,并创建 bundle transactions,一个bundle transactions 可以包含多个UserOperation
传到 Entry Point 合约的handleOps
接口。 -
Miner 将 bundle transaction 打包出块。
-
Entry Point 有以下两个验证和执行的循环阶段。
在验证循环,对
handleOps
接口的调用必须为每个UserOperation
遵循以下步骤:5.1 CA创建。
如果没有钱包就创建一个,通过
UserOperation
中提供的initcode
来创建。如果钱包不存在,并且initcode
为空,或者没有在sender
地址部署合约,该调用则失败。5.2 验证签名。在钱包中调用
validateUserOp
,传入UserOperation
需要的 gas 和聚合器(如果有)。让 CA (sender
)验证操作签名有效,则支付 gas。如果validateUserOp
调用失败,handleOps
必须至少跳过这个执行,并且能够完全 revert(恢复)。5.3 检查 gas。验证钱包在 Entry Point 中的存款足够覆盖最大可能的花费。 EP 发起请求,发送
UserOperation
给 CA,CA 验证完,返回给 EP,然后 EP 继续。执行循环,handleOps 调用必须为每个UserOperation 遵循以下步骤
5.4 CA执行。通过
UserOperation
的 calldata 来调用钱包。钱包决定如何解析 calldata。钱包的预期工作流是,钱包自己有一个execute
函数解析剩余的 calldata ,就像钱包应该发起的一次或多次系列调用(make a series of one or more),然后执行逻辑。5.5 在接受一个
UserOperation
之前,捆绑器应该使用 RPC 方式来本地调用入口点的simulateValidation
函数,来验证签名是正确的并且操作已经付费。一个节点/捆绑器应该跳过(或者不添加到内存池)验证失败的UserOperation
。
😍优点
-
非共识。EIP-4337 可在无需更新以太坊核心协议的情况下实现较大程度的账户抽象,推进难度相对 EIP-2938、EIP-3074 等共识提案更低。
-
可升级。钱包可更改自己的 public keys,如果使用了代理调用,则可升级整体代码。
-
去中心。没有一个实体可以影响整个流程的运转,一切都是通过点对点内存池完成的。
-
高度可编程。基本实现账户抽象的目的,可以对钱包进行丰富的自定义。a)签名自定义,可以支持 ECDSA 之外的签名算法,聚合签名;b)验证自定义,如黑白名单;c)执行自定义,可以支持如 gas 代付、多签、交易管理、社会恢复、隐私保护等在内的多种功能。任何新加的功能理论上在这个 4337 流程中加一个模块就可以实现。
😲缺点
更多 gas。比常规交易有更多链上操作,产生额外的 gas
模块堆积。随着功能不断增加,可能存在安全漏洞。
协议兼容。与既有的合约钱包协议/工作流不兼容,既有的钱包开发商动力不够。
🐒盘点
钱包通过合约复制 mempool 对交易的处理,用户不再进行交易。相反,用户的钱包将 UserOperations
发送到更高级别的内存池。矿工或 Bundler(捆绑器)可以将一组 UserOperation
打包成捆绑交易,发送到 EntryPoint 合约并协调钱包 CA 执行,并确保矿工/捆绑者得到适当的交易费用补偿。
钱包可以通过 require(msg.sender == ENTRY_POINT)
,即只相信通过一个特定网关来发起,然后钱包再执行指令、支付 gas 以及成功后的 nonce increment 等。Entry Point本质上完成对钱包的安全保障。通过受信任的 entry point 发起,合约钱包可以完成任何指令动作、gas支付。
学习资料
https://eips.ethereum.org/EIPS/eip-4337
https://github.com/ethereum/EIPs/blob/3fd65b1a782912bfc18cb975c62c55f733c7c96e/EIPS/eip-4337.md
https://zenn.dev/sivira/articles/d041f1ac44ca1e
https://www.notion.so/EIP-4337-0baad80755eb498c81d4651ccb527eb2
https://www.notion.so/EIP-4337-0baad80755eb498c81d4651ccb527eb2
<>