REMIX智能合约实例BALLOT分析

本文介绍了一个基于Solidity语言的区块链投票合约实现。合约通过定义投票人与提案的数据结构,实现了投票、委托投票及计算获胜提案等功能。合约还限制了投票权只能由主持人分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pragma solidity ^0.4.0;
contract Ballot { //投票类

struct Voter { //投票人
uint weight; //权重
bool voted; //该投票人是否投票,true表示已投票,false表示未投票
uint8 vote; //给谁(提案索引号)投票
address delegate; //委托的投票代表
}
struct Proposal { //提案
uint voteCount; //提案累计获得票数
}

address chairperson; // 投票主持人
mapping(address => Voter) voters; //声明一个状态变量voters,保存每个独立地址的Voter结构体
Proposal[] proposals; //声明一个存储Proposal结构的动态数组

/// Create a new ballot with $(_numProposals) different proposals. //用_numProposals个不同提案创建一个新的投票
function Ballot(uint8 _numProposals) public {
chairperson = msg.sender; //合约发送者为投票主持人
voters[chairperson].weight = 1; //主持人权重为1
proposals.length = _numProposals; //提案个数
}

/// Give $(toVoter) the right to vote on this ballot.
/// May only be called by $(chairperson).//投票主持人给每个投票者投票权,只能由投票主持人调用
function giveRightToVote(address toVoter) public {
if (msg.sender != chairperson || voters[toVoter].voted) return; //若合约发送者不是主持人或者投票者已经投票,则返回
voters[toVoter].weight = 1; // 给每个投票者各自投票权限
}

/// Delegate your vote to the voter $(to). //将自己(该函数的调用者)的投票权委托给委托人to
function delegate(address to) public {
Voter storage sender = voters[msg.sender]; // assigns reference 指定引用
if (sender.voted) return;
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
to = voters[to].delegate;//当委托人的票也委托给了别人时,将委托人to指向委托人的委托人。
if (to == msg.sender) return;//当委托人的委托人是自己时,返回。这里不允许自己委托给自己。
sender.voted = true;//自己已投票
sender.delegate = to;//将自己的委托人设为委托人to
Voter storage delegateTo = voters[to];//将委托人的信息保存到delegateTo中
if (delegateTo.voted)//若委托人已投票,则将自己的权重赋给委托人的票数
proposals[delegateTo.vote].voteCount += sender.weight;
else
delegateTo.weight += sender.weight; //若委托人未投票,则将自己的权重增加到委托人权重上。
}

/// Give a single vote to proposal $(toProposal).//这里自己(调用函数者)给提案投票,包括委托的票。
function vote(uint8 toProposal) public {
Voter storage sender = voters[msg.sender];//指定引用
if (sender.voted || toProposal >= proposals.length) return;//若自己已经投票或要投的提案索引范围超过给定提案数组范围,则返回
sender.voted = true;//自己已投票
sender.vote = toProposal;//自己给提案索引toProposal投票
proposals[toProposal].voteCount += sender.weight; //给提案索引为toProposal的票数加上自己的权重
}

//根据当前所有的投票计算出胜出的提案
function winningProposal() public constant returns (uint8 _winningProposal) {
uint256 winningVoteCount = 0;
for (uint8 prop = 0; prop < proposals.length; prop++)
if (proposals[prop].voteCount > winningVoteCount) {
winningVoteCount = proposals[prop].voteCount;
_winningProposal = prop;
}
}

}


msg.sender表示当前执行函数者的地址

在Solidity中编写一个班长投票的智能合约,我们可以创建一个简单的代币持有者系统,其中每个参与者(比如学生)持有代表他们投票权的代币。以下是基本步骤: 1. 定义一个`Voter`合约,其中包含学生的账户地址、代币余额等基本信息。同时,可以添加一个字段表示该学生是否已经投过票。 ```solidity pragma solidity ^0.8.0; contract Voter { address public owner; mapping(address => uint256) public balance; bool public hasVoted; constructor() { owner = msg.sender; } function deposit() public payable { require(msg.value > 0, "Deposit amount must be greater than zero"); balance[msg.sender] += msg.value; } // 添加其他函数如退票或查看投票状态 } ``` 2. 创建一个`Ballot`合约,用于存储班长候选人的列表,并提供投票功能。这可能包括一个映射结构,将学生的地址关联到他们的投票偏好。 ```solidity contract Ballot { address[] public candidates; mapping(address => address) public votes; function addCandidate(address candidate) public { candidates.push(candidate); } function vote(address voter, address candidate) public { require(voter != address(0), "Invalid voter address"); require(!voter.hasVoted && balance[voter] > 0, "Already voted or no tokens"); votes[voter] = candidate; voter.hasVoted = true; voter.transfer(balance[voter]); } // 提供查询结果的方法 } ``` 3. 投票过程通常涉及`deposit`操作(支付代币获得投票资格),`vote`函数(对候选人进行选择并消耗代币),以及最后可能有`collectVotes`函数来统计结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值