示例以及其在remix上部署测试"/>
solidity的投票示例以及其在remix上部署测试
solidity的投票示例以及其在remix上部署测试
1.solidity投票实现
pragma solidity >=0.4.22 <0.7.0;/// @title 委托投票
contract Ballot {// 这里声明了一个新的复合类型用于稍后的变量// 它用来表示一个选民struct Voter {uint weight; // 计票的权重bool voted; // 若为真,代表该人已投票address delegate; // 被委托人uint vote; // 投票提案的索引}// 提案的类型struct Proposal {bytes32 name; // 简称(最长32个字节)uint voteCount; // 得票数}address public chairperson;// 这声明了一个状态变量,为每个可能的地址存储一个 `Voter`。mapping(address => Voter) public voters;// 一个 `Proposal` 结构类型的动态数组Proposal[] public proposals;/// 为 `proposalNames` 中的每个提案,创建一个新的(投票)表决constructor(bytes32[] memory proposalNames) public {chairperson = msg.sender;voters[chairperson].weight = 1;//对于提供的每个提案名称,//创建一个新的 Proposal 对象并把它添加到数组的末尾。for (uint i = 0; i < proposalNames.length; i++) {// `Proposal({...})` 创建一个临时 Proposal 对象,// `proposals.push(...)` 将其添加到 `proposals` 的末尾proposals.push(Proposal({name: proposalNames[i],voteCount: 0}));}}// 授权 `voter` 对这个(投票)表决进行投票// 只有 `chairperson` 可以调用该函数。function giveRightToVote(address voter) public {// 若 `require` 的第一个参数的计算结果为 `false`,// 则终止执行,撤销所有对状态和以太币余额的改动。// 在旧版的 EVM 中这曾经会消耗所有 gas,但现在不会了。// 使用 require 来检查函数是否被正确地调用,是一个好习惯。// 你也可以在 require 的第二个参数中提供一个对错误情况的解释。require(msg.sender == chairperson,"Only chairperson can give right to vote.");require(!voters[voter].voted,"The voter already voted.");require(voters[voter].weight == 0);voters[voter].weight = 1;}/// 把你的投票委托到投票者 `to`。function delegate(address to) public {// 传引用Voter storage sender = voters[msg.sender];require(!sender.voted, "You already voted.");require(to != msg.sender, "Self-delegation is disallowed.");// 委托是可以传递的,只要被委托者 `to` 也设置了委托。// 一般来说,这种循环委托是危险的。因为,如果传递的链条太长,// 则可能需消耗的gas要多于区块中剩余的(大于区块设置的gasLimit),// 这种情况下,委托不会被执行。// 而在另一些情况下,如果形成闭环,则会让合约完全卡住。while (voters[to].delegate != address(0)) {to = voters[to].delegate;// 不允许闭环委托require(to != msg.sender, "Found loop in delegation.");}// `sender` 是一个引用, 相当于对 `voters[msg.sender].voted` 进行修改sender.voted = true;sender.delegate = to;Voter storage delegate_ = voters[to];if (delegate_.voted) {// 若被委托者已经投过票了,直接增加得票数proposals[delegate_.vote].voteCount += sender.weight;} else {// 若被委托者还没投票,增加委托者的权重delegate_.weight += sender.weight;}}/// 把你的票(包括委托给你的票),/// 投给提案 `proposals[proposal].name`.function vote(uint proposal) public {Voter storage sender = voters[msg.sender];require(!sender.voted, "Already voted.");sender.voted = true;sender.vote = proposal;// 如果 `proposal` 超过了数组的范围,则会自动抛出异常,并恢复所有的改动proposals[proposal].voteCount += sender.weight;}/// @dev 结合之前所有的投票,计算出最终胜出的提案function winningProposal() public viewreturns (uint winningProposal_){uint winningVoteCount = 0;for (uint p = 0; p < proposals.length; p++) {if (proposals[p].voteCount > winningVoteCount) {winningVoteCount = proposals[p].voteCount;winningProposal_ = p;}}}// 调用 winningProposal() 函数以获取提案数组中获胜者的索引,并以此返回获胜者的名称function winnerName() public viewreturns (bytes32 winnerName_){winnerName_ = proposals[winningProposal()].name;}
}
2.remix下调试
2.1构造函数deploy时输入构造函数的参数
["0xd4967590eb024589dfb6b9e48a576eb49ebc19d764b0d1d67dc21975e7258e97",
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x065e0be95fb43db528a20ba65c0e575e33cd4a9e1ca089dba4efff24596e8553"]
2.2deploy后合约函数说明
对应地址为如下所示账户地址
其中部署合约地址为0xca35b7d915458ef540ade6068dfe2f44e8fa733c
chairperson 获取当前提案创建者为0xca35b7d915458ef540ade6068dfe2f44e8fa733c
delegate委托投票,将自己投票权给其他address。此时需切换上方account进行委托
giveRightToVote 授权投票 只有chairperson可以进行调用
vote给某个提案投票
还有其他问题,可以站内私信我
更多推荐
solidity的投票示例以及其在remix上部署测试
发布评论