How DApp users can interact with your Smart Contracts with ZERO ETH
Your blockchain users shouldn’t have to pay for your infrastructure if you want mainstream adoption.
The problem is well known. In order to perform a transfer transaction or interact with a specific application smart contract, you need to pay the infrastructure cost (gas) in Ether. No user, especially new to the blockchain ecosystem, is going to be willing to do so. There is a reason why FREEMIUM model is so widely implemented in the current Web2 stack. Taste before you buy.
In this article, you will learn how to pay transactions on behalf of your users by implementing a new Ethereum concept called GSN into your DApp in 5 steps.
Gas Station Network
GSN is a concept designed and developed by a cyber security firm TabooKey. TabooKey submitted an official EIP-1613 design draft in December 2018.
Complicated?
No worries. The concept was later adopted and enhanced by established Ethereum auditing company OpenZeppelin (OZ) who developed a friendly set of JS helper tools to ease the GSN usage.
STEP 0: Choose your Ethereum-compatible blockchain network
I will demonstrate the usage on Lightstream’s PoA Ethereum compatible blockchain powered by Tendermint consensus.
Why?
- Addressing gas issues is just part of the solution. Mainstream apps need to be responsive. Ethereum’s 15s blocks without a guarantee a TX won’t be reverted is unfortunately insufficient for any user facing, interactive DApp. Lightstreams provides instant finality in 3s blocks.
- Already deployed RelayHub and active RelayServer means you don’t have to worry about half of the previously visualised complicated GSN diagram and can ONLY FOCUS on your app business-case.
STEP 1: Take YOUR existing Smart Contract
E.g, given you, have a simple Voter.sol
smart contract and your users can either up-vote or down-vote some arbitrary value.
contract Voter {
uint256 public count;
event Voted(uint256 newCount, address account);
function upVote() public {
address lastVoter = _msgSender();
count++;
emit Voted(count, lastVoter);
}
function downVote() public {
address lastVoter = _msgSender();
count--;
emit Voted(count, lastVoter);
}
}
STEP 2: Inherit the Gas Free feature
Inherit GSN.sol to convert your traditional SC to a GSN compatible one. The GSN.sol
is extending the official OpenZeppelin, TabooKey contracts.
npm i --save lightstreams-js-sdk
import "@lightstreams-js-sdk/contracts/utils/GSN.sol";
contract Voter is GSN {
STEP 3: Register the Voter.sol SC in a global RelayHub
Deploy the Voter.sol
and call the initialize
method. As RELAY_HUB
argument specify “0xECf278654f73000F9cB3b05858158AC49c29ed68”.
This is a official RelayHub deployed on Lightstream’s Sirius test network.
voter.initialize(RELAY_HUB)
STEP 4: Pay for your users transactions
The users transactions will be free but the voting application still has to pay for it. This is done by pre-funding the SC you want to be gas-free in RelayHub.
Install OZ GSN Helpers:
"@openzeppelin/gsn-helpers": "0.1.9",
Import the fundRecipient
method:
const { fundRecipient } = require('@openzeppelin/gsn-helpers');
Fund the Voter.sol
with as many PHTs you are willing to pay for your users transactions gas costs:
await fundRecipient(web3, {
recipient: voter.address,
relayHubAddress: RELAY_HUB,
amount: web3.utils.toWei("10", "ether"),
from: YOUR_PHT_ACCOUNT
});
STEP 5: Let users perform FREE transactions
In order to do this, you will need a special Web3 lib decorated with HTTP Relay functionality. Why? Because the users gas-free transactions will be now submitted to previously mentioned HTTP Relayer Server https://gsn.sirius.lightstreams.io/getaddr and decorated before they are broadcasted to blockchain.
Require the Lightstream’s adjusted OZ Network library:
const { fromConnection } = require('@lightstreams-js-sdk/node_modules/openzeppelin/network');
Create a new GSN powered Web3 object:
gsnCtx = await fromConnection(
web3.eth.currentProvider.host, {
gsn: {
dev: false,
signKey: emptyAcc.privateKey
}
});web3 = gsnCtx.lib;
Execute the gas-free TX!
const voterGSN = await new gsnCtx.lib.eth.Contract(voter.abi, voter.address);
const tx = await voterGSN.methods.upVote().send({
from: emptyAcc.address,
gasPrice: gasPrice,
gasLimit: "1000000",
});
Full source code available HERE:
I have a few more questions, who can I ask and where?
First of all, thank you for your interest! Drop a comment below or DM me on LinkedIn and I will be happy to support your GSN integration.
Conclusion
Blockchain mainstream adoption is around the corner if you combine the right technologies together.
Visit Lightstreams docs to start developing mainstream, responsive applications today.
https://docs.lightstreams.network
PS: Special thanks to OpenZeppelin team (Andrew, Nicolas, Igor and Marti) for supporting us in the GSN integration!