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.