智能合约投票系统:时间限制、投票结果判定、Hardhat/Truffle 测试
以下是一个实现投票的智能合约的示例:\n\nsolidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport "@openzeppelin/contracts/utils/math/SafeMath.sol";\nimport "@openzeppelin/contracts/access/Ownable.sol";\n\ncontract Voting is Ownable {\n using SafeMath for uint256;\n \n struct Voter {\n uint256 timestamp;\n bool agree;\n }\n \n struct Proposal {\n uint256 id;\n uint256 timestamp;\n string content;\n address proposer;\n uint256 deadline;\n uint256 agreeCount;\n uint256 disagreeCount;\n bool passed;\n }\n \n mapping(address => Voter) private voters;\n Proposal private proposal;\n \n event Vote(address indexed voter, bool agree);\n event Result(bool passed);\n \n constructor(uint256 _deadline, string memory _content) {\n proposal.timestamp = block.timestamp;\n proposal.content = _content;\n proposal.proposer = msg.sender;\n proposal.deadline = _deadline;\n }\n \n function vote(bool _agree) public {\n require(block.timestamp <= proposal.deadline, "Voting has ended");\n require(voters[msg.sender].timestamp == 0, "Already voted");\n \n voters[msg.sender].timestamp = block.timestamp;\n voters[msg.sender].agree = _agree;\n \n if (_agree) {\n proposal.agreeCount = proposal.agreeCount.add(1);\n } else {\n proposal.disagreeCount = proposal.disagreeCount.add(1);\n }\n \n emit Vote(msg.sender, _agree);\n }\n \n function getResult() public {\n require(block.timestamp > proposal.deadline, "Voting has not ended yet");\n require(!proposal.passed, "Result has already been determined");\n \n uint256 totalVotes = proposal.agreeCount.add(proposal.disagreeCount);\n uint256 agreePercentage = proposal.agreeCount.mul(100).div(totalVotes);\n \n if (agreePercentage > 50) {\n proposal.passed = true;\n }\n \n emit Result(proposal.passed);\n }\n \n function getProposal() public view returns (Proposal memory) {\n return proposal;\n }\n}\n\n\n使用 Hardhat 进行测试的示例代码如下:\n\nsolidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport "hardhat/console.sol";\nimport "@openzeppelin/contracts/utils/Address.sol";\nimport "@openzeppelin/contracts/utils/Strings.sol";\nimport "@openzeppelin/contracts/utils/math/SafeMath.sol";\nimport "@openzeppelin/contracts/access/Ownable.sol";\nimport "./Voting.sol";\n\ncontract VotingTest is Ownable {\n using SafeMath for uint256;\n using Strings for uint256;\n using Address for address payable;\n \n Voting private voting;\n \n constructor() {\n voting = new Voting(block.timestamp.add(3600), "Test Proposal");\n }\n \n function testVote(bool agree) public {\n voting.vote(agree);\n }\n \n function testGetResult() public {\n voting.getResult();\n }\n \n function testGetProposal() public view returns (string memory) {\n Voting.Proposal memory proposal = voting.getProposal();\n \n string memory agreeCountStr = proposal.agreeCount.toString();\n string memory disagreeCountStr = proposal.disagreeCount.toString();\n string memory passedStr = proposal.passed ? "true" : "false";\n \n string memory result = string(abi.encodePacked(\n "Content: ", proposal.content, "\n",\n "Proposer: ", Strings.toHexString(uint256(uint160(proposal.proposer))), "\n",\n "Deadline: ", Strings.toHexString(proposal.deadline), "\n",\n "Agree Count: ", agreeCountStr, "\n",\n "Disagree Count: ", disagreeCountStr, "\n",\n "Passed: ", passedStr\n ));\n \n return result;\n }\n}\n\n\n使用 Truffle 进行测试的示例代码如下:\n\nsolidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport "@openzeppelin/contracts/utils/Address.sol";\nimport "@openzeppelin/contracts/utils/Strings.sol";\nimport "@openzeppelin/contracts/utils/math/SafeMath.sol";\nimport "@openzeppelin/contracts/access/Ownable.sol";\nimport "./Voting.sol";\n\ncontract VotingTest is Ownable {\n using SafeMath for uint256;\n using Strings for uint256;\n using Address for address payable;\n \n Voting private voting;\n \n constructor() {\n voting = new Voting(block.timestamp.add(3600), "Test Proposal");\n }\n \n function testVote(bool agree) public {\n voting.vote(agree);\n }\n \n function testGetResult() public {\n voting.getResult();\n }\n \n function testGetProposal() public view returns (string memory) {\n Voting.Proposal memory proposal = voting.getProposal();\n \n string memory agreeCountStr = proposal.agreeCount.toString();\n string memory disagreeCountStr = proposal.disagreeCount.toString();\n string memory passedStr = proposal.passed ? "true" : "false";\n \n string memory result = string(abi.encodePacked(\n "Content: ", proposal.content, "\n",\n "Proposer: ", Strings.toHexString(uint256(uint160(proposal.proposer))), "\n",\n "Deadline: ", Strings.toHexString(proposal.deadline), "\n",\n "Agree Count: ", agreeCountStr, "\n",\n "Disagree Count: ", disagreeCountStr, "\n",\n "Passed: ", passedStr\n ));\n \n return result;\n }\n}\n\n\n请注意,在运行测试之前,您需要使用以下命令安装必要的依赖项:\n\n\nnpm install --save-dev hardhat\nnpm install @nomiclabs/hardhat-waffle ethereum-waffle chai\nnpm install --save-dev truffle\nnpm install @openzeppelin/contracts\n\n\n然后,您可以使用 Hardhat 运行测试:\n\n\nnpx hardhat test\n\n\n或者,您可以使用 Truffle 运行测试:\n\n\nnpx truffle test\n\n\n希望对您有帮助!
原文地址: https://www.cveoy.top/t/topic/qhv1 著作权归作者所有。请勿转载和采集!