• Discover
  • Partner with us
  • Chapters
  • Blog

Learn everything about Solidity

Getting Started
✨Connect Your Profile to Open Campus
Introduction to Remix IDE
Counter Contract and Solidity Basics
Submit Your First Homework
Solidity Cheat Sheet
Creating Proposal Structure
Submit Your Second Homework

Creating a Counter
Creating a Proposal
Submit Your Third Homework
The Constructor
OnlyOwner Modifier
Voting Functionality

Correcting the Voting Functionality
Correcting the Voting Functionality 2
Calculating the Current State of a Proposal
Submit Your Fourth Task
Finalizing Proposal Contract
Final Version of the Proposal Contract

Submit Your Final Homework
Next Steps

You also need to modify your vote function. At the third part (end) of the function you set activefield of theProposalstruct to false. Under that line you will also reset the that are voted:

if ((proposal.total_vote_to_end - total_vote == 1) && (choice == 1 || choice == 2 || choice == 0)) {
    proposal.is_active = false;
    voted_addresses = [owner];
}

Also before the if-else statements you will add the address to the array:

voted_addresses.push(msg.sender);

So, your vote function becomes:

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];
    }
}

Notice that, in the function definition, you also added the modifiers active and newVoter. You have not created the newVotermodifier, so let's create that one too.

modifier newVoter(address _address) {
    require(!isVoted(_address), "Address has already voted");
    _;
}

You may have noticed that we have used the functionisVoted(). Do not worry if it looks unfamiliar, since you have not implement this function yet, but you will be in the future lessons. For now, just know that this function checks if the given address has voted or not.

// 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 already voted");
        _;
    }


//     // ****************** 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];
        }
    }
}

In the next section you will be implementing thecalculateCurrentStatefunction to help you to retrieve the state of the current proposal.

Previous
Next

Lesson discussion

Swap insights and ask questions about “Learn everything about Solidity”.

Enroll to participate
Start the course to unlock the discussion. Enrolling helps us keep conversations relevant to learners.
WebsiteDiscoverPartner with UsBlogEvents
Discover
CoursesCircleRustSoliditySolanaWeb3 FundamentalsBlockchain Basics
CompanyAbout UsBrand GuidelineFAQsTerms of UsePrivacy PolicyGDPR NoticeCookies
Don't miss any update!

Disclaimer: The information, programs, and events provided on https://risein.com is strictly for upskilling and networking purposes related to the technical infrastructure of blockchain platforms. We do not provide financial or investment advice, nor do we make any representations regarding the value, profitability, or future price of any blockchain or cryptocurrency. Users are encouraged to conduct their own research and consult with licensed financial professionals before engaging in any investment activities. https://risein.com disclaims any responsibility for financial decisions made by users based on the information provided here.

© 2026 Rise In, All rights reserved