投票合约编写

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(一个钱包地址代表一个账号)

 

posted @ 2019-04-04 02:47  风不再来  阅读(377)  评论(0编辑  收藏  举报