案例分析
角色分析:包括主持人、選民
功能分析:
- 僅主持人能授權(quán)給每個(gè)選民1票,即每個(gè)參與投票的選民擁有1票投票權(quán)。
- 選民可以選擇將票數(shù)委托給其它選民,當(dāng)然,收委托的選民仍然可以將票數(shù)繼續(xù)委托給其它選民,即存在a—>b–>c–>d,但是,一旦將票數(shù)委托給其它選民后,自己將不再有投票的權(quán)利
- 選民和主持人可以選擇任意的提案項(xiàng)目進(jìn)行投票
代碼實(shí)例
pragma solidity^0.6.1;
contract ballot{
//選民結(jié)構(gòu)
struct Voter{
uint weight; //可以投票的數(shù)量
bool isVoted;//是否已投
address delegate;//授權(quán)給他人
uint index;//選擇的提案編號
}
//提案結(jié)構(gòu),這里的提案就是要進(jìn)行投票的項(xiàng)目
struct Proposal{
bytes32 name;//投票名稱
uint voteCount;//投票數(shù)
}
Proposal []public proposals;//提案數(shù)組
address public chairman;//主持人
mapping(address=>Voter) public voters;//全部選民信息
//構(gòu)造函數(shù)
constructor(bytes32[]memory _proposalNames)public{
chairman=msg.sender;
voters[chairman].weight=1;//主持人可以投1票
uint i=0;
//提案初始化
for(i=0;i<_proposalNames.length;i++){
Proposal memory p = Proposal(_proposalNames[i],0);
//存入提案數(shù)組中
proposals.push(p);
}
}
//授權(quán),僅主持人具有權(quán)利,主持人給每個(gè)選民一票的權(quán)利
function giveRightToVoter(address _to)public{
require(msg.sender==chairman,"must be chairman");
require(!voters[_to].isVoted);
require(voters[_to].weight==0);
voters[_to].weight=1;
}
//委托,選民可以將投票給自己信任的代表
function delegate(address _to)public{
//獲取調(diào)用函數(shù)的賬戶
address voter = msg.sender;
//當(dāng)前賬戶必須還未投票
require(!voters[voter].isVoted,"must not voted");
//當(dāng)前賬戶的可投的票數(shù)必須>0
require(voters[voter].weight>0,"must weight >0");
//委托的賬戶不能是自己
require(_to!=voter);
//a--->b--->c-->d
//循環(huán)判斷待委托人,由于待委托人可能還把票委托給其它人,所以循環(huán)判斷,直到委托賬戶地址不存在為止
while(voters[_to].delegate!=address(0)){
_to=voters[_to].delegate;
}
//執(zhí)行到這里,_to已經(jīng)是要委托的那個(gè)人,委托給他
voters[voter].delegate=_to;
//委托后,認(rèn)為該選民已經(jīng)投過票了
voters[voter].isVoted=true;
//如果_to已經(jīng)投過了,自然是無條件支持,直接將自己的票數(shù)累加
if(voters[_to].isVoted){
uint index = voters[_to].index;
proposals[index].voteCount+=voters[voter].weight;
}else{
voters[_to].weight+=voters[voter].weight;
}
voters[voter].weight=0;
}
//投票操作
function vote(uint _index)public{
require(!voters[msg.sender].isVoted,"must not voted");
voters[msg.sender].isVoted=true;
voters[msg.sender].index=_index;
//增加提案的投票數(shù)
proposals[_index].voteCount+=voters[msg.sender].weight;
}
//獲取票數(shù)最高的提案編號
function getWinIndex()public view returns(uint){
uint i=0;
uint index=0;
uint maxCount=0;
for(i=0;i<proposals.length;i++){
if(proposals[i].voteCount>maxCount){
maxCount=proposals[i].voteCount;
index=i;
}
}
return index;
}
//獲取獲勝的提案名稱
function getWinName()public view returns(bytes32){
uint index=getWinIndex();
return proposals[index].name;
}
}
函數(shù)功能測試
1. 設(shè)置賬戶
1號為主持人賬戶,2-8號為選民賬戶
2. 主持人部署合約
輸入提案參數(shù):[“0x7465737400000000000000000000000000000000000000000000000000000000”,“0x8535737400000000000000000000000000000000000000000000000000000000”]
3. 查詢初始化的提案
提案存入到Proposals數(shù)組里面,查看只需要輸入數(shù)組索引即可
4.主持人授權(quán)給每個(gè)選民1票投票權(quán)
5. 查看選民的票數(shù)信息
注意:主持人也有1票權(quán)
6. 選民將自己的票數(shù)委托給其它選民
2號–>3號,3號–>4號,6號–>8號,7號–>6號
注意:選民將票數(shù)委托給其它選民后,無論其它選民是否再次將票數(shù)委托給自己,自己都將沒有投票權(quán)
2號–>3號
3號票數(shù)變?yōu)?
3號–>4號
3號票數(shù)變?yōu)?
4號票數(shù)變?yōu)?
6號–>8號
8號票數(shù)變?yōu)?
7號–>6號
6號票數(shù)仍未0,因?yàn)檫x民已經(jīng)參與過投票,便不可再次參與投票
7.選民進(jìn)行投票
經(jīng)過上輪的投票委托,現(xiàn)在選民情況為:1號有1票,4號有3票,8號有2票,1號投—>提案1,4號投–>提案2,8號投–>提案2
8. 獲取票數(shù)最高的提案編號
提案1有4票,提案2有2票文章來源:http://www.zghlxwxcb.cn/news/detail-795016.html
9.獲取票數(shù)最高的提案名稱
文章來源地址http://www.zghlxwxcb.cn/news/detail-795016.html
到了這里,關(guān)于solidity經(jīng)典案例-----智能投票的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!