投票合约编写
pragma solidity ^0.4.0; contract VoteDemo{ //声明一个投票者的结构 struct Voter{//在下面可以直接定义投票者 uint weight;//投票人的权重 bool voted;//是否已经投票 address delegate;//委托代理人投票,投票者的地址 uint vote;//代表当前投票人投的是哪一个主题 } //投票主题的结构,有主题名字,有投票数量 struct Posposal{ bytes name; uint voteCount;//记录当前投票主题投了多少票 } address public chairperson;//定义投票者发起人 mapping(address=>Voter) public voters;//所有人的投票人,和voter这个投票的地址的映射 //通过voter变量记录下来.地址和vouter结构的映射 //具体的投票主题,定义所有的投票主题 Posposal[] public posposals; //构造函数,初始化投票发起者 function voteDemo(bytes8[] peposposalName) {//传进来的额也是一个数组类型的全部投票人 //初始化投票的发起人,就是当前合约的部署者 chairperson=msg.sender//投票的发起者 //给当前发起人投票权 voters[chairperson].weight=1;//当前投票人有一票的权重 //其他的默认为false,0 //初始化投票的主题 for (uint i=0; i<peposposalName.length;i++){ posposals.push(Posposal({name:peposposalName[i],voteCount:0}))//投票主题数组。push就是加元素进去 } } //添加投票者 //接收投票人地址的参数 function giveRightToVote(address _voter) { //判断只有投票的发起人才能添加投票者 //添加的投票者不能是已经参加过投票的 if (msg.sender !=chairperson|| voters[_voter].voted){//如果当前投票人不是发起者的话或者是已经投过票了 throw;//抛出异常 } //将合格的投票者赋予权重 voters[_voter].weight=1//合格的投票者 //将自己的票委托给to来投 function delegate(address to) { //检查当前交易的发起者是不是已经投过票了 Voter sender=voters[msg.sender]//定义当前委托人 //如果是的话,程序终止 if (sender.voted){ throw;//假如已经投票过的话,就抛出异常 } while (voters[to].delegate!=address(0)){ to=voters[to].delegate //如果发现最终的委托人是自己的话,终止 if(to==msg.sender){//如果当前的委托人返回到自己的haul,程序就终止 throw; } } //交易的发起者不能再投票了 sender.voted=true//可以在形式投票权 //设置交易的发起者是投票代理人 sender.delegate=to //定义投票者 Vouter delegate=voters[to] if (delegate.voted){ //假如当前代理人已经投过票了的话 posposals[delegate.vote].voteCount+=sender.weight;//当前委托人的全部主题数量+代理人的数量 } //否则的话,当前代理人的投票权就是之前委托这个代理人的投票权 else{ delegate.weight+=sender.weight//加上委托人的投票权 } //投票开始 function vote(uint pid) { //找到投票者 Voter sender=voters[msg.sender]; //检查是不是已经投过票了 if (sender.voted){ //如果投票过,则终止程序 throw; }else{ sender.voted=true; sender.vote=pid; posposals[pid].voteCount+=sender.weight } } //计算票数最多的主题 function winid() constant returns(uint winningid){//copnstant是用常量来修饰 //得到票数主题最多的 uint winningCount=0;//首先声明当主题最多的Wie0 //循环这个之前定义的投票数组,得到投票数最多得到 for (uint i=0;i<posposals.length;i++){ //循环这个投票数组,找到投票最多的那个主题 if (posposals[i].voteCount>winningCount){ winningCount=posposals[i].voteCount;//重新赋值这个得票数最多的部分 winningid=i;//得到这个获胜的id } } } function winname() constant returns(bytes8 winnername) { winnername=posposals[winid()].name;//说明一下,这个winid是方法winid,得到之前的那个返回值,得票数最多的返回值 } } }
部署:Mist上面部署,选择相对应的合约contract(一个钱包地址代表一个账号)