【Solidity】第7章第5回:ランダム性の実装と注意点

本記事では、スマートコントラクトにおけるランダム性の実装方法と、それに伴う課題や注意点について詳しく解説します。ランダム性は、ゲームや抽選機能など多くのDAppで重要な役割を果たしますが、ブロックチェーン環境で安全に実現するためには特別な配慮が必要です。
0. 記事の概要
この記事を読むメリット
- ランダム性の重要性を理解:ランダム性がスマートコントラクトでどのように使われるかを学べます。
- 実装方法を習得:Solidityで安全にランダム性を導入する手法を習得できます。
- 課題への対処法を理解:ブロックチェーン上でのランダム性の課題とその解決策を知ることができます。
この記事で学べること
- ランダム性の基礎概念と用途
- Solidityでのランダム性の基本的な実装方法
- ランダム性を導入する際のセキュリティ上の注意点
1. スマートコントラクトにおけるランダム性の課題

1.1 ランダム性とは?
ランダム性とは、予測不可能で一様に分布した値を生成するプロセスです。スマートコントラクトでは、ゲームの抽選機能やNFTの属性生成など、さまざまな場面で使用されます。
1.2 ブロックチェーンでランダム性を実現する難しさ
ブロックチェーンの特性上、以下の理由でランダム性の実現が難しいとされています:
- 公開性:すべてのトランザクションとデータが公開されており、値が予測可能になり得る。
- 不変性:生成された値は変更できないため、後から操作することが不可能。
- 操作可能性:悪意のあるマイナーが生成プロセスを操作して結果を改変するリスク。
2. ランダム性の基本的な実装例

2.1 脆弱なランダム性の例
// 脆弱なランダム性の実装例
pragma solidity ^0.8.0;
contract WeakRandomness {
function getRandomNumber() public view returns (uint256) {
return uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty)));
}
}
動作解説
このコードはblock.timestamp
やblock.difficulty
を利用して乱数を生成していますが、これらは予測可能であり、マイナーに操作される可能性があります。このため、安全性が不十分です。
2.2 より安全な方法の一例
// より安全なランダム性の実装例(Chainlinkを使用)
pragma solidity ^0.8.0;
import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
contract SecureRandomness is VRFConsumerBase {
bytes32 internal keyHash;
uint256 internal fee;
uint256 public randomResult;
constructor()
VRFConsumerBase(
0xD3dFCB00fa3C21Ef9EAFaE7fDe5706A24f7dD12E, // VRF Coordinator
0x514910771AF9Ca656af840dff83E8264EcF986CA // LINK Token
) {
keyHash = 0xAA77729D3466CA35AE8D28C925A74D26168c4A2AF6E8A3D3A7A55BB7F74C8B5C;
fee = 0.1 * 10**18; // 0.1 LINK
}
function requestRandomNumber() public returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK");
return requestRandomness(keyHash, fee);
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
randomResult = randomness;
}
}
動作解説
このコードは、Chainlink VRF(Verifiable Random Function)を利用して安全な乱数を生成しています。requestRandomness
関数を使用して乱数をリクエストし、fulfillRandomness
が呼び出されることで乱数が提供されます。
3. ランダム性を安全に実装するためのベストプラクティス

3.1 外部サービスの利用
ChainlinkやOraclizeなどの外部サービスを利用することで、信頼性の高い乱数を生成できます。
3.2 複数の要素を組み合わせた乱数生成
複数の要素(例:トランザクションデータやユーザー入力)を組み合わせることで、ランダム性を高めることができます。
4. 練習問題
以下の課題に挑戦してみましょう:
- Chainlinkを使用して安全な乱数生成機能を実装してください。
- 独自のランダム性生成アルゴリズムを考案し、脆弱性を特定してください。
5. まとめ
本記事では、ランダム性の基本概念、Solidityでの実装方法、および安全性を確保するための注意点について解説しました。ランダム性の実装には特別な注意が必要ですが、適切な手法を用いることで安全で信頼性の高いDAppを構築できます。