ホームページ >テクノロジー周辺機器 >IT業界 >堅実さの落とし穴:イーサリアムの乱数生成
この記事は、Ioliteが後援し、作成しました。 SitePointを可能にしたパートナーをサポートしてくれてありがとう。
Solidityは、完全なコードがないため、コードとその意図した使用に関連する問題を含む比較的新しい言語です。この記事では、イーサリアムスマートコントラクトへの入力として乱数を使用する場合、ベストプラクティスと落とし穴を導きます。
キーポイント
block.timestamp
とblock.difficulty
に依存すると、鉱夫はこれらの値を操作できます。 堅牢性乱数生成堅牢性乱数を作成できません。実際、乱数を作成するすべてのアルゴリズムは擬似ランダムです。言語は完全に乱数を作成できません。堅牢性の問題は、複雑なアルゴリズムが高すぎるため、より基本的なソリューションが使用されていることです。それとは別に、複数のノードで実行されるため、Solitidityコードは決定論的でなければなりません。乱数を一度に生成し、複数のノードで使用できるアルゴリズムが必要です。乱数を生成するためにクロック時間などの情報は利用できないため、他のオプションを探す必要があります。開発者として、攻撃者は特定の状況で結果を予測できるため、この問題に注意する必要があります。
最も一般的に使用されるアルゴリズムの1つは、「線形合同ジェネレーター」(LCG)です。それは最も古いアルゴリズムの1つであり、高速で理解しやすいです。 LCGは、メモリが限られているだけなので、組み込みシステムに適しています。ただし、パスワードセキュリティアプリケーションでは動作しません。それにもかかわらず、ガスコストの点で高速アルゴリズムが安価であるため、スマートコントラクトではまだ使用されています。
アルゴリズム自体は、次の手順を実行します
入力を受け入れます
block.timestamp
&block.difficulty
マイナーがトランザクションを確認するたびに、a block.timestamp
が割り当てられます。宝くじ契約のプレーヤーはそれを制御できません。乱数を作成するために使用されるこのコードを見てみましょう。
<code class="language-solidity">function random() private view returns (uint8) { return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251); }</code>
ここでgistを見つけます。
このコードは、最初にブロックタイムスタンプと難易度をハッシュします。次に、ハッシュ値を整数に変換し、それを251で割って0〜250の間の整数を取得します。ただし、このコードの問題は、鉱夫が勝者を選択することを信頼してはならないということです。
宝くじのスマートコントラクトに提出できる数字。ユーザーは、Ethereumアドレスで選択したハッシュ番号を持っている必要があります。これにより、かなり乱数が得られます。
ChainLink VRFは、ChainLinkノードがイベントを読み取り、乱数を返すブロックチェーンにイベントを追加します。オンチェーンランダムされたチェックは、いわゆるVRFコーディネーターを介して実行されます。これは、Oracleからの特定のキーハッシュとユーザーからのシードフレーズ、およびいくつかの暗号化を使用して、数字が真の乱数であることを確認します。このようにして、公平な乱数を取得できます。
より良いオプションは、イーサリアム目覚まし時計を使用することです。これは、スケジューリングトランザクションをEthereumブロックチェーンで後で実行できるようにするサービスです。このサービスは完全に信頼できません。つまり、サービス全体がスマートコントラクトとして実行されます。基本的に、Ethereumアラームはブロック番号を使用してトランザクションをスケジュールします。これは、契約が単独で開始されることを意味しないことに注意してください。 「select winner」関数(エーテル報酬)を呼び出すことにユーザーの関心に依存しています。もちろん、誰もあなたの機能を呼び出さなければ、あなたの宝くじは失敗します。
random.orgは、JSONを介してランダムデータソースを提供するAPIを提供します。 Ethereum Smart Contractsは、このデータソースを使用して、乱数を選択するためのアルゴリズムをフィードすることができます。セキュリティは重要であるため、デジタル署名を使用できます。ランダムデータはrandom.orgによって署名されます。データの整合性を確認して、それが実際にrandom.orgからであり、データが改ざんされていないことを証明できるようにすることができます。
Randaoは、ブロックチェーンフィールドの新しいプロジェクトであり、乱数の提供に完全に焦点を当てています。彼らはあなたに乱数を与えるためにオラクルとスマートコントラクトの組み合わせを使用します。ただし、Randaoサービスは現在非常に遅いです。頻繁に使用するアプリがある場合、これは理想的ではありません。
設定したターゲット番号に一致するまでブロック番号をチェックするコードでモニターを使用することもできます。
<code class="language-solidity">function random() private view returns (uint8) { return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251); }</code>
ソース。 gist。
ioliteは、スマートコントラクトを作成するために自然言語を受け入れる製品を作成しています。 Stanford Natural Language Processing(NLP)エンジンを使用しています。これは、高速適応エンジン(FAE)と呼ばれます。 Ioliteは、コミュニティトレーニングのためにSolidityの専門家に依存しています。 Solidity Expert(Contributor)は、1つ以上の文を含む構造を定義し、対応するスマートコントラクトコードに追加できます。
スタンフォードNLPエンジンは、複雑な言語を理解するように設計されています。言語の複雑さは、マシントレーニングの量に依存します。適切なトレーニングの後、エンジンは複雑なスマートコントラクトを作成できます。複雑な契約は実際にはそれほど複雑ではないため、FAEはそのような契約を作成することができます。専門家は、リクエストを複数の小さなコードのスニペットに分割し、文に追加できます。
誰かが複数の文に入ると、「複雑な」契約を構築するための対応する構造/文を探します。貢献者は、新しい構造のマイニングプロセスを通じてioliteトークンの報酬を受け取ります。
結論
ご覧のとおり、真のランダム入力を生成するのは簡単ではありません。ランダム性のソースとして、block.timestamp
、now
に依存しないでください。優れたソリューションには、いくつかの擬似ランダムデータ入力を組み合わせて、オラクルまたはスマートコントラクトを使用して信頼性を高めることが含まれます。スマートコントラクトに入力されたデータを誰も改ざんできないことを100%確信する必要があります。 block.blockhash
堅牢性(FAQ)
の乱数生成のFAQ 堅牢性で乱数を生成するのが難しいのはなぜですか?
堅牢性で乱数を生成する一般的な方法は何ですか?
keccak256ハッシュ関数を使用して乱数を生成するリスクは何ですか?
Oracle Serviceを使用して堅実さで乱数を生成する方法は?
コミットメント - 乱数を生成する際のスキームを明らかにすることの役割は何ですか?
スマートコントラクトで真の乱数を生成することが重要なのはなぜですか?
ブロックハッシュ関数を使用して、堅牢性で乱数を生成できますか?
現在のブロックタイムスタンプを入力として使用して乱数を生成することには大きな制限があります。鉱夫は、彼らが採掘するブロックのタイムスタンプにある程度の影響を及ぼします。つまり、乱数によって生成される出力に影響を与えるためにタイムスタンプを操作する可能性があります。
Randao(乱数DAO)ビーコンは、乱数を生成するための分散型で透明な方法です。 Randao Beaconの参加者は、秘密の数字を約束します。秘密の数字は明らかにされ、組み合わされて乱数が生成されます。このアプローチは、単一の参加者が乱数によって生成される出力に影響を与えることができないように設計されています。
堅牢性およびその他のブロックチェーンプラットフォームの乱数生成の改善に関する研究と提案が進行中です。たとえば、Ethereum 2.0(Ethereum Networkへの今後のアップグレード)には、組み込みの乱数ジェネレーターが含まれると予想されます。ただし、これらの改善が実装される前に、開発者は既存のアプローチとその固有の制限と潜在的なセキュリティリスクを引き続き使用する必要があります。
以上が堅実さの落とし穴:イーサリアムの乱数生成の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。