Jordi Planes 5 anni fa
parent
commit
974fd2ac1d
1 ha cambiato i file con 149 aggiunte e 0 eliminazioni
  1. 149
    0
      contract.sol

+ 149
- 0
contract.sol Vedi File

@@ -0,0 +1,149 @@
1
+pragma solidity ^0.4.22;
2
+
3
+/// @title Voting with delegation.
4
+contract Ballot {
5
+    // This declares a new complex type which will
6
+    // be used for variables later.
7
+    // It will represent a single voter.
8
+    struct Voter {
9
+        uint weight; // weight is accumulated by delegation
10
+        bool voted;  // if true, that person already voted
11
+        address delegate; // person delegated to
12
+        uint vote;   // index of the voted proposal
13
+    }
14
+
15
+    // This is a type for a single proposal.
16
+    struct Proposal {
17
+        bytes32 name;   // short name (up to 32 bytes)
18
+        uint voteCount; // number of accumulated votes
19
+    }
20
+
21
+    address public chairperson;
22
+
23
+    // This declares a state variable that
24
+    // stores a `Voter` struct for each possible address.
25
+    mapping(address => Voter) public voters;
26
+
27
+    // A dynamically-sized array of `Proposal` structs.
28
+    Proposal[] public proposals;
29
+
30
+    /// Create a new ballot to choose one of `proposalNames`.
31
+    constructor(bytes32[] proposalNames) public {
32
+        chairperson = msg.sender;
33
+        voters[chairperson].weight = 1;
34
+
35
+        // For each of the provided proposal names,
36
+        // create a new proposal object and add it
37
+        // to the end of the array.
38
+        for (uint i = 0; i < proposalNames.length; i++) {
39
+            // `Proposal({...})` creates a temporary
40
+            // Proposal object and `proposals.push(...)`
41
+            // appends it to the end of `proposals`.
42
+            proposals.push(Proposal({
43
+                name: proposalNames[i],
44
+                voteCount: 0
45
+            }));
46
+        }
47
+    }
48
+
49
+    // Give `voter` the right to vote on this ballot.
50
+    // May only be called by `chairperson`.
51
+    function giveRightToVote(address voter) public {
52
+        // If the first argument of `require` evaluates
53
+        // to `false`, execution terminates and all
54
+        // changes to the state and to Ether balances
55
+        // are reverted.
56
+        // This used to consume all gas in old EVM versions, but
57
+        // not anymore.
58
+        // It is often a good idea to use `require` to check if
59
+        // functions are called correctly.
60
+        // As a second argument, you can also provide an
61
+        // explanation about what went wrong.
62
+        require(
63
+            msg.sender == chairperson,
64
+            "Only chairperson can give right to vote."
65
+        );
66
+        require(
67
+            !voters[voter].voted,
68
+            "The voter already voted."
69
+        );
70
+        require(voters[voter].weight == 0);
71
+        voters[voter].weight = 1;
72
+    }
73
+
74
+    /// Delegate your vote to the voter `to`.
75
+    function delegate(address to) public {
76
+        // assigns reference
77
+        Voter storage sender = voters[msg.sender];
78
+        require(!sender.voted, "You already voted.");
79
+
80
+        require(to != msg.sender, "Self-delegation is disallowed.");
81
+
82
+        // Forward the delegation as long as
83
+        // `to` also delegated.
84
+        // In general, such loops are very dangerous,
85
+        // because if they run too long, they might
86
+        // need more gas than is available in a block.
87
+        // In this case, the delegation will not be executed,
88
+        // but in other situations, such loops might
89
+        // cause a contract to get "stuck" completely.
90
+        while (voters[to].delegate != address(0)) {
91
+            to = voters[to].delegate;
92
+
93
+            // We found a loop in the delegation, not allowed.
94
+            require(to != msg.sender, "Found loop in delegation.");
95
+        }
96
+
97
+        // Since `sender` is a reference, this
98
+        // modifies `voters[msg.sender].voted`
99
+        sender.voted = true;
100
+        sender.delegate = to;
101
+        Voter storage delegate_ = voters[to];
102
+        if (delegate_.voted) {
103
+            // If the delegate already voted,
104
+            // directly add to the number of votes
105
+            proposals[delegate_.vote].voteCount += sender.weight;
106
+        } else {
107
+            // If the delegate did not vote yet,
108
+            // add to her weight.
109
+            delegate_.weight += sender.weight;
110
+        }
111
+    }
112
+
113
+    /// Give your vote (including votes delegated to you)
114
+    /// to proposal `proposals[proposal].name`.
115
+    function vote(uint proposal) public {
116
+        Voter storage sender = voters[msg.sender];
117
+        require(!sender.voted, "Already voted.");
118
+        sender.voted = true;
119
+        sender.vote = proposal;
120
+
121
+        // If `proposal` is out of the range of the array,
122
+        // this will throw automatically and revert all
123
+        // changes.
124
+        proposals[proposal].voteCount += sender.weight;
125
+    }
126
+
127
+    /// @dev Computes the winning proposal taking all
128
+    /// previous votes into account.
129
+    function winningProposal() public view
130
+            returns (uint winningProposal_)
131
+    {
132
+        uint winningVoteCount = 0;
133
+        for (uint p = 0; p < proposals.length; p++) {
134
+            if (proposals[p].voteCount > winningVoteCount) {
135
+                winningVoteCount = proposals[p].voteCount;
136
+                winningProposal_ = p;
137
+            }
138
+        }
139
+    }
140
+
141
+    // Calls winningProposal() function to get the index
142
+    // of the winner contained in the proposals array and then
143
+    // returns the name of the winner
144
+    function winnerName() public view
145
+            returns (bytes32 winnerName_)
146
+    {
147
+        winnerName_ = proposals[winningProposal()].name;
148
+    }
149
+}

Powered by TurnKey Linux.