[Part One] Second Layer Solutions: A journey into Meta Transactions, Counterfactual Instantiation and P2P networks

Taking an idea, making it your own and running away with it

TL;DR

We started working on Universal Ids suggested by Alex Van de Sande. We strayed of the smart contract standard and changed the guidelines to optimise for UX. Also created a full p2p second layer network of relayer nodes. Made the network Sybil attack proof by instantiating contracts counterfactually — upon meaningful action.

About this article

This is the first part of three-part article series about our second layer solution of sending meta transaction through relayer network. This part is about smart contracts. Look forward to the next parts.

Word of Caution

This article outlines just one approach towards Meta Transactions. I know at least dozen more teams working on the same problem, drawing different conclusions due to coming from a different context. We actually have a Telegram group discussing it together.

The tech solutions below are based on our (the team of LimeChain) understanding and our feeling on what is important and what is not. Feel free to disagree and crucify us in the comments, but please make sure you’ve thought hard about what we did — we thought hard too.

You can see the source code here.

Dozens of teams working on MetaTx. Photo credit: Pet3rpan

How it all began — Universal Identities

At the moment of this writing, I’ve been developing on the Ethereum blockchain for a year and a half. At Limechain we’ve been blessed to be able to work on various different projects and we’ve faced a multitude of different problems.

Optimising for low dapp gas usage is one of them. One particularly potent solution is the now very popular ecrecover solidity function. Ever since I learned how to use it, I knew it would be a game changer. I could see it used everywhere.

Another problem is the low adoption rate of dapps due to the inherent complexity of the blockchains — wallets, ethers, tokens, signing. If it is complicated to me as a tech person, I can feel the excruciating pain of the not tech-savvy users we are trying to onboard.

It wasn’t until I went to a conference in Berlin — DappCon — that I made the connection between the two. It was a speech given by Alex Van de Sande(AVSA) on the topic of Universal Id/Universal Login.

Universal Identities

To put the concept simply, it means that you have a smart contract that is representing yourself in front of the blockchain world — your Identity Contract. Instead of you signing transactions with your own wallet, thus requiring you to have ether and/or tokens, you are signing “intent messages”. These messages are “relayed” to your Identity Contract, through a special Relayer, and upon successful validation (via ecrecover obviously) the contract acts on your behalf. Ultimately you’ve not paid a single wei, as the Relayer has paid the gas cost for the transaction.

Obviously, the Relayer needs to be reimbursed, but that is a matter we will get into later.

Meta Transactions

The latest name I’ve heard about that kind of “relayed transactions” is Meta Transactions. It’s been popularised by Austin Griffith and he’s done an amazing job. I love this name, as it shows that these transactions can be used for much more than just universal identity. Going forward I will refer to these transactions as Meta Transactions or MetaTx.

Building the Universal Identity

I loved the concept presented by AVSA, but there was still a thing bugging me — how does the user create such an identity and who assumes the costs? It later became apparent that this question is the main difference point between all the different implementations. My immediate solution to the problem and one that I am still sticking to is to instantiate counterfactually — more to that in the upcoming part 2. Let’s dive into the smart contracts.

The Universal Identity Smart Contract

Source code: https://github.com/LimeChain/IdentityProxy/blob/master/contracts/

The initial suggestion to create the universal identity smart contract was to use ERC725 and ERC735 by Fabian Vogelsteller. Albeit very well written as a standard we’ve opted not to use it. Here is why.

ERC20 and User Experience

ERC20 is the defacto standard for creating tokens. It’s awesome and it works. It’s also very very tough on the UX. We’ve learned it, the hard way - from our clients (we do blockchain development services — ping me if you need help with your dapp).

I’ve lost count of how many times I’ve heard cries of desperation once I’ve explained that one should perform two transactions for a single action — approve and transferFrom. To this date, there is no better solution without an inherent security issue, so ERC20 stands tall despite all that.

ERC725 proposes a similar thing — two-phase intent submission. You first submit your intent and receive an execution id. Then you have to sign and approve the execution with that id. Similar thing — two transactions = cries of desperation.

I know and understand why two transactions are needed. Still, we opted for a different nonce-based solution.

The nonce!

Making it work, without killing the UX

Our identity smart contract has an execute function:

The meat of the Identity Smart Contract

You pass the contract you wish to interact with, the data you wish to send, the wei value you wish to transfer and signature of the keccak256 of the previous 3 params + a nonce.

The nonce, as usual, is a number that is incremented after each successful execution of the transaction. The nonce adds security against replay attacks without sacrificing UX.

As the dapp, you fetch the most recent nonce, add the params, hash and sign it all. If you are truthful your transaction will go through. If you dear cheat — cryptography will take care of you.

Note: This function will be changed when we add the relayer to the game

Deployment gas costs

Once we started playing around with the contract, we saw that it starts to get out of hand in terms of the deployment cost for such contract. In order to make it as thin as possible, we’ve called upon an old friend of ours — the delegatecall .

The concept was made famous by Gnosis with their Gnosis Safe. It’s basically deploying a single “Master copy” smart contract and deploying a proxy smart contract for every user.

The proxy smart contract is very thin and contains just a constructor and fallback function, that delegates the execution of the actual action to the Master copy smart contract. Our deployment was down to a couple of hundred thousand gas.

Now what?

All is good in the smart contract world, but how does one send transactions to this smart contract if you do not posses ether in your wallet. This is where the Relayer comes into play.

The Relayer

Read about the relayer in the upcoming Part Two

Decentralising the Relayer

Read about decentralizing the relayer in the upcoming Part Three