Skip to Content

@cfxdevkit/compiler


@cfxdevkit/compiler / VOTING_SOURCE

Variable: VOTING_SOURCE

const VOTING_SOURCE: ”// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\n/**\n * @title Voting\n * @notice A simple ballot contract. The chairperson registers voters and\n * proposals. Voters cast one vote (or delegate). Teaches structs,\n * mappings, weighted voting, and delegation.\n */\ncontract Voting {\n struct Voter {\n bool registered;\n bool voted;\n address delegate;\n uint256 vote; // index of the voted proposal\n uint256 weight; // delegated weight (starts at 1 for registered voters)\n }\n\n struct Proposal {\n string name;\n uint256 voteCount;\n }\n\n address public chairperson;\n mapping(address => Voter) public voters;\n Proposal[] public proposals;\n bool public votingOpen;\n\n event VoterRegistered(address indexed voter);\n event VoteCast(address indexed voter, uint256 indexed proposalIndex);\n event VoteDelegated(address indexed from, address indexed to);\n event VotingStatusChanged(bool open);\n\n modifier onlyChairperson() {\n require(msg.sender == chairperson, “Voting: not the chairperson”);\n _;\n }\n\n modifier whenOpen() {\n require(votingOpen, “Voting: voting is not open”);\n _;\n }\n\n /// @param proposalNames Array of human-readable proposal names\n constructor(string[] memory proposalNames) {\n chairperson = msg.sender;\n voters[chairperson].weight = 1;\n\n for (uint256 i = 0; i < proposalNames.length; i++) {\n proposals.push(Proposal({ name: proposalNames[i], voteCount: 0 }));\n }\n }\n\n /// @notice Open or close the voting period.\n function setVotingOpen(bool open) external onlyChairperson {\n votingOpen = open;\n emit VotingStatusChanged(open);\n }\n\n /// @notice Register a voter (chairperson only; must be done before they vote).\n function registerVoter(address voter) external onlyChairperson {\n require(!voters[voter].registered, “Voting: already registered”);\n voters[voter] = Voter({ registered: true, voted: false, delegate: address(0), vote: 0, weight: 1 });\n emit VoterRegistered(voter);\n }\n\n /// @notice Delegate your vote to `to`.\n function delegate(address to) external whenOpen {\n Voter storage sender = voters[msg.sender];\n require(sender.registered, “Voting: not registered”);\n require(!sender.voted, “Voting: already voted”);\n require(to != msg.sender, “Voting: self-delegation”);\n\n // Follow delegation chain (detect loops)\n address delegatee = to;\n while (voters[delegatee].delegate != address(0)) {\n delegatee = voters[delegatee].delegate;\n require(delegatee != msg.sender, “Voting: delegation loop”);\n }\n sender.voted = true;\n sender.delegate = delegatee;\n Voter storage d = voters[delegatee];\n if (d.voted) {\n proposals[d.vote].voteCount += sender.weight;\n } else {\n d.weight += sender.weight;\n }\n emit VoteDelegated(msg.sender, delegatee);\n }\n\n /// @notice Cast your vote for proposal at `proposalIndex`.\n function vote(uint256 proposalIndex) external whenOpen {\n Voter storage sender = voters[msg.sender];\n require(sender.registered, “Voting: not registered”);\n require(!sender.voted, “Voting: already voted”);\n require(proposalIndex < proposals.length, “Voting: invalid proposal”);\n sender.voted = true;\n sender.vote = proposalIndex;\n proposals[proposalIndex].voteCount += sender.weight;\n emit VoteCast(msg.sender, proposalIndex);\n }\n\n /// @notice Returns the index of the winning proposal.\n function winningProposal() public view returns (uint256 winnerIndex) {\n uint256 maxVotes;\n for (uint256 i = 0; i < proposals.length; i++) {\n if (proposals[i].voteCount > maxVotes) {\n maxVotes = proposals[i].voteCount;\n winnerIndex = i;\n }\n }\n }\n\n /// @notice Returns the name of the winning proposal.\n function winnerName() external view returns (string memory) {\n return proposals[winningProposal()].name;\n }\n\n /// @notice Total number of proposals.\n function proposalCount() external view returns (uint256) {\n return proposals.length;\n }\n}”

Defined in: templates/voting.ts:13