How to Build a Gasless Dapp
This blog explores how to create a gassless dapp using Permissionless.js and ERC-4337 custom paymaster smart contract.
When we transact on a blockchain, many processes occur behind the scenes. Each of these processes comes with a cost, which we refer to as the "Gas Cost." But what is Gas?
Gas is a unit that measures the computational work required to perform transactions or execute smart contracts on a blockchain network, such as Ethereum. Gas is crucial because it regulates and prioritizes transactions within the network. Since blockchain networks have limited processing capacity, gas fees serve two key purposes:
- Incentivizing Validators or Miners: Gas fees reward validators or miners for processing and confirming transactions, ensuring the network remains secure and operational.
- Preventing system abuse: By imposing a cost on every operation, it discourages spam attacks and malicious use of computational resources, safeguarding the network from potential abuse.
Considering that gas is the "fuel" needed for a blockchain to function, the idea of a gasless dapp might seem contradictory—like trying to run a car without fuel. So, how can a blockchain operate without gas?
In reality, gas does not disappear. Instead, the responsibility for paying the gas fees shifts from the user to another party—either the service provider or the dapp itself. This approach allows users to interact with the dapp without directly incurring gas costs, enhancing user experience and accessibility.
Implementing gasless transactions with ERC-4337 and Paymasters smart contract
Typically, users are responsible for paying gas fees, which can increase the cost of their transactions based on the gas price. In a gasless dapp, however, the gas fee is covered by a third party, who signs and pays for the transaction on behalf of the user. This third party is often a relayer, though in some cases, account abstraction mechanisms are used instead.
There are two types of standards used to make a gasless dapp possible: ERC-4337 and ERC-2771. Let's take a closer look at them:
-
ERC-4337: This standard introduces account abstraction, allowing Ethereum accounts to behave like smart contracts. It enables greater flexibility in how transactions are initiated and authorized, particularly by decoupling transaction initiation from traditional Externally Owned Accounts (EOAs). This allows for more complex transaction workflows, such as bundling multiple actions into one transaction or enabling programmable wallets.
-
ERC-2771: This standard introduces a meta-transaction framework, allowing users to interact with dapps without needing ETH to pay for gas fees directly. A trusted forwarder handles the transaction on behalf of the user, and the dapp reimburses the forwarder for the gas costs. This simplifies onboarding new users who don't have ETH in their wallets but still want to interact with dapps.
In this case, we will use permissionless.js and ERC-4337 to create a custom paymaster with accounts that cover creating clients (public and Pimlico paymaster clients), setting up a smart account, and defining custom logic for the paymaster. But first, let’s understand what a paymaster is.
A paymaster is a specialized smart contract in Ethereum's account abstraction system (like ERC-4337). It acts as a sponsor for transaction gas fees, enabling users to pay in tokens other than ETH or even have the fees covered entirely. The paymaster decides whether to sponsor the gas cost based on custom logic, providing more flexibility for dapps, where the transaction cost can be handled by a third party, making the process easier for users without needing them to hold ETH.
1. First, let’s create a utils/index.ts
file where we’re going to store our code.
2. Create the public client (optional): this is the Pimlico paymaster client that will be used to interact with the SimpleSmartAccount:
import { createPublicClient, http } from "viem";
import { createPimlicoClient } from "permissionless/clients/pimlico";
import { lineaSepolia } from "viem/chains";
export const publicClient = createPublicClient({
chain: lineaSepolia,
transport: http("<https://rpc.ankr.com/eth_sepolia>"),
})
const pimlicoUrl = <https://api.pimlico.io/v2/sepolia/rpc?apikey=${apiKey}>
export const pimlicoClient = createPimlicoClient({
transport: http(pimlicoUrl),
entryPoint: {
address: entryPoint07Address,
version: "0.7",
},
})
3. Create an account: This can be any of the accounts supported by permissionless.js or custom accounts conforming to the interface. For this example, we'll use a SimpleSmartAccount
.
import { toSimpleSmartAccount } from "permissionless/accounts";
import { privateKeyToAccount } from "viem/accounts";
const simpleAccount = await toSimpleSmartAccount({
client: publicClient,
owner: privateKeyToAccount("YOUR_PRIVATE_KEY"),
entryPoint: {
address: entryPoint07Address,
version: "0.7",
}
})
4. Create the Smart Account client with custom paymaster logic: When creating the smartAccountClient
, we can pass in a sponsorUserOperation
function that will be called before a user operation is signed and sent. This function must return the paymasterAndData
, preVerificationGas
, verificationGasLimit
, and callGasLimit
fields.
import { createSmartAccountClient } from "permissionless";
import { lineaSepolia } from "viem/chains";
const smartAccountClient = createSmartAccountClient({
account,
chain: lineaSepolia,
bundlerTransport: http(pimlicoUrl),
paymaster: pimlicoClient,
userOperation: {
estimateFeesPerGas: async () => {
return (await pimlicoClient.getUserOperationGasPrice()).fast
},
}
})
5. Send a transaction: You can now send transactions as normal. The sponsorUserOperation function will be called before each transaction is signed and sent, applying the custom paymaster logic you have set.
const txHash = await smartAccountClient.sendTransaction({
to: "YOUR_CONTRACT_ADDRESS",
value: parseEther("0.1")
});
We have set up a smart account integrated with custom paymaster logic using permissionless.js and the Pimlico client. This setup allows seamless interaction with the blockchain while automating gas fees and transaction management through the paymaster. Now, it’s time for you to try this.
Security considerations for gasless dapps
1. Trusted relayers and paymasters: Since gasless dapps rely on third-party relayers or paymasters to handle transactions on behalf of users, it’s crucial to ensure that these entities are trusted and secure. A malicious or compromised relayer could alter or block transactions. Use reputable services and implement fallback mechanisms in case the relayer fails.
2. Transaction integrity: When using a relayer, the transaction might be signed by the relayer on behalf of the user. Make sure that the relayer does not alter the transaction in any malicious way before submitting it to the blockchain. Ensure the smart contract or logic verifies that the transaction details (e.g., destination address, value) match what the user intended.
3. Paymaster logic security: Since the paymaster determines whether to sponsor gas fees based on custom logic, ensure that this logic is secure and doesn’t allow unintended parties to exploit the paymaster to execute free transactions. Implement robust rules and checks to avoid abuse or unintended sponsorship of transactions.
4. Smart contract audits: Gasless dapps often involve complex smart contracts for account abstraction or meta-transactions. Regularly audit the smart contracts for security vulnerabilities, as these contracts manage transaction flow and fees. Contract vulnerabilities could lead to potential exploits where attackers manipulate transaction flows.
5. Gas price manipulation: In a gasless dapp, where a paymaster covers gas fees, attackers might attempt to manipulate gas prices to increase the costs borne by the paymaster. Include safeguards in the paymaster logic to cap gas fees and reject excessively costly operations.
6. Secure storage of private keys: When using solutions like permissionless.js or Pimlico, ensure that the private keys used to sign transactions are stored securely. Never hard-code private keys in your application, and consider using secure environments like hardware wallets or secure enclaves for key management.
Unlocking the potential of gasless dapps
Gasless dapps are an innovative way to enhance user experience on dapps by offloading gas fees to a third party. By utilizing standards like ERC-4337, developers can create more flexible and user-friendly applications that lower the barriers to entry for new users.
The provided code snippets demonstrate how to implement gasless transactions using permissionless.js, Pimlico clients, and custom paymaster logic. By following these steps, you can build dapps that simplify blockchain interaction, making it more accessible to a wider audience. Now, it’s your turn to build and explore the potential of gasless dapps!
Keep reading our latest stories
Developers, security news, and more