Delegated voting with a proposal count fixed at deployment
Context
Deployed in August 2015, three weeks after Frontier launched, and compiled with solc v0.1.1.
Key Facts
Description
The struct form of the Solidity Ballot example. Each address maps to a Voter record holding a weight, a voted flag, the chosen proposal and a delegate, and the proposals array is sized by the constructor argument. The deployer becomes chairperson, is given a weight of one, and is the only account that may call giveRightToVote. A voter either votes directly or delegates, and delegate walks the delegation chain to its end before moving the weight. winningProposal scans the tallies for the leader, but its loop advances the counter twice per iteration, once in the for header and once in the body, so it inspects only every second proposal.
Source Verified
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
contract Ballot {
struct Voter {
uint weight;
bool voted;
uint8 vote;
address delegate;
}
struct Proposal {
uint voteCount;
}
address chairperson;
mapping(address => Voter) voters;
Proposal[] proposals;
/// Create a new ballot with $(_numProposals) different proposals.
function Ballot(uint8 _numProposals) {
chairperson = msg.sender;
voters[chairperson].weight = 1;
proposals.length = _numProposals;
}
/// Give $(voter) the right to vote on this ballot.
/// May only be called by $(chairperson).
function giveRightToVote(address voter) {
if (msg.sender != chairperson || voters[voter].voted) return;
voters[voter].weight = 1;
}
/// Delegate your vote to the voter $(to).
function delegate(address to) {
Voter sender = voters[msg.sender]; // assigns reference
if (sender.voted) return;
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
to = voters[to].delegate;
if (to == msg.sender) return;
sender.voted = true;
sender.delegate = to;
Voter delegate = voters[to];
if (delegate.voted)
proposals[delegate.vote].voteCount += sender.weight;
else
delegate.weight += sender.weight;
}
/// Give a single vote to proposal $(proposal).
function vote(uint8 proposal) {
Voter sender = voters[msg.sender];
if (sender.voted || proposal >= proposals.length) return;
sender.voted = true;
sender.vote = proposal;
proposals[proposal].voteCount += sender.weight;
}
function winningProposal() constant returns (uint8 winningProposal) {
uint256 winningVoteCount = 0;
for (uint8 proposal = 0; proposal < proposals.length; proposal++) {
if (proposals[proposal].voteCount > winningVoteCount) {
winningVoteCount = proposals[proposal].voteCount;
winningProposal = proposal;
}
++proposal;
}
}
}External Links
Related contracts
globalregistrar
Same deployerA second deployment of the Ethereum GlobalRegistrar — the early name registry that predated ENS — made on August 10, 2015.
0x2272d8...18f1a9August 10, 2015Contract 0xa85146...9bbf06
Same deployergo-ethereum's built-in hash registrar, mapping a key to a content hash
0xa85146...9bbf06August 10, 2015Contract 0x87ad8f...46d9bc
Same deployergo-ethereum's built-in URL hinter, turning a content hash into a download location
0x87ad8f...46d9bcAugust 10, 2015Ballot
Same deployerDelegated voting with a proposal count fixed at deployment
0x3cf26c...b6a8e1August 18, 2015MessageStore
Same eraA 6-line contract storing a single public string, deployed Day 9 of Ethereum by a prolific early experimenter who shipped 18 contracts in one week.
0xd2eccd...ff3d6bAugust 8, 2015Ballot
Same eraDelegated voting over five proposals, with the chairperson handing out voting rights
0x640fa6...b57e8aAugust 25, 2015