Second layer scaling with EIP-712

Ivo Zieliński
Indorse
Published in
3 min readDec 12, 2018

--

Usability, Security and Transparency!

For the last couple of months, we have implemented our claim voting feature using a 1st layer solution: in order to vote, users needed to make a transaction via MetaMask or otherwise. There are several disadvantages to that approach:

  • Users need to bear the GAS costs
  • There is a learning curve to using MetaMask and understanding transaction parameters
  • The encoded smart contract call data is meaningless for the user
  • Validators require Ether to start voting
  • Tracking user transactions is challenging and required us to handle multiple edge cases
  • Ethereum congestion slows down the voting progress

Our voting smart contract basically is a data store for recording user votes, which are then processed by our hybrid service to assign rewards.

In particular, we needed:

1. A user signature tying a user address to a vote
2. A claim signature tying an Indorse address to a claim

EIP-712

The EIP-712 standard is a great step forward and actually brought us exactly what we needed — a simplified and more transparent process of signing messages. Not only is the signed message human-readable, but also voters no longer need to pay anything for voting!

The signature generated with MetaMask can be verified using a call to the verifying contract at :

pragma solidity ^0.4.24;

contract VoteSignatureVerifier {

uint256 public constant chainId = 1;
bytes32 public constant salt = 0x9567bfc1ad28e9dac18d12e131b4a45f5d9a3c6cbfe69ff8b34b0fb47703faa0;

string public constant EIP712_DOMAIN = "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)";
string public constant VOTE_TYPE = "Vote(string claim_id,string decision,uint256 timestamp,string version,string skill)";
string public constant DAPP_NAME = "Indorse";
string public constant VERSION = "1";

bytes32 public constant EIP712_DOMAIN_TYPEHASH = keccak256(abi.encodePacked(EIP712_DOMAIN));
bytes32 public constant VOTE_TYPEHASH = keccak256(abi.encodePacked(VOTE_TYPE));

bytes32 public DOMAIN_SEPARATOR;

constructor() public {
DOMAIN_SEPARATOR = keccak256(abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(DAPP_NAME),
keccak256(VERSION),
chainId,
this,
salt
));
}

function verify(string claim_id, string decision, uint256 timestamp,
string version, string skill, uint8 sigV, bytes32 sigR, bytes32 sigS) public view returns (address) {
bytes32 voteHash = keccak256(abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(
VOTE_TYPEHASH,
keccak256(claim_id),
keccak256(decision),
timestamp,
keccak256(version),
keccak256(skill)
))
));

return ecrecover(voteHash, sigV, sigR, sigS);
}
}

Contract is deployed on mainnet. The verify method returns the address that was used to sign the vote payload.

The generate signature is sent to our backend, which verifies it using the smart contract. All the subsequent claim/vote retrieval requests return the signatures, which can be verified on the frontend using the said smart contract.

All the daily signatures from claims and votes are bundled together in a Merkle tree, of which the root is published on an Ethereum mainnet smart contract. In this way, the integrity of the user’s submitted votes and claims can be guaranteed. The data that is being signed effectively serves as our own protocol. Anyone can download all the votes and signatures, process them sequentially, verify the signatures, and compute the actual state of the Indorse system.

Switching from transactions to EIP-712 signatures led to a significant simplification of our codebase and a much more streamlined user experience! The feedback from our users and Validators arrived quasi-instantly. To mention a few:

“Voting process was smooth as butter, I didn’t notice any hiccups. Near instant too.”

“Especially in blockchain, and even more so in Ethereum. Almost nothing is as smooth as the whole IND experience, only thing that competes is BAT […].”

“Absolutely incredible, cost nothing to validate the claim and seeing the object I am signing in MetaMask almost made me cry. Great job Indorse team!”

About Indorse

If you’re a fellow programmer, feel free to create your profile on the Indorse platform and have your code evaluated by expert programmers, for free. On Indorse, it all starts with a claim!

  • Interested in becoming a Validator? Then wait no more and send a “Hello” to Dipesh!
  • Considering using Indorse to filter your candidates? We got you covered with here.

--

--