這個(gè)例子相對復(fù)雜一些,用到了以太坊編程語言Solidity的很多特性。例子實(shí)現(xiàn)了一個(gè)投票智能合約。電子投票系統(tǒng)的一個(gè)主要問題是如何分配合理的權(quán)限給正確的人,并且要防止篡改。這個(gè)例子不能解決所有問題,但是實(shí)現(xiàn)了如何去委托投票,整個(gè)投票計(jì)數(shù)過程是自動(dòng)且完全透明的。
功能上首先要為投票設(shè)立一個(gè)簡稱創(chuàng)建一個(gè)合約,發(fā)起者作為主席來給每一個(gè)獨(dú)立的地址分配權(quán)限。每一個(gè)參與者可以自己投票或者委托給信任的人。程序最后會(huì)返回得票數(shù)最多的那個(gè)提議。
// 一個(gè)有委托功能的投票系統(tǒng)
contract Ballot {
// 定義一個(gè)復(fù)雜類型,后面作為變量來使用,
// 代表一個(gè)投票人。
struct Voter {
unit weight; // weight在代表投票過程中會(huì)累積
bool voted; // 如果值為true,代表這個(gè)投票人已經(jīng)投過票
address delegate; // 投票人地址
unit vote; // 當(dāng)前投票的索引
}
// 代表一份提議的數(shù)據(jù)結(jié)構(gòu)
struct Posposal {
bytes32 name; // 提議的名稱
unit voteCount; // 提議接受的投票數(shù)
}
// 定義投票發(fā)起人
address public chairperson;
// 這個(gè)狀態(tài)變量存儲(chǔ)了所有潛在投票人
mapping(address => Voter) public voters;
// 定義動(dòng)態(tài)數(shù)組存儲(chǔ)所以提議
Posposal[] public proposals;
// 傳入提議名稱來定義一個(gè)投票對象
function Ballot(bytes32[] proposalNames){
chairperson = msg.sender;
voters[chairperson].weight = 1;
// 把傳入的提議名稱創(chuàng)建一個(gè)提議,并加入到前面定義的提議數(shù)組
for(unit i = 0; i < proposalNames.length; i++){
// 創(chuàng)建一個(gè)臨時(shí)提議對象,加入提議數(shù)組
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0;
}));
}
}
// 給投票人分配投票權(quán)限,這個(gè)操作只有發(fā)起人(主席)才可以
function giveRightToVote(address: voter){
if(msg.sender != chairperson || voter.voted) {
throw;
}
voters.weight = 1;
}
// 委托投票給另外一個(gè)投票人
function delegate(address to){
// 找出委托發(fā)起人,如果已經(jīng)投票,終止程序
Voter sender = voters[msg.sender];
if(sender.voted)
throw;
while(voters[to].delegate != address[0] &&
voters[to].delegate != msg.sender){
to = voters[to].delegate;
}
// 發(fā)起人、委托人不能是同一個(gè),否則終止程序
if(to == msg.sender){
throw;
}
// 標(biāo)識(shí)發(fā)起人已經(jīng)投過票
sender.voted = true;
sender.delegate = to;
Voter delegate = voters[0];
if (delegate.voted) {
// 投票成功,投票總數(shù)加上相應(yīng)的weight
proposals[delegate.vote].voteCount += sender.weight;
}
else {
// 如果還沒投票,發(fā)起人weight賦值給委托人
delegate += sender.weight;
}
}
// 投票給某個(gè)提議
function vote(unit proposal) {
Voter sender = voters[msg.sender];
if (sender.voted)
throw;
sender.voted = true;
sender.voter = proposal;
proposals[proposal].voteCount += sender.weight;
}
// 找出投票數(shù)最多的提議
function winningProposal() constant returns (winningProposal)
{
unit winningVoteCount = 0;
for (unit p = 0; p < voteCount; p++) {
if (proposals[p].voteCount > winningVoteCount){
winningVoteCount = proposals[p].voteCount;
winningProposal = p;
}
}
}
}
以上就是完整的投票智能合約,對新人有點(diǎn)復(fù)雜,需要花點(diǎn)時(shí)間學(xué)習(xí),后面我們通過更多例子加深對代碼的理解。
原文:http://wangxiaoming.com/blog/2016/05/11/blockchain-tech-voting/