Solidity Fundamentals
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; contract ProposalContract { // ****************** Data *********************** //Owner address owner; uint256 private counter; struct Proposal { string description; // Description of the proposal uint256 approve; // Number of approve votes uint256 reject; // Number of reject votes uint256 pass; // Number of pass votes uint256 total_vote_to_end; // When the total votes in the proposal reaches this limit, proposal ends bool current_state; // This shows the current state of the proposal, meaning whether if passes of fails bool is_active; // This shows if others can vote to our contract } mapping(uint256 => Proposal) proposal_history; // Recordings of previous proposals address[] private voted_addresses; //constructor constructor() { owner = msg.sender; voted_addresses.push(msg.sender); } modifier onlyOwner() { require(msg.sender == owner); _; } modifier active() { require(proposal_history[counter].is_active == true); _; } modifier newVoter(address _address) { require(!isVoted(_address), "Address has not voted yet"); _; } // ****************** Execute Functions *********************** function setOwner(address new_owner) external onlyOwner { owner = new_owner; } function create(string calldata _description, uint256 _total_vote_to_end) external onlyOwner { counter += 1; proposal_history[counter] = Proposal(_description, 0, 0, 0, _total_vote_to_end, false, true); } function vote(uint8 choice) external active newVoter(msg.sender){ Proposal storage proposal = proposal_history[counter]; uint256 total_vote = proposal.approve + proposal.reject + proposal.pass; voted_addresses.push(msg.sender); if (choice == 1) { proposal.approve += 1; proposal.current_state = calculateCurrentState(); } else if (choice == 2) { proposal.reject += 1; proposal.current_state = calculateCurrentState(); } else if (choice == 0) { proposal.pass += 1; proposal.current_state = calculateCurrentState(); } if ((proposal.total_vote_to_end - total_vote == 1) && (choice == 1 || choice == 2 || choice == 0)) { proposal.is_active = false; voted_addresses = [owner]; } } function terminateProposal() external onlyOwner active { proposal_history[counter].is_active = false; } function calculateCurrentState() private view returns(bool) { Proposal storage proposal = proposal_history[counter]; uint256 approve = proposal.approve; uint256 reject = proposal.reject; uint256 pass = proposal.pass; if (proposal.pass %2 == 1) { pass += 1; } pass = pass / 2; if (approve > reject + pass) { return true; } else { return false; } } // ****************** Query Functions *********************** function isVoted(address _address) public view returns (bool) { for (uint i = 0; i < voted_addresses.length; i++) { if (voted_addresses[i] == _address) { return true; } } return false; } function getCurrentProposal() external view returns(Proposal memory) { return proposal_history[counter]; } function getProposal(uint256 number) external view returns(Proposal memory) { return proposal_history[number]; } }
Comments
You need to enroll in the course to be able to comment!