Pectra 升级的核心:EIP-7702的原理分析和实操

EIP-7702 是以太坊引入的新交易类型,赋予 EOA 账户临时合约能力,实现批量交易与 Gas 代付。其核心是通过签名授权,节点在交易时注入合约逻辑,执行后自动卸载,无需部署,链上无残留。EIP-7702推动了账号抽象发展:https://learnblockchain.cn/shawn_sh

ps: EIP-7702 内容较新,笔者编写文章之时,主网还未上线,若小白感觉有一定难度,可跳过此篇文章

什么是 EIP-7702

EIP-7702 是以太坊 Pectra 升级的内容之一。是一种新的交易类型( 0x4 )。提高了以太坊的账号抽象的能力,支持直接使用 EOA 账号去执行临时智能合约。可以实现批量交易、gas 代付 等能力,这将会在钱包开发中起到很大作用。

EIP-7702 的能力

  • 批量交易:可以在一次 EOA 账号发起交易时,发送多次交易。(非 EIP-7702 类型的 EOA 账号一次只能发送一笔交易)

  • gas 代付:允许第三方(例如接收方或代理机构)为你支付本次交易的 gas 费用。(原始 EOA 交易没有 gas 代付能力)

  • 安全访问:授予临时的对合约的访问,用完后 EOA 账号恢复成为普通账号。调用时无须暴露私钥。

  • 合约共享:逻辑合约可以共享,只需部署一次,便可提供给多个 EOA 账号使用。逻辑合约可永久存在链上(临时合约用完即毁)。

EIP-7702 在钱包场景下的作用

可以用在交易所钱包的 归集 操作上。传统的以太坊 EOA 账号进行归集操作,从用户地址发送到归集地址,只能一笔一笔进行归集,并且需要交易所下发一笔小额资金作为归集 gas 费用。效率十分低下且存在粉尘资金增多、额外消耗 gas 的问题。而采用 EIP-7702 的新交易类型,可以在共用 EOA 账号的同时,平滑升级到支持批量归集gas 代付的能力。

EIP-7702 实现的核心原理

  • 签名授权 EOA 账号在签名时候,签订一个授权信息,内容包括 链 IDnonce委托地址EIP-712 的签名。这个授权信息供验证者节点打包交易时,从委托地址中查出运行代码,然后附加到 EOA 账号中。

    image.png

  • 临时代码注入 节点收到 EOA 账号发送的交易后,验证 EOA 账号的签名,从链上读取委托合约的 bytecode 然后临时注入到 EOA 账号的地址上。

  • 自动代码卸载 在交易执行完后,该地址又会变回普通 EOA 地址,EXTCODEHASH(address) == 0x0。代码区会变回 0。且状态不会存储到链上,确保不存在污染。

EIP-7702 实操及流程解析

  1. 下载仓库
git clone https://github.com/quiknode-labs/qn-guide-examples.git
cd qn-guide-examples/ethereum/eip-7702
  1. 安装依赖 安装 forge 库和 OZ 代码库
    
    forge install foundry-rs/forge-std
    forge install OpenZeppelin/openzeppelin-contracts
3. **启动 anvil**
注意,在未完全升级之前,必须携带`--hardfork prague` 参数,否则无法执行。
```js
anvil --hardfork prague
  1. 使用 script 部署合约
❯ forge script script/BatchCallAndSponsor.s.sol \
  --rpc-url http://127.0.0.1:8545 \
  --broadcast \
  --tc BatchCallAndSponsorScript -vvvv

观察到以下结果,代码部署成功。 image.png

  1. 观察日志
    • performDirectExecution() 批量转账日志观察

image.png

  • performSponsoredExecution() gas 代付日志观察

image.png

  1. 部署流程解析
    • 原始 EOA 转账 首先来分析一下没有 EIP-7702 的原始转账情况,用户 A 通过离线签名,将交易发送到以太坊 RPC 节点,在通过对用户 A 的签名认证之后,可以将交易广播到以太坊网络。此时,交易只能一笔一笔的发送,且无 gas 代付能力。

image.png

  • performDirectExecution() 批量转账 而在使用了 EIP-7702 后,交易流程发生了变化。首先,我们来看一个总的执行图。后面再回去根据代码分析。

image.png

  1. 在这个执行图中(A 代指 AliceB 代指 Bob),EOA 账户 Alice 离线发起委托签名,签名时,将委托的逻辑合约包含在其中,发送给以太坊 RPC 节点。

    image.png

  2. 然后,RPC 节点经过验证签名有效后,读取这个逻辑合约的字节码,注入给 EOA 用户 Alice。此时,用户 Alice 从一个 EOA 账户升级成为一个临时合约账户(合约的地址和用户 Alice 的地址一致),可以执行合约的逻辑(批量转账等)

    image.png

  3. 在此处 Alice 的临时合约中,因为合约的调用者是 Alice,无须对 Alice 进行验签处理,使用 require(msg.sender == address(this)) 即可完成签名的验证。 image.png

  4. 此外,由于发送给 RPC 节点时 from 地址为 Aliceto 地址也为 Alice。在此过程中,Alice 为合约账户,属于合约内部交易,所以这条记录不会被记录在以太坊的交易记录中。

    1. 最后,这个账户就拥有了合约的调用能力,其中的交易给 Bob 的两笔交易(ETHERC20 代币)都通过 B.call()的方式进行发送到以太坊网络中。(from 地址为 Aliceto 地址为 Bobfrom 地址属于合约地址,to 地址属于 EOA 地址,属合约内部交易,故也不存在交易记录中)

image.png

  • performSponsoredExecution() gas 代付

    image.png gas 代付的情况相对于普通批量转账的场景而言,稍微复杂与一点。可以分为以下几步:

    1. Alice 构造委托合约,并签名image.png
    2. Bob 持有 Alice 的数据,并签名image.png
    3. Bob 发送交易到 RPC 节点

    image.png

    1. RPC 节点对 Bob 进行验签,通过后读取 Alice 委托的逻辑合约代码,注入到 Alice 的地址中。然后广播交易。此时,用户 Alice 从一个 EOA 账户升级成为一个临时合约账户(合约的地址和用户 Alice 的地址一致),可以执行合约的逻辑(批量转账等)

      1. 并且,由于在这种 gas 代付的方案中,交易的发起者是 Bob,所以 RPC 节点在进行验签的时候,只会验证 Bob 的签名,Alice 的签名并不会去处理。在合约中,没办法像上面批量交易那样使用 require(msg.sender == address(this)) 故我们临时合约中还需要去验证 Alice 的签名,以防止伪造交易的情况出现。

    image.png

    1. 此外,由于发送给 RPC 节点时,发送者 fromBob,接受者 to 地址为 AliceBob 是一个 EOA 账户,Alice 为一个合约账户,故这笔交易记录会被记录上。
      image.png
      1. 但是,由于在 Alice 合约内部,发生了从 Alice 转账给 Tom(也可以是 Bob) 的情况,Alice 属于合约地址,TomBob) 属EOA 地址,属合约内部交易,故这笔记录也不会存在以太坊的交易记录中。

image.png

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
shawn_shaw
shawn_shaw
web3潜水员、技术爱好者、web3钱包开发工程师、欢迎交流工作机会。欢迎骚扰:vx:cola_ocean