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-contracts
3. **启动 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 地址,属合约内部交易,故这笔记录也不会存在以太坊的交易记录中。如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!