This section is a work in progress.
Writing a GSN compatible application requires the following changes/workarounds on your application:
- In your DApp's smart contract
- The smart contract is to be made capable of listening to 'collect calls'
- Meaning, it should be able to make a difference between a regular transaction and a transaction from a Relayer
- On your Client application
- Instead of talking directly to the blockchain, the client now talks to a Relayer/a network of relayers
- Calls from such clients need to be directed via a relayer
In this tutorial, we will edit the client side code and contracts to make it GSN-compatible.
We start by cloning the repository from here
Writing GSN compatible smart contract
install openzeppelin contracts package and other dependencies, we'd be needing them later,
Head over to
add the following import in your contract
Next, we'd like the contract to do something when it receives a 'collect-call' or a relayed call, for that, the GSNRecipient interface defines
acceptRelayedCall(), add the following function in your contract code
Next, we compile our contract, run the following in terminal window
Before we migrate, we'll edit our migrations file to call
initialize() function right after deployment of the contract. We do this for our contract to be aware of the RelayHub address sitting on the network
Make sure this is how your
./migrations/2_deploy_contracts.js file looks like,
To be able to deploy our contract on Matic network and not on a local blockchain, we'll edit out
truffle-config.js file in root directory to look something like this:
Notice, it requires mnemonic to be passed in for maticProvider, this is the seed phrase for the account you'd like to deploy from. Create a new
.secret file in root directory and enter your 12 word mnemonic seed phrase to get started (gas price on testnet3 can be set to 0, so you don't have to worry about funds right now)
If all goes well, you should get your GSN compatible contract address,
We have our contract deployed at
0xbFa33D565Fcb81a9CE8e7a35B61b12B04220A8EB (your address would differ, but you can play around with this address in the next steps)
Now that we have a contract that is "aware" of the RelayHub and "collect-calls", we'd like to fund it on the RelayHub.
Remember, the gas-less transactions are being paid by the DApp developer through their deposit for the smart contract on the RelayHub.
Remember to replace your ABI file!
Fund your smart contract on the RelayHub
This deposit is where the gas cost is deducted from.
You can either use the DApp tool at GSN's website,
Head over to https://gsn.openzeppelin.com/recipients, switch to testnetv3 on Metamask, enter your contract address, and fund it with sufficient amount of ETH to pay for your user's gas costs.
Or you can use a js-helper library by OpenZeppelin,
You can look at the available balance for our contract (deployed in the previous step) here: https://gsn.openzeppelin.com/recipients/0xbFa33D565Fcb81a9CE8e7a35B61b12B04220A8EB
Writing client side code for ether-less users
Head over to
./dapp-ui/plugins/utils.js, this is where all our contract calls reside.
Edit the contract address variable,
Since now we can potentially cater to users having no money at all, they won't be requiring to approve anything on metamask, which means for the user, experience would be similar to what it is on any other web application. And for you as the developer, have to change just a few lines of code, that direct user calls via a relayer.
setProvider function in your
utils.js to look something like,
Notice, we use a new instance of GSNProvider here, it is a provider that elegantly sits inside the Web3 object, to provide the developer similar function calls as that of Web3, but instead the
send() calls will now be routed via a Relayer.
Ideally, you'd want a random private key generated here, instead of a fixed private key for all your users' accounts. Read more about ephemeral keys here: https://github.com/OpenZeppelin/openzeppelin-network.js
We import the GSNProvider in our file,
Next, we change all instances of
Following is how the
utils.js now looks:
And that's it!
You can now run
and view your DApp now compatible with the web2 world 😄
Following are the addresses of the Airbnb contract and the RelayHub contract on testnetv3,
You can check our contract's balance here: https://gsn.openzeppelin.com/recipients/0xbFa33D565Fcb81a9CE8e7a35B61b12B04220A8EB
clone https://github.com/maticnetwork/ethindia-workshop.git, and checkout on branch