Created
July 3, 2019 13:00
-
-
Save Pzixel/36efaaa5d1a2fcd68d6cf8b1b2a900bd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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