Midnight の公式ドキュメントのリポジトリ midnight-docs に、日本時間 10 月 31 日朝、「Compact でまだできないことと、その回避策をまとめたページを追加してほしい」という Issue #1632 が立ちました。約 1 時間半後には、開発者の kshot9000 氏が公式ドキュメントだけを根拠に、小数・組み込みの割り算・再帰・上限のないループの 4 つが使えないことと、それぞれの回避策を整理した文書を公開しています。
Midnight でスマートコントラクトを書く言語 Compact は、ゼロ知識証明の回路に変換される前提で設計されているため、一般的なプログラミング言語では当たり前の書き方がいくつか使えません。同じ質問が何度も繰り返されていることが Issue の出発点です。公式リファレンスの記述に沿って、4 つの制約と回避策を確認します。
5 週間あまりで 29 件、同じ質問が繰り返されていた
Issue #1632 によると、9 月 21 日から 10 月 29 日までに、10 人から 29 件の関連する質問の記録がありました。小数は使えるのか、回路の中で暗号化や復号はできるのか、「The requested length exceeds 65,536 bytes」というエラーは何なのか、といった内容です。
Issue は、AI アシスタント (Kapa) の回答が曖昧だったり誤っていたりした例も挙げています。ある回答では value * percentage / 100 と書いたうえで、Compact には割り算がないと説明していました。情報はリファレンス・概念解説・サンプルに散らばっていて、小数がないこと、回路の中で暗号化できないこと、外部の証明を検証できないことを、はっきり書いたページがない、というのが Issue の指摘です。
公式リファレンスに書かれている 4 つの制約
Compact のリファレンス (言語バージョン 0.27.0 との互換を 9 月 25 日に確認と明記) には、4 つの制約が次のように書かれています。
- 小数がない: 数値は符号なし整数に限られます。浮動小数点の型はありません
- 割り算の演算子がない: 二項の算術演算子は足し算 (
+)・引き算 (-)・掛け算 (*) の 3 つだけです - 再帰ができない: 回路は、直接にも間接にも自分自身を呼び出せません
- 上限のないループがない: ループは、定数の上限か、大きさが一定のオブジェクトの大きさで区切られます。
forの範囲の始点と終点は、数値の直書きか、総称の自然数パラメータでなければなりません
あわせて、ベクトルとバイト列の長さの上限は 16,777,216 で、この値が for ループの範囲も決めると書かれています。リファレンスは、こうした上限が将来のコンパイラで変わりうることも明記しています。
4 つに共通する理由は、Compact のすべての型の大きさがコンパイル時に決まることにあります。ゼロ知識証明の回路は、実行前に計算の形が固定されていなければ組み立てられません。何回繰り返すか分からないループや、どこまで深くなるか分からない再帰は、その前提と相いれません。
回避策は「計算は外で、確認は回路で」
割り算の回避策は、Midnight の公式ブログ (2025 年 4 月 16 日) に具体的に書かれています。割り算は回路の外で行い、その結果が正しいことを回路の中で確かめる方法です。回路の外で計算を担う witness (ウィットネス) が商と余りを返し、回路はそれを自分で計算せず、「割られる数 = 割る数 × 商 + 余り」が成り立つかを確かめます。掛け算と足し算だけで確かめられるので、割り算の演算子がなくても成り立ちます。
kshot9000 氏の整理では、ほかの 3 つにも同じ考え方の回避策が並んでいます。
- 小数・パーセント: 整数に桁をそろえて扱う (例: 1% を 100 ベーシスポイントとして持つ) か、witness で計算して結果を回路で確かめる
- 再帰: ループに展開するか、上限のある繰り返しに書き直す
- 上限のないループ: 大きさの決まったベクトルやバイト列、または定数の上限で
forを回す
どれも、答えの求め方は回路の外に出し、回路には答えが正しいかだけを確かめさせる、という同じ設計に収まります。Compact に慣れることは、この役割分担に慣れることでもあります。
次に見るもの
Issue #1632 は、まだ答えの出ていない論点も挙げています。回路の中での暗号化と復号、Groth16 のような外部の証明の検証、そして 65,536 バイトのエラーがどこから来るのかです。kshot9000 氏の文書も、暗号化と外部の証明の検証の 2 点は公式ドキュメントに記述がないとして、回避策を作らずに残しています。
確かめたいのは、midnight-docs の Issue #1632 に公式の回答が付き、「Compact でまだできないこと」のページがドキュメントに加わるかどうかです。ページが入れば、65,536 バイトのエラーの説明がどう書かれるかが、開発者にとって最も実用的な一点になるはずです。Compact のコードを点検する道具としては、10 月 30 日に紹介した静的解析ツール Nightshade もあわせて参考になります。
ことば
- Compact — Midnight のスマートコントラクトを書くための言語。書いたコードはゼロ知識証明の回路に変換されます。回路の形を固定する必要から、使える書き方に今回のような制約があります。
- witness (ウィットネス) — 回路の外で動き、回路に値を渡す関数。秘密のデータや回路で書けない計算を受け持ち、回路は受け取った値が条件を満たすかだけを確かめます。割り算の回避策の要になる仕組みです。
- 回路 (circuit) — Compact で書いた処理のうち、ゼロ知識証明の対象になる部分。中身を明かさずに「正しく計算した」ことを証明できる代わりに、計算の形を実行前に固定する必要があります。
一次ソース / 関連リンク
Compact のリファレンス (Midnight 公式ドキュメント)(docs.midnight.network)
Simulating a division in Compact (Midnight 公式ブログ・2025 年 4 月 16 日)(docs.midnight.network)
- kshot9000 氏の X 投稿
https://x.com/kshot9000/status/2116315348878152042

