ランダムな番号の生成
Ethereumのsmart contractでは、現状単一のトランザクションでランダムな値を生成することはできませんが、複数のユーザーの入力値と、ハッシュ関数を用いることでランダムな値を生成することが出来ます。
仕組みの要点は以下になります
はじめに、以下のような変数を用意しておきます。
mapping(address => bytes32) userHash; //addressとユーザーが選んだ番号を紐づける
uint random; //結果として得られるrandom number
phase1. ユーザーは自分で選択した任意の番号(n)をcontractに提出し、contractにはそのhash値hash(n)を保持する。
例
function postNum(uint _num) public {
userHash[msg.sender] = keccak256(_num);
}
phase2. ユーザーはphase1で選択した番号nをcontractに提出し、hash(n)がコントラクトに保時されているhash値に一致する場合は、nを正当な値として、randam numberの結果に追加します。
例
function commitNum(uint _num) public {
require(keccak256(_num) == userHash[msg.sender]);
random += _num;
}
phase3. 一定時間経過後のrandom(ユーザーが選んだランダム値nの合計)をランダムナンバーとして利用します。
phase1で n のhash値 hash(n)を登録させ(この時点でnの合計値は確定しているが確認は出来ない状態)、phase2でnとhash値を提出させることで、nの合計値を計算します。
このように、phase1でhashのみを集めることで、結果は確定しているが、その値は確認できないという状態を作り出すことで、マイナーにもランダム番号の出力値を確認することが出来ない状態を作ることが出来ます。
しかし、実運用の観点ではユーザーにgasを負担させることになるため、番号nの提出に対して何らかのインセンティブ設計が必要になるかと思われます。
それをコンセプトとして提案しているコントラクトが、randaoというコントラクトですが、gas代よりも高い報酬を支払えるようにできるほどrandom numberに需要があるかどうかというのがポイントになりそうです。
ちなみに、このランダム番号生成の仕組みを使ったdappsゲームを開発していて公開予定でして、うまくいくかどうか検証できれば面白いなと思ってます。