这个例子相对复杂一些,用到了以太坊编程语言Solidity的很多特性。例子实现了一个投票智能合约。电子投票系统的一个主要问题是如何分配合理的权限给正确的人,并且要防止篡改。这个例子不能解决所有问题,但是实现了如何去委托投票,整个投票计数过程是自动且完全透明的。
功能上首先要为投票设立一个简称创建一个合约,发起者作为主席来给每一个独立的地址分配权限。每一个参与者可以自己投票或者委托给信任的人。程序最后会返回得票数最多的那个提议。
// 一个有委托功能的投票系统
contract Ballot {
// 定义一个复杂类型,后面作为变量来使用,
// 代表一个投票人。
struct Voter {
unit weight; // weight在代表投票过程中会累积
bool voted; // 如果值为true,代表这个投票人已经投过票
address delegate; // 投票人地址
unit vote; // 当前投票的索引
}
// 代表一份提议的数据结构
struct Posposal {
bytes32 name; // 提议的名称
unit voteCount; // 提议接受的投票数
}
// 定义投票发起人
address public chairperson;
// 这个状态变量存储了所有潜在投票人
mapping(address => Voter) public voters;
// 定义动态数组存储所以提议
Posposal[] public proposals;
// 传入提议名称来定义一个投票对象
function Ballot(bytes32[] proposalNames){
chairperson = msg.sender;
voters[chairperson].weight = 1;
// 把传入的提议名称创建一个提议,并加入到前面定义的提议数组
for(unit i = 0; i < proposalNames.length; i++){
// 创建一个临时提议对象,加入提议数组
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0;
}));
}
}
// 给投票人分配投票权限,这个操作只有发起人(主席)才可以
function giveRightToVote(address: voter){
if(msg.sender != chairperson || voter.voted) {
throw;
}
voters.weight = 1;
}
// 委托投票给另外一个投票人
function delegate(address to){
// 找出委托发起人,如果已经投票,终止程序
Voter sender = voters[msg.sender];
if(sender.voted)
throw;
while(voters[to].delegate != address[0] &&
voters[to].delegate != msg.sender){
to = voters[to].delegate;
}
// 发起人、委托人不能是同一个,否则终止程序
if(to == msg.sender){
throw;
}
// 标识发起人已经投过票
sender.voted = true;
sender.delegate = to;
Voter delegate = voters[0];
if (delegate.voted) {
// 投票成功,投票总数加上相应的weight
proposals[delegate.vote].voteCount += sender.weight;
}
else {
// 如果还没投票,发起人weight赋值给委托人
delegate += sender.weight;
}
}
// 投票给某个提议
function vote(unit proposal) {
Voter sender = voters[msg.sender];
if (sender.voted)
throw;
sender.voted = true;
sender.voter = proposal;
proposals[proposal].voteCount += sender.weight;
}
// 找出投票数最多的提议
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;
}
}
}
}
以上就是完整的投票智能合约,对新人有点复杂,需要花点时间学习,后面我们通过更多例子加深对代码的理解。
原文:http://wangxiaoming.com/blog/2016/05/11/blockchain-tech-voting/