Stack Exploder: Implementing Costless Transactions Using Recycled Gas Tokens

Leonardo Simone Digiorgio
Sagaxyz
Published in
10 min readJan 25, 2024

Introduction

In Stack Exploder: Unblocking Web3 Products With Costless Transactions we introduced Recycled Gas Tokens, a new method for Chainlet developers to achieve costless transactions using Saga’s revolutionary token flows.

In this article, we are going to explain how to implement this flow using a faucet that dispenses an appropriate amount of tokens into the user’s wallet just-in-time (JIT).

Launch of your Chainlet with the “Gas Return Account” feature

First of all you need to launch a chainlet. Saga already provides excellent documentation and a blog post for exploration. However, I’ll briefly walk you through what I did to build my chainlet.

Where:

  1. The name of your chainlet (this case TUTORIALWORLDTWO)
  2. The denomination or simply the main currency of your chainlet (this case TWT)
  3. The Number of days of Chainlet operation that will be credited to the escrow account.
    The cost is SetupFee(10 psaga) + (num of days * 10psaga/day), so in this case 10 + ( 30 * 10 ) = 310 psaga (+ gas fee for the launch)
    IMPORTANT NOTE: it should be equal or more than 30 days
  4. The EVM address and the desired amount of full tokens ( TWT )

And then for our example we want some custom configurations for the chainlets. To enable advanced settings click on the cogs and enable advanced options:

5. Gas Return Account: The designed wallet that will collect all fees paid by users for transactions executed to interact with the Chainlet.

6. Fixed Base Gas Price: Allows the developer to specify the base gas price per unit of transaction gas (in my case 0.0000001 TWT) instead of demand-based market pricing of gas.

Note about the Fixed Base Gas Price: You can still manage how much the gas price is in your dApp. For example, my fixed gas price is 0.0000001 TWT, but if I wanted, I could create a subscription model where:

  • if the users are NOT subscribed, they paid, for example 0.1 TWT as gas fee
  • if the users are subscribed, they paid the base fixed fee, which is 0.0000001 TWT

And keep in mind that the gas fees will be returned to the designated wallet, in this case, the specified developer’s wallet.

After this just click “Launch Chainlet” and approve the transaction to create your Chainlet.

If everything is done correctly, you will see that the Saga Web App brings you to this screen.

Now you have all needed for your dApp, you can check this article if you need guidance about “Connecting your own chain to a block explorer and Metamask” and “Connecting your own chain into your personal projects

The project

The project is just a simple Address Book project built using:

And of course Saga, using my chainlet created in the section above. We are first going to deploy a simple example without Recycled Gas Tokens; then add the components afterwards.

Feel free to fork my GitHub and go to the saga_v2 branch and follow along with the article for a concise and a better understanding guide.

If you want to see the recycled token economic flow in action directly, feel free to navigate to the live demo.

⚠️ Note: At the time this article was written, an old version of the chainlet was used. The GitHub repository and live demo now use the latest version of chainlets (with a chainlet under a different name, Omegachain). However, don’t worry because the procedure described in this article remains the same.

The smart contract

There is nothing special about this contract, it allows one to save a list of Ethereum account addresses to the blockchain with an alias name. However it also implemented the ability to be able to add multiple contacts with only a single transaction that saves gas fees (if you want details about Multicall you can check this article).

Deploy the Smart Contract in your chainlet

For this project I am going to use Foundry. However, if you choose to use Hardhat or Remix, you can refer to this article.

To deploy the AddressBook smart contract using Foundry, you need your smart contract in the folder src/AddressBook.sol (src/your_contract.sol). Then try compiling your contract to make sure everything is in order.

forge build

If your output looks like this, the contracts are successfully compiled.

And you should be able to get your ABI in out/AddressBook.sol/AddressBook.json (out/Your_Contract.sol/your_contract.json)

Next, in the folder script I created a file in it called AddressBook.s.sol. This is where we will create the deployment script itself.

Where you have to import your smart contract from the src folder, and then add new AddressBook() between the vm.startBroadcast() and vm.stopBroadcast() inside the run function.

Lastly, before deploy you need to export your private key from Metamask and the use this command in your terminal:

export PRIVATE_KEY=<your_private_key>

Then to deploy run the command:

forge script script/AddressBook.s.sol:AddressBookScript — rpc-url https://tutorialworldtwo-2705143118829000-1.jsonrpc.testnet-sp1.sagarpc.io — private-key $PRIVATE_KEY — broadcast

If done correctly you should have

And have the contract address in the folder broadcast/AddressBook.s.sol/2705143118829000 (which remember that 2705143118829000 is the chain id of the chainlet)

Connecting my chainlet into the front end project

To configure your dApp, set up the following configuration in your _app.tsx file (if you’re using Next.js) or main.tsx file (if you’re using Vite, as in this case). Ensure that all functions are called outside the App component.

But, most importantly, if you want to use your chain in your dApp, you need to apply this configuration.

In the end you should have your file _app.tsx or main.tsx like this:

If everything is configured correctly, you should be able to connect your wallet to the dApp and see that your dApp network is your chainlet.

The front-end of the Address Book project

We’ll begin with the addContacts transaction which if you remember correctly in the smart contract is:

The AddContacts function simply allows the user to save an Ethereum address with an alias name.

To be able to use addContact and execute this write function on the AddressBook contract, we utilize the Wagmi hooks: usePrepareContractWrite and useContractWrite.

From a UI point of view, the interaction should look like this.

But you may notice that a user checking your dApp doesn’t have any of your tokens, including for paying gas fees.

Indeed every operation on the smart contract, even on a chainlet with the lowest gas fees, requires a minimum balance. If a user has a balance of 0, they cannot execute any operations, even if the operation costs as little as 0.000000000001 TWT.

There are two solution for this:

  • Create a website faucet for the user. However, it could be inconvenient for the user to navigate back and forth.
  • Create a recycled token economic flow using Saga’s revolutionary token flows and implement an auto faucet on your dApp.

The second option is more interesting and we will show how to improve the example to implement Recycled Gas Tokens.

A visual representation of the recycled token economic flow

Let’s see conceptually how the recycled token economic flow will look visually. I want to focus on these two wallets.

The Developer wallet was specified as the tutorialworldtwo chainlet’s designated wallet, which consequently collects all fees paid by users (including the User wallet in this case) for transactions executed to interact with the chainlet.

The User wallet is the one we are using in this visual representation. Note that this wallet doesn’t have any TWT tokens.

Note: To have a greater visual representation of the recycle, I have increased the gas price of the write function call ‘addContact’ from the base gas fee price of 0.0000001 TWT to 0.00005 TWT (but on the live demo is the base gas fee which is 0.0000001 TWT).

Now let’s finally dive into the visual representation of the front end.

After the User wallet fills the address input with an Ethereum address, provides a name of his choice, and clicks on ‘Add Contact’, we want it to begin with borrowing TWT from the Developer wallet to the User wallet.

After the first part, this should be the status of the wallets.

In the second part, the User just needs to sign for the actual intended transaction.

Lastly, there is the third and final part, which involves the execution of the addContact write call and the confirmation of the block.

As you can see, the total cost of the transaction should be 4.48555 TWT (total gas = gas price * gas usage == 0.00005 * 89711).

After the confirmation of the block, this should be the status of the wallets.

You can see that the 4.48555 TWT came back to the developer, thanks to the recycled token mechanism.

The intended flow is to implement the flow discussed in Stack Exploder: Unblocking Web3 Products With Costless Transactions

The code implementation

To transfer the token from the Developer to the User, first, you need to obtain your private key (to get your private key follow this guide from Metamask).

⚠️ Note: Please ensure that you keep your private key hidden from anyone by adding it to the .env file and including the .env file in your .gitignore.

If you are a beginner check this guide: How to Avoid Uploading Your Private Key to GitHub and use your dev/test wallet for your projects NOT your main one.

This is where the auto faucet mostly operates:

(1) Instantiate a Private Key Account (Developer) using privateKeyToAccount and create a Wallet Client which provides the ability to execute transactions, sign messages, etc through Wallet Actions.

(2) Create a sendGasToken function that sends the TWT token (or the token of your choice in your chainlet) using the client.sendTransaction() method.
In the function, I specified the Developer wallet (accountDev) as the sender account and the User Wallet (utilizing the useAccount Wagmi hook) as the recipient (address).
Lastly, I set the value, representing the amount of gas needed for the transaction (See the code below for a better understanding).
Then using the client.waitForTransactionReceipt method, we wait for confirmation of at least 1 block, ensuring that the User Wallet receives the TWT token.

const hash = await client.sendTransaction({
account: <Developer_Wallet>,
to: <User_Wallet>,
value: parseEther((<estimate_contract_gas_fee> * <chainlet_gas_price>).toString()),
ty});

[Fast-speaking medical warning]

The amount of gas needed for your smart contract transactions can vary significantly from one contract to another. To ensure a smooth and error-free transaction, it is crucial that you consult with your trusted smart contract professional.

Be advised, Sagaxyz will not assume responsibility for any miscalculations or errors made by the developer. Your financial safety is of the utmost importance. Act responsibly and seek professional advice for your smart contract needs.

After this, you can proceed with your regular write function call, in this case, using the ‘addContact’ method.
(The code is simplified for a better understanding of the implementation, excluding variables, hooks, and functions that may lead to confusion. For more details, you can check here)

Conclusion

Congratulations! You have successfully integrated a new economic model into your dApp, leveraging the transformative capabilities of the Saga Revolutionizes Token Flows to compete effectively with other dApps.

For more details around how you can evolve your dApp, follow us on X, join our Discord and Telegram and subscribe to our Medium.

--

--

Leonardo Simone Digiorgio
Sagaxyz
Editor for

Web3 Software Engineer | Wagmi | Ethers | React.js | Next.js | Smart Contracts | Solidity | Ethereum | I help build the future of the internet.