From 334461f854d61adabb288b6e75e802c1a1f561ba Mon Sep 17 00:00:00 2001 From: Antonin Duvauchel <antonin.duvauchel.etu@univ-lille.fr> Date: Mon, 6 Nov 2023 10:22:50 +0100 Subject: [PATCH] Update file voting-contract.sol --- voting-contract.sol | 170 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/voting-contract.sol b/voting-contract.sol index 8b13789..e9dcd21 100644 --- a/voting-contract.sol +++ b/voting-contract.sol @@ -1 +1,171 @@ +import "@openzeppelin/contracts/access/Ownable.sol"; +pragma solidity ^0.8.0; + +contract Voting is Ownable{ + + enum WorkflowStatus { + RegisteringVoters, + ProposalsRegistrationStarted, + ProposalsRegistrationEnded, + VotingSessionStarted, + VotingSessionEnded, + VotesTallied + } + + WorkflowStatus public status; + uint public winningProposalId; + + struct Voter { + bool isRegistered; + bool hasVoted; + uint votedProposalId; + } + + struct Proposal { + string description; + uint voteCount; + } + + struct VoterProposal { + string description; + bool hasVoted; + } + + mapping(address => VoterProposal) public voterProposals; + mapping(address => Voter) public voters; + mapping(address => address) public delegatedVotes; + + Proposal[] public proposals; + + event VoterRegistered(address voterAddress); + + event WorkflowStatusChange(WorkflowStatus previousStatus, WorkflowStatus newStatus); + + event ProposalRegistered(uint proposalId); + + event Voted(address voter, uint proposalId); + + constructor() Ownable(msg.sender) { + status = WorkflowStatus.RegisteringVoters; + } + + function registerVoter(address _voter) public onlyOwner { + require(status == WorkflowStatus.RegisteringVoters, "Le vote n'est pas en cours d'inscription des votants."); + require(!voters[_voter].isRegistered, "Le votant est deja inscrit."); + voters[_voter].isRegistered = true; + emit VoterRegistered(_voter); + } + + function startProposalsRegistration() public onlyOwner { + require(status == WorkflowStatus.RegisteringVoters, "Le vote n'est pas en cours d'inscription des votants."); + + status = WorkflowStatus.ProposalsRegistrationStarted; + emit WorkflowStatusChange(WorkflowStatus.RegisteringVoters, WorkflowStatus.ProposalsRegistrationStarted); + } + + function endProposalsRegistration() public onlyOwner { + require(status == WorkflowStatus.ProposalsRegistrationStarted, "Le vote n'est pas en cours d'enregistrement des propositions."); + + status = WorkflowStatus.ProposalsRegistrationEnded; + emit WorkflowStatusChange(WorkflowStatus.ProposalsRegistrationStarted, WorkflowStatus.ProposalsRegistrationEnded); + } + + function registerProposal(string memory _description) public { + require(status == WorkflowStatus.ProposalsRegistrationStarted, "Le vote n'est pas en cours d'enregistrement des propositions."); + require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit."); + + Proposal memory newProposal = Proposal({ + description: _description, + voteCount: 0 + }); + + proposals.push(newProposal); + emit ProposalRegistered(proposals.length - 1); + } + + function startVotingSession() public onlyOwner { + require(status == WorkflowStatus.ProposalsRegistrationEnded, "Le vote n'est pas en cours d'enregistrement des propositions."); + + status = WorkflowStatus.VotingSessionStarted; + emit WorkflowStatusChange(WorkflowStatus.ProposalsRegistrationEnded, WorkflowStatus.VotingSessionStarted); + } + + function endVotingSession() public onlyOwner { + require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote."); + + status = WorkflowStatus.VotingSessionEnded; + emit WorkflowStatusChange(WorkflowStatus.VotingSessionStarted, WorkflowStatus.VotingSessionEnded); + } + + function vote(uint _proposalId) public { + require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote."); + require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit."); + require(!voters[msg.sender].hasVoted, "Le votant a deja vote."); + require(_proposalId < proposals.length, "Proposition invalide."); + + voters[msg.sender].hasVoted = true; + voters[msg.sender].votedProposalId = _proposalId; + proposals[_proposalId].voteCount++; + emit Voted(msg.sender, _proposalId); + } + + function tallyVotes() public onlyOwner { + require(status == WorkflowStatus.VotingSessionEnded, "Le vote n'est pas en cours de vote."); + + uint winningVoteCount = 0; + for (uint i = 0; i < proposals.length; i++) { + if (proposals[i].voteCount > winningVoteCount) { + winningVoteCount = proposals[i].voteCount; + winningProposalId = i; + } + } + + status = WorkflowStatus.VotesTallied; + emit WorkflowStatusChange(WorkflowStatus.VotingSessionEnded, WorkflowStatus.VotesTallied); + } + + function getWinner() public view returns (string memory) { + require(status == WorkflowStatus.VotesTallied, "Le vote n'a pas encore ete comptabilise."); + + return proposals[winningProposalId].description; + } + + function revokeVoterRegistration(address _voter) public onlyOwner { + require(status == WorkflowStatus.RegisteringVoters, "Le vote n'est pas en cours d'inscription des votants."); + require(voters[_voter].isRegistered, "Le votant n'est pas inscrit."); + + voters[_voter].isRegistered = false; + } + + function registerOrUpdateProposal(string memory _description) public { + require(status == WorkflowStatus.ProposalsRegistrationStarted, "Le vote n'est pas en cours d'enregistrement des propositions."); + require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit."); + + voterProposals[msg.sender].description = _description; + voterProposals[msg.sender].hasVoted = false; + } + + function delegateVote(address _delegate) public { + require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote."); + require(voters[msg.sender].isRegistered, "Le votant n'est pas inscrit."); + require(voters[_delegate].isRegistered, "Le delegue n'est pas inscrit."); + + require(msg.sender != _delegate, "Vous ne pouvez pas vous deleguer a vous-meme."); + + delegatedVotes[msg.sender] = _delegate; + } + + function voteByDelegation(uint _proposalId) public { + address delegate = delegatedVotes[msg.sender]; + require(delegate != address(0), "Vous n'avez pas delegue votre vote."); + require(status == WorkflowStatus.VotingSessionStarted, "Le vote n'est pas en cours de vote."); + require(voters[delegate].hasVoted, "Le delegue n'a pas encore vote."); + + voters[msg.sender].hasVoted = true; + voters[msg.sender].votedProposalId = _proposalId; + proposals[_proposalId].voteCount++; + emit Voted(msg.sender, _proposalId); + } + +} -- GitLab