You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.2 KiB

//SPDX-License-Identifier: MIT
pragma solidity 0.7.4;
import "./Forum.sol";
contract Voting {
Forum public forum;
constructor(Forum addr) {
forum = Forum(addr);
}
struct Poll {
uint topicID;
uint numOptions;
string dataHash;
4 years ago
mapping (address => uint) votes;
uint[] voteCounts; // First element will hold total count
4 years ago
uint timestamp; // Timestamp of creation
}
mapping (uint => Poll) polls;
event PollCreated(uint topicID);
event UserVoted(address userAddress);
function createPoll(uint topicID, uint numOptions, string memory dataHash) public returns (uint) {
require(forum.hasUserSignedUp(msg.sender)); // Only registered users can create polls
require(topicID<forum.getNumberOfTopics()); // Only allow poll creation if topic exists
require (forum.getTopicAuthor(topicID) == msg.sender); // Only allow poll creation from the author of the topic
require(polls[topicID].timestamp == 0); // Only allow poll creation if it doesn't exist yet
Poll storage poll = polls[topicID];
poll.topicID = topicID;
poll.numOptions = numOptions;
poll.dataHash = dataHash;
poll.voteCounts = new uint[](numOptions+1);
poll.timestamp = block.timestamp;
emit PollCreated(topicID);
return topicID;
}
// Verify that poll exists
function isPollExistent(uint topicID) public view returns (bool) {
if (polls[topicID].timestamp != 0)
return true;
return false;
}
function hasVoted(uint topicID, address voter) public view returns (bool) {
require(isPollExistent(topicID));
4 years ago
if (polls[topicID].votes[voter] != 0)
return true;
return false;
}
4 years ago
function getVote(uint topicID, address voter) public view returns (uint) {
require(hasVoted(topicID, voter));
return polls[topicID].votes[voter];
}
function getPollInfo(uint topicID) public view returns (uint, string memory, uint, uint) {
require(isPollExistent(topicID));
return (
polls[topicID].numOptions,
polls[topicID].dataHash,
polls[topicID].timestamp,
polls[topicID].voteCounts[0]
);
}
// Gets vote count for a specific option (option 0 will return total count)
function getVoteCount(uint topicID, uint option) public view returns (uint) {
require(isPollExistent(topicID)); // Verify that poll exists
return (polls[topicID].voteCounts[option]);
}
4 years ago
function getTotalVotes(uint topicID) public view returns (uint) {
return getVoteCount(topicID, 0);
}
function vote(uint topicID, uint option) public {
require(isPollExistent(topicID));
Poll storage poll = polls[topicID];
require(option > 0 && option <= poll.numOptions); // Verify that this option exists
address voter = msg.sender;
4 years ago
uint currentVote = poll.votes[voter];
if(currentVote == option)
return;
if(currentVote == 0) // Voter hadn't voted before
poll.voteCounts[0]++;
else
poll.voteCounts[currentVote]--;
poll.voteCounts[option]++;
4 years ago
poll.votes[voter] = option;
emit UserVoted(voter);
}
}