T31 · AI-assisted Crypto Development
AIが書いたコントラクトをメインネットへ公開できるか?
- 練習する能力
- AI LiteracyBuilder
- 実践
- AI にモジュールを書かせ、行ごとにレビューして、存在しない API をいくつ捏造したか数える。
- AI Lab
- 失敗した取引のトレースを AI に渡して原因を調べさせ、自分でデバッグツールを使って結論を検証する。
現実の問題
金曜午後四時、ステーキング機能が必要になった。利用者がトークンを預け、時間に応じて報酬が増え、いつでも引き出せるものだ。
モデルに要件を説明すると四十秒で二百行が出た。コンパイルは通り、テストも頼むと十二件すべて成功した。
一行も読んでいないのに、自分が半日かけるより整って見える。コメント、命名、再入防止まで付いている。
月曜に公開する。デプロイするだろうか?
答える前に二つの小さな問いを考えよう。
- コンパイル成功は何を証明するか? 呼ぶものが存在し、型が合うことだ。意図した動作は証明しない。
- テスト成功は何を証明するか? 同じモデルが同じ会話で、同じ誤解かもしれない理解から書いた十二件だ。実装とテストが一致することしか示さない。
本章は、生成速度が二十倍になっても検証速度は変わらないという差を扱う。
思考実験
モデルを人に置き換えよう。
新しい同僚に三つの特徴がある。
- 生成が非常に速い。 要件を話せば三十分で実装を仕上げる。
- 知識は広いが、ある時点で止まる。 二年前の事情は知るが先月の公開物は知らず、知らないことにも気づかない。
- 不確かだと言わない。 正確なインターフェース名を思い出せなければ、最もありそうな名前を書き、いつもと同じ自信で続ける。
どう協働するだろうか?
少なくとも 速く書くからといって一行でも読む量を減らさない。第三のため、論理だけでなく 使ったものが実在するかも調べる。通常の同僚レビューではあまりしない確認だ。
さらに週五千行を生成し、自分は八百行しか丁寧に読めないとする。
差には三つの行き先しかない。
- 徹夜で全部読む。数週間で手を抜き始める。
- 一部だけ読む。その選択が必要になる。
- 読まない。賭けになる。
生成能力が増え、受入能力が増えなければ、制約は書く側から読む側へ移る。 これが本章の中心だ。
あなたが決める
月曜公開のステーキング機能に、二時間だけある。どう使うか?
結果を観察する
各方法は違う問題を発見する。
| 方法 | 発見できるもの | 発見できないもの | 単位費用 |
|---|---|---|---|
| テストネットの手動操作 | 主経路の不具合、配備設定 | 順序、境界、経済論理 | 非常に低い |
| 別モデルのレビュー | 一般パターン欠落、明白な反パターン | 架空API、要件不一致、同じ誤解 | 非常に低い |
| 全行読解と文書照合 | 架空API、版のずれ、意味の誤り | 全体不変条件、関数をまたぐ状態順序 | 非常に高い |
| 分類して読む | 資金経路の三種類の誤り | 非資金経路の誤り | 中 |
| コンパイラ | 未定義識別子、型不一致 | 存在しても意味が違う動作 | ゼロ |
| モデル自身のテスト | モデルの理解に合わない実装 | モデルの 誤解に合う実装 | ゼロ |
最後の二行を特に見よう。
無料のコンパイラは 存在しないものの参照を検出する。コンパイル言語では架空の関数名は三十秒も生き残れない。
危険なのは 識別子も型も正しく、テストも通るが、求めた動作ではない場合だ。毎秒の報酬を毎ブロックと誤解すれば、実装もテストもブロック基準になり十二件が成功する。
AIは誤ったコードを作る費用をほぼゼロにしたが、その誤りを検証する費用は下げていない。 リスクは正常に見えるコードへ集中する。
モデルを作る
生成コードの誤りを分類する。発見する主体が異なる点が有用だ。
| 種類 | 形 | 発見者 | 危険度 |
|---|---|---|---|
| 架空API | 存在しないメソッド、引数、ライブラリ、イベント | コンパイラ、ビルド | 低い。目立つが通常は無害 |
| バージョンのずれ | 存在する識別子の意味が版によって変わった | 文書を照合する人 | 高い |
| 意味のずれ | 誤った理解を正しく実装する | 要件へ戻る人 | 最大 |
| 同じ理解に基づくテスト | 実装とテストが同じ誤解を裏付ける | 人、外部由来の不変条件 | 最大 |
危険度は見た目の異常さと 逆だ。架空名は目立つがコンパイル不能で、整って正常動作する意味のずれが事故を起こす。
各段階に得意な役割を与える。
- 生成
- コンパイル
- 静的解析
- 分類した人のレビュー
- 外部由来の不変条件テスト
- Forkテスト
- 安全レビュー
次章の構造にも通じる鉄則がある。
配備した人が責任を負う。生成方法によってレビュー責任は移らない。
モデルには口座も資産も責任追及もない。配備ボタンを押せば、誰が入力したかに関係なく自分のコードになる。
週に丁寧に受け入れられる量をレビュー予算とする。
公開可能なコード量 = min(生成量, レビュー予算)
AIは生成量を10〜20倍にする。
レビュー予算は楽観的にも2倍以下の改善。
したがって公開量 ≈ レビュー予算で、ほぼ変わらない。示す使い方は 受け入れられる量を、より短い時間で生成することだ。読む側でも未知の契約の説明、失敗取引Trace解析、不変条件の推定に使える。レビュー予算を上げる方が、二千行追加生成するより有用だ。
何と呼ぶか
合理的な名前だが存在しない関数、引数、イベント、設定、依存パッケージ。
次に来そうな語を生成するモデルには safeTransferWithDeadline が自然に見えても、実在するとは限らない。
強い型を持つコンパイル言語では通常検出できるが、設定、スクリプト、依存一覧にはその保護がない。
知識には収録が止まる時点があるが、モデルは通常それを伝えない。
Cryptoでは更新が速く、コンパイラの既定動作、標準ライブラリの署名、推奨手法が変わるので高くつく。
モデルに最新か問うのではなく、公式文書の更新日を見る。モデルは最新と答える。
誤った要件理解を、コードが正しく実装すること。
形式が正しいので型、コンパイラ、静的解析では分からない。各行が要件のどの文に対応するかを確認する。
実装とテストが同じ理解から生まれ、テストが実装を再度書くだけになること。
期待値が要件ではなく実装由来なのが兆候だ。報酬を rewardPerBlock とブロック数の積とする断言は、実装が誤っていても通る。
手計算、白書の式、別実装、不変条件など 独立した出所を持たせる。
呼出元と先、引数、revert位置、Gasを含む全実行経路。
失敗情報は四バイトの識別子だけの場合もある。全Traceをモデルへ渡した 位置特定はパターン認識に適し、直ちに検証できる。ここが重要だ。
単位時間で本当に受け入れられるコード量。知識、注意、時間で決まる。
明示すれば生成量に押されず、能動的に配分できる。
実践
成果物は機能ではなく 自分の誤り分布表だ。
先に三十行以内の仕様を書いて渡す。 口頭説明だけにせず、次を含める。
状態:誰の残高か、いつ更新するか
操作:deposit / withdraw / claimと各前提条件
数学:報酬計算、単位、小数桁数
境界:最初の預入、最後の退出、同一ブロックの預入と引出
不変条件:契約残高 ≥ 全員の引出可能額の合計省略すると 照合できる独立した基準がなくなる。モデル自身の説明との比較だけでは検証にならない。
一回で実装を生成させる。 会話で何度も修正せず、四十秒二百行の最初の成果を使う。
別に保存し、全統計をこの版に基づける。
各行を読んで分類する。 行番号、種類、発見方法、危険度の四列を作る。
四分類に「正しい」を加える。
全外部識別子を公式文書で確認する。関数名、引数順、イベント署名、修飾子、依存を含め、検索結果の要約ではなく文書自体を開く。
少なくとも四つ集計する。
- 架空APIの数とコンパイラが検出した数
- 版のずれの数と各ずれの期間
- 意味のずれの数と発生した論理の種類
- 二百行を読むのにかかった分数
第四が今後使うレビュー予算の基準になる。
十二のテストを確認する。 各々 期待値は要件から計算したか、実装から写したか? と問う。
写したものは削除して書き直す。半分以上消えることがある。
テストネットで預入、待機、引出を行う。 仕様の数学を手計算し、チェーンの報酬と照合する。
実資産を使わない。 独立検証を終えていないため、メインネットではT28、T29、T30の安全工程を先に通す。
表を自分の文書に載せる。一般的なAI開発の推奨記事より有用だ。このモデルと技術構成での実測分布だからだ。
AI Lab
Trace解析が有用なのは 数分で独立検証できるからだ。第七層のrevertという指摘は再実行で確かめられ、根拠のないコード生成とリスクが違う。
テストネットで承認不足、スリッページ制限、アクセス拒否などを意図的に起こし、ハッシュを記録する。
材料を全部渡す。
これはテストネットで失敗した取引です。
[各層のto、selector、calldata、戻り値を含む完全なTrace]
[from、to、value、gas limit、実際のgas used]
[関係する契約ソース、少なくともABI]
[期待していた動作]
答えてください:
1. どの層のどの呼出しで失敗しましたか
2. 識別子はソースのどのerror定義に対応しますか
3. 条件を発動した直接原因は何ですか
4. 上流原因は何が考えられますか。仮説と信頼度を示してください
5. どう修正し、効果をどう検証しますか
3と4ではTraceから直接見えることと推測を明確に分けてください。最後の文が最も重要だ。なければ事実と推測が同じ口調で混ざる。
検証順も重要だ。 位置を一分、識別子をソースで五分、その後に最も難しい因果を検証する。先の二つが誤れば三つ目を見る必要はない。
五、六回試すと、位置特定は得意でも原因帰属では自信を持って外れることが分かる。その分布を持ち帰ろう。
AI の回答後、自分で必ず検証すること
- 指摘したrevert位置をデバッガで再実行して確認した
- selectorやエラー名の定義をソースで見つけた
- 関数署名、引数順、イベントをソースか公式文書で照合した
- 提案した変更でその段階がrevertしなくなる理由を説明できる
- 可能性を確定原因としていないか、各結論を仮説か事実に分類し直した
- 修正後にForkで同じ取引を再実行し、成功を確認した
実例
生成時に提案するパッケージには、合理的でも未公開の架空名が混ざる。
研究者は、頻出する架空名を集め、公開レジストリへ先に登録し、悪性コードを入れて、開発者が提案どおりインストールするのを待つ経路を報告している。
コンパイラを回避する。存在するようになればインストールもコンパイルも正常に進む。
依存一覧を全行、人が確認する。発行者、ダウンロード数、リポジトリ、更新日を見る。鍵と資金を扱う製品では機能開発より優先する。
年率を日数で按分する手数料要件を、呼出回数で按分し、その実装を完全に裏付けるテストを書いた。
全件成功し、レビュアーは名前とカバレッジを見て通した。
共通点は 独立した出所を持つ数値がないことだ。期待値は実装由来、実装は誤解由来で、内部だけで整合する。
手計算、白書の式、元本のX%を超えないなどの独立不変条件で外部基準を入れる。T30の手法が使える。
契約言語の主版更新で整数オーバーフロー検査が既定になり、それまで必要だった安全数学ライブラリが冗長になった。
モデルは新版に不要な旧ライブラリを入れ、逆に 旧版でも自動検査されると仮定する。後者は実際の脆弱性だ。
症状がなく、短く整った現代的コードに見えても、特定版では誤っている。
版番号の確認はコード確認以上に重要だ。
自動出力が 専門的に見えると、人の確認が弱まる心理傾向がある。
命名、コメント、対称構造、防御検査が、専門家の保証を受けたような印象を生む。
同じ人でも乱れた二百行には平均九件、整った生成二百行には二件しか指摘しないレビュー記録が、この傾向を示す。
読み方を変える。各状態変更から値の出所と影響できる人を逆にたどる。逆向きなら外見に左右されにくい。
変数を一つ変える
架空APIは大幅に、版のずれは多少減るが、意味のずれは ほぼ変わらない。
前二つは知識不足だが、意味のずれは 自分の要件記述の曖昧さから生まれ、自分側の不足だからだ。
強いモデルほど仕様が重要になる。弱いモデルの誤りは目立つが、強いものは未記述部分を、自分が思う意味で滑らかに埋める。
リスクは一、二段階下がるがゼロにはならない。
再配備できても 取引を組み立てるコードの単位、精度、受取先、許容幅と、依存一覧は厳しく見る。前者は実資金を失わせ、後者の木と攻撃機会は契約より二桁大きい。
索引では再編処理が正常経路だけになる誤りがあり、T17で扱った。
費用対効果のよい使い方だ。
実装は自分、テストはモデルなら 同じ理解の問題がなくなる。自分の頭の誤解を知らず、要件から見落とした境界を探せる。
ただし実装を渡すと通る断言へ寄せ、同じ問題が戻る。仕様だけを渡し、実装は渡さない。
読んでいる人がいるという本章の前提が失われる。
次章で禁じる、不可逆の実行力を出力に与え、誤りを発見する場所のない構造になる。
自動配備するなら 人のレビューを通った成果物を自動化し、生の生成物を使わない。T32はコードと取引共通の構造として説明する。
持ち帰る問い
下がるのは 生成費用で、検証費用ではない。安い側が急増し、高い側は制約され、ボトルネックが移る。開発ツールがどちらの費用を下げるかで評価する。
損失を負うのは 配備した人だ。モデルには口座、資産、契約上の当事者性がない。事故時に提示できるレビュー記録自体が価値ある資産になる。
依存確認、状態変更と資金移動のコード、配備操作の三つは人に残す。供給網、意味の誤り、不可逆性のためだ。口約束ではなくCI検査項目へ入れる。
権限はLevel 2で、コードの読書きとTrace解析はできるが、鍵、配備資格情報、本番環境には触れない。T32で実行時にも同じ境界を引く前提だ。
章末チェック
コンパイルは 識別子の問題を排除する。存在、型、署名が一致し、架空関数名を検出できる。
テストが排除するのは 期待値に合わない実装だ。要件に合わない実装とは限らず、同じ理解から両方を書くと差がリスクになる。
両方成功しても、誤った要件を正しく実装する意味のずれは残る。
一次確認には使えても、署名する人が違う。
訓練データの重なりで同じ誤りを犯し、第二モデルも架空情報を作る。確認済みの結論ではなく、確認が必要な材料が二つになる。
結果を負担するモデルはいない。配備する自分が受入を終える必要がある。T32でモデル出力をモデルで検査しない規則と同じだ。
期待値の出所を見る。
実装が誤ればこの断言は失敗するか? と問う。
- 報酬が
rewardPerBlockとブロック数の積という断言は実装を写し、同じ誤りでも通る。 - 100トークン、30日、年率5%なら約0.41という断言は要件からの手計算で、誤った実装は失敗する。
常に成立する性質を表す不変条件も、実装ではなく要件から来る。
先に分類する。
第一は 状態、資金、権限を変える行。全行、数学の手計算、外部呼出しを確認し、二、三十行に時間の八割を使う。
第二は ビューと読取経路。第一が戻り値を信頼する読取は実質的に第一へ入る。
第三はコメント、イベント、ログ、書式。ほぼ読み流すが、イベント引数と実際の変更の一致は確認する。
大切なのは 何を読まなかったかを明示的に知ること。分類なしでも三十行しか実際には読まず、どの三十行か分からなくなる。
次を確認する。
- 割合を答えられるか。分からなければ追跡していないことが問題だ。
- 未読部分に状態変更や資金移動があるか。あれば規模不明のリスクがある。
- 今月の読解速度が上がったなら、習熟か読み流しへの移行か確かめる。
- 未知の契約説明、不変条件推定、Traceなど読む側にもAIを使ったか。書く側だけなら制約を積み上げる。
第四が本章の主な実践提案だ。
要点
AI が速めるのは成果物を作る速度だけ。レビューの責任は一切移らない。