Context
Frontier and Homestead era deployment.
Key Facts
Description
A voting body from the AIRA contract set. Members are added and removed by an owner, each carrying a name and the block at which they joined. Proposals hold a recipient, an amount, a description and an optional bytecode payload that executes once the vote passes.
Source Verified
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Spurious Dragon Era
Continued DoS protection. State trie clearing.
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)
pragma solidity ^0.4.4;
/**
* @title Contract for object that have an owner
*/
contract Owned {
/**
* Contract owner address
*/
address public owner;
/**
* @dev Store owner on creation
*/
function Owned() { owner = msg.sender; }
/**
* @dev Delegate contract to another person
* @param _owner is another person address
*/
function delegate(address _owner) onlyOwner
{ owner = _owner; }
/**
* @dev Owner check modifier
*/
modifier onlyOwner { if (msg.sender != owner) throw; _; }
}
pragma solidity ^0.4.4;
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;
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
) {
changeVotingRules(minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority);
// It’s necessary to add an empty first member
changeMembership(0, false, ''); // and let's add the founder, to save a step later
if (congressLeader != 0)
changeMembership(congressLeader, true, 'founder');
}
/*make member*/
function changeMembership(address targetMember, bool canVote, string memberName) onlyOwner {
uint id;
if (memberId[targetMember] == 0) {
memberId[targetMember] = members.length;
id = members.length++;
members[id] = Member({member: targetMember, canVote: canVote, 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
)
onlyMembers
returns (uint proposalID)
{
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:
- Has the voting deadline arrived?
- Has it been already executed or is it being executed?
- Does the transaction code match the proposal?
- Has a minimum quorum?
*/
if (now < p.votingDeadline
|| p.executed
|| p.proposalHash != sha3(p.recipient, p.amount, transactionBytecode)
|| p.numberOfVotes < minimumQuorum)
throw;
/* execute result */
/* If difference between support and opposition is larger than margin */
if (p.currentResult > majorityMargin) {
// Avoid recursive calling
p.executed = true;
if (!p.recipient.call.value(p.amount * 1 ether)(transactionBytecode)) {
throw;
}
p.proposalPassed = true;
} else {
p.proposalPassed = false;
}
// Fire Events
ProposalTallied(proposalNumber, p.currentResult, p.numberOfVotes, p.proposalPassed);
}
function () payable {}
}
pragma solidity ^0.4.4;
library CreatorCongress {
function create(uint256 minimumQuorumForProposals, uint256 minutesForDebate, int256 marginOfVotesForMajority, address congressLeader) returns (Congress)
{ return new Congress(minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority, congressLeader); }
function version() constant returns (string)
{ return "v0.5.0 (6d589277)"; }
function abi() constant returns (string)
{ return '[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"delegate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"payable":false,"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]'; }
}
pragma solidity ^0.4.4;
/**
* @title Contract for objects that can be morder
*/
contract Mortal is Owned {
/**
* @dev Destroy contract and scrub a data
* @notice Only owner can kill me
*/
function kill() onlyOwner
{ suicide(owner); }
}
pragma solidity ^0.4.4;
/**
* @title Builder based contract
*/
contract Builder is Mortal {
/**
* @dev this event emitted for every builded contract
*/
event Builded(address indexed client, address indexed instance);
/* Addresses builded contracts at sender */
mapping(address => address[]) public getContractsOf;
/**
* @dev Get last address
* @return last address contract
*/
function getLastContract() constant returns (address) {
var sender_contracts = getContractsOf[msg.sender];
return sender_contracts[sender_contracts.length - 1];
}
/* Building beneficiary */
address public beneficiary;
/**
* @dev Set beneficiary
* @param _beneficiary is address of beneficiary
*/
function setBeneficiary(address _beneficiary) onlyOwner
{ beneficiary = _beneficiary; }
/* Building cost */
uint public buildingCostWei;
/**
* @dev Set building cost
* @param _buildingCostWei is cost
*/
function setCost(uint _buildingCostWei) onlyOwner
{ buildingCostWei = _buildingCostWei; }
/* Security check report */
string public securityCheckURI;
/**
* @dev Set security check report URI
* @param _uri is an URI to report
*/
function setSecurityCheck(string _uri) onlyOwner
{ securityCheckURI = _uri; }
}
//
// AIRA Builder for Congress contract
//
// Ethereum address:
// - Mainnet:
// - Testnet:
//
pragma solidity ^0.4.4;
/**
* @title BuilderCongress contract
*/
contract BuilderCongress is Builder {
/**
* @dev Run script creation contract
* @return address new contract
*/
function create(uint256 minimumQuorumForProposals,
uint256 minutesForDebate,
int256 marginOfVotesForMajority,
address congressLeader,
address _client) payable returns (address) {
if (buildingCostWei > 0 && beneficiary != 0) {
// Too low value
if (msg.value < buildingCostWei) throw;
// Beneficiary send
if (!beneficiary.send(buildingCostWei)) throw;
// Refund
if (msg.value > buildingCostWei) {
if (!msg.sender.send(msg.value - buildingCostWei)) throw;
}
} else {
// Refund all
if (msg.value > 0) {
if (!msg.sender.send(msg.value)) throw;
}
}
if (_client == 0)
_client = msg.sender;
var inst = CreatorCongress.create(minimumQuorumForProposals,
minutesForDebate,
marginOfVotesForMajority,
congressLeader);
if (congressLeader == 0) {
inst.changeMembership(_client, true, 'founder');
inst.delegate(_client);
} else {
inst.delegate(congressLeader);
}
getContractsOf[_client].push(inst);
Builded(_client, inst);
return inst;
}
}External Links
Related contracts
Ether test token
Same deployerWraps ether one for one, minting units on deposit and burning them on withdrawal.
0xfddfee...e21727November 18, 2016Contract 0x15b0fa...478ba1
Same deployerAn AIRA congress, produced by its builder
0x15b0fa...478ba1November 26, 2016Association
Same deployerAn AIRA association, produced by its builder
0x4ef758...02ddc0November 29, 2016Association
Same deployerAn AIRA association, produced by its builder
0xbbbe60...7a5355November 30, 2016Contract 0x24fe45...1837fc
Same eraThe public counter that sells permissioned storage deployments for a fee
0x24fe45...1837fcNovember 23, 2016Crowdsale
Same eraThe ethereum.org crowdsale tutorial: contributions run to a deadline against a goal, pay out a separate reward token, and are refunded if the goal is missed.
0xf90503...bf62efNovember 23, 2016