Skip to content

Instantly share code, notes, and snippets.

@Pzixel
Created July 3, 2019 13:00
Show Gist options
  • Save Pzixel/36efaaa5d1a2fcd68d6cf8b1b2a900bd to your computer and use it in GitHub Desktop.
Save Pzixel/36efaaa5d1a2fcd68d6cf8b1b2a900bd to your computer and use it in GitHub Desktop.
pragma solidity ^0.5.2;
contract Owned {
address public owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
function isDeployed() public pure returns (bool) {
return true;
}
function changeOwner(address newOwner) public onlyOwner {
owner = newOwner;
}
}
contract Root is Owned {
uint public Count;
mapping(uint => address) _addressMap;
uint[] public _pollIds;
address[] public _pollAddresses;
function pushAddress(uint pollId, address contractAddress) public onlyOwner {
if (_addressMap[pollId] == contractAddress) {
return;
}
_addressMap[pollId] = contractAddress;
_pollIds.push(pollId);
_pollAddresses.push(contractAddress);
Count++;
}
function getAllPollIds() public view returns(uint[] memory) {
return _pollIds;
}
function getAllPollAddresses() public view returns(address[] memory) {
return _pollAddresses;
}
function getPolls() public view returns (uint[] memory, address[] memory) {
return (_pollIds, _pollAddresses);
}
function getAddress(uint pollId) public view returns (address) {
if (Count == 0) {
return address(0);
}
return _addressMap[pollId];
}
}
contract Poll is Owned {
string public Name;
address[] _questions;
uint[] _questionIds;
constructor(string memory name) public Owned() {
Name = name;
}
event QuestionAdded(address questionAddress);
function addQuestion(
uint id,
uint versionId,
string memory name,
string memory answers,
uint[] memory answerIds) onlyOwner() public {
address questionAddress = address(new PollQuestion(id, versionId, name, answers, answerIds));
PollQuestion question = PollQuestion(questionAddress);
question.changeOwner(msg.sender);
_questions.push(questionAddress);
_questionIds.push(id);
emit QuestionAdded(questionAddress);
}
function QuestionsAddress() public view returns (address[] memory) {
return _questions;
}
function QuestionIds() public view returns (uint[] memory) {
return _questionIds;
}
}
contract PollQuestion is Owned {
uint public QuestionId;
uint _voterCount;
uint _reversalCount;
mapping(uint => Version) public _versions;
uint _currentVersion;
uint[] _versionsExisting;
mapping (string => Types.OptionU256) _userVersionsVotes;
mapping (string => OptionString) _userReversalReason;
constructor(uint id, uint versionId, string memory name, string memory answers, uint[] memory answerIds) public Owned() {
QuestionId = id;
addVersion(versionId, name, answers, answerIds);
}
struct Version {
bool Exists;
string Answers;
string Name;
uint[] AnswerIds;
uint[] Results;
mapping (string => uint[]) Votes;
mapping (string => string) AnswerValues1;
mapping (string => string) AnswerValues2;
}
function addVersion(uint versionId, string memory name, string memory answers, uint[] memory answerIds) public onlyOwner() {
require(!VersionExists(versionId));
if (versionId > _currentVersion) {
_currentVersion = versionId;
}
_versionsExisting.push(versionId);
_versions[versionId].Exists = true;
_versions[versionId].Answers = answers;
_versions[versionId].Name = name;
_versions[versionId].AnswerIds = answerIds;
_versions[versionId].Results = new uint[](0);
for (uint i = 0; i < answerIds.length; i++) {
_versions[versionId].Results.push(0);
}
}
function VersionExists(uint versionId) public view returns (bool) {
return _versions[versionId].Exists;
}
function CurrentVersion() public view returns (uint result) {
return _currentVersion;
}
function AllExistingVersions() public view returns(uint[] memory) {
return _versionsExisting;
}
function vote(uint version, string memory userKey, uint[] memory options, string memory customAnswer, string memory customAnswer2) public onlyOwner() {
require(VersionExists(version));
require(!VoteExists(userKey));
_voterCount++;
Version storage voteVersion = _versions[version];
voteVersion.Votes[userKey] = options;
voteVersion.AnswerValues1[userKey] = customAnswer;
voteVersion.AnswerValues2[userKey] = customAnswer2;
_userVersionsVotes[userKey] = Types.OptionU256(true, version);
for (uint i = 0; i < options.length; i++) {
voteVersion.Results[options[i]] += 1;
}
}
function VoteExists(string memory userKey) public view returns (bool) {
return _userVersionsVotes[userKey].hasValue;
}
function IsReversalEnabled() public pure returns (bool) {
return true;
}
function ReverseVote(string memory userKey, string memory reason) public onlyOwner() {
if (_userVersionsVotes[userKey].hasValue && !_userReversalReason[userKey].hasValue) {
_reversalCount++;
_voterCount--;
_userReversalReason[userKey] = OptionString(true, reason);
uint versionId = _userVersionsVotes[userKey].value;
uint[] storage options = _versions[versionId].Votes[userKey];
for (uint i = 0; i < options.length; i++) {
_versions[versionId].Results[options[i]] -= 1;
}
}
}
function CurrentVersionTitle() public view returns (string memory) {
return _versions[_currentVersion].Name;
}
function VoterCount() public view returns(uint) {
return _voterCount;
}
function ReversalCount() public view returns(uint) {
return _reversalCount;
}
function CurrentVersionResults() public view returns (uint[] memory) {
return ResultsByVersion(_currentVersion);
}
function ResultsByVersion(uint version) public view returns (uint[] memory) {
return _versions[version].Results;
}
function VoteOfUser(string memory userKey) public view returns (uint[] memory results, string memory value1, string memory value2) {
Types.OptionU256 storage userVersion = _userVersionsVotes[userKey];
if (!userVersion.hasValue) {
return (new uint[](0), "", "");
}
Version storage version = _versions[userVersion.value];
return (version.Votes[userKey], version.AnswerValues1[userKey], version.AnswerValues2[userKey]);
}
function HasReversalVote(string memory userKey) public view returns (bool reversalExists, string memory reversalReason) {
OptionString storage reversal = _userReversalReason[userKey];
return (reversal.hasValue, reversal.value);
}
function AnswersByVersion(uint version) public view returns (string memory results) {
return _versions[version].Answers;
}
function AnswerIdsByVersion(uint version) public view returns (uint[] memory results) {
return _versions[version].AnswerIds;
}
struct OptionString {
bool hasValue;
string value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment