🚀 Build your Smart Contract for vote

In the lesson, you are asked to develop a Smart Contract that statisfies the following specifications:

We want to build a voting DApp that enables authorities to initiate a vote.

  • A vote is limited in time.
  • A vote has multiple stages:
    • launching : A new vote must define it start / end dates, its choices and its set of participants. Optional metadata can be provided such as a short description of the vote goal. Choices are a set of string and participants are identified by their addresses. Only a valid campaign that has an end date greater than the start date and a positive goal can be created. Only users registered as authorities can initiate or cancel a vote.
    • voting : during the vote duration, registered users can participate. Only the creator can cancel the vote at any time. Participants cannot cancel their participations. Only a set of registered participants can participate during the voting stage (whitelist).
    • closing : Results must be accessible by anyone. The vote cannot be canceled anymore.

Technical hints:

  • contract deployment corresponds to the launching stage. Parameters of the contract can be given in the contract constructor: constructor(bytes32[] memory choices_, address[] memory voters_, uint start_, uint end_, string metadata_);

The Smart Contract must implement the following interface (note that interfaces do not define constructor and modifiers):

interface IVote {
    
    function creator() external view returns (address);
    function closed() external view returns (bool);
    function start() external view returns (uint);
    function end() external view returns (uint);
    function metadata() external view returns (string memory);

    function choices(uint256) external view returns (bytes32, uint256);
    function getChoicesCount() external view returns (uint);

    function voters(uint256) external view returns (address);
    function getVotersCount() external view returns (uint);
    
    function votes(address) external view returns (uint256, bool, uint256);
    function votesCount() external view returns (uint);
   
    function vote(uint) external;
    function cancel() external;
    
    event Voted(address indexed voter, uint choice);
    event Canceled();
    event Closed();
}