Paymaster

Implement a paymaster flow into your project.

Welcome to the final part of our ZKsync 101 series on mastering ZKsync development! In this guide, we move beyond the basics of smart contract deployment and the creation of contract factories to explore the innovative concept of paymasters in the ZKsync ecosystem. This guide will illuminate the power of paymasters to revolutionize transaction fee management and enhance user experiences within your dApps.

Delve deeper into ZKsync development with the introduction of paymasters.

Learn how paymasters can cover transaction fees for your dApp users, enhancing accessibility and user experience.

Discover the flexibility of fee payment with paymasters, including the ability to pay fees in ERC20 tokens on ZKsync Era.

What is a Paymaster?

Paymasters in the ZKsync ecosystem represent a groundbreaking approach to handling transaction fees. They are special accounts designed to subsidize transaction costs for other accounts, potentially making certain transactions free for end-users. This feature is particularly useful for dApp developers looking to improve their platform's accessibility and user experience by covering transaction fees on behalf of their users.

Built-in Paymaster Flows

Paymasters can operate under various flows, some of which may require user interaction, such as setting allowances for token swaps. These flows enable paymasters to support a wide range of use cases, from simple fee subsidies to more complex scenarios involving ERC20 token exchanges for transaction fees.

  • General Paymaster Flow: This default flow requires no preliminary actions from users, allowing paymasters to interpret transaction data as needed to cover fees.
  • Approval-Based Paymaster Flow: For operations requiring user permissions, such as token allowances, this flow provides a structured approach. It ensures that user tokens can be seamlessly exchanged for transaction fees, subject to user-approved limits.

As we explore paymasters, remember that while they offer enhanced flexibility for fee management, their implementation should always prioritize security and user trust.

The paymaster smart contract code is provided "as-is" without any express or implied warranties.
  • Users are solely responsible for ensuring that their design, implementation, and use of the paymaster smart contract software complies with all applicable laws, including but not limited to money transmission, anti-money laundering (AML), and payment processing regulations.
  • The developers and publishers of this software disclaim any liability for any legal issues that may arise from its use.

Paymaster flow

Select the paymaster type you want to use.

Understanding the GaslessPaymaster contract

Let's start by reviewing the contracts/4-paymaster/gasless/GaslessPaymaster.sol contract:

Key components:

  • The GaslessPaymaster contract ensures that transaction fees are handled automatically without user intervention.
  • validateAndPayForPaymasterTransaction Method: This mandatory method assesses whether the paymaster agrees to cover the transaction fees. If affirmative, it transfers the necessary funds (calculated as tx.gasprice * tx.gasLimit) to the operator. It returns a context for the postTransaction method.
  • postTransaction Method: An optional method invoked post-transaction execution, provided the transaction doesn't fail due to out-of-gas errors. It receives several parameters, including the transaction's context and result, aiding in finalizing paymaster duties.
  • onlyBootloader Modifier: Ensures that certain methods are exclusively callable by the system's bootloader, adding an extra layer of security and control.

Compile and deploy the GaslessPaymaster contract

Run the npm script compile to compile the contracts:

npm
npm run compile

The script to deploy the GaslessPaymaster is located at `/deploy/4-paymaster/gasless/deploy.ts.

Key Components:

  • deployContract Method: Utilized for deploying the GaslessPaymaster contract. This method takes the name of the contract and any constructor arguments needed for initialization, mirroring the deployment process used for the CrowdfundingCampaign contract.
  • Funding the Paymaster: An important step where the deployed GaslessPaymaster contract is funded with ETH to cover transaction fees for users. The script sends a transaction from the deployer's wallet to the paymaster contract, ensuring it has sufficient balance to operate.

Execute the deploy npm script command to upgrade:

npm
npm run deploy:gasless-paymaster

Upon successful deployment, you'll receive output detailing the deployment process, including the contract address, source, and encoded constructor arguments:

GaslessPaymaster contract deployed at <0xYOUR_PAYMASTER_ADDRESS>

Paymaster ETH balance is now 0.005

Interact with the GaslessPaymaster contract

We will interact with the GaslessPaymaster by creating a CrowdfundCampaign and have the paymaster pay for the transaction fees for your contribution.

The interaction script is situated in the /deploy/4-paymaster/gasless directory, named interact.ts.

Ensure the YOUR_PAYMASTER_ADDRESS variable is set to your deployed paymaster address.

Key Components:

  • Paymaster Parameters: Before executing transactions that involve the contract, the script prepares paymaster parameters using getPaymasterParams. This specifies the paymaster contract to be used and the type of paymaster flow, which in this case is General.
  • Transaction with Paymaster: Demonstrated by the contribute function call, the script shows how to include paymaster parameters in transactions. This allows the paymaster to cover transaction fees, providing a seamless experience for users.

Run the npm script that interacts with the gasless paymaster:

npm
npm run interact:gasless-paymaster

Upon successful usage, you'll receive output detailing the transaction:

Deploying a CrowdfundingCampaign contract...
Contributing 0.01 to the crowdfund contract...
Transaction hash: 0x1281592537c81f4d4ca259022b649dc582b186911af8f6b3612568383ea99b1b
Contribution successful!

🎉 Great job! You've successfully interacted with the CrowdfundingCampaign using a paymaster to cover the transaction fees.

Understanding the ApprovalPaymaster contract

Let's start by reviewing the contract at contracts/4-paymaster/approval/ApprovalFlowPaymaster.sol:

Key components:

  • The ApprovalFlowPaymaster contract allows for transactions costs to be covered using an allowed ERC20 token at the exchange of 1.
  • Allowed Token: Transactions are facilitated using the CROWN token that we'll deploy along with the ApprovalPaymaster contract, with a fee set at a constant value of 1.
  • validateAndPayForPaymasterTransaction Method: This critical method evaluates transactions to decide if the contract will cover the gas fees. It confirms the token used matches the allowed token and checks if the token allowance is adequate. If conditions are met, it proceeds to transfer funds calculated as tx.gasprice * tx.gasLimit to the bootloader.
  • postTransaction Method: An optional method invoked post-transaction execution, provided the transaction doesn't fail due to out-of-gas errors. It receives several parameters, including the transaction's context and result, aiding in finalizing paymaster duties.
    • onlyBootloader Modifier: Ensures that certain methods are exclusively callable by the system's bootloader, adding an extra layer of security and control.

Deploy the ApprovalFlowPaymaster and CrownToken contracts

Run the npm script compile to compile the contracts:

npm
npm run compile

The script to deploy the ApprovalFlowPaymaster contract is located at /deploy/4-paymaster/approval/deploy.ts.

The script deploys the Crown token and the ApprovalFlowPaymaster contracts. It also funds the ApprovalFlowPaymaster with "0.005" ETH to use for transaction payments.

Run the deploy script from npm using the following command:

npm
npm run deploy:approval-paymaster

On success, the console will return the addresses of the Crown token as well as the ApprovalFlowPaymaster.

CrownToken contract deployed at <0xCROWN_TOKEN_ADDRESS>
ApprovalFlowPaymaster contract deployed at <0xYOUR_PAYMASTER_ADDRESS>

Paymaster ETH balance is now 0.005

Interact with the ApprovalFlowPaymaster contract

This section will navigate you through the steps to interact with the ApprovalFlowPaymaster contract, using it to cover transaction fees for your operation.

Obtain CROWN tokens

The ApprovalFlowPaymaster requires CROWN tokens to cover transaction gas costs. To use this paymaster, you will first need to acquire CROWN tokens by minting them yourself. We will use ZKsync CLI to interact with the Crown token contract:

Run the following in your console to mint yourself Crown tokens. Replace the contract address with your Crown token contract's address. The private key is for the local rich wallet used to deploy the smart contracts.

zksync-cli contract write \
--chain in-memory-node \
--abi artifacts-zk/contracts/4-paymaster/approval/CrownToken.sol/CrownToken.json \
--contract <0xCROWN_TOKEN_ADDRESS> \
--pk 0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110

The CLI will prompt for the method, navigate with the arrow keys and press Enter on mint(address to, uint256 amount).

The next prompt will ask for an address, we will use the local rich wallet address, 0x36615Cf349d7F6344891B1e7CA7C72883F5dc049.

The final prompt will ask for the amount to mint, type in 500000000000000000.

Interact with the ApprovalFlowPaymaster contract

We will interact with the ApprovalFlowPaymaster by creating a CrowdfundCampaign and have the paymaster pay for the contribution transaction.

The interaction script is found at deploy/4-paymaster/approval/interact.ts.

Set the YOUR_PAYMASTER_ADDRESS and YOUR_TOKEN_ADDRESS variables to the addresses of your paymaster and crown token addresses.

Key Components:

  • Paymaster Parameters: Before executing transactions that involve the contract, the script prepares paymaster parameters using getPaymasterParams. This specifies the paymaster contract to be used and the type of paymaster flow, which in this case is Approval, and includes the token address of the ERC20 token, and the minimum allowance set to 1.
  • Transaction with Paymaster: Demonstrated by the contribute function call, the script shows how to include paymaster parameters in transactions. This allows the paymaster to cover transaction fees using the CROWN token, providing a seamless experience for users.

Run the npm script that interacts with the approval paymaster:

npm
npm run interact:approval-paymaster

Upon successful usage, you'll receive output detailing the transaction:

Deploying a CrowdfundingCampaign contract...
Contributing 0.0001 to the crowdfund contract...
Transaction hash: 0xf26ee884ef116b226a45b45ec689ca1f2e9367f83164959b27a960802f89e627
Contribution successful!

🎉 Great job! You've successfully interacted with the CrowdfundingCampaign using a paymaster to cover the transaction fees using the CROWN token.

Takeaways

  • Comprehensive Understanding of Paymaster Contracts: This guide has provided a detailed look at both the ApprovalFlowPaymaster and the GaslessPaymaster contracts, illustrating how they manage transaction fees in ZKsync. These paymasters are pivotal in handling gas payments, offering a more accessible transaction experience for users.
  • Flexibility and User Empowerment: By covering the transaction fees through ERC20 tokens or general subsidies, these paymaster contracts offer significant flexibility and reduce the friction typically associated with on-chain interactions. This feature enhances user engagement and adoption of dApps.

Next Steps

  • Learn more about Paymasters: Read further on our section on Paymasters to deepen your understanding.
  • Experiment with Different Paymaster Contracts: Now that you are familiar with both approval-based and general paymaster flows, you can experiment with these contracts by deploying them under various conditions and with different types validations, restrictions and enhancements.
  • Develop a Front-End Interface: Consider building a user interface with ZKsync CLI that interacts with the paymaster contracts you have deployed. This will not only improve the usability of your contracts but also provide practical insights into how end-users interact with your dApps in real-world scenarios.
  • Community Engagement and Contribution: Join the vibrant ZKsync developer community. Participate in forums, Discord, or GitHub discussions. Sharing insights, asking queries, and contributing can enrich the ecosystem and your understanding of ZKsync.

Made with ❤️ by the ZKsync Community