solidity系列教程<十二>投票合約實(shí)現(xiàn)

注意點(diǎn):mapping(string => uint) aa芹助; 當(dāng)mapping的key類型為string時(shí)候,不能將aa聲明未public類型
其次當(dāng)我們使用string類型作為函數(shù)參數(shù)的時(shí)候徒坡,目前版本需要加入pragma experimental ABIEncoderV2;否則無(wú)法編譯通過(guò);

pragma solidity ^0.4.14;
pragma experimental ABIEncoderV2;

contract Vote {
     /* 1箍鼓、 合約主人初始化候選人列表
        2崭参、 合約主人才能賦予某個(gè)地址投票權(quán)
        2、 每個(gè)人都能給某一個(gè)候選人投票款咖,或者代理給其他人投票何暮,不能重復(fù)投票
        3、 合約能計(jì)算誰(shuí)的投票數(shù)最多
     */
     // 定義一個(gè)投票的結(jié)構(gòu)體
     struct Voter {
          uint weight; // 累計(jì)的權(quán)重
            bool voted; // 是否已經(jīng)投票
            address delegate; // 委托的投票代表
            uint vote; // 投票的索引
     }
     // 定義一個(gè)需要投票的結(jié)構(gòu)體
     struct NeedVoter{
          string name;
            uint voteCount;
     }
     // 定義一個(gè)需要投票的數(shù)組
     NeedVoter[] public needVoters; 
     address ownerAddress;
    // mapping存儲(chǔ)每一個(gè)投票人的地址
     mapping(address => Voter) voters;
     string[] public winName;
     uint public winCount;
    uint public len;
    // 初始化候選人列表
    constructor (string[] personName)public{

         // 保存創(chuàng)建此合約的地址
         ownerAddress = msg.sender;
         // 初始化候選人數(shù)組
         len = personName.length;
         for(uint i=0;i< personName.length;i++){
              needVoters.push(NeedVoter({
                     name: personName[i],
           voteCount: 0})
                );
         }
    }
    // 合約主人才能賦予某個(gè)地址投票權(quán)
    function giveRightToVote(address voter)public{
         // 這個(gè)地址首先有三個(gè)要求
         // 1铐殃、必須是合約持有者調(diào)用的此方法
         require(msg.sender == ownerAddress, "只有合約持有者才能賦予此地址投票權(quán)");
         // 2海洼、此地址必須沒(méi)有投過(guò)票
         require(!voters[voter].voted, "此地址已經(jīng)投票了");
         // 3、此地址的投票權(quán)重為0
         require(voters[voter].weight==0);
         voters[voter].weight = 1;
    }
    // 投票
    function vote(uint personal)public{
            // 1富腊、給誰(shuí)投票
            // 2坏逢、投票后我自己要改變什么內(nèi)容
            // 3、給投票的人改變什么內(nèi)容
            // 拿出我們存在mapping里面的voters
            Voter storage sender = voters[msg.sender];
           require(sender.weight!=0,"nihai你還meiyou你還沒(méi)有toupiao你還沒(méi)有投票quanxian");
          require(!sender.voted, "已經(jīng)投過(guò)票,不能重復(fù)投票");
            sender.voted = true;
      sender.vote = personal;
            // 改變索引為personal的count
            // 如果你的選中的人超出了數(shù)組界限是整,則會(huì)自動(dòng)拋出肖揣,并回滾所有的改變
            needVoters[personal].voteCount +=sender.weight;
    }
    // 代理投票,將投票權(quán)代理給其他人
    function delegate(address to)public{
         // 有哪幾種情況不能代理?
         /*
                1浮入、你必須沒(méi)有投過(guò)票龙优,否則無(wú)法代理
                2、你不能代理給你自己
                3事秀、你不能代理給一個(gè)不存在的人
                4彤断、你不能代理給一個(gè)已經(jīng)投過(guò)票的人:分2種,一種是已經(jīng)投票了但是沒(méi)有代理給別人易迹,一種是你的代理已經(jīng)代理給了別人(這種就是要防止循環(huán)代理)
         */
       //  拿到引用
         Voter storage sender = voters[msg.sender];
         require(!sender.voted, "您已經(jīng)投票");
         require(msg.sender != to , "不能自己代理給自己");
         require(voters[to].weight!=0,  "不能自己代理給沒(méi)有投票權(quán)限的人");
        // require(voters[to].delegate==address(0) && !voters[to].voted, "你代理的人已經(jīng)投票宰衙,無(wú)法代理");
         while(voters[to].delegate != address(0)){
              to = voters[to].delegate;
                // 如果循環(huán)引用則死循環(huán)
                require(to!=msg.sender, "循環(huán)代理");
         }
         // 能到這個(gè)地方那么前面的都通過(guò)了
         // 修改需要代理的sender 的內(nèi)容
         sender.voted = true;
         sender.delegate = to;
         // 修改代理的voter內(nèi)容
         // 拿到代理的voter
         Voter storage delegate_ = voters[to];
         if(delegate_.voted){
             // 代理的人已經(jīng)投票,把sender的票加到needVoters
             needVoters[delegate_.vote].voteCount += sender.weight;
         }else {
              // 代理的人沒(méi)有投票
                delegate_.weight += sender.weight;
         }
    }
    // 計(jì)算勝出
    function winningPersonal()public{
         uint winPoint = 0;
         // 每次調(diào)用計(jì)算勝出的要清零數(shù)組
         winName.length = 0;
         uint count = needVoters[0].voteCount;
         for(uint i=1;i< needVoters.length;i++){
              if(count < needVoters[i].voteCount){
                     winPoint = i;
                     count = needVoters[i].voteCount;
                }
         }
         // 賦值最多的計(jì)數(shù)
         winCount = count;
         // 查看有沒(méi)有并列相同票數(shù)的人
         for(uint j=0;j< needVoters.length;j++){
              if(count == needVoters[j].voteCount){
                      winName.push(needVoters[j].name);
                }
         }
    }
    
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市睹欲,隨后出現(xiàn)的幾起案子供炼,更是在濱河造成了極大的恐慌,老刑警劉巖句伶,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劲蜻,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡考余,警方通過(guò)查閱死者的電腦和手機(jī)先嬉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)楚堤,“玉大人疫蔓,你說(shuō)我怎么就攤上這事∩矶” “怎么了衅胀?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)酥筝。 經(jīng)常有香客問(wèn)我滚躯,道長(zhǎng),這世上最難降的妖魔是什么嘿歌? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任掸掏,我火速辦了婚禮,結(jié)果婚禮上宙帝,老公的妹妹穿的比我還像新娘丧凤。我一直安慰自己,他們只是感情好步脓,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布愿待。 她就那樣靜靜地躺著浩螺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仍侥。 梳的紋絲不亂的頭發(fā)上要出,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音农渊,去河邊找鬼厨幻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛腿时,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饭宾,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼批糟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了看铆?” 一聲冷哼從身側(cè)響起徽鼎,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弹惦,沒(méi)想到半個(gè)月后否淤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棠隐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年石抡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片助泽。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡啰扛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嗡贺,到底是詐尸還是另有隱情隐解,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布诫睬,位于F島的核電站煞茫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏摄凡。R本人自食惡果不足惜续徽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望架谎。 院中可真熱鬧炸宵,春花似錦、人聲如沸谷扣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至裹匙,卻和暖如春瑞凑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背概页。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工籽御, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惰匙。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓技掏,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親项鬼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哑梳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容