Lesson 4 Chapter4 乱数
Solidityでの乱数生成。
keccak256経由での乱数生成
uint random = uint(keccak256(now, msg.sender, randNonce)) % 100;
randNonce++;
uint random2 = uint(keccak256(now, msg.sender, randNonce)) % 100;
-
クリプトゾンビ Lesson 1 Chapter11 Keccak256と型キャスト
Lesson 1 Chapter11 Keccak256と型キャスト Keccak256(ケッチャック) イーサリアムにはSHA3のバージョンの一つであるkeccak256関数が組み込まれている。 k ...
keccakで入力値をランダムなハッシュ値に変換しそのハッシュ値をuint型に変換したらその末尾2桁のみ残すように% 100をする。
こうして0から99の間の、完全にランダムな数値を生成する。
この方法は、不誠実なノードの攻撃に対して脆弱である
悪意のノード管理者が 自分のノードに向けて 乱数により勝敗を決める関数を動かして勝ちのトランザクションを発行すると不正に利益を出すことが可能だ。
randNonce++;
return uint(keccak256(now, msg.sender, randNonce)) % _modulus;
}
安全ではない擬似乱数生成
ブロックチェーンに記録された値の利用
基本的に、乱数生成のインプットとしてブロックチェーンに記録されるデータを利用すると潜在的にマイナーがその乱数を悪意を持って操作できてしまう危険性があります。
例えば、乱数生成に利用されうるブロックチェーンのデータとしては以下のようなデータがあげられます。
block.coinbase:ブロックを生成したマイナーのアドレス
block.difficulty:PoW由来のブロックの生成難易度
block.gaslimit:ブロックに含めることができる最大のgas量
block.number:ブロック高
block.timestamp:ブロックが生成された時間
これらのうちdifficultyやtimestampは一見、乱数として利用することができるように感じますが、これらの値もマイナーがブロックチェーンに記録することになるのでマイナーに不正操作されてしまう脆弱性があります。例えば、block.timestampを乱数として利用したゲームで高額報酬が得られる場合、マイナーが不正操作するインセンティブになってしまうのです。
なのでこのような値をベースに擬似乱数を生成することは避けなければなりません。ブロックハッシュを利用した擬似乱数生成
EVMにおいて、block.blockhash(uint blockNumber)を利用するとblockNumberとして与えられたブロック高におけるブロックハッシュ値を得ることができます。
例えば、以下のようなブロックハッシュが考えられます。
block.blockhash(block.number):トランザクションを処理しているブロックのハッシュ
block.blockhash(block.number -1 ):直近のブロックのハッシュ
block.blockhash():256ブロック前のブロックハッシュ(スケーラビリティのため得られるブロックハッシュは256ブロック前までに制限されています)
これらのうち、block.blockhash(block.number)については0x00が返ってきてしまうので注意しなければなりません。
なぜなら、この関数を処理している時点ではそのブロック高のハッシュ値は決まっていないからです。
また、block.blockhash(block.number-1)やblock.blockhash()については他のコントラクトでinternal messageにより同じ関数を呼び出すことができてしまうので、複数のコントラクトで同じランダム値が生成されてしまう脆弱性があります。
さらに、ブロックハッシュの他の活用方法として任意の値saltを用いたblock.blockhash(block.number - salt)などを擬似乱数として活用することも考えられます。
例えば、コントラクトに任意の変数saltをprivate修飾子をつけて保持していれば他のコントラクトがsaltを参照することを防ぐとともに上記のblock.blockhash(block.number - salt)を利用することができます。
しかし、saltについてはオンチェーンでの参照を防ぐことはできますが、web3.eth.getStorageAt()などでオフチェーンから参照することができてしまいランダム値の予測をすることができてしまうのです。
以上のようにブロックハッシュを用いた擬似乱数の安全な生成も難しいことが分かります。より安全な擬似乱数生成
以上のように基本的にブロックチェーン由来のデータを活用した擬似乱数生成はマイナーが不正操作するインセンティブを与えてしまったり、同じブロックに含まれると複数のコントラクトで同じランダム値が得られてしまうという脆弱性がありました。
出典 スマートコントラクトでの擬似乱数生成について
https://blockchain.gunosy.io/entry/prngs-in-smartcontract
ではイーサリアムではどうやって安全に乱数を生成するのだろう?
prev
-
クリプトゾンビLesson 4 Chapter3 ゾンビ・バトル
新規コントラクト作成の復習 条件 Solidity version ^0.4.19を用いることを宣言 zombiehelper.solをimport ZombieHelperを継承するZombieBa ...
next
-
クリプトゾンビLesson 4 Chapter5 ゾンビが闘う
Lesson 4 Chapter5 ゾンビが闘う 仕様 自分のゾンビから一体を選び,さらに攻撃する相手のゾンビを選ぶ。 攻撃するゾンビは勝率70%、守備するゾンビは30%の勝率となる。 全ゾンビ(攻撃 ...