Let’s build an ERC20 token that gives etherless accounts the ability to transfer() and we’ll build a relay that pays the gas. Let’s fire up a Clevis Docker container pointing to ~/native-meta-transactions to get started:

docker run -ti --rm --name clevis -p 3000:3000 -p 8545:8545 -p 9999:9999 -v ~/native-meta-transactions:/dapp austingriffith/clevis:latest

If you are unfamiliar with Clevis and Dapparatus, you might want to run through this article and/or this article.

If you would like to skip to the completed repo, it is here. To build this POC we are going to reuse a lot of code from two different #BuidlGuidl articles: #BUIDLGUIDL — 0x1: guidlcoin and #BUIDLGUIDL — 0x2: meta transactions.

Once your empty project spins up and you see the Clevis prompt, let’s create our token contract called MetaCoin:

clevis create MetaCoin

We will extend OpenZepplin’s ERC20Mintable to add a metaTransfer() function:

You can view the full contract code here. You will also need the correct dependencies.

The metaTransfer() function will perform the exact same actions as a normal transfer(), but first it will validate a signature of the hash of the parameters and ecrecover() a signature to prove the signer so everything is still cryptographically backed. Then, instead of doing actions on behalf of msg.sender, it will transfer the signer’s tokens. Finally, we can also wrap in a token reward to incentivise the relayer.

Let’s get our contract compiled and deployed to our local blockchain with:

clevis test full

Like in many previous Clevis & Dapparatus demos, you will want to make sure your MetaMask is pointed to the localhost:8545 RPC and give your account some test ETH in the metamask section of the tests/clevis.js file. Once you have that, you should get a blank dApp and have a little test ETH:

Let’s uncomment all the scaffolding code in src/App.js and make a few changes. First, let’s simplify the UI down to just showing the address of the MetaCoin contract and following the metaTransfer events:

View the full code of this commit here.

Next, we’ll steal a bunch of code from #BUIDLGUIDL — 0x1: guidlcoin that will allow us to mint coins and view token balances. Let’s start with a poll function to grab token balances and figure out if our account is a minter:

View code here.

We will need to fire off our poll() function once the <ContractLoader/> component signals that it is ready:

View code here.

Next, we’ll create some UI for minting, transferring, and viewing tokens:

View this full code here.

We’ll place these components in our main UI:

Then, just like we did in the GuidlCoin article, we’ll make sure our MetaMask user can mint tokens every time we deploy our contracts by adding an addMinter() test to tests/clevis.js:

View the full code here.

Don’t forget to run that function in tests/deploy.js:

View this code here.

Now run a full deploy:

clevis test full

And we should see that our MetaMask user can deploy MetaCoins:

At this point you should be able to mint and transfer tokens to and from accounts that have some test ETH. View the full code up to this point here.