Skip to content

Commit 3ec99cf

Browse files
authored
feat: improved syntax highlighting for the solidity language (#435)
1 parent 8a56e5e commit 3ec99cf

File tree

5 files changed

+908
-10
lines changed

5 files changed

+908
-10
lines changed
Lines changed: 153 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,156 @@
1-
pragma solidity ^0.8.9;
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity >=0.7.0 <0.9.0;
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[] memory proposalNames) {
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) external {
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) external {
76+
// assigns reference
77+
Voter storage sender = voters[msg.sender];
78+
require(sender.weight != 0, "You have no right to vote");
79+
require(!sender.voted, "You already voted.");
80+
81+
require(to != msg.sender, "Self-delegation is disallowed.");
82+
83+
// Forward the delegation as long as
84+
// `to` also delegated.
85+
// In general, such loops are very dangerous,
86+
// because if they run too long, they might
87+
// need more gas than is available in a block.
88+
// In this case, the delegation will not be executed,
89+
// but in other situations, such loops might
90+
// cause a contract to get "stuck" completely.
91+
while (voters[to].delegate != address(0)) {
92+
to = voters[to].delegate;
93+
94+
// We found a loop in the delegation, not allowed.
95+
require(to != msg.sender, "Found loop in delegation.");
96+
}
97+
98+
Voter storage delegate_ = voters[to];
99+
100+
// Voters cannot delegate to accounts that cannot vote.
101+
require(delegate_.weight >= 1);
102+
103+
// Since `sender` is a reference, this
104+
// modifies `voters[msg.sender]`.
105+
sender.voted = true;
106+
sender.delegate = to;
107+
108+
if (delegate_.voted) {
109+
// If the delegate already voted,
110+
// directly add to the number of votes
111+
proposals[delegate_.vote].voteCount += sender.weight;
112+
} else {
113+
// If the delegate did not vote yet,
114+
// add to her weight.
115+
delegate_.weight += sender.weight;
116+
}
117+
}
118+
119+
/// Give your vote (including votes delegated to you)
120+
/// to proposal `proposals[proposal].name`.
121+
function vote(uint proposal) external {
122+
Voter storage sender = voters[msg.sender];
123+
require(sender.weight != 0, "Has no right to vote");
124+
require(!sender.voted, "Already voted.");
125+
sender.voted = true;
126+
sender.vote = proposal;
127+
128+
// If `proposal` is out of the range of the array,
129+
// this will throw automatically and revert all
130+
// changes.
131+
proposals[proposal].voteCount += sender.weight;
132+
}
133+
134+
/// @dev Computes the winning proposal taking all
135+
/// previous votes into account.
136+
function winningProposal() public view
137+
returns (uint winningProposal_)
138+
{
139+
uint winningVoteCount = 0;
140+
for (uint p = 0; p < proposals.length; p++) {
141+
if (proposals[p].voteCount > winningVoteCount) {
142+
winningVoteCount = proposals[p].voteCount;
143+
winningProposal_ = p;
144+
}
145+
}
146+
}
2147

3-
contract HelloWorld {
4-
function render () public pure returns (string memory) {
5-
return 'Hello World';
148+
// Calls winningProposal() function to get the index
149+
// of the winner contained in the proposals array and then
150+
// returns the name of the winner
151+
function winnerName() external view
152+
returns (bytes32 winnerName_)
153+
{
154+
winnerName_ = proposals[winningProposal()].name;
6155
}
7156
}

0 commit comments

Comments
 (0)