現在地

ブロックチェーンEthereum入門 4



目的

今回はトークンを使った投票システムを紹介する。

トークンを使った投票システム

提案(Proposal)に対して各アカウントが賛成か反対かの投票を行い、可決されたらその提案を実行するような投票システムのコントラクトを見てみる。
ここでの提案は、あるアカウントに対するether送金可否である。提案が可決なら当該アカウントへのether送金が実行される。投票権にはトークンを利用し、トークンの保持割合により投票の重み付けを行う。

投票システムコントラクトに対し、上記にて作成したトークン(MyPoint)を投票権として利用するように設定し、投票率がトークンの6割以上あり、賛成票が多ければ提案が実行されるようにしてみる。
トークンの総量は100.00ptなので、たとえばトークンを次のように割り振っておく。

トークンの割り当てと結果の表

割り当て投票例1投票例2投票例3
アカウントトークン(MyPoint)
Main Account55.00 pt賛成賛成反対
Account130.00 pt賛成無投票賛成
Account215.00 pt無投票賛成賛成
Account30 pt投票権なし投票権なし投票権なし
賛成の合計(賛成は+、反対は-)+85+70-5
結果可決可決否決

提案への投票例として、Main Accountの投票は結果に大きな影響を与える(賛成しないと可決となることはない)が、Account3は投票する権利自体がない。
なお、今回のサンプルコントラクトでは賛否同数だと決着がつかない状態のままになってしまう。

それでは、投票システム自体のコントラクトをデプロイし、提案の生成、投票の実施、提案の実行と進んでいく。各アカウントには、表の通りにトークンMyPointを割り振る(ここまで同じ手順を踏んでいるならMain AccountからAccount2に15.00ptを送金すれば同じになる)。

投票システムのコントラクトのデプロイ

トークンのデプロイと同様に、コントラクト画面の 新しいコントラクトを配置 からコントラクトのデプロイ画面に進む。

FROMにMain Accountを選択する。
AMOUNTにこのコントラクトに送金するetherの額を設定する。FROMのアドレスからコントラクトへのether送金となる。
このetherの用途は提案可決時に実行されるether送金の原資である。送金提案が可決されると、コントラクトが保持しているetherから対象Accountへ送金されるようにプログラムされている。

なお、後からコントラクトのether額を増やすことも可能である。この送金はAccount間の送金と同様で、FROMに送金元のアドレス、TOにコントラクトのアドレスを指定して送金すればよい。

以下のリンク先のソースコードを全選択してコピーし、SOLIDITY コントラクトソースコード の枠内に貼り付ける。

配置するコントラクトを選択 でDemocracyを選択する。
コンストラクタパラメーターを決定する。先ほど作成したトークンを投票権として使用し、トークンの6割以上の投票率で投票を有効とするには、下表のように設定する。

項目備考
Shares addressトークンのコントラクトアドレスコントラクトの画面を開いてCopy Addressし、この欄に貼り付け。
Minimum shares for voting60(=100.00ptの6割なので)投票結果が有効となる投票率
Minutes for debate3(単位は分)提案が実行可能になるまでの時間。少なくとも設定した時間を待つ必要があるので、お試しならあまり長くしないほうがよい。

設定値の入力が完了したら、デプロイトランザクションを実行する。
デプロイが完了すれば(デプロイトランザクションがブロックに記録されたら)、コントラクト画面にDemocracyコントラクトが表示される。

提案の作成と確認

コントラクト画面でDemocracyコントラクトをクリックする。

Democracyコントラクト画面では、以下のように コントラクトから読む と コントラクトを書く の2つの表示が見える。それぞれ、コントラクトに実装されているファンクション呼び出しに対応する表示である。

コントラクトから読む側は、ブロックチェーンからの値の読み込みだけを行うファンクション呼び出しに対応し、トランザクションなし(ether不要)で実行できる。引数なしのファンクションは呼び出し値が自動的に表示され、引数ありのファンクションは適切な引数に適用することで呼び出し結果値が表示される。

コントラクトを書く側は、ブロックチェーンへ何らかの状態書き込みを行うファンクション呼び出しに対応し、etherを消費するトランザクションとして実行する必要がある。

ここで、コントラクトを書く側のSelect Functionで実行対象を選択する。提案作成ではNew Proposalを選択する。
次にNew Proposal関数の引数の値を設定していく。
例えば、Account2に10etherを送金するかどうかの提案なら、以下の通り設定を行う。

項目内容実行画面例での値
Beneficiary送金対象のアカウントAccount2のアドレス
Ether amount送金ether量10
Job description任意の説明文字列Account2への送金
Transaction bytecodeここでは使用しない空欄のまま
Execute Fromトランザクションを実行するアカウントMainAccountのアドレス
Send ETHERここでは使用しない0のまま

設定後、EXECUTEをクリックし、トランザクションを実行する。
なお、Execute Fromのアカウントでトランザクションを実行するので、当該アカウントはetherを持っていること(以降でのトランザクション実行時も同様)。

作成した提案の内容を確認する。
再びDemocracyコントラクト画面を開く。
コントラクトから読む で、Proposalsに0を入力すると、上記New Proposalの実行で作成した提案を確認できる。

投票の実行

以下の通り投票してみることとする。

項目MyPoint保持値投票備考
Main Account55.00賛成 
Account130.00賛成 
Account215.00無投票 
Account30無投票投票権がない
賛成の合計値85 
結果可決 

Democracyコントラクト画面を開く。
コントラクトを書く のSelect Functionで実行対象を選択する。
投票ではVoteを選択する。
上記の表のMain Accountとして投票する場合、Vote関数の引数を以下の通り設定して、トランザクションを実行する。

項目内容実行画面例での値
Proposal Number投票対象の提案番号0
Ether amount賛成かどうかはい(チェックを入れる)
Execute From投票者アカウントMainAccountのアドレス
Send ETHERここでは使用しない0のまま

同様に、Acount1での投票(賛成の投票)も実行する。

投票状態確認と提案実行

Democracyコントラクト画面を開く。
コントラクトから読む でProposals=0の状態を確認してみると、投票者数が2人であることが表示される。

送金の提案を実行するためには、締め切り時間(Democracyコントラクトデプロイ時のMinutes for debate)の経過まで待つ必要がある。経過すれば、Voting Deadlineの表示がXX分後からXX分前に変わる。なお、あまりにも長い時間設定にしてしまい待ちきれなくなってしまったなら、Democracyコントラクトを再デプロイして設定変更してほしい。
時間が経過したら、 コントラクトを書く のSelect FunctionでExecute Proposalを選択する。

Execute Proposal関数の引数の値を以下の通り設定して、トランザクションを実行する。

項目内容実行画面例での値
Proposal Number投票対象の提案番号0
Execute Fromトランザクションを実行するアカウントMainAccountのアドレス
Send ETHERここでは使用しない0のまま

トランザクションがブロックチェーンに書き込まれれば、DemocracyコントラクトからAccount2にetherが送金されたはずだ。(例の通りなら10ether分の増減があるはず)

提案実行後、Democracyコントラクトの状態を確認してみると、以下の通りとなる。
(Democracyコントラクトの コントラクトから読む 側でProposals=0を表示させる)
Open to voteは投票受付状態(提案実行済み締め切りのNO)、Proposal passedは議決状態(可決のYES)が表示されている。

他の投票パターンでの実行

同様に否決の投票パターンなども試してみてほしい。別のトークンを使うように変更したい場合はDemocracyコントラクトの再デプロイが必要になる。

また、トークン不保持アカウントでの投票がどうなるかも確認してみるとよい。
例えば、上記例の手順通りであればAcount3はトークンMyPointをまだ保持していない。投票トランザクション(Vote)を実行しようとすると、以下のようなエラーとなり実行できないはずだ。(ただし、Acount3がetherを保持しているとする。保持していないとトランザクション自体が実行できないだけである)
トークンが投票権として機能していることが確認できる。

最後に

Ethereumではコントラクトにより、ブロックチェーン基盤上に任意の処理ロジックを持つシステムを実現できる。本コラムではサンプルコードを利用しただけであったが、次は実際にSolidity言語でコードを書き、コントラクトの開発を試していただければと思う。

ブロックチェーンEthereum入門コラムはこれで完結となる。入門としてお役に立つ情報となったなら幸いだ。
Ethereumについてさらに理解を深めるには、以下のサイトをよく覗いていくのがよいかもしれない。

ブロックチェーン技術は分散台帳管理の基盤であり、過去の全取引履歴(トランザクション履歴)を安全に保持していくことができる。仮想通貨の基盤技術として登場したブロックチェーンだが、それに留まらない可能性を秘めていると思われる。ブロックチェーンは発展途上であり、得意とする領域を見極め、仮想通貨の次なるキラーアプリとなるアイディアが待たれている状況なのかもしれない。
本コラムではEthereumを取り上げたが、ブロックチェーン基盤の選択肢は複数出てきている。ブロックチェーン基盤の開発競争にも注目だろう。