orchard_votes.sol in Solidity
One member one vote: propose, vote to deadline, tally.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
// One member, one vote: propose, vote until the deadline, tally.
contract OrchardVotes {
struct Proposal {
string text;
uint256 deadline;
uint256 yes;
uint256 no;
bool executed;
}
Proposal[] public proposals;
mapping(uint256 => mapping(address => bool)) public voted;
event Proposed(uint256 indexed id, string text);
event Voted(uint256 indexed id, address indexed voter, bool yes);
event Decided(uint256 indexed id, bool passed);
function propose(string calldata text, uint256 votingSeconds)
external returns (uint256 id)
{
proposals.push(Proposal(
text, block.timestamp + votingSeconds, 0, 0, false));
id = proposals.length - 1;
emit Proposed(id, text);
}
function vote(uint256 id, bool inFavor) external {
Proposal storage p = proposals[id];
require(block.timestamp < p.deadline, "voting closed");
require(!voted[id][msg.sender], "already voted");
voted[id][msg.sender] = true;
if (inFavor) p.yes += 1;
else p.no += 1;
emit Voted(id, msg.sender, inFavor);
}
function execute(uint256 id) external returns (bool passed) {
Proposal storage p = proposals[id];
require(block.timestamp >= p.deadline, "still voting");
require(!p.executed, "already tallied");
p.executed = true;
passed = p.yes > p.no;
emit Decided(id, passed);
}
}
How it works
- Proposals carry text, a deadline, and both counts.
- The nested mapping stops a double vote per proposal.
executewaits out the clock, then decides once.
Keywords and builtins used here
addressboolcontractelseemiteventexternalfalsefunctionifmappingpublicrequirereturnsstringstructtrueuint256
The run, in numbers
- Lines
- 48
- Characters to type
- 1291
- Tokens
- 296
- Three-star pace
- 55 tpm
At the three-star pace of 55 tokens a minute, this run takes about 323 seconds.
Step 3 of 3 in Encore, step 28 of 28 in Language basics.