Skip to content

Instantly share code, notes, and snippets.

Created August 28, 2017 19:46
Show Gist options
  • Save anonymous/0fc3be212b527442b930dee1ee608959 to your computer and use it in GitHub Desktop.
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=
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);
}
}
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;
}
}
}
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;
}
}
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