账户
0x19...c777
0x19...C777

0x19...C777

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.1+commit.df193b15
语言
Solidity
合同源代码
文件 1 的 1:VotingContract.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract MoonCatKeyVote {

    // Should the MoonCatRescue developers destroy their private key so that no future Genesis MoonCats can ever be released?
    // true  = Yes
    // false = No

    event VoteSubmitted(address voter, bool vote);

    uint public voteStartTime = 0;
    bool public voteCancelled = false;
    mapping (address => bool) public hasVoted;
    uint32 public yesVotes = 0;
    uint32 public noVotes = 0;

    //bytes32 public immutable voterRollSha256;
    bytes32 public immutable merkleRoot;
    address public immutable owner;

    modifier onlyOwner {
        require(msg.sender == owner, "Owner Only");
        _;
    }

    modifier voteContractIsPending {
        require(!voteCancelled, "Vote Contract Cancelled");
        require(voteStartTime == 0, "Vote Already Started");
        _;
    }

    modifier voteContractIsActive {
        require(!voteCancelled, "Vote Contract Cancelled");
        require(voteStartTime > 0, "Vote Not Started");
        require(block.timestamp < (voteStartTime + 48 hours), "Vote Ended");
        _;
    }

    modifier voteContractIsComplete {
        require(!voteCancelled, "Vote Contract Cancelled");
        require(voteStartTime > 0, "Vote Not Started");
        require(block.timestamp > (voteStartTime + 48 hours), "Vote Not Ended");
        _;
    }

    constructor(bytes32 merkleRoot_) {
        merkleRoot = merkleRoot_;
        owner = msg.sender;
    }

    function startVote() public onlyOwner voteContractIsPending  {
        voteStartTime = block.timestamp;
    }

    function cancelVote() public onlyOwner voteContractIsPending {
        voteCancelled = true;
    }

    function getResult() public view voteContractIsComplete returns (bool) {
        return (yesVotes > noVotes);
    }

    uint24 empty = 0;

    function submitVote(bytes32[] calldata eligibilityProof, bool vote) public voteContractIsActive  {
        require(!hasVoted[msg.sender], "Duplicate Vote");

        // https://github.com/miguelmota/merkletreejs-solidity/blob/master/contracts/MerkleProof.sol
        bytes32 computedHash = keccak256(abi.encodePacked(msg.sender));
        for (uint256 i = 0; i < eligibilityProof.length; i++) {
            bytes32 proofElement = eligibilityProof[i];

            if (computedHash < proofElement) {
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        require(computedHash == merkleRoot, "Ineligible Voter");

        hasVoted[msg.sender] = true;

        if(vote){
            yesVotes++;
        } else {
            noVotes++;
        }

        emit VoteSubmitted(msg.sender, vote);

    }
}
设置
{
  "compilationTarget": {
    "browser/VotingContract.sol": "MoonCatKeyVote"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"bool","name":"vote","type":"bool"}],"name":"VoteSubmitted","type":"event"},{"inputs":[],"name":"cancelVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getResult","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"noVotes","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"eligibilityProof","type":"bytes32[]"},{"internalType":"bool","name":"vote","type":"bool"}],"name":"submitVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"voteCancelled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voteStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yesVotes","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"}]