バージョン付きトランザクション

概要

Solanaには3つのトランザクションフォーマットがあります:legacy、v0、v1。v0は1バイトインデックスでアカウントを参照するアドレスルックアップテーブル(ALT)を追加します。v1はサイズ制限を4,096バイトに引き上げ、リソース制限をメッセージ自体に組み込み、ALTを廃止します。

Solanaは3つのトランザクションフォーマットをサポートしています:legacyv0v1。それぞれについて、ワイヤー上のバイト配置、アカウントの参照方法、リソース制限の出所という3つの観点から説明します。

v1の有効化状況

v1フォーマットはまだどのクラスターでも有効化されていません。有効化はAgave v4.2で予定されています。solana-test-validator 4.2以降を使用すると、v1トランザクションをローカルでテストできます。既存のアプリはv1への移行準備を確認してください。

フォーマット比較

制限legacyv0v1
最大トランザクションサイズ1,232バイト1,232バイト4,096バイト
アカウントアドレス~32個、サイズ制限あり64個、ルックアップテーブル経由64個、インライン
アドレスルックアップテーブル非対応対応非対応
リソース制限ComputeBudget instructionsComputeBudget instructionsメッセージ設定

ジャンプ先:Legacy · v0 · v1

Legacyフォーマット

オリジナルのフォーマットであり、ほとんどのツールでいまだにデフォルトとして使用されています。バージョンプレフィックスは一切なく、トランザクションの最初のバイトはシグネチャ配列のcompact-u16カウント、メッセージの最初のバイトはnum_required_signaturesであり、その最上位ビットは常に未設定です。

Legacyワイヤーレイアウト

フィールドサイズ説明
num_signaturescompact-u16シグネチャの数
signaturesnum_signatures x 64バイトEd25519シグネチャ
header3バイトMessageHeader — 最初のバイトはバージョンビット未設定
num_account_keyscompact-u16アカウントキーの数
account_keysnum_account_keys x 32バイト公開鍵、すべてインライン
recent_blockhash32バイト有効期限指定子
num_instructionscompact-u16instructionsの数
instructions可変長各instructionを連続してシリアライズ

可変長配列はすべてcompact-u16長プレフィックスが付きます:値0〜127は1バイト、より大きい値は2〜3バイトです。instruction単位のレイアウトとサイズ計算の例については、トランザクションバイナリフォーマットを参照してください。

Legacyのアカウント

すべてのアカウントはaccount_keys内に32バイトの完全な公開鍵として書き込まれ、instructionsは1バイトのインデックスでその配列を参照します。トランザクションに明示的に記載されていないアカウントを参照する方法はなく、これがlegacyトランザクションを1,232バイトを使い切る前におよそ32アカウントに制限する要因です。

Legacyのリソース制限

コンピュートユニット制限、ロード済みアカウントデータサイズ制限、ヒープサイズ、優先手数料はすべて、トランザクションにComputeBudgetプログラムのinstructionsを含めることでリクエストされます。それぞれがinstructionスロットを1つと150コンピュートユニットを消費します。省略しても安全です:ランタイムはデフォルト値(instruction当たり200,000 CU、上限1.4M、データサイズ制限64 MiB、ヒープ32 KiB、優先手数料ゼロ)にフォールバックします。

V0フォーマット

v0はlegacyメッセージに2つの要素を加えたものです:0x80バージョンプレフィックスバイトと、instructionsの後に追加されるaddress_table_lookups配列です。それ以前の部分はlegacyとバイト単位で同一です。

V0ワイヤーレイアウト

フィールドサイズ説明
num_signaturescompact-u16シグネチャの数
signaturesnum_signatures x 64バイトEd25519シグネチャ
0x801バイトバージョンプレフィックスバイト — メッセージの最初のバイト
header3バイトMessageHeader(レガシーと同じ)
num_account_keyscompact-u16静的アカウントキーの数
static_account_keysnum_account_keys x 32バイトトランザクション内に文字通り表示されるキー
recent_blockhash32バイト有効期限指定子
num_instructionscompact-u16instructionsの数
instructions可変長レガシーと同じ形式
address_table_lookupscompact-u16 + 可変ALT参照(下記参照)

各アドレステーブルルックアップエントリには以下が含まれます:

フィールドサイズ説明
account_key32バイトALTアカウントの公開鍵
writable_indexescompact-u16 + N x 1バイト書き込み可能アカウント用のALTへのインデックス
readonly_indexescompact-u16 + N x 1バイト読み取り専用アカウント用のALTへのインデックス

アドレスルックアップテーブル

ALTは最大256個の公開鍵を保存するオンチェーンアカウントです。ALTを参照することで、トランザクションは32バイトの公開鍵の代わりに1バイトのインデックスを使用して追加のアカウントを含めることができ、アカウントごとのオーバーヘッドを大幅に削減します。

実行開始前のランタイムにおいて、validatorはすべてのALT参照を完全な公開鍵に解決します。解決されたアドレスは静的アカウントキーに追加され、完全なアカウントキーリストを形成します。ALTで解決されたアカウントは、静的アカウントと同じ順序に従います。書き込み可能なルックアップが読み取り専用ルックアップの前に配置されます。

アドレスルックアップテーブルは、オンワイヤトランザクションでアカウントがどのように参照されるかにのみ影響します。実行時には、ランタイムがすべてのインデックスを完全なアカウントアドレスに解決します。ALTで解決されたアカウントは書き込み可能または読み取り専用(非署名者)のみ可能で、署名者にはなれません。

v0のリソース制限

legacyから変更なし:ComputeBudget instructions、省略時のデフォルト値も同様。

V1フォーマット

v1はサイズ制限を4,096バイトに引き上げ、トランザクション設定を中心にメッセージを再構築します:リソース制限はComputeBudget instructionsから外れ、メッセージ自体の固定位置フィールドに移動します。これにより、ネットワークはinstructionリストをスキャン・デシリアライズせず、単一の固定オフセット読み取りでトランザクションを優先手数料でランク付けできます。

V1ワイヤーレイアウト

フィールドサイズ説明
0x811バイトバージョンプレフィックスバイト — トランザクションの最初のバイト
header3バイトMessageHeader(legacyと同様)
config_mask4バイトどの設定値が存在するかを示すu32 LEビットマスク
recent_blockhash32バイト有効期限指定子
num_instructions1バイト固定幅カウント、最大64
num_addresses1バイト固定幅カウント、最大64
addressesN x 32バイトアカウントアドレス、すべてインライン — ルックアップテーブル参照なし
config_values0〜20バイト設定されたマスクビットごとに1つの値、ビット順(下記参照)
instruction_headersN x 4バイトinstruction単位:program_id_index(u8)、num_accounts(u8)、data_len(u16 LE)
instruction_payloads可変長instruction単位:アカウントインデックス、続いてinstruction data
signaturesN x 64バイト末尾に配置、長さプレフィックスなし — カウントはヘッダーから取得

デコーダーを実装する際に注意すべきlegacyおよびv0との構造上の相違点が2つあります。カウントはcompact-u16ではなく固定幅のu8フィールドであること、そしてinstructionsは各instructionを連続して配置するのではなく、固定サイズのヘッダーをすべて先に並べ、その後に可変長ペイロードをすべて並べるという2つのランクに分割されることです。

v1のアカウント:アドレスルックアップテーブルなし

v1はALTサポートを意図的に廃止しています。64個の生アドレスは2,048バイトであり、4,096バイト制限内に十分収まるため、legacyと同様にすべてのアドレスをインラインで記述します。アプリケーションがルックアップテーブルに依存している場合、v1への移行はそれらのアドレスをインライン化することを意味します。

v1のリソース制限:トランザクション設定

設定はu32ビットマスクに続いて、そのビットが設定された各フィールドの固定幅値で構成されます:

ビットフィールド備考
0〜1優先手数料u64合計lamport数 — 両ビットを同時に設定
2コンピュートユニット制限u32
3ロード済みアカウントデータサイズ制限u32
4要求ヒープサイズu32

未知のビットは拒否されます。メッセージは署名されているため、未認識の設定フィールドを暗黙的に破棄することはできません。

優先手数料は単価ではなく合計lamport数

legacyおよびv0では、優先手数料はSetComputeUnitPriceを通じてコンピュートユニット当たりのマイクロlamport数として設定され、コンピュートユニット制限と乗算されます。v1ではlamport単位の絶対合計値となり、乗算も丸めも不要です。CU単位の演算をそのまま持ち込まないでください。合計手数料の計算式はその他の点では変わりません:(signatures × lamports_per_signature) + priority_fee

v1でのComputeBudget instructionsはno-op

v1トランザクションはComputeBudget instructionsを拒否しません — 設定においては無視されます。これらは引き続き成功したno-opとして実行され、150コンピュートユニットと64あるinstructionスロットのうちの1つを消費しますが、バジェットには何の影響も与えません。v1トランザクションを構築する際はこれらを取り除き、v1トランザクションを読み取る際はスキャンを止めてください:値はメッセージ設定に格納されています。

設定フィールドは明示的に指定する必要があります

送信者にとって最も重要な動作上の変更点:legacyおよびv0とは異なり、v1トランザクションはコンピュートユニット制限とロード済みアカウントデータサイズ制限を明示的に設定しなければならず、設定しない場合トランザクションは失敗します。

未設定フィールドlegacy / v0v1省略時の症状
コンピュートユニット制限instruction当たり200k、最大1.4M0 CU即時失敗、予算不足
ロード済みアカウントデータサイズ64 MiB0バイト最初にロードされたアカウントでMaxLoadedAccountsDataSizeExceeded
優先手数料00
ヒープサイズ32 KiB32 KiB

推奨されるアプローチは、両方の制限を最大値にして一度シミュレーションを実行し、返されたunitsConsumedloadedAccountsDataSizeを設定に書き戻すことです。データサイズは余裕を持たせるために次の32 KiBページに切り上げてください(ブロックコストモデルは32 KiBページ単位で課金されるため、次のページ境界未満の余裕はコストがかかりません)。

v1への移行準備

v1はトランザクションの読み取りも変更します。送信だけではありません。v1が有効化されると、オプトインせずにgetTransactiongetBlockを呼び出すクライアントはv1トランザクションで失敗し始めます:

  • getTransactionおよびgetBlockmaxSupportedTransactionVersion: 1 — 文字列"1"ではなくJSON整数1 — を渡してください。0を渡すとパラメーターを省略した場合と同様にv1トランザクションで失敗します。v0のロールアウト時にコードベースを更新していても、値を変更する必要があります。
  • getTransactionはv1トランザクションに対してエラー-32015で失敗し、getBlockレスポンスに1つでもv1トランザクションがあると、同じエラーでレスポンス全体が失敗します — 部分的な結果は返されません。
  • blockSubscribeblock: nullを返して進行を停止するため、これを空のブロックとして読み取るコンシューマーは最初のv1 slot以降から静かに遅延します。
  • getSignaturesForAddressはトランザクション本体を検査しないため、v1のシグネチャは通常通り一覧表示されます。
  • オプトイン済みのレスポンスには、v1トランザクションのメッセージにtransactionConfigオブジェクトが含まれます(legacyおよびv0では完全に省略されます)。ComputeBudget instructionsをスキャンして優先手数料やコンピュート制限を導出するパイプラインは、すべてのv1トランザクションに対してゼロを静かに報告します。
  • クライアント側でトランザクションをデコードする場合、および1,232バイトを超えるトランザクションのsendTransaction/simulateTransactionにはencoding: 'base64'を使用してください — base58エンコーディングは旧来のサイズ上限のままです。
  • クライアントライブラリのサポートには最新バージョンが必要です:@solana/kit 8.0以降、Agave 4.2.x世代のRustクレート、またはweb3.js v3。web3.js v1は1.99.0以降でv1を読み取れますが、構築または送信はできません。

クライアントライブラリのサポート、ストリーミング(Geyser/gRPC)のバージョン検出、シミュレーション動作を含む完全な移行ガイドについては、トランザクションフォーマットv1アップグレードページを参照してください。

Is this page helpful?

© 2026 Solana Foundation. 無断転載を禁じます。