EIP-7702 是以太坊引入的新交易类型,赋予 EOA 账户临时合约能力,实现批量交易与 Gas 代付。其核心是通过签名授权,节点在交易时注入合约逻辑,执行后自动卸载,无需部署,链上无残留。EIP-7702推动了账号抽象发展:https://learnblockchain.cn/shawn_sh
ps:
EIP-7702内容较新,笔者编写文章之时,主网还未上线,若小白感觉有一定难度,可跳过此篇文章。什么是 EIP-7702
EIP-7702是以太坊Pectra升级的内容之一。是一种新的交易类型(0x4)。提高了以太坊的账号抽象的能力,支持直接使用EOA账号去执行临时智能合约。可以实现批量交易、gas代付 等能力,这将会在钱包开发中起到很大作用。
批量交易:可以在一次 EOA 账号发起交易时,发送多次交易。(非 EIP-7702 类型的 EOA 账号一次只能发送一笔交易)
gas 代付:允许第三方(例如接收方或代理机构)为你支付本次交易的 gas 费用。(原始 EOA 交易没有 gas 代付能力)
安全访问:授予临时的对合约的访问,用完后 EOA 账号恢复成为普通账号。调用时无须暴露私钥。
合约共享:逻辑合约可以共享,只需部署一次,便可提供给多个 EOA 账号使用。逻辑合约可永久存在链上(临时合约用完即毁)。
可以用在交易所钱包的 归集 操作上。传统的以太坊 EOA 账号进行归集操作,从用户地址发送到归集地址,只能一笔一笔进行归集,并且需要交易所下发一笔小额资金作为归集 gas 费用。效率十分低下且存在粉尘资金增多、额外消耗 gas 的问题。而采用 EIP-7702 的新交易类型,可以在共用 EOA 账号的同时,平滑升级到支持批量归集、gas 代付的能力。
签名授权
EOA 账号在签名时候,签订一个授权信息,内容包括 链 ID、nonce、委托地址、EIP-712 的签名。这个授权信息供验证者节点打包交易时,从委托地址中查出运行代码,然后附加到 EOA 账号中。

临时代码注入
节点收到 EOA 账号发送的交易后,验证 EOA 账号的签名,从链上读取委托合约的 bytecode 然后临时注入到 EOA 账号的地址上。
自动代码卸载
在交易执行完后,该地址又会变回普通 EOA 地址,EXTCODEHASH(address) == 0x0。代码区会变回 0。且状态不会存储到链上,确保不存在污染。
git clone https://github.com/quiknode-labs/qn-guide-examples.git
cd qn-guide-examples/ethereum/eip-7702
forge 库和 OZ 代码库
forge install foundry-rs/forge-std
forge install OpenZeppelin/openzeppelin-contracts3. **启动 anvil**
注意,在未完全升级之前,必须携带`--hardfork prague` 参数,否则无法执行。
```js
anvil --hardfork prague
❯ forge script script/BatchCallAndSponsor.s.sol \
--rpc-url http://127.0.0.1:8545 \
--broadcast \
--tc BatchCallAndSponsorScript -vvvv
观察到以下结果,代码部署成功。



EIP-7702 的原始转账情况,用户 A 通过离线签名,将交易发送到以太坊 RPC 节点,在通过对用户 A 的签名认证之后,可以将交易广播到以太坊网络。此时,交易只能一笔一笔的发送,且无 gas 代付能力。
EIP-7702 后,交易流程发生了变化。首先,我们来看一个总的执行图。后面再回去根据代码分析。
在这个执行图中(A 代指 Alice,B 代指 Bob),EOA 账户 Alice 离线发起委托签名,签名时,将委托的逻辑合约包含在其中,发送给以太坊 RPC 节点。

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

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

此外,由于发送给 RPC 节点时 from 地址为 Alice,to 地址也为 Alice。在此过程中,Alice 为合约账户,属于合约内部交易,所以这条记录不会被记录在以太坊的交易记录中。
Bob 的两笔交易(ETH 和 ERC20 代币)都通过 B.call()的方式进行发送到以太坊网络中。(from 地址为 Alice,to 地址为 Bob,from 地址属于合约地址,to 地址属于 EOA 地址,属合约内部交易,故也不存在交易记录中)
performSponsoredExecution() gas 代付
gas 代付的情况相对于普通批量转账的场景而言,稍微复杂与一点。可以分为以下几步:



RPC 节点对 Bob 进行验签,通过后读取 Alice 委托的逻辑合约代码,注入到 Alice 的地址中。然后广播交易。此时,用户 Alice 从一个 EOA 账户升级成为一个临时合约账户(合约的地址和用户 Alice 的地址一致),可以执行合约的逻辑(批量转账等)
gas 代付的方案中,交易的发起者是 Bob,所以 RPC 节点在进行验签的时候,只会验证 Bob 的签名,Alice 的签名并不会去处理。在合约中,没办法像上面批量交易那样使用 require(msg.sender == address(this)) 故我们临时合约中还需要去验证 Alice 的签名,以防止伪造交易的情况出现。
RPC 节点时,发送者 from 为 Bob,接受者 to 地址为 Alice,Bob 是一个 EOA 账户,Alice 为一个合约账户,故这笔交易记录会被记录上。
Alice 合约内部,发生了从 Alice 转账给 Tom(也可以是 Bob) 的情况,Alice 属于合约地址,Tom(Bob) 属EOA 地址,属合约内部交易,故这笔记录也不会存在以太坊的交易记录中。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!