Blockchain
Ethereum
solidity
ERC1202


ERCとは

Ethereum Request for Comment, ERC for short, is a memo describing methods, behaviors, research, or innovations that can be used on the Ethereum ecosystem. It is written by Ethereum developers. After developing the memo, the developer submits an Ethereum Improvement Proposal (EIP). After core developers and community approves it, the proposal becomes a standard.

For more information about ERC, please visit these links:

https://medium.com/wepower/erc-standards-to-move-ethereum-forward-erc-20-erc-223-erc-721-e1712456449d

https://medium.freecodecamp.org/lets-talk-about-the-ethereum-token-standards-you-need-to-know-8af9fcb7e54b

You also visit this link to see a list of ERC memos:

https://eips.ethereum.org/erc


ERC1202とは

ERC1202 is a memo for Voting Standards. This standard aims to create an API for implementing voting within a Smart Contract. It provides functionalities to voting as well as to view the vote result and set voting status. The authors of ERC1202 are Zainan Victor Zhou, Evan, and Yin Xu.


開発者の動機

Voting is one of the earliest example of Ethereum Virtual Machine (EVM) programming, and also a key to decentralized autonomous organization (DAO) or organizational governance process. The developers foresee many DAOs will ultimately need to leverage voting as one of the most important part of their governance.


ERC1202のメリット

By creating a voting standard for smart contract / token, the users can have the following benefits:


  1. Allow general UI and applications to be built on top of a standardized voting to allow more general user to participate, and encourage more DApp and DAO to think about their governance.

  2. Allow delegate voting / smart contract voting, automatic voting.

  3. Allow voting results to be recorded on-chain, in a standard way, and allow DAOs and DApps to honor the voting result programmatically.

  4. Allow the compatibility with token standard such as ERC-20 or other new standards(EIP-777) and item standard such as ERC-721.

  5. Create massive potential for interoperability within Ethereum echo systems and other system.

  6. Allow setting voting deadline, allow determine on single or multiple options. Allow requiring voting orders. (trade-off is interface complexity, we might need ERC-20 approach and later a EIP-777 for advanced voting).

  7. Recording the voting with weights with token amount.

  8. Possibly allow trust-worthy privacy-safe voting and anonymous voting (with either voter address being not associated with the vote they cast, given a list of randomized/obfuscated voting options).

  9. Possibly allow result in reward by voting participation or voting result.


使用事例

These are the use-cases for ERC1202.


  1. Determine on issuing new token, issuing more token or issuing sub-token

  2. Determine on creating new item under ERC721

  3. Determine on election on certain person or smart contract to be delegated leader for project or subproject

  4. Determine on auditing result ownership allowing migration of smart contract proxy address


ERC1202のコード

ERC1202 is still a draft and is still currently in development. The developers only provides simple example codes. We will study one of the examples here.


function vote(uint option) public

The main function that casts the user's vote. In this example, there are only 2 candidates, '1' and '2'. The function checks if the user votes a candidate from the list. It also checks if the user have already voted.

function vote(uint option) public returns (bool success) {

require(option == 1 || option == 2, "Vote option has to be either 1 or 2.");
require(ballotOf_[msg.sender] == 0, "The sender has casted ballots."); // no re-vote
ballotOf_[msg.sender] = option;
voteCounts[option] = voteCounts[option] + 1; // TODO(xinbenlv): use SafeMath in a real implementation
emit OnVote(msg.sender, option);
return true;
}


function ballotOf(address addr) public

This function returns the ballot of a user.

function ballotOf(address addr) public view returns (uint option) {

return ballotOf_[addr];
}


function getStatus() public

This function returns the status, if the voting is already done or not. In this example, there is no time limit so the status is always true.

function getStatus() public pure returns (bool isOpen) {

return true; // always open
}


function weightedVoteCountsOf(uint option) public

This function returns the number of votes of a candidate.

function weightedVoteCountsOf(uint option) public view returns (uint count) {

return voteCounts[option];
}


function winningOption() public

This function returns the winner of the election.

function winningOption() public view returns (uint option) {

if (voteCounts[1] >= voteCounts[2]) {
return 1; // in a tie, 1 wins
} else {
return 2;
}
}


function issueDescription() public

This function returns the description of the election.

function issueDescription() public pure returns (string desc) {

return "Should we make John Smith our CEO?";
}


function availableOptions() public

This function returns the candidates name/identifier.

function availableOptions() public view returns (uint[] options_) {

return options;
}


function optionDescription(uint option) public

This function returns the description of a certain candidate.

function optionDescription(uint option) public view returns (string desc) {

return optionDescMap[option];
}


全体コード


SimplestVote1202.sol

pragma solidity ^0.4.22;

/**
A simplest vote interface.
(1) single issue
(2) only 1 or 2 as the vote option
(3) no voting time limit
(4) each address can only vote once.
(5) each address has the same weight.
Deployed on [Etherscan:Ropsten](https://ropsten.etherscan.io/address/0xec27791163cd27229d4d54ee69faf5a70058d90b#code)
*/

contract SimplestVote1202 {
uint[] options = [1, 2];
mapping(uint => string) internal optionDescMap;
mapping (uint => uint) private voteCounts;
mapping (address => uint) private ballotOf_;

constructor() public {
optionDescMap[1] = "Yes";
optionDescMap[2] = "No";
}

function vote(uint option) public returns (bool success) {
require(option == 1 || option == 2, "Vote option has to be either 1 or 2.");
require(ballotOf_[msg.sender] == 0, "The sender has casted ballots."); // no re-vote
ballotOf_[msg.sender] = option;
voteCounts[option] = voteCounts[option] + 1; // TODO(xinbenlv): use SafeMath in a real implementation
emit OnVote(msg.sender, option);
return true;
}

function setStatus(bool /* isOpen */) public pure returns (bool success) {
require(false); // always public status change in this implementation
return false;
}

function ballotOf(address addr) public view returns (uint option) {
return ballotOf_[addr];
}

function weightOf(address /* addr */) public pure returns (uint weight) {
return 1;
}

function getStatus() public pure returns (bool isOpen) {
return true; // always open
}

function weightedVoteCountsOf(uint option) public view returns (uint count) {
return voteCounts[option];
}

function winningOption() public view returns (uint option) {
if (voteCounts[1] >= voteCounts[2]) {
return 1; // in a tie, 1 wins
} else {
return 2;
}
}

function issueDescription() public pure returns (string desc) {
return "Should we make John Smith our CEO?";
}

function availableOptions() public view returns (uint[] options_) {
return options;
}

function optionDescription(uint option) public view returns (string desc) {
return optionDescMap[option];
}

event OnVote(address indexed _from, uint _value);
event OnStatusChange(bool newIsOpen);
}


ソース:

https://github.com/xinbenlv/eip-1202-draft/blob/master/EIP-1202.md

https://eips.ethereum.org/EIPS/eip-1202