Election Result Verification

What it does:
Verifies and audits election or voting results on-chain to ensure integrity, transparency, and trustworthiness of the outcomes.

Why it matters:
Prevents tampering or fraud, allows public and auditors to independently confirm results, and increases trust in democratic processes or DAO governance.

How it works:

  • Votes are cast on-chain or recorded from verified off-chain sources

  • Each vote is cryptographically signed and timestamped

  • Smart contracts tally votes and store results immutably

  • Public and auditors can verify each vote without revealing voter identity

  • Final results are automatically published on-chain

  • Can integrate with DAO referendums, civic participation rewards, or local governance systems

  • Auditable dashboards allow real-time verification of tallies and voter participation

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title ElectionResultVerification
 * @author Nam
 * @notice Verifies and audits election results on-chain with cryptographic vote integrity
 */
contract ElectionResultVerification is Ownable {

    struct Candidate {
        string name;
        uint256 votes;
    }

    struct Election {
        string description;
        uint256 startTime;
        uint256 endTime;
        bool executed;
        Candidate[] candidates;
        mapping(address => bool) hasVoted;
    }

    mapping(uint256 => Election) private elections;
    uint256 public electionCount;

    // -------------------- EVENTS --------------------

    event ElectionCreated(uint256 indexed electionId, string description);
    event VoteCast(uint256 indexed electionId, address voter, uint256 candidateIndex);
    event ElectionExecuted(uint256 indexed electionId, uint256 winningCandidateIndex);

    // -------------------- ELECTION MANAGEMENT --------------------

    function createElection(string calldata _description, string[] calldata _candidateNames, uint256 _duration) external onlyOwner {
        require(_candidateNames.length >= 2, "At least two candidates required");
        electionCount += 1;
        Election storage e = elections[electionCount];
        e.description = _description;
        e.startTime = block.timestamp;
        e.endTime = block.timestamp + _duration;

        for (uint256 i = 0; i = e.startTime && block.timestamp <= e.endTime, "Voting period closed");
        require(!e.hasVoted[msg.sender], "Already voted");
        require(_candidateIndex  e.endTime, "Election still active");

        uint256 winningIndex = 0;
        uint256 highestVotes = 0;

        for (uint256 i = 0; i  highestVotes) {
                highestVotes = e.candidates[i].votes;
                winningIndex = i;
            }
        }

        e.executed = true;
        emit ElectionExecuted(_electionId, winningIndex);
        // Optional: trigger DAO action based on winner
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function getCandidates(uint256 _electionId) external view returns (Candidate[] memory) {
        return elections[_electionId].candidates;
    }

    function hasVoted(uint256 _electionId, address _voter) external view returns (bool) {
        return elections[_electionId].hasVoted[_voter];
    }
}