Aiken の開発チームは 9 月 26 日、スマートコントラクト言語 Aiken の v1.1.24 を GitHub で公開しました。目玉は、Cardano 上の複数トークンの残高を表す Value を、言語の組み込み型として直接扱えるようにしたことです。
これは、プロトコルバージョン 11 (PV11) で Plutus V3 に入った Value 用の組み込み関数を、Aiken から呼べるようにする対応です。これまで各言語が自前の標準ライブラリで組み立てていた処理を、チェーン側に用意された共通の関数へ任せられるようになります。以下、なぜ Value だけが特別扱いされるのかと、開発者がいま確かめておくことまでを整理します。
v1.1.24 に入ったもの
リリースノートの「Added」には 2 点が並んでいます。1 つ目は UPLC (Cardano のスマートコントラクトが最終的に実行される低水準言語) の Value 型を、Aiken の Value として公開したことです。aiken/builtin に次の 7 つの関数が追加され、Plutus V3 の正式な適合テストで挙動が照合されています。
insert_value/lookup_value— 特定のトークンの数量を書き込む・読み出すunion_value— 2 つの Value を足し合わせるcontains_value— 一方の Value がもう一方を含むかを判定するvalue_data/un_value_data— 汎用データ形式 (Data) との相互変換scale_value— すべての数量を整数倍する
2 つ目は、Value をソースコード上にそのまま書ける「Value リテラル」です。ポリシー ID ごとにトークン名と数量を波括弧で入れ子にして書く記法で、テストの期待値やパラメーターを読みやすく書けます。あわせて、中身が Value と同じ形のデータを Value の式として書き戻す処理 (reify) にも対応し、整形されたリテラルの形で表示されるようになりました。
なぜ Value だけが組み込み型になったのか
Cardano のバリデーター (取引を通すかどうかを判定するスクリプト) の仕事の大半は、「どのトークンが、どれだけ、どこへ動くか」を確かめることです。ところが UPLC にはこれまで Value という概念がなく、各言語は Value を「ポリシー ID → トークン名 → 数量」という入れ子のマップとして自前で実装してきました。
組み込み化の元になった CIP-153 は、この状態の問題を具体的に挙げています。台帳 (レジャー) が守っている約束事 — キーの重複なし、昇順の並び、数量ゼロの項目や空の内側マップを残さない — を、Plinth・Aiken・Plutarch・Helios がそれぞれ手作業で再現しなければならず、処理が重複し、言語ごとに挙動がずれる余地も生まれていました。足し算や比較といった基本操作でさえ、毎回正規化のコードがバリデーターに埋め込まれていたわけです。
PV11 で入った組み込み関数は、この約束事をチェーン側で一律に守ります。たとえば un_value_data (Plutus 側の名前は unValueData) は、並びが崩れていたり数量ゼロの項目を含んでいたりする非正規のデータを受け付けず、失敗させる仕様です。検証ロジックの中で「形の崩れた Value」を誤って受け入れる余地が、関数の側で閉じられます。
なお、Plutus V1〜V3 では、Value を Data に変換したときの形は従来のライブラリ実装と同じで、既存のスクリプトとの互換性は保たれます。CIP-153 によれば、Data の中に Value 専用の形を持たせて変換を一定時間で済ませる改良は、次の Dijkstra 期の Plutus V4 で入る計画です。
実行予算は同じまま、評価は数倍速く
「Changed」には、開発者の体感に直結する変更も入っています。Aiken に付属する UPLC 評価器 (テスト実行などでスクリプトを走らせる部分) で、Data やペアを扱う一部の組み込み関数について、コスト計算が一定のときは引数のサイズを数えない処理にしました。リスト系の関数ではすでに同じ扱いになっていたものです。
リリースノートは、実行予算 (手数料の基になる計算量の見積もり) は変わらない一方、スクリプトコンテキストのような大きな Data を読むスクリプトの評価が「数倍速くなる」と説明しています。つまり、チェーン上で払うコストは同じまま、手元でテストを回す時間が短くなる改善です。
修正は 8 件あります。型推論で要素の型が決まらない空リストを放置すると実行時エラーになる UPLC を生成しうる問題への対処、BLS12-381 楕円曲線のマルチスカラー乗算に渡す引数の型変換 (issue #1378)、定数評価で失敗したときに最適化処理が異常終了せず呼び出しをそのまま残す修正などです。テスト実行やコンパイラ最適化のメモリ使用量と処理時間の削減も含まれます。
開発者がいま確かめておくこと
Value 関連の関数は、Plutus のソースコード上で「van Rossem ハードフォーク (PV10 から PV11)」の追加分としてまとめられています。9 月 27 日時点のメインネットはプロトコルバージョン 11 で稼働しているため、Plutus V3 のスクリプトからこれらの組み込み関数を呼ぶ前提は整っています。
既存の Aiken プロジェクトでは、標準ライブラリの入れ子マップ実装から新しい組み込み型へ移すかどうかが実務上の判断になります。大量のトークンを扱う DEX やトレジャリー系のバリデーターほど、正規化のコードをバリデーターから外せる効果は大きくなります。一方で、Value を Data から取り出すたびに正規性の検査が走るため、どの経路で組み込み型を使うかは、自分のスクリプトで実行予算を測って決めるのが確実です。
次に見るもの
確認先は 2 つあります。1 つは aiken-lang/stdlib のリリースページで、標準ライブラリの資産 (assets) まわりが新しい組み込み型を前提に書き換わるかどうかは、次の stdlib リリースノートで分かります。もう 1 つは Plutus の Versions.hs です。ここには、実装済みだがどのプロトコルバージョンでもまだ承認されていない次の組み込み関数 (Policies・AssetCount・KeepPolicies・DropPolicies など) が「batch7」として並んでいます。これらがどのハードフォークに割り当てられるかが、Value まわりの次の一歩です。
ことば
- UPLC — Untyped Plutus Core の略。Aiken や Plinth で書いたコードは最終的にこの言語へ変換され、ノードが実行します。組み込み関数が増えると、どの言語からでも同じ処理を呼べるようになります。
- Value — ADA とネイティブトークンの数量をまとめて表す型。台帳は並び順や数量ゼロの扱いに厳密な約束事を持っており、これをスクリプト側で再現する負担が組み込み化の動機になりました。
- PV11 (van Rossem) — Cardano のプロトコルバージョン 11 を導入したハードフォーク。Plutus 側では Value 用の関数や配列操作などの組み込み関数がこの段階で有効になっています。
一次ソース / 関連リンク
- Aiken v1.1.24 リリースノート(GitHub)
https://github.com/aiken-lang/aiken/releases/tag/v1.1.24 - CIP-153: Plutus Core Builtin Type – MaryEraValue
https://github.com/cardano-foundation/CIPs/blob/master/CIP-0153/README.md - Plutus: 組み込み関数とプロトコルバージョンの対応(Versions.hs)
https://github.com/IntersectMBO/plutus/blob/master/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs
