solidity的投票示例以及其在remix上部署测试

编程入门 行业动态 更新时间:2024-10-09 05:25:10

solidity的投票<a href=https://www.elefans.com/category/jswz/34/1770116.html style=示例以及其在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上部署测试

本文发布于:2024-03-07 14:35:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1718085.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:示例   测试   solidity   remix

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!