A Congress DAO with separate voting and proposing rights, deployed by Alex Van de Sande on 29 January 2016.
Historical Significance
The source is the tutorial revision of 28 December 2015 with four changes, every one of them forced by the deployed bytecode: the owner renamed to administrator, the second permission flag added to the member record and to changeMembership, the proposal guard reading that new flag while the voting guard keeps reading the old one, and the quorum test tightened from less than or equal to strictly less than. Compiled with v0.1.7+commit.b4e666cc with the optimizer on, it reproduces all 5489 bytes of the deployment transaction exactly, constructor arguments included.
Context
Deployed on 29 January 2016, a month after the DAO tutorial page went up and about two weeks before the run of Congress and token deployments this account made on 11 February 2016. The two permission flags and the administrator naming are both steps toward the later version, which replaced the plain canVote flag with a numeric vote weight.
Key Facts
Description
Congress is the voting organisation from the ethereum.org DAO tutorial. This deployment splits membership into two permissions rather than one: each member record carries a canVote flag and a canAddProposals flag, and the two are enforced separately. Putting up a proposal requires canAddProposals, voting on one requires canVote, and the owner sets both when adding or updating a member. The owner is called the administrator here rather than the owner. A proposal names a recipient, an amount of ether and a payload; once the debating period has run out anyone can call executeProposal, which requires that the vote count reached the quorum and that the margin favours the proposal before sending the ether and running the payload. It was configured with a quorum of one, a debating period of five minutes and a majority margin of zero.
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 owned {
address public administrator;
function owned() {
administrator = msg.sender;
}
modifier onlyOwner {
if (msg.sender != administrator) throw;
_
}
function transferOwnership(address newOwner) onlyOwner {
administrator = newOwner;
}
}
contract Congress is owned {
/* Contract Variables and events */
uint public minimumQuorum;
uint public debatingPeriodInMinutes;
int public majorityMargin;
Proposal[] public proposals;
uint public numProposals;
mapping (address => uint) public memberId;
Member[] public members;
event ProposalAdded(uint proposalID, address recipient, uint amount, string description);
event Voted(uint proposalID, bool position, address voter, string justification);
event ProposalTallied(uint proposalID, int result, uint quorum, bool active);
event MembershipChanged(address member, bool isMember);
event ChangeOfRules(uint minimumQuorum, uint debatingPeriodInMinutes, int majorityMargin);
struct Proposal {
address recipient;
uint amount;
string description;
uint votingDeadline;
bool executed;
bool proposalPassed;
uint numberOfVotes;
int currentResult;
bytes32 proposalHash;
Vote[] votes;
mapping (address => bool) voted;
}
struct Member {
address member;
bool canVote;
bool canAddProposals;
string name;
uint memberSince;
}
struct Vote {
bool inSupport;
address voter;
string justification;
}
/* modifier that allows only shareholders to vote and create new proposals */
modifier onlyMembers {
if (memberId[msg.sender] == 0
|| !members[memberId[msg.sender]].canVote)
throw;
_
}
/* First time setup */
function Congress(uint minimumQuorumForProposals, uint minutesForDebate, int marginOfVotesForMajority, address congressLeader) {
minimumQuorum = minimumQuorumForProposals;
debatingPeriodInMinutes = minutesForDebate;
majorityMargin = marginOfVotesForMajority;
members.length++;
members[0] = Member({member: 0, canVote: false, canAddProposals: false, memberSince: now, name: ''});
if (congressLeader != 0) administrator = congressLeader;
}
/*make member*/
function changeMembership(address targetMember, bool canVote, bool canAddProposals, string memberName) onlyOwner {
uint id;
if (memberId[targetMember] == 0) {
memberId[targetMember] = members.length;
id = members.length++;
members[id] = Member({member: targetMember, canVote: canVote, canAddProposals: canAddProposals, memberSince: now, name: memberName});
} else {
id = memberId[targetMember];
Member m = members[id];
m.canVote = canVote;
}
MembershipChanged(targetMember, canVote);
}
/*change rules*/
function changeVotingRules(uint minimumQuorumForProposals, uint minutesForDebate, int marginOfVotesForMajority) onlyOwner {
minimumQuorum = minimumQuorumForProposals;
debatingPeriodInMinutes = minutesForDebate;
majorityMargin = marginOfVotesForMajority;
ChangeOfRules(minimumQuorum, debatingPeriodInMinutes, majorityMargin);
}
/* Function to create a new proposal */
function newProposal(address beneficiary, uint etherAmount, string JobDescription, bytes transactionBytecode) returns (uint proposalID) {
if (memberId[msg.sender] == 0 || !members[memberId[msg.sender]].canAddProposals) throw;
proposalID = proposals.length++;
Proposal p = proposals[proposalID];
p.recipient = beneficiary;
p.amount = etherAmount;
p.description = JobDescription;
p.proposalHash = sha3(beneficiary, etherAmount, transactionBytecode);
p.votingDeadline = now + debatingPeriodInMinutes * 1 minutes;
p.executed = false;
p.proposalPassed = false;
p.numberOfVotes = 0;
ProposalAdded(proposalID, beneficiary, etherAmount, JobDescription);
numProposals = proposalID+1;
}
/* function to check if a proposal code matches */
function checkProposalCode(uint proposalNumber, address beneficiary, uint etherAmount, bytes transactionBytecode) constant returns (bool codeChecksOut) {
Proposal p = proposals[proposalNumber];
return p.proposalHash == sha3(beneficiary, etherAmount, transactionBytecode);
}
function vote(uint proposalNumber, bool supportsProposal, string justificationText) onlyMembers returns (uint voteID){
Proposal p = proposals[proposalNumber]; // Get the proposal
if (p.voted[msg.sender] == true) throw; // If has already voted, cancel
p.voted[msg.sender] = true; // Set this voter as having voted
p.numberOfVotes++; // Increase the number of votes
if (supportsProposal) { // If they support the proposal
p.currentResult++; // Increase score
} else { // If they don't
p.currentResult--; // Decrease the score
}
// Create a log of this event
Voted(proposalNumber, supportsProposal, msg.sender, justificationText);
}
function executeProposal(uint proposalNumber, bytes transactionBytecode) returns (int result) {
Proposal p = proposals[proposalNumber];
/* Check if the proposal can be executed */
if (now < p.votingDeadline // has the voting deadline arrived?
|| p.executed // has it been already executed?
|| p.proposalHash != sha3(p.recipient, p.amount, transactionBytecode) // Does the transaction code match the proposal?
|| p.numberOfVotes < minimumQuorum) // has minimum quorum?
throw;
/* execute result */
if (p.currentResult > majorityMargin) {
/* If difference between support and opposition is larger than margin */
p.recipient.call.value(p.amount*1000000000000000000)(transactionBytecode);
p.executed = true;
p.proposalPassed = true;
} else {
p.executed = true;
p.proposalPassed = false;
}
// Fire Events
ProposalTallied(proposalNumber, p.currentResult, p.numberOfVotes, p.proposalPassed);
}
}External Links
Related contracts
Association (Mist D.A.O.)
Same deployerA token-weighted governance contract deployed by Avsa on Dec 3, 2015, using MistCoin as voting shares. 0.1 ETH remains locked after 10 years.
0x8d554c...d9b8dcDecember 3, 2015Congress
Same deployerAlex Van de Sande's Congress DAO from Dec 28, 2015: on-chain voting with member registry (mapping) and configurable quorum.
0xb3d47f...7c6c0cDecember 28, 2015Congress
Same deployerAlex Van de Sande's Congress DAO from Dec 28, 2015: on-chain voting system for proposals with configurable quorum and majority threshold.
0x7f6b46...03f101December 28, 2015Congress
Same deployerAlex Van de Sande's Congress DAO from Dec 28, 2015: on-chain voting system for proposals with configurable quorum and majority threshold.
0x1e5cbb...b7ff63December 28, 2015Congress
Same deployerA Congress DAO from the ethereum.org tutorial, deployed 28 December 2015, 23 minutes before the tutorial revision it came from was published.
0xe8e80d...4ed2daDecember 28, 2015Doge-ETH Bounty DAO
Same deployerThe Doge-Ethereum Bounty DAO created by avsa on Dec 28, 2015. Funded over 5,400 ETH in bridge development, holds 50,000 MistCoin. Active 2015-2021.
0xdbf03b...c8c6fbDecember 28, 2015