# ERC-4337账户抽象实践 **Published by:** [小竹爱学习](https://paragraph.com/@chengzhu/) **Published on:** 2023-03-27 **URL:** https://paragraph.com/@chengzhu/erc-4337 ## Content 目前在网上搜索ERC-4337基本只能搜到科普介绍性质的文章,缺乏动手实践指导的文章,本文希望能补上这部分的空白。 很多同学在学习ERC-4337的时候会去了解eip-4337中提到的account-abstraction项目,但其中给的单测例子用的是simulateValidation,并没有发送真正的交易,所以我参考erc-4337-examples实现了抽象账户(AA)简单的几种交易。 已在goerli测试网上实践,项目地址:https://github.com/sunchengzhu/erc-4337-examples 前置步骤(已执行) 合约部署 首先我们需要部署account-abstraction中所需的合约,EntryPoint合约不需要我们自己部署,从Infinitism的discord上可以找到最新的EntryPoint地址,其他合约需要我们自己部署。为了让合约可被核验,需要利用multisol把主合约及其依赖合约放到同级目录下,命令如下: #以VerifyingPaymaster.sol为例 cd account-abstraction multisol contracts/samples/VerifyingPaymaster.sol #执行后得到multisol-verifyingpaymaster目录 然后利用remixd让remix访问本地的multisol-verifyingpaymaster目录,在remix上连接metamask传入EntryPoint的合约地址和verifyingSigner的账户地址部署VerifyingPaymaster。 remixd -s multisol-verifyingpaymaster --remix-ide https://remix.ethereum.org VerifyingPaymaster代付gas费的交易必须由verifyingSigner签名原始UserOperation,否则验签不通过。所以我们要不掌握这个verifyingSigner直接签名原始的UserOperation,要不有个paymaster服务可以让verifyingSigner签名我们原始的UserOperation,我的方案为了简单选了前者,stackup收费的paymaster api则是后者。 合约核验 Compiler Type选择Solidity (Multi-Part files),上传multisol-verifyingpaymaster目录下所有的sol文件核验即可。 质押、充值eth 想要让paymaster可用还需要为其质押(addStake)、充值(depositTo)eth,参考verifying_paymaster.test.ts,因为我们的合约已经被核验过了,所以可以直接在etherscan上连接metamask调用这两个函数,可以通过addStake交易日志和depositTo交易日志了解调用详情,可以通过向EntryPoint的read方法deposits和getDepositInfo传入paymaster的地址查询质押和充值的余额。 合约地址 其他合约也跟VerifyingPaymaster.sol一样部署,所需的合约如下: EntryPoint VerifyingPaymaster TestToken(erc20合约,任何账户都可以通过它mint任意token) SimpleAccountFactory(SimpleAccount的工厂合约) sender(向SimpleAccountFactory中的createAccount传入signingKey对应的账户地址创建出来的一个SimpleAccount实例,即抽象账户,为UserOperation中的sender) Bundler搭建 我们需要一个bundler将UserOperations捆绑并创建一个EntryPoint.handleOps() 交易,可以使用stackup的免费bundler实例,也可以在本地搭建bundler,这边更推荐在本地搭建bundler,方便查看日志。 需要注意的是ERC4337_BUNDLER_PRIVATE_KEY对应的bundler账户必须持有足够支付gas fee的eth,ERC4337_BUNDLER_ETH_CLIENT_URL对应的节点必须支持debug_traceCall。 alchemy、infura、quicknode等主流的节点提供商都不支持debug_traceCall,而geth则需要full node才可以使用debug_traceCall,snap和light均不支持,这对本地机器资源要求较高。 所以我在chainlist上试了几个goerli的rpc server,下面这个看起来是可用的,测试命令如下: curl https://goerli.blockpi.network/v1/rpc/public \ -X POST \ -H "Content-Type: application/json" \ --data '{"method":"debug_traceCall","params":[{"from":null,"to":"0x6b175474e89094c44da98b954eedeac495271d0f","data":"0x70a082310000000000000000000000006E0d01A76C3Cf4288372a29124A26D4353EE51BE"}, "latest"],"id":1,"jsonrpc":"2.0"}' 使用命令 可以用erc-4337-examples中的配置直接跑 获取simpleAccount账户地址 yarn run simpleAccount address eth转账 yarn run simpleAccount transfer --to <address> --amount <eth> 例子: yarn run simpleAccount transfer --to 0x413978328AA912d3fc63929d356d353F6e854Ee1 --amount 0.001 erc20转账 yarn run simpleAccount erc20Transfer --token <address> --to <address> --amount <decimal> 例子: yarn run simpleAccount erc20Transfer --token 0x61a89342F52d9F31626B56b64A83579E5c368f4c --to 0x413978328AA912d3fc63929d356d353F6e854Ee1 --amount 0.1 使用paymaster 附加 --withPaymaster即可 yarn run simpleAccount:erc20Transfer --withPaymaster ... 例子: yarn run simpleAccount erc20Transfer --token 0x61a89342F52d9F31626B56b64A83579E5c368f4c --to 0x413978328AA912d3fc63929d356d353F6e854Ee1 --amount 0.1 --withPaymaster 交易分析 例子中的eth转账交易中from账户为ERC4337_BUNDLER_PRIVATE_KEY对应的bundler账户,to为EntryPoint合约,执行的函数是handleOps,0.026864612848902924 ETH从sender转到EntryPoint,EntryPoint转给目标地址0.001 ETH(命令行传入的值),EntryPoint又补给bundler账户0.015580453241024552 ETH(因为这笔交易花掉的gas费扣到了bundler账户身上)。 例子中的erc20转账交易中与eth转账交易类似,只不过EntryPoint发起的不再是eth转账而是erc20转账。 例子中的用了paymaster的erc20转账交易中只有EntryPoint补给bundler账户gas费这一笔互动,因为只需要扣paymaster存在EntryPoint里面的eth即可。 原生支持gasless交易的链推荐 如果开发者有为用户代付gas费的需求的话强烈推荐使用godwoken团队的gasless feature,可以直接处理UserOperation而不需要搭建bundler,UserOperation也能在区块链浏览器直观展示。 ## Publication Information - [小竹爱学习](https://paragraph.com/@chengzhu/): Publication homepage - [All Posts](https://paragraph.com/@chengzhu/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@chengzhu): Subscribe to updates