// ------------------------------------------------------------------------------ // This file is part of netvote. // // netvote is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // netvote is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with solidity. If not, see // // (c) 2017 netvote contributors. //------------------------------------------------------------------------------ pragma solidity ^0.4.17; import "../../lib/Bytes32Set.sol"; import "../links/PoolRegistry.sol"; import "./TieredElection.sol"; import "./TieredPool.sol"; import "../BaseBallot.sol"; /** * @title TieredBallot * @dev A tiered ballot represents one instance of a ballot in a tiered eleciton. * This allows one to partition pools into groups for the purposes of separating votes. */ contract TieredBallot is BaseBallot, PoolRegistry { using Bytes32Set for Bytes32Set.SetData; // events for subscribing to this ballot event BallotVote(address pool, bytes32 voteId); // default group (popular vote) bytes32 constant GROUP_ALL = "ALL"; // configuration Bytes32Set.SetData groupSet; mapping (bytes32 => AddressSet.SetData) groupPoolSet; mapping (address => Bytes32Set.SetData) poolGroupSet; address public election; // state // map of voters to prevent duplicates mapping (bytes32 => bool) voterVoted; // pools to the list of voters mapping (address => bytes32[]) poolVoters; function TieredBallot(address electionAddress, address ownerAddress, string location) BaseBallot(ownerAddress, location) public { require(electionAddress != address(0)); election = electionAddress; groupSet.put(GROUP_ALL); } modifier validPool() { require(poolSet.contains(msg.sender)); _; } function groupPoolCount(bytes32 group) constant public returns (uint256) { return groupPoolSet[group].size(); } function getGroupPool(bytes32 group, uint256 index) constant public returns (address) { return groupPoolSet[group].getAt(index); } function getPoolVoterCount(address pool) constant public returns(uint256) { return poolVoters[pool].length; } // gets voter address by pool and index (for iteration) function getPoolVoter(address pool, uint256 i) constant public returns(bytes32) { return poolVoters[pool][i]; } // adds a pool to the ballot function addPool(address p) public building admin { poolSet.put(p); addPoolToGroup(p, GROUP_ALL); } function checkElection() public constant returns (bool) { return election != address(0) && TieredElection(election).ballotExists(this); } function checkPools() public constant returns (bool) { // there must be at least one pool set if (poolSet.size() == 0) { return false; } for (uint256 i = 0; i