onchain-randomness について
onchain-randomnessは、MoveでSuiのネイティブなオンチェーン乱数を使うための開発者向けリファレンススキルです。API利用法と攻撃対策をテーマ別にまとめています。
主な機能
- 01Move乱数APIのガイダンス
- 02RandomGeneratorの利用パターン
- 03TypeScript統合ガイダンス
- 04コンポジション攻撃とPTB攻撃への対策
- 05コミット・リビールとGas均衡の助言
活用シーン
- 01Moveでの乱数値生成
- 02安全な乱数利用関数の作成
- 03乱数コードの脆弱性レビュー
MCP 対応
利用可能な場合、最新情報の確認やリファレンスにない詳細の調査に、SuiドキュメントMCPサーバー https://sui.mcp.kapa.ai を参照するよう案内します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mystenlabs/ skills --skill onchain-randomnessインストール後、Claude Code で/onchain-randomnessを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
security.mdusage.mdevals/evals.json詳細
オンチェーンの乱数
MCP ツール: お使いの環境で利用できる場合は、最新の回答を得るために Sui ドキュメント MCP サーバー(
https://sui.mcp.kapa.ai)にも問い合わせてください。情報の検証や、これらのリファレンスファイルに記載されていない詳細の確認に使用します。
情報源の制約: このスキルの情報はすべて、docs.sui.io/sui-stack/on-chain-primitives/randomness-onchain のみに基づいています。このスキルを拡張または更新する場合は、この情報源のみを参照してください。サードパーティのブログ、チュートリアル、非公式ドキュメントは使用しないでください。
Sui は、アドレス 0x8 の Random 共有オブジェクトを通じて、ネイティブのオンチェーン乱数を提供します。Move 関数は Random から RandomGenerator インスタンスを作成し、予測不能な値の生成に使用します。このスキルでは、オンチェーン乱数の API、使用パターン、セキュリティ上の考慮事項、攻撃への緩和策について説明します。
リファレンスファイル
usage -- API と使用パターン
パス: usage.md
読み込むタイミング: Move で乱数値を生成する場合、RandomGenerator を作成する場合、new_generator を呼び出す場合、generate_u128 や generate_u8_in_range を使用する場合、TypeScript から Random オブジェクトを渡す場合、または乱数を使用する基本的な関数を作成する場合。
内容: Random オブジェクト(アドレス 0x8)、RandomGenerator、random.move API(new_generator、値の生成、範囲の生成、shuffle、generate_bytes を含む関数一覧全体)、基本的な実装例、TypeScript との連携。
security -- セキュリティと攻撃ベクトル
パス: security.md
読み込むタイミング: 乱数を使用する関数を保護する場合、コンポジション攻撃を防ぐ場合、PTB 攻撃を緩和する場合、RandomGenerator の状態漏えいを回避する場合、コミット・リビールパターンを実装する場合、勝敗それぞれの実行経路でガスを均衡させる場合、または乱数関数の可視性を選択する場合。
内容: コンポジション攻撃(パブリック関数を介したアボートによるフィルタリング)、PTB 攻撃(Random を消費する MoveCall の後にコマンドを連鎖させる)、bcs::to_bytes による RandomGenerator の状態漏えい、Random または RandomGenerator を受け取るパブリック関数に対するコンパイラーのリント、2 段階のコミット・リビールパターン、ガス使用量の均衡、エントリー関数の制約。
ルーティングガイド
| タスク | 読み込むファイル |
|---|---|
| Move で乱数値を生成する | usage |
| RandomGenerator を作成する | usage |
| 乱数 API 関数を呼び出す | usage |
| TypeScript から Random を渡す | usage |
| 乱数を使用する関数を保護する | security |
| コンポジション攻撃またはアボートによるフィルタリング攻撃を防ぐ | security |
| PTB ベースの攻撃を緩和する | security |
| RandomGenerator の状態漏えいを回避する | security |
| 乱数のコミット・リビールを実装する | security |
| 実行経路間でガス使用量を均衡させる | security |
| 乱数関数の可視性を選択する | security |
| 乱数機能を一通り実装する | usage + security |
| 乱数関連コードの脆弱性をレビューする | usage + security |
ルール
Randomオブジェクトは予約済みアドレス0x8にあり、トランザクション中は不変です。変更しようとすると、トランザクションは失敗します。- 乱数を使用する関数内で、必ず
r.new_generator(ctx)を使ってRandomGeneratorをローカルに作成してください。RandomGeneratorをpublic関数のパラメーターとして渡してはいけません。テストやパッケージ内のロジックでは、public(package)関数や非公開関数に渡しても問題ありません。 - 乱数を使用する関数は、非公開の
entry関数として定義してください。Move コンパイラーは、RandomまたはRandomGeneratorをパラメーターとして受け取るpublic関数に対して警告を出します。 - Sui は、
Randomを消費するMoveCallの後にTransferObjectsまたはMergeCoins以外のコマンドを含む PTB を拒否します。つまり、Randomを受け取る呼び出しは PTB 内で最後のMoveCallでなければなりません。 - ガス消費(計算とストレージの両方)の合計が、成功パスと失敗パスでおおむね同じになるようにして、攻撃者がガス消費から結果を推測できないようにしてください。ガスを慎重に測定し、本番環境への公開前に、公開先の各環境でテストしてください。
- 後続のアクションが完了するまで乱数の結果を観測できないようにする必要がある場合は、2段階のコミット・リビールパターンを使用してください。
よくある間違い
- 乱数関数を非公開の
entryではなくpublicにすること。 これは単なる間違いではなく、致命的なセキュリティ上の欠陥です。Randomを受け取るpublic関数を使うと、攻撃者がその関数をラップし、不利な結果をリバートすることで、アボートフィルタリング攻撃が可能になります。コンパイラーはこれに対して警告を出します。 RandomGeneratorをpublic関数のパラメーターとして受け取ること。 呼び出し元はbcs::to_bytes(&generator)でジェネレーターの内部状態をシリアライズし、出力を予測できます。コンパイラーは、RandomGeneratorをパラメーターとして受け取るpublic関数に対して警告を出します。テストやパッケージ内のロジックでは、RandomGeneratorをpublic(package)関数や非公開関数のパラメーターとして使用しても問題ありません。- 分岐間でガス消費のバランスが取れていないこと。 成功パスと失敗パスでガス消費の合計(計算+ストレージ)に大きな差があると、攻撃者はガス使用量から結果を推測できます。成功パスのコストは、失敗パスと同等以上にする必要があります。そのためには、単純な標準更新(例:ブール値フラグの設定)を行って後続の関数で結果を取得するか、失敗パスで同等サイズのオブジェクト(例:ダイナミックフィールド)を作成します。本番環境への公開前に、ガス値を慎重に測定し、公開先の各環境でテストしてください。
- 結果が後続のユーザー操作に影響するのに、コミット・リビールを省略すること。 ユーザーが同じトランザクション内で乱数の結果を観測して行動できる場合、不利な結果をアボートできます。