EIP-4337 for Off-Chain Verification Signature Supported by Zero-Knowledge Proof

11 min readAug 9, 2023


With the EIP-4337 account abstraction contract deployed to the Ethereum mainnet, in the not-too-distant future, the AA (Account Abstraction) contract will gradually become a very important activity carrier among Ethereum ecological users in the future. AA will be deployed in the Ethereum network in the form of smart contracts, and its operational flexibility will be greatly enhanced. Compared with EOA account, it can bring users:

  • Flexible Signature Verification
  • Gas Abstration
  • Session Keys
  • Social Recovery
  • Multi-factor authentication

While the AA account brings convenience to the user, it will increase the user’s use cost. The cost here is mainly in the gas fee. The main reason is that the logic increase of the AA contract brings a relatively large gas cost.

Gas comparative analysis

In the account abstraction contract of EIP-4337, transaction signature verification, nonce value and gas fee calculation and deduction logic are all in the aggregation process , resulting in consuming more Gas than normal transaction execution.

In an ERC20 transfer initiated by an EOA address, the verification of the signature and nonce update is verified by the rpc node and submitted to the chain protocol for final chaining. The main composition of gas is the basic gas of 21000 and the operation of ERC20 contract transfer The gas consumed, we use the OpenZeppelin template to create ERC20 tokens, the gas is 34330.

If the transfer is initiated by the AA account, signature verification (using solidity recovery), nonce update verification, and gas fee payment will all occur on the chain, and the gas will become 57135.

If we are not using Ethereum’s ecdsa signature, but a non-EVM built-in signature algorithm such as BLS, the gas will become an astonishing 148123!

We designed a bundler service based on the zk environment architecture to handle:

  • Verification of the correctness of the signature of the user Tx,
  • Merkle world state tree, used to maintain the nonce value and Gas balance of the AA account.

Merkle Root was finally updated to the EntryPoint contract of the Ethereum mainnet. By aggregating multiple Tx transactions and sharing zkp verification gas equally, the threshold for using AA accounts was lowered, while retaining the flexibility of AA accounts in L1 transactions. An ordinary ERC20 The transfer can save 30% of Gas in the end. In our experimental environment, the average gas obtained after aggregating 128 Tx is 23843.

Final Goal

  • Reduce the cost for users to use AA accounts
  • AA account contract, the interface of Bundler is compatible with EIP4337
  • Decentralization of Bundler nodes, protection of user Tx privacy, anti-MEV


We can see from the above figure that in the original architecture of 4337, Bundler is responsible for collecting the Tx list of aggregated AA accounts. We will not explain some preset checking logic here. After bundler submits the aggregated Tx list to the EP contract , the EP contract will perform signature verification on the aggregated Tx list, and the nonce value of the AA account will be updated.

Merkle world state tree

We designed a merkle world state tree to maintain the nonce value and gas balance of each AA account. Before each batch of Tx execution in the ZK circuit, the last Tx gas of the AA account is deducted, but this The deduction behavior occurs off-chain, and the gas balance on the AA account chain will eventually be consistent with the balance of the zk environment.

At the same time, we impose a monotonically increasing constraint on the nonce of each transaction of each account to prevent double-spending security issues. The Merkle world state tree is as follows:

The Value of each leaf node is a hash, and the hash calculation process is as follows:

The path calculation of each account in MPT is as follows:

In the end, we converted it into a binary bit string and used it as the path on our final MPT, so that the processing in the zk circuit will be more efficient and friendly.[1]

AA Account Life Cycle

The process is as shown in the figure below:

After the bundler receives the batch of AA Txs, we will process the gas balance of the account in three steps, in order to solve the timeliness of the synchronization of the user’s fee balance between the PayMaster contract on the chain and the mpt off the chain question.


When the user recharges the service fee to PayMaster, the PayMaster contract will retain a hash as a certificate.

Then the user sends the tx of the deposit to the bundler, and the bundler will verify the correctness of the above hash process in zk, then update the balance of the MPT corresponding to the user, and use the hash as a public output as VerifyTicketList, and EntryPoint will verify these hashes , and mark and delete the corresponding ticket. If the verification fails, the recharge will be invalid and the transaction will be rolled back (note that the attack scenario will not be easily constructed here, because the bundler will perform a quick off-chain check before receiving the tx. If the abnormal tx will be directly rejected, the bundler will suffer losses if it accepts such abnormal tx).


The process for users to withdraw service fees from PayMaster is similar to that of DepositTicket.

When a user makes a Deposit to PayMaster, there will be a minimum value. We initially set it to 0.005ETH, which is used to prevent the node from being attacked by DoS to a certain extent.


The specific cost of each Tx in the Tx list of the previous batch needs to be aggregated and hashed to obtain.

This hash will be recorded in the PayMaster contract during the execution of the last BatchTx. In the zk circuit, the hash here will be calculated and verified, and used as the public output part of zkp, and then according to the gas information here. Each account is deducted separately, and the latest gas balance of each account is updated. When EntryPoint receives the message, it will verify the hash and delete it.

This will lead to a delay of one block in the settlement of each TxGas fee, that is, the mode of execution first and payment later, the reasons are as follows:

  • If you pay first, there is no guarantee that the bundler will package Tx on the chain after payment
  • The protocol cannot accurately pre-calculate the final Gas consumed by tx
  • The pre-calculated Gas must be greater than the actual Gas, which is easier to achieve


During the execution of the circuit, we will perform a summary hash on the Txs list, and use the hash value as a public output, so as to bind the association between zkp and the final Txs to be executed. After the zkp verification is completed, the EntryPoint contract needs to Txs repeats the calculation of the summary hash and verifies the correctness of the hash. After the verification is passed, Txs can be executed.

The calculation method of the summary hash is as follows:

It is relatively easy to overflow during the addition process. By right-shifting the uint256 type data by 10 bits to get uint246, it can be guaranteed that the addition of tx numbers < 1024 will not overflow. Although the security of keccak256 is weakened, it is still very safe. within the range.

MPTRoot Update

We need to perform a merkle verification on OldMPTRoot in the circuit.

After the previous zkp verification link, we get the latest nonce and gasBlance of each account after executing Txs, and calculate NewMPTRoot in the circuit. Finally, OldMPTRoot and NewMPTRoot will also be used as the public output of the circuit. EntryPoint is affected by these two When creating a Root, first verify whether the OldMPTRoot is consistent with the MPTRoot saved by yourself, and then replace it with NewMPTRoot, thus completing a world state conversion.

Bundler prepaid Gas fee final settlement

The gas fee for each Tx executed by the user is actually temporarily replaced by the bundler’s operating node, and the settlement of the Gas fee for each Tx can be updated in mpt in real time (delay of one block) , but the bundler eventually needs to recover the previously paid gas payment.

Bundler needs to perform the process of withdrawing and paying Gas fees from the withdrawal interface provided by PayMaster.

The interface is as follows:

function withdrawPrePayGas(
zkProof: bytes,
pubIns: uint256[2],
withdrawAddress: address

The bundler needs to run to generate a zk Proof, which is used to calculate and prove each leaf node of the current MPT root, that is, a root obtained after calculating the status of all users, and add the sum of the user’s balance in the circuit a total quota.
When zkp is verified and verified that the root of zkp is equal to the mpt root of the EP contract, the withdrawn amount is:

Self Custody

We follow the principle of “Your Keys Your Coins”. Every Tx initiated by the AA account must be verified by the signature algorithm, that is, the user’s assets are always controlled by the user’s private key.
EntryPoint and bundler have no right to directly manipulate the assets of the AA account, and we will add a feature to EntryPoint.

  • When the bundler is out of operation for a long time, the AA account can initiate an appeal process to prove to EntryPoint that the bundler has stopped operating. At this time, the AA account can withdraw its gas balance from PayMaster and convert the AA account into a normal contract account without relying on EntryPoint / Bundler can initiate transactions by itself.

ZKP architecture selection

We rely heavily on the zkp technology stack to optimize the gas consumption of the AA account. Therefore, the performance of the ZKP service plays a vital role in the experience of using the entire service.

There is an indicator that needs attention:

  • gas verified by zkp on the chain
  • Generation time of proof data

Comparing ZK-Stark and ZK-Snark

ZK-Stark benefits from FRI’s polynomial merkle proof technology in terms of the proof generation speed of zkp recursive proofs. It has relatively high performance and can ensure that the complexity of proof generation and the complexity of circuit constraints are Log(n) relationship (rather than a linear relationship). However, when the conventional ZK-Snark algorithm realizes the proof of ZKP in the circuit, the size of the verification circuit will expand to 100 times due to the problem of Wrong-field[2], resulting in a very fast generation of proof for the recursive circuit.

ZK-Stark also has its disadvantages, that is, the verification gas cost on its chain is too high, the verification of each stark is about 5M, and the verification of snark is about 300k, so we will integrate the advantages and disadvantages of stark and snark respectively, Our zk hybrid algorithm architecture design idea is similar to Prover[3] of Ploygon’s ZKEVM, but our technology stack will be different from them. We use the Halo2 framework as the framework of the ZK-Snark algorithm, Cairo-1.0 As a framework for the ZK-Stark algorithm.

Tx is submitted in different segments on the timeline. After each submission, the Tx will be verified in real time and ZKP of Snark will be generated. After sorting the batches of Tx, each Tx and its corresponding ZKP will be sorted. Perform recursive verification, generate Stark’s ZKP after verification, and finally we put it in the Snark circuit and then verify it with snark, and finally get a snark’s ZKP, so that we can ensure that Tx can be proved in real time and the final ZKP on the chain The verification cost is controlled at around 300K.

How to be compatible with the RPC interface of the current wallet

At present, there is no blockchain wallet compatible with the 4337 bundler RPC standard. We have designed a solution that is compatible with the RPC interface of ordinary wallets. As a transitional state, users can use the functions of AA accounts through ordinary wallets. The design scheme is as follows , it can be compatible with the Tx structure of the Ethereum RPC node, and then converted into the Tx structure of the bundler RPC format, but in our ZK circuit, additional data type proofs need to be added.

"hash": "",
"nonce": "",
"blockHash": "",
"blockNumber": "",
"transactionIndex": "",
"from": "",
"to": "",
"value": "",
"gasPrice": "",
"gas": "",
"input": "",
"v": "",
"r": "",
"s": "",
"type": "",
"accessList": [],
"maxPriorityFeePerGas": "",
"maxFeePerGas": "",
"chainId": ""

The UserOperation of the AA account will be encoded into the input field, and the ZK circuit will perform constraint verification on the signature.

Based on the above zk circuit constraints, we can ensure that the structural data in userOperaton is indeed signed by the user through the private key.

In the Dapp layer of the AA account, there needs to be a corresponding SDK to assemble the data structure of UserOperation and contract interaction, and encapsulate it into callData, and then send the transaction to the bundler RPC interface eth_sendRawTransaction in the usual way of the wallet.

After bundler RPC receives the request data, it will disassemble the data, parse the input data into the corresponding UserOperation structure, and finally forward it to eth_sendUserOperation.

In this way, the current wallet can allow users to use account abstraction functions at almost zero cost, just switch the corresponding RPC service!

Decentralization & Privacy

We are designing a decentralized economic model that allows any user to run the future zkProver node and participate in the incentive task of binding Tx of the 4337 AA account.

In zkProver’s Tx Mempool, the order of each batch of tx is ranked by the gas fee paid by the user from high to low. We put this mechanism in the zk circuit for constraints.

By sharing the memory pool, build a decentralized anti-MEV, anti-DDoS 4337 bundler service, this part is still in the research state.


We are very concerned about the future ecological development of account abstraction, and are committed to creating a product that is convenient for users to use on the Ethereum ecological network, and will eventually achieve ease of use, fairness, decentralization, and user privacy protection, becoming an Ethereum ecological important part of the infrastructure.

stage 1

  • Reduce the cost of using AA accounts
  • Guarantee the effectiveness of Tx submission on the chain

stage 2

Study TxMempool’s privacy encryption technology

  • Protect the privacy of the Tx of the AA account, and the sorting mechanism of the tx Mempool is executed according to a trusted mechanism

stage 3

  • Completely decentralized, users can deploy their own nodes as bundlers to participate in the packaging Tx process and get incentives on the chain

Our Project Engineering Code

  • zkProver:


  • Account Abstract Wallet Contract:


  • zkProver:



  1. https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751/3 ↩︎
  2. https://github.com/daira/halographs/blob/master/deepdive.pdf : Accumulation schemes Section ↩︎
  3. https://docs.hermez.io/zkEVM/zkProver/Overview/zkProver-Overview




Orbiter Finance is a decentralized cross-rollup Layer 2 bridge with a contract only on the destination side.