Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
nucleo
Manage
Activity
Members
Labels
Plan
Issues
4
Issue boards
Milestones
Wiki
Code
Merge requests
1
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
blockchain
nucleo
Commits
d0ef1cdd
Commit
d0ef1cdd
authored
6 years ago
by
Robert Martin-Legene
Browse files
Options
Downloads
Patches
Plain Diff
Cambie mucho
parent
02c93060
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/Ballot.sol
+111
-112
111 additions, 112 deletions
src/Ballot.sol
with
111 additions
and
112 deletions
src/Ballot.sol
+
111
−
112
View file @
d0ef1cdd
pragma solidity ^0.4.11;
// Basado en https://soliditycookbook.com/voting
// vim:syntax:filetype=javascript:ai:sm
// vim:expandtab:backspace=indent,eol,start:softtabstop=4
pragma solidity ^0.4.25;
/// @title Voting with delegation.
/// @title Voting with delegation.
contract Ballot {
contract
Ballot
{
// This declares a new complex type which will
// This declares a new complex type which will
// be used for variables later.
// be used for variables later.
// It will represent a single voter.
// It will represent a single voter.
struct Voter {
struct Voter {
uint weight; // weight is accumulated by delegation
address voter;
bool voted; // if true, that person already voted
int vote; // index of the voted proposal or -1 if not voted
address delegate; // person delegated to
uint vote; // index of the voted proposal
}
}
// This is a type for a single proposal.
// This is a type for a single proposal.
struct Proposal {
struct Proposal {
bytes32 name; // short name (up to 32 bytes)
bytes32 name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
uint voteCount; // number of accumulated votes
}
struct Votingrules {
string title;
address chairman;
uint voteAtOrAfter;
uint voteAtOrBefore;
// Which percentage of the registered voters must
// vote in order for the vote to be considered valid.
// e.g. 0.0
float percentOfRegisteredVotersReqToBeValid;
// Which percentage of the cast votes are required
// for the motion/title to pass?
// MAJORITY VOTE:
// specify 50.00000000001
// TWO-THIRDS:
// specify 67.77777777777
float percentOfVotesCastToWin;
// Counting registered voters who do not vote as blank
// votes, has the effect that it is more difficult
// to acquire the desired votes.
bool countNonvotesAsBlanks;
}
}
address public chairperson;
Votingrules public rules;
mapping( address => int ) public voterMap;
// This declares a state variable that
Voter[] public voterList;
// stores a `Voter` struct for each possible address.
uint public numvoters;
mapping(address => Voter) public voters;
Proposal[] public proposalList;
uint public numproposals;
// A dynamically-sized array of `Proposal` structs.
Proposal[] public proposals;
/// Create a new ballot to choose one of `proposalNames`.
/// Create a new ballot to choose one of `proposalNames`.
function Ballot(bytes32[] proposalNames) {
constructor(
chairperson = msg.sender;
string ballotTitle,
voters[chairperson].weight = 1;
uint voteAtOrAfter,
uint voteAtOrBefore,
float percentOfRegisteredVotersReqToBeValid,
float percentOfVotesCastToWin,
bool countNonvotesAsBlanks,
bytes32[] proposalNames
) {
require( voteAtOrBefore > now );
// chairman can not automatically vote. Chairman must
// giveRightToVote to himself if he wants to vote.
rules.chairman = msg.sender;
rules.title = ballotTitle;
rules.voteAtOrAfter = voteAtOrAfter;
rules.voteAtOrBefore = voteAtOrBefore;
rules.percentOfRegisteredVotersReqToBeValid = percentOfRegisteredVotersReqToBeValid,
rules.percentOfVotesCastToWin = percentOfVotesCastToWin,
rules.countNonvotesAsBlanks = countNonvotesAsBlanks,
// For each of the provided proposal names,
// For each of the provided proposal names,
// create a new proposal object and add it
// create a new proposal object and add it
// to the end of the array.
// to the end of the array.
for (uint i = 0; i < proposalNames.length; i++) {
numproposals = proposalNames.length;
// `Proposal({...})` creates a temporary
int i = 0;
// Proposal object and `proposals.push(...)`
while ( i < numproposals )
// appends it to the end of `proposals`.
{
proposals.push(Proposal({
Proposal newprop;
name: proposalNames[i],
newprop.name = proposalNames[i];
voteCount: 0
newprop.voteCount = 0;
}));
proposalList.push( newprop );
i++;
}
}
}
}
// Give `voter` the right to vote on this ballot.
// Give `voter` the right to vote on this ballot.
// May only be called by `chairperson`.
function giveRightToVote( address voter )
function giveRightToVote(address voter) {
{
// If the argument of `require` evaluates to `false`,
// May only be called by chairman.
// it terminates and reverts all changes to
require( msg.sender == chairman );
// the state and to Ether balances. It is often
require( voteAtOrBefore <= now );
// a good idea to use this if functions are
uint idx = voterMap[voter];
// called incorrectly. But watch out, this
// Can't add voters more than once.
// will currently also consume all provided gas
require( idx == 0 );
// (this is planned to change in the future).
// Not even the voter listed in [0].
require((msg.sender == chairperson) && !voters[voter].voted && (voters[voter].weight == 0));
if ( voterList.length > 0 )
voters[voter].weight = 1;
require( voterList[0].voter != voter );
}
// If the voter's address doesn't match, it is because
// he doesn't exist (and then we always have idx=0).
/// Delegate your vote to the voter `to`.
// So we push him onto the voterList.
function delegate(address to) {
Voter newvoter;
// assigns reference
newvoter.voter = voter;
Voter storage sender = voters[msg.sender];
newvoter.vote = -1;
require(!sender.voted);
idx = voterList.push( newvoter ) - 1;
voterMap[voter] = idx;
// Self-delegation is not allowed.
numvoters++;
require(to != msg.sender);
// Forward the delegation as long as
// `to` also delegated.
// In general, such loops are very dangerous,
// because if they run too long, they might
// need more gas than is available in a block.
// In this case, the delegation will not be executed,
// but in other situations, such loops might
// cause a contract to get "stuck" completely.
while (voters[to].delegate != address(0)) {
to = voters[to].delegate;
// We found a loop in the delegation, not allowed.
require(to != msg.sender);
}
// Since `sender` is a reference, this
// modifies `voters[msg.sender].voted`
sender.voted = true;
sender.delegate = to;
Voter storage delegate = voters[to];
if (delegate.voted) {
// If the delegate already voted,
// directly add to the number of votes
proposals[delegate.vote].voteCount += sender.weight;
} else {
// If the delegate did not vote yet,
// add to her weight.
delegate.weight += sender.weight;
}
}
/// Give your vote (including votes delegated to you)
/// to proposal `proposals[proposal].name`.
function vote(uint proposal) {
Voter storage sender = voters[msg.sender];
require(!sender.voted);
sender.voted = true;
sender.vote = proposal;
// If `proposal` is out of the range of the array,
// this will throw automatically and revert all
// changes.
proposals[proposal].voteCount += sender.weight;
}
}
/// @dev Computes the winning proposal taking all
function getVoterIdx( address voter )
/// previous votes into account.
readonly
function winningProposal() constant
returns int
returns (uint winningProposal)
{
{
uint winningVoteCount = 0;
int idx = voterMap[voter];
for (uint p = 0; p < proposals.length; p++) {
if ( idx > 0 )
if (proposals[p].voteCount > winningVoteCount) {
return idx;
winningVoteCount = proposals[p].voteCount;
if ( voterList[0].voter == voter )
winningProposal = p;
return 0;
}
return -1;
}
}
}
// Calls winningProposal() function to get the index
/// Give your vote to proposal `proposals[proposal].name`.
// of the winner contained in the proposals array and then
function vote( uint proposal )
// returns the name of the winner
function winnerName() constant
returns (bytes32 winnerName)
{
{
winnerName = proposals[winningProposal()].name;
require( proposal < numproposals );
require( rules.voteAtOrAfter >= now );
require( rules.voteAtOrBefore <= now );
int idx = getVoterIdx( msg.sender );
require( idx > -1 );
int formervote = voterList[idx].vote;
require( formervote != int(proposal) );
if ( formervote > -1 )
{
// He changed his vote - this is normal for politicians, too.
proposals[ uint(formervote) ].voteCount--;
}
proposals[ proposal ].voteCount++;
voterList[ uint(idx) ].vote = uint(proposal);
}
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment