簡単な投票システムのコントラクトを作成してみました。
今回は、以下のページを参照し投票システムを作成しています。
Solidity
Solidity by Example Voting
作成したコントラクトの概略は以下となります。
1, コントラクト生成時に候補者名を入力し、そのコントラクト生成者が議長となる。
2, 議長は投票者に対して、投票権を与える。
3, 投票権を与えられた投票者は、候補者名を入力して投票できる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
pragma solidity ^0.4.18; contract Voting { //投票者ストラクト struct Voter{ bool voted; //投票したかどうか trueなら投票済 初期値はfalse uint weight; //投票の重み 初期値は0 } //投票者マッピング mapping(address => Voter) public voters; //議長 address public chairperson; //候補者リスト bytes32[] public candidateList; //候補者名と得票数 mapping (bytes32 => uint) public votesReceived; //コンストラクタ function Voting(bytes32[] candidateNames) public { chairperson = msg.sender; //議長を設定 candidateList = candidateNames; //候補者名を登録 } //議長が投票者に投票権を与える function giveRightToVote(address voter) public { //議長であることかつ投票者が未投票であること require((msg.sender == chairperson) && !voters[voter].voted); voters[voter].weight = 1; } //候補者名を記述して投票する function voteForCandidate(bytes32 candidate) public { require(validCandidate(candidate)); //正しい候補者名が入力されたか Voter storage sender = voters[msg.sender]; require((sender.weight>0) && !sender.voted); //投票権を持ちかつ未投票であること votesReceived[candidate] += sender.weight; sender.voted = true; //投票完了 } //候補者の得票数を知る function totalVotesFor(bytes32 candidate) view public returns (uint) { require(validCandidate(candidate)); return votesReceived[candidate]; } //候補者名チェック function validCandidate(bytes32 candidate) view public returns (bool) { for(uint i = 0; i < candidateList.length; i++) { if (candidateList[i] == candidate) { return true; } } return false; } } |
6〜9行目
投票者の構造体です。構造体として宣言した型は、12行目のmappingにおいて設定しています。boolのデフォルト値はfalseで、これを未投票の状態としています。投票の際にtrueに指定し(44行目)、投票完了としています。
8行目
参照ページでは投票権を他の投票者に移譲する仕組みを取り入れているためweightは1よりも大きくなる場合があります。今回の投票システムでは、投票者は1票よりも多く持つことはありません。
24〜27行目
コントラクト生成時に一度だけ呼ばれるコンストラクタです。この時に、以下のような候補者を入力します。
1 |
["漱石","治","春樹"] |