Created
August 28, 2017 19:46
-
-
Save anonymous/0fc3be212b527442b930dee1ee608959 to your computer and use it in GitHub Desktop.
Created using browser-solidity: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.16+commit.d7661dd9.js&optimize=undefined&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.2; | |
contract owned { | |
address public owner; | |
function owned() { | |
owner = msg.sender; | |
} | |
modifier onlyOwner { | |
require (msg.sender != owner); | |
_; | |
} | |
function transferOwnership(address newOwner) onlyOwner { | |
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){ | |
Token t = Token(_token); | |
require (!t.transferFrom(_from, this, _value)); | |
receivedTokens(_from, _value, _token, _extraData); | |
} | |
function () payable { | |
receivedEther(msg.sender, msg.value); | |
} | |
} | |
contract Token { | |
function transferFrom(address _from, address _to, uint256 _value) 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 votingDeadline; | |
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); | |
_; | |
} | |
/* First time setup */ | |
function Congress() { | |
//changeVotingRules(minimumQuorumForProposals, minutesForDebate, marginOfVotesForMajority); | |
//if (congressLeader != 0) owner = congressLeader; | |
// 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'); | |
} | |
/*make member*/ | |
function addMember(address targetMember, string memberName) onlyOwner { | |
uint id; | |
if (memberId[targetMember] == 0) { | |
memberId[targetMember] = members.length; | |
id = members.length++; | |
} else { | |
id = memberId[targetMember]; | |
} | |
members[id] = Member({member: targetMember, memberSince: now, name: memberName}); | |
MembershipChanged(targetMember, true); | |
} | |
function removeMember(address targetMember) onlyOwner { | |
require(memberId[targetMember] != 0); | |
for (uint i = memberId[targetMember]; i<members.length-1; i++){ | |
members[i] = members[i+1]; | |
} | |
delete members[members.length-1]; | |
members.length--; | |
} | |
/*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 storage 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; | |
return proposalID; | |
} | |
/* function to check if a proposal code matches */ | |
function checkProposalCode( | |
uint proposalNumber, | |
address beneficiary, | |
uint etherAmount, | |
bytes transactionBytecode | |
) | |
constant | |
returns (bool codeChecksOut) | |
{ | |
Proposal storage p = proposals[proposalNumber]; | |
return p.proposalHash == sha3(beneficiary, etherAmount, transactionBytecode); | |
} | |
function vote( | |
uint proposalNumber, | |
bool supportsProposal, | |
string justificationText | |
) | |
onlyMembers | |
returns (uint voteID) | |
{ | |
Proposal storage p = proposals[proposalNumber]; // Get the proposal | |
require(!p.voted[msg.sender]); // 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); | |
return p.numberOfVotes; | |
} | |
function executeProposal(uint proposalNumber, bytes transactionBytecode) { | |
Proposal storage 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? | |
*/ | |
require (now > p.votingDeadline | |
&& !p.executed | |
&& p.proposalHash == sha3(p.recipient, p.amount, transactionBytecode) | |
&& p.numberOfVotes >= minimumQuorum); | |
/* execute result */ | |
/* If difference between support and opposition is larger than margin */ | |
if (p.currentResult > majorityMargin) { | |
// Avoid recursive calling | |
p.executed = true; | |
require(p.recipient.call.value(p.amount * 1 ether)(transactionBytecode)); | |
p.proposalPassed = true; | |
} else { | |
p.proposalPassed = false; | |
} | |
// Fire Events | |
ProposalTallied(proposalNumber, p.currentResult, p.numberOfVotes, p.proposalPassed); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.0; | |
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 storage 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 storage delegateTo = voters[to]; | |
if (delegateTo.voted) | |
proposals[delegateTo.vote].voteCount += sender.weight; | |
else | |
delegateTo.weight += sender.weight; | |
} | |
/// Give a single vote to proposal $(proposal). | |
function vote(uint8 proposal) { | |
Voter storage 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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.13; | |
contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); } | |
contract MyToken { | |
/* Public variables of the token */ | |
string public name; | |
string public symbol; | |
uint8 public decimals; | |
uint256 public totalSupply; | |
/* This creates an array with all balances */ | |
mapping (address => uint256) public balanceOf; | |
mapping (address => mapping (address => uint256)) public allowance; | |
/* This generates a public event on the blockchain that will notify clients */ | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
/* This notifies clients about the amount burnt */ | |
event Burn(address indexed from, uint256 value); | |
/* Initializes contract with initial supply tokens to the creator of the contract */ | |
function MyToken( | |
uint256 initialSupply, | |
string tokenName, | |
uint8 decimalUnits, | |
string tokenSymbol | |
) { | |
balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens | |
totalSupply = initialSupply; // Update total supply | |
name = tokenName; // Set the name for display purposes | |
symbol = tokenSymbol; // Set the symbol for display purposes | |
decimals = decimalUnits; // Amount of decimals for display purposes | |
} | |
/* Internal transfer, only can be called by this contract */ | |
function _transfer(address _from, address _to, uint _value) internal { | |
require (_to != 0x0); // Prevent transfer to 0x0 address. Use burn() instead | |
require (balanceOf[_from] > _value); // Check if the sender has enough | |
require (balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows | |
balanceOf[_from] -= _value; // Subtract from the sender | |
balanceOf[_to] += _value; // Add the same to the recipient | |
Transfer(_from, _to, _value); | |
} | |
/// @notice Send `_value` tokens to `_to` from your account | |
/// @param _to The address of the recipient | |
/// @param _value the amount to send | |
function transfer(address _to, uint256 _value) { | |
_transfer(msg.sender, _to, _value); | |
} | |
/// @notice Send `_value` tokens to `_to` in behalf of `_from` | |
/// @param _from The address of the sender | |
/// @param _to The address of the recipient | |
/// @param _value the amount to send | |
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) { | |
require (_value < allowance[_from][msg.sender]); // Check allowance | |
allowance[_from][msg.sender] -= _value; | |
_transfer(_from, _to, _value); | |
return true; | |
} | |
/// @notice Allows `_spender` to spend no more than `_value` tokens in your behalf | |
/// @param _spender The address authorized to spend | |
/// @param _value the max amount they can spend | |
function approve(address _spender, uint256 _value) | |
returns (bool success) { | |
allowance[msg.sender][_spender] = _value; | |
return true; | |
} | |
/// @notice Allows `_spender` to spend no more than `_value` tokens in your behalf, and then ping the contract about it | |
/// @param _spender The address authorized to spend | |
/// @param _value the max amount they can spend | |
/// @param _extraData some extra information to send to the approved contract | |
function approveAndCall(address _spender, uint256 _value, bytes _extraData) | |
returns (bool success) { | |
tokenRecipient spender = tokenRecipient(_spender); | |
if (approve(_spender, _value)) { | |
spender.receiveApproval(msg.sender, _value, this, _extraData); | |
return true; | |
} | |
} | |
/// @notice Remove `_value` tokens from the system irreversibly | |
/// @param _value the amount of money to burn | |
function burn(uint256 _value) returns (bool success) { | |
require (balanceOf[msg.sender] > _value); // Check if the sender has enough | |
balanceOf[msg.sender] -= _value; // Subtract from the sender | |
totalSupply -= _value; // Updates totalSupply | |
Burn(msg.sender, _value); | |
return true; | |
} | |
function burnFrom(address _from, uint256 _value) returns (bool success) { | |
require(balanceOf[_from] >= _value); // Check if the targeted balance is enough | |
require(_value <= allowance[_from][msg.sender]); // Check allowance | |
balanceOf[_from] -= _value; // Subtract from the targeted balance | |
allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance | |
totalSupply -= _value; // Update totalSupply | |
Burn(_from, _value); | |
return true; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.2; | |
contract owned { | |
address public owner; | |
function owned() { | |
owner = msg.sender; | |
} | |
modifier onlyOwner { | |
require (msg.sender == owner); | |
_; | |
} | |
function transferOwnership(address newOwner) onlyOwner { | |
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){ | |
Token t = Token(_token); | |
require (!t.transferFrom(_from, this, _value)); | |
receivedTokens(_from, _value, _token, _extraData); | |
} | |
function () payable { | |
receivedEther(msg.sender, msg.value); | |
} | |
} | |
contract Token { | |
function transferFrom(address _from, address _to, uint256 _value) 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 votingDeadline; | |
bool computed; | |
bool approved; | |
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); | |
_; | |
} | |
/* First time setup */ | |
function Congress () payable { | |
changeVotingRules(0, 3, 0); | |
// 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'); | |
} | |
/// @notice 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) { | |
uint id = memberId[targetMember]; | |
if (id == 0) { | |
memberId[targetMember] = members.length; | |
id = members.length++; | |
} | |
members[id] = Member({member: targetMember, memberSince: now, name: memberName}); | |
MembershipChanged(targetMember, true); | |
} | |
/// @notice Remove membership from `targetMember` | |
/// @param targetMember ethereum address to be removed | |
function removeMember(address targetMember) onlyOwner { | |
require(memberId[targetMember] != 0); | |
for (uint i = memberId[targetMember]; i<members.length-1; i++){ | |
members[i] = members[i+1]; | |
} | |
delete members[members.length-1]; | |
members.length--; | |
} | |
/// @notice Make so that proposals need tobe discussed for at least `minutesForDebate/60` hours, have at least `minimumQuorumForProposals` votes, and have 50% + `marginOfVotesForMajority` votes to be executed | |
/// @param minimumQuorumForProposals how many members must vote on a proposal for it to be executed | |
/// @param minutesForDebate the minimum amount of delay between when a proposal is made and when it can be executed | |
/// @param marginOfVotesForMajority the proposal needs to have 50% plus this number | |
function changeVotingRules( | |
uint minimumQuorumForProposals, | |
uint minutesForDebate, | |
int marginOfVotesForMajority | |
) onlyOwner { | |
minimumQuorum = minimumQuorumForProposals; | |
debatingPeriodInMinutes = minutesForDebate; | |
majorityMargin = marginOfVotesForMajority; | |
ChangeOfRules(minimumQuorum, debatingPeriodInMinutes, majorityMargin); | |
} | |
/// @notice Propose to send `weiAmount / 1E18` ether to `beneficiary` for `JobDescription`. `transactionBytecode ? Contains : Does not contain` code. | |
/// @param beneficiary who to send the ether to | |
/// @param weiAmount amount of ether to send, in wei | |
/// @param JobDescription Description of job | |
/// @param transactionBytecode bytecode of transaction | |
function newProposal( | |
address beneficiary, | |
uint weiAmount, | |
string JobDescription, | |
bytes transactionBytecode | |
) | |
onlyMembers | |
returns (uint proposalID) | |
{ | |
proposalID = proposals.length++; | |
Proposal storage p = proposals[proposalID]; | |
p.recipient = beneficiary; | |
p.amount = weiAmount; | |
p.description = JobDescription; | |
p.votingDeadline = now + debatingPeriodInMinutes * 1 minutes; | |
p.proposalHash = sha3(beneficiary, weiAmount, p.votingDeadline, transactionBytecode); | |
p.computed = false; | |
p.approved = false; | |
p.numberOfVotes = 0; | |
ProposalAdded(proposalID, beneficiary, weiAmount, JobDescription); | |
numProposals = proposalID+1; | |
return proposalID; | |
} | |
/// @notice Propose to send `etherAmount` ether to `beneficiary` for `JobDescription`. `transactionBytecode ? Contains : Does not contain` code. | |
/// @param beneficiary who to send the ether to | |
/// @param etherAmount amount of ether to send | |
/// @param JobDescription Description of job | |
/// @param transactionBytecode bytecode of transaction | |
function newProposalInEther( | |
address beneficiary, | |
uint etherAmount, | |
string JobDescription, | |
bytes transactionBytecode | |
) | |
onlyMembers | |
returns (uint proposalID) | |
{ | |
return newProposal(beneficiary, etherAmount * 1 ether, JobDescription, transactionBytecode); | |
} | |
/* function to check if a proposal code matches */ | |
function checkProposalCode( | |
uint proposalNumber, | |
bytes transactionBytecode | |
) | |
constant | |
returns (bool codeChecksOut) | |
{ | |
Proposal storage p = proposals[proposalNumber]; | |
return p.proposalHash == sha3(p.recipient, p.amount, p.votingDeadline, transactionBytecode); | |
} | |
/// @notice Vote `supportsProposal? in support of : against` proposal #`proposalNumber` | |
/// @param proposalNumber number of proposal | |
/// @param supportsProposal either in favor or against it | |
/// @param justificationText optional justification text | |
function vote( | |
uint proposalNumber, | |
bool supportsProposal, | |
string justificationText | |
) | |
returns (uint voteID) | |
{ | |
Proposal storage p = proposals[proposalNumber]; // Get the proposal | |
require(!p.voted[msg.sender]); // 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); | |
return p.numberOfVotes; | |
} | |
/// @notice Count the votes proposal #`proposalNumber` and execute it if approved | |
/// @param proposalNumber proposal number | |
/// @param transactionBytecode optional: if the transaction contained a bytecode, you need to send it | |
function executeProposal(uint proposalNumber, bytes transactionBytecode) { | |
Proposal storage 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? | |
*/ | |
require (now > p.votingDeadline | |
&& !p.computed | |
&& checkProposalCode(proposalNumber, transactionBytecode) | |
&& p.numberOfVotes >= minimumQuorum); | |
/* execute result */ | |
/* If difference between support and opposition is larger than margin */ | |
if (p.currentResult > majorityMargin) { | |
// Avoid recursive calling | |
p.approved = true; | |
if(p.recipient.call.value(p.amount)(transactionBytecode)){ | |
p.computed = true; | |
} | |
} else { | |
p.computed = true; | |
p.approved = false; | |
} | |
// Fire Events | |
ProposalTallied(proposalNumber, p.currentResult, p.numberOfVotes, p.approved); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment