1/5
## Unpacking the zkSync TxType 113 Account Abstraction Lifecycle Welcome to a detailed exploration of the zkSync TxType 113 (also known as 0x71) transaction lifecycle. This specific transaction type is exclusively designed for enabling account abstraction on the zkSync network. Understanding this flow is crucial for developers building and interacting with smart contract accounts on zkSync. The entire lifecycle, from user initiation to final execution, is meticulously defined and can be broadly categorized into two primary phases: Validation and Execution. The `ZkMinimalAccount.sol` contract itself provides a concise summary: ```solidity /** * Lifecycle of a type 113 (0x71) transaction * * Phase 1 Validation * 1. The user sends the transaction to the "zkSync API client" (sort of a "light node") * 2. The zkSync API client checks to see the nonce is unique by querying the NonceHolder system contract * 3. The zkSync API client calls validateTransaction, which MUST update the nonce * 4. The zkSync API client checks the nonce is updated * 5. The zkSync API client calls payForTransaction, or prepareForPaymaster & * validateAndPayForPaymasterTransaction * 6. The zkSync API client verifies that the bootloader gets paid * * Phase 2 Execution * 7. The zkSync API client passes the validated transaction to the main node / sequencer (as of today, they are * the same) * 8. The main node calls executeTransaction * 9. If a paymaster was used, the postTransaction is called */ ``` Let's delve into each phase and its constituent steps. ## Phase 1: The Validation Gauntlet for TxType 113 Transactions The validation phase is a critical series of checks performed by the zkSync network to ensure the transaction is legitimate and the account is prepared for execution before it reaches the sequencer. 1. **User Initiates Transaction to API Client:** The journey begins when a user sends their TxType 113 transaction to a "zkSync API client." This client can be thought of as a light node, serving as the initial entry point into the zkSync network. 2. **Nonce Uniqueness Check via `NonceHolder`:** The zkSync API client immediately verifies the uniqueness of the transaction's nonce. This is paramount for preventing replay attacks. The check involves querying the `NonceHolder` system contract. The `NonceHolder.sol` contract (typically found at `lib/foundry-era-contracts/src/system-contracts/contracts/NonceHolder.sol`) is a foundational system contract responsible for managing nonces for all accounts, including smart contract accounts, on zkSync. It utilizes mappings to track the nonce for every contract. A key data structure within `NonceHolder.sol` is: ```solidity // RawNonces for accounts are stored in format // /// minNonce + 2^128 * deploymentNonce, where deploymentNonce // /// is the nonce used for deploying smart contracts. mapping(uint256 account => uint256 packedMinAndDeploymentNonce) internal rawNonces; ``` This mapping allows the API client to efficiently retrieve the current nonce for the sending account and ensure the submitted transaction's nonce is correct and has not been used before. 3. **Invoking `validateTransaction` on the Account Contract:** Next, the zkSync API client calls the `validateTransaction` function directly on the user's smart contract account. This function is a cornerstone of zkSync's account abstraction model. A crucial requirement is that **this `validateTransaction` call MUST update the account's nonce**. This is a state-changing operation that signals the nonce has been consumed for this specific transaction validation. An example from `ZkMinimalAccount.sol` shows the function signature: ```solidity contract ZkMinimalAccount is IAccount { // ... function validateTransaction( bytes32 _txHash, bytes32 _suggestedSignedHash, Transaction memory _transaction ) external payable returns (bytes4 magic) { // ... logic to validate signature, permissions, and update nonce ... } // ... } ``` If `validateTransaction` executes successfully (e.g., signature is valid, permissions are met, and nonce is updated) and returns the expected `bytes4 magic` value, zkSync nodes consider the transaction valid up to this point. Otherwise, it's rejected. 4. **The Bootloader as `msg.sender` during Validation:** A critical question arises: who is the `msg.sender` when `validateTransaction` is invoked? Since it's a state-changing call (updating the nonce), the caller identity matters significantly for security and contract logic. For a TxType 113 transaction, the `msg.sender` during the `validateTransaction` call (and other system-initiated calls within this AA flow) is always the **Bootloader system contract**. The Bootloader is a "super admin" system contract, analogous to the EntryPoint contract (ERC-4337) on Ethereum mainnet. It plays a fundamental role in orchestrating zkSync's native account abstraction, acting as the trusted intermediary that calls into the account contract for validation and execution steps. You can find more details in the official zkSync documentation (e.g., `docs.zksync.io/zk-stack/components/zksync-evm/bootloader.html`). 5. **Confirmation of Nonce Update:** After the `validateTransaction` call returns, the zkSync API client performs a secondary check to confirm that the account's nonce has indeed been incremented as expected. If the nonce wasn't updated by the `validateTransaction` implementation, the transaction will be reverted at this stage. 6. **Handling Transaction Payment:** The API client then proceeds to handle the payment logic for the transaction. This can involve: * Directly calling `payForTransaction` on the account if the account pays for itself. * If a paymaster is utilized, the flow involves calls to `prepareForPaymaster` and subsequently `validateAndPayForPaymasterTransaction`. These functions allow a third-party (the paymaster) to sponsor the transaction fees. 7. **Verification of Bootloader Compensation:** Finally, the zkSync API client verifies that the Bootloader contract has been adequately compensated for its role in processing the transaction. The Bootloader incurs costs for orchestrating these steps, and it needs to have a sufficient balance to cover them, similar to how an ERC-4337 EntryPoint contract might be pre-funded or reimbursed. Once all these validation steps are successfully completed, Phase 1 concludes. ## Phase 2: Executing the Validated TxType 113 Transaction With the transaction thoroughly validated, it moves to the execution phase, which is primarily handled by the main zkSync node or sequencer. 8. **Validated Transaction Relayed to Main Node/Sequencer:** The zkSync API client (light node) forwards the now-validated transaction to the main zkSync node, which also currently serves as the sequencer. It's worth noting that efforts are ongoing within the zkSync ecosystem to decentralize the sequencer role. This separation of concerns—validation by API clients and execution by the main node/sequencer—is a strategic design choice. It helps protect the main sequencer from potential Denial of Service (DoS) attacks by offloading the initial, potentially resource-intensive, validation checks. 9. **Invoking `executeTransaction` on the Account Contract:** The main node (sequencer) takes the validated transaction and calls the `executeTransaction` function on the user's smart contract account. The `executeTransaction` function in `ZkMinimalAccount.sol` typically has a signature like this: ```solidity function executeTransaction( bytes32 _txHash, bytes32 _suggestedSignedHash, Transaction memory _transaction ) external payable { // ... logic for actual transaction execution (e.g., token transfer, contract call) ... } ``` This function contains the actual logic the user intended to perform (e.g., transferring tokens, interacting with another DeFi protocol). This is analogous to the `execute` or `executeBatch` functions in an ERC-4337 `MinimalAccount.sol`. For robust security, the `executeTransaction` function, when part of this native TxType 113 account abstraction flow, should be implemented to ensure it can **only be called by the Bootloader contract**. This prevents unauthorized external calls from bypassing the established validation and fee payment mechanisms. 10. **Post-Transaction Logic (Paymaster Involvement):** If a paymaster was used to sponsor the transaction fees, a `postTransaction` function is invoked. This function allows the paymaster to perform any necessary cleanup, reconciliation, or finalization logic after the main transaction execution is complete. This sequence—from validation by the API client to execution by the sequencer via the Bootloader—constitutes the complete lifecycle for a standard TxType 113 account abstraction transaction on zkSync. ## Beyond the Standard Flow: `executeTransactionFromOutside` The `ZkMinimalAccount.sol` contract, and similar account implementations, may also feature another function: `executeTransactionFromOutside`. ```solidity function executeTransactionFromOutside(Transaction memory _transaction) external payable { // ... logic to process transactions initiated by any EOA or contract ... } ``` This function is distinct from the `executeTransaction` function discussed earlier, which is specifically called by the Bootloader within the native account abstraction (TxType 113) flow. `executeTransactionFromOutside` is designed to be callable by *any external actor*, such as an Externally Owned Account (EOA) or another smart contract interacting directly with the smart contract wallet. Even when a transaction is initiated through this external pathway, if the account intends for it to be processed with account abstraction features (like custom validation logic), the underlying mechanisms within the account contract would still need to engage its validation logic (e.g., checking signatures, permissions). The exact flow might differ from the strict TxType 113 protocol but would leverage the account's inherent capabilities. ## Key Pillars of zkSync's Native Account Abstraction The TxType 113 lifecycle highlights several core components and concepts fundamental to zkSync's native account abstraction: * **TxType 113 (0x71):** This is zkSync's designated transaction type for enabling sophisticated account abstraction features natively at the protocol level. * **System Contracts are Central:** * **`NonceHolder`:** A global system contract that meticulously manages nonces for all accounts, ensuring transaction order and preventing replays. Its role in the initial validation step is critical. * **`Bootloader`:** This powerful system contract is the orchestrator of the account abstraction flow. It acts as the `msg.sender` for crucial calls like `validateTransaction` and `executeTransaction` on the smart contract account. The Bootloader must also be compensated for the gas costs it incurs. Its function is comparable to the `EntryPoint` contract in Ethereum's ERC-4337 standard. * **Mandatory Nonce Update in Validation:** A strict requirement of the `validateTransaction` function is that it *must* update the account's nonce. This is a key part of the stateful validation process. * **`msg.sender` Context Awareness:** Understanding that the `Bootloader` is the `msg.sender` during system-initiated AA calls is vital for developers writing secure account contracts. Access controls within `validateTransaction` and `executeTransaction` often rely on verifying the caller is indeed the Bootloader. * **Modular Account Interface (`IAccount`):** Functions such as `validateTransaction`, `payForTransaction`, and `executeTransaction` represent distinct, modular steps defined by zkSync's `IAccount` interface, allowing for flexible and custom implementations by smart contract account developers. * **Security Through Restricted Access:** Implementing robust security measures, such as restricting `executeTransaction` to be callable only by the Bootloader during the AA flow, is essential to maintain the integrity of the account abstraction system. By understanding these phases, system contracts, and design principles, developers can effectively leverage the power of native account abstraction on zkSync to build next-generation smart contract wallets and applications.
A clarifying exploration to Unpacking the zkSync TxType 113 Account Abstraction Lifecycle - Discover the two-phase (Validation and Execution) process for native account abstraction (TxType 113) on zkSync. You'll understand the vital roles of the Bootloader, `NonceHolder`, and the key `IAccount` methods `validateTransaction` and `executeTransaction`.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Course Overview
About the course
Advanced smart contract development
How to develop a stablecoin
How to develop a DeFi protocol
How to develop a DAO
Advanced smart contracts testing
Fuzz testing
Manual verification
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Security researcher
$49,999 - $120,000 (avg. salary)
Guest lecturers:
Juliette Chevalier
Lead Developer relations at Aragon
Nader Dabit
Director of developer relations at EigenLayer
Ally Haire
Developer relations at Protocol Labs
Harrison
Founder at GasliteGG
Last updated on May 12, 2025
Solidity Developer
Advanced FoundryDuration: 36min
Duration: 3h 06min
Duration: 5h 02min
Duration: 6h 02min
Duration: 2h 47min
Duration: 1h 23min
Duration: 4h 28min
Duration: 1h 19min
Duration: 1h 10min
Course Overview
About the course
Advanced smart contract development
How to develop a stablecoin
How to develop a DeFi protocol
How to develop a DAO
Advanced smart contracts testing
Fuzz testing
Manual verification
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Security researcher
$49,999 - $120,000 (avg. salary)
Guest lecturers:
Juliette Chevalier
Lead Developer relations at Aragon
Nader Dabit
Director of developer relations at EigenLayer
Ally Haire
Developer relations at Protocol Labs
Harrison
Founder at GasliteGG
Last updated on May 12, 2025