1/5
## Understanding Native Account Abstraction on zkSync Era: A Recap This lesson revisits the fundamental concepts of native account abstraction (AA) as implemented on zkSync Era. While we've covered significant ground, the true understanding will solidify when we dive into practical coding. For now, let's reinforce the core mechanics. ## Native Account Abstraction: A zkSync Superpower Account Abstraction on zkSync Era is not an afterthought or an application-layer solution like ERC-4337 on Ethereum. Instead, it's a **native feature** deeply embedded into the protocol. This means that smart contracts can inherently function as primary accounts. This native integration unlocks powerful capabilities, allowing developers to define custom validation logic, implement diverse signature schemes beyond ECDSA, and create sophisticated rules for gas payments. ## Type 113 Transactions: The Gateway to AA The specific transaction type that enables account abstraction on zkSync is **Type 113 (0x71)**. When you want to interact with or as a smart contract account, you'll be using this transaction type. A key difference from Ethereum's ERC-4337 approach is how these transactions reach the network. On Ethereum, ERC-4337 transactions (UserOperations) are typically sent to an "alt-mempool" managed by bundlers, who then package them into standard Ethereum transactions. On zkSync Era, Type 113 transactions can be sent **directly to the standard zkSync nodes or API clients**, streamlining the process. ## The Bootloader: Orchestrating AA Transactions The **Bootloader** is a critical **system contract** within the zkSync architecture. When a user initiates a Type 113 transaction, the Bootloader contract effectively takes "ownership" of processing it. Crucially, for your custom account contract, the `msg.sender` for both the `validateTransaction` and `executeTransaction` function calls will be the address of this Bootloader system contract. Understanding this context is vital when implementing your account logic. You can learn more about its intricacies in the official zkSync documentation: `docs.zksync.io/zk-stack/components/zksync-evm/bootloader`. ## System Contracts: The Protocol's Core Engine zkSync Era utilizes several **system contracts** that operate with special privileges in what can be described as a "kernel space." These contracts are responsible for managing the core functionalities of the protocol. Besides the Bootloader, another prime example is the NonceHolder contract. Further details on these contracts can be found here: `docs.zksync.io/zk-stack/components/smart-system-contracts/system-contracts`. ## The NonceHolder Contract: Ensuring Order and Security The **NonceHolder contract** is a dedicated system contract tasked with managing and storing the nonces for all accounts on zkSync. Its role is paramount in ensuring correct transaction ordering and preventing replay attacks. Any custom account contract, including the `ZkMinimalAccount.sol` example we'll discuss, must interact with the NonceHolder system contract to validate a transaction's nonce and subsequently update it. ## The Lifecycle of a Type 113 Transaction A Type 113 transaction on zkSync undergoes a two-phase lifecycle, meticulously managed by the system. The comments within the `ZkMinimalAccount.sol` file provide an excellent overview: **Phase 1: Validation** 1. **Submission:** The user sends the Type 113 transaction to a "zkSync API client" (which acts somewhat like a light node). 2. **Nonce Check:** The API client queries the `NonceHolder` system contract to ensure the transaction's nonce is unique for the account. 3. **Account Validation:** The API client calls the `validateTransaction` function on the user's custom account contract. **This function *MUST* update the account's nonce within the `NonceHolder` system.** 4. **Nonce Verification:** The API client verifies that the nonce was indeed updated by the `validateTransaction` call. 5. **Fee Payment Setup:** The API client calls `payForTransaction` if the account is paying its own fees. If a paymaster is involved, it calls `prepareForPaymaster` on the account and then `validateAndPayForPaymasterTransaction` on the paymaster contract. 6. **Bootloader Reimbursement Check:** The API client ensures that the Bootloader, which initially fronts resources for execution, will be properly compensated. **Phase 2: Execution** 7. **Forwarding to Sequencer:** The zkSync API client, having validated the transaction, passes it to the main node/sequencer. 8. **Transaction Execution:** The main node, via the Bootloader, calls the `executeTransaction` function on the user's account contract. This is where the actual state changes intended by the transaction (e.g., token transfers, contract calls) occur. 9. **Paymaster Post-Action:** If a paymaster was used to sponsor the transaction, its `postTransaction` function is called, allowing for any necessary cleanup or post-execution logic. ## `executeTransactionFromOutside`: Enabling Meta-Transactions The `ZkMinimalAccount.sol` interface includes a function named `executeTransactionFromOutside`. This function allows an entity *other* than the Bootloader (such as an Externally Owned Account (EOA) or another smart contract) to submit a pre-signed transaction on behalf of the smart contract account. In this scenario, the `msg.sender` of the `executeTransactionFromOutside` call is the external entity submitting the transaction. Consequently, this external entity is responsible for paying the gas fees for this "meta-transaction." The account contract itself must still implement robust logic to verify the signature and nonce of the underlying, pre-signed transaction it is being asked to execute. ## Handling Gas Payments in zkSync AA Gas payment flexibility is a cornerstone of account abstraction: * **Standard Flow:** * **Self-Pay:** The account can pay its own gas fees. Logic for this is typically implemented within the `payForTransaction` function of the account contract. * **Paymaster Sponsored:** A third-party paymaster can cover the transaction fees. This is orchestrated through the `prepareForPaymaster` function on the account and corresponding functions on the paymaster contract. * **`executeTransactionFromOutside` Flow:** * As mentioned, the entity calling `executeTransactionFromOutside` (the `msg.sender` of that specific call) bears the gas cost for submitting and executing the pre-signed transaction. ## Exploring `ZkMinimalAccount.sol` The `ZkMinimalAccount.sol` contract serves as a foundational, minimal implementation of the `IAccount` interface required for custom accounts on zkSync Era. Let's briefly touch upon its key functions: ```solidity // File: src/zksync/ZkMinimalAccount.sol contract ZkMinimalAccount is IAccount { // ... (lifecycle comments as previously detailed) ... function validateTransaction( bytes32 _txHash, bytes32 _suggestedSignedHash, Transaction memory _transaction ) external payable returns (bytes4 magic) { // Core validation logic resides here. // This includes verifying signatures against the account's defined scheme // and, critically, incrementing the account's nonce by interacting // with the NonceHolder system contract. // Must return a specific magic value upon successful validation. } function executeTransaction( bytes32 _txHash, bytes32 _suggestedSignedHash, Transaction memory _transaction ) external payable { // This function contains the logic for the transaction's actual payload. // For example, making a call to another contract, transferring assets, // or any other state-changing operation the account intends to perform. } function executeTransactionFromOutside( Transaction memory _transaction ) external payable { // Enables an external EOA or contract to submit a pre-signed transaction // for this account. The caller (msg.sender of this function) pays the gas. // Internal logic must rigorously verify the signature and nonce of the // wrapped '_transaction' against the account's rules. } function payForTransaction( bytes32 _txHash, bytes32 _suggestedSignedHash, Transaction memory _transaction ) external payable { // Implements the logic for the account to pay its own transaction fees. // This might involve checking balances and transferring the required // fee amount to the Bootloader. } function prepareForPaymaster( bytes32 _txHash, bytes32 _possibleSignedHash, Transaction memory _transaction ) external payable { // Contains logic to prepare for a paymaster to sponsor the transaction. // This could involve approving the paymaster to spend tokens or // performing other checks required by the paymaster's policy. } } ``` While the `NonceHolder.sol` contract itself isn't deeply explored in this recap, its interaction with `ZkMinimalAccount.sol` (particularly within `validateTransaction`) is fundamental. ## Key Reminders and Best Practices * **Mandatory Nonce Update:** It cannot be overstated: the `validateTransaction` function in your custom account contract **MUST** update the account's nonce by correctly interacting with the `NonceHolder` system contract. Failure to do so will lead to transaction validation failure. * **Bootloader as `msg.sender`:** In the standard AA transaction flow (Type 113), remember that the `msg.sender` for calls to your account's `validateTransaction` and `executeTransaction` functions will be the Bootloader's address. Design your authorization logic accordingly. * **Embrace Native AA:** The native implementation of Account Abstraction is a powerful differentiator for zkSync Era, offering unparalleled flexibility for user experience and security enhancements. ## Future Possibilities: Advanced Account Rules This foundational understanding paves the way for more sophisticated account logic. Imagine implementing custom rules such as: * Daily or per-transaction spending thresholds. * Requiring multi-factor authentication for high-value transactions. * Using GitHub keys, passkeys, or session keys for transaction signing and authorization. These advanced use cases highlight the true potential of smart contract accounts on zkSync. As you continue your learning journey, especially with upcoming coding exercises, these core concepts of native account abstraction, system contracts, and the transaction lifecycle will be your guide.
A foundational guide to zkSync Era's Native Account Abstraction - Discover how smart contracts become primary accounts through zkSync Era's native AA and Type 113 transactions. Learn the roles of the Bootloader, NonceHolder, the transaction lifecycle, and how gas fees are managed.
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