pragma solidity ^0.4.16; contract owned { address public owner; function owned() public { owner = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } function transferOwnership(address newOwner) onlyOwner public { owner = newOwner; } } contract tokenRecipient { event receivedEther(address sender, uint amount); event receivedTokens(address _from, uint256 _value, address _token, bytes _extraData); function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public { Token t = Token(_token); require(t.transferFrom(_from, this, _value)); emit receivedTokens(_from, _value, _token, _extraData); } function () payable public { emit receivedEther(msg.sender, msg.value); } } interface Token { function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); } contract Congress is owned, tokenRecipient { // 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 newMinimumQuorum, uint newDebatingPeriodInMinutes, int newMajorityMargin); struct Proposal { address recipient; uint amount; string description; uint minExecutionDate; bool executed; bool proposalPassed; uint numberOfVotes; int currentResult; bytes32 proposalHash; Vote[] votes; mapping (address => bool) voted; } struct Member { address member; 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 { require(memberId[msg.sender] != 0); _; } /** * Constructor function */ function Congress ( uint minimumQuorumForProposals, uint minutesForDebate, int marginOfVotesForMajority ) payable public { changeVotingRules(minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority); // It’s necessary to add an empty first member addMember(0, ""); // and let's add the founder, to save a step later addMember(owner, 'founder'); } /** * Add member * * Make `targetMember` a member named `memberName` * * @param targetMember ethereum address to be added * @param memberName public name for that member */ function addMember(address targetMember, string memberName) onlyOwner public { uint id = memberId[targetMember]; if (id == 0) { memberId[targetMember] = members.length; id = members.length++; } members[id] = Member({member: targetMember, memberSince: now, name: memberName}); emit MembershipChanged(targetMember, true); } /** * Remove member * * @notice Remove membership from `targetMember` * * @param targetMember ethereum address to be removed */ function removeMember(address targetMember) onlyOwner public { require(memberId[targetMember] != 0); for (uint i = memberId[targetMember]; i p.minExecutionDate // If it is past the voting deadline && !p.executed // and it has not already been executed && p.proposalHash == keccak256(p.recipient, p.amount, transactionBytecode) // and the supplied code matches the proposal && p.numberOfVotes >= minimumQuorum); // and a minimum quorum has been reached... // ...then execute result if (p.currentResult > majorityMargin) { // Proposal passed; execute the transaction p.executed = true; // Avoid recursive calling require(p.recipient.call.value(p.amount)(transactionBytecode)); p.proposalPassed = true; } else { // Proposal failed p.proposalPassed = false; } // Fire Events emit ProposalTallied(proposalNumber, p.currentResult, p.numberOfVotes, p.proposalPassed); } }