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.

Lukas Lukac
Sep 23 · 4 min read
Lightstreams RelayServer on Sirius Test Network

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.

src: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1613.md

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.

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.
Pre-deployed Lightstream’s RelayServer

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);
}
}

Inherit GSN.sol to convert your traditional SC to a GSN compatible one. The GSN.solis extending the official OpenZeppelin, TabooKey contracts.

npm i --save lightstreams-js-sdk
import "@lightstreams-js-sdk/contracts/utils/GSN.sol";

contract Voter is GSN {

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)

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
});

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",
});
PS: Notice the fast ~3s block time

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!

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Lukas Lukac

Written by

I teach devs how to program their first blockchain app so they can work remotely on a challenging but exciting tech. Apply for coaching: https://web3.coach

Coinmonks

Coinmonks

Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade