Transaksi berversi

Ringkasan

Solana memiliki tiga format transaksi: legacy, v0, dan v1. v0 menambahkan Address Lookup Tables (ALT) untuk mereferensikan akun melalui indeks 1-byte. v1 meningkatkan batas ukuran menjadi 4.096 byte, memindahkan batas sumber daya ke dalam pesan itu sendiri, dan menghapus ALT.

Solana mendukung tiga format transaksi: legacy, v0, dan v1. Masing-masing dijelaskan di bawah dengan tiga bagian yang sama: cara byte ditata dalam transmisi, cara akun direferensikan, dan dari mana batas sumber dayanya berasal.

Status aktivasi v1

Format v1 belum aktif di cluster mana pun. Aktivasi ditargetkan pada Agave v4.2. solana-test-validator 4.2+ memungkinkan Anda menguji transaksi v1 secara lokal. Aplikasi yang sudah ada sebaiknya meninjau persiapan untuk v1.

Perbandingan format

Bataslegacyv0v1
Ukuran transaksi maksimal1.232 byte1.232 byte4.096 byte
Alamat akun~32, dibatasi ukuran64, melalui lookup table64, inline
Address lookup tabletidak didukungdidukungtidak didukung
Batas sumber dayaInstruksi ComputeBudgetInstruksi ComputeBudgetkonfigurasi pesan

Langsung ke: Legacy · v0 · v1

Format legacy

Format asli, dan masih menjadi default di sebagian besar tooling. Format ini sama sekali tidak memiliki prefiks versi: byte pertama dari transaksi adalah hitungan compact-u16 dari array tanda tangan, dan byte pertama dari pesan adalah num_required_signatures, yang bit tertingginya selalu tidak disetel.

Tata letak wire legacy

FieldSizeDescription
num_signaturescompact-u16Jumlah tanda tangan
signaturesnum_signatures x 64 byteTanda tangan Ed25519
header3 byteMessageHeader — byte pertama memiliki bit versi yang tidak disetel
num_account_keyscompact-u16Jumlah kunci akun
account_keysnum_account_keys x 32 byteKunci publik, semua inline
recent_blockhash32 bytePenentu masa berlaku
num_instructionscompact-u16Jumlah instruksi
instructionsvariabelSetiap instruksi diserialisasi secara berurutan

Setiap array dengan panjang variabel diawali dengan panjang compact-u16: 1 byte untuk nilai 0–127, 2–3 byte untuk nilai yang lebih besar. Untuk tata letak per instruksi dan perhitungan ukuran secara rinci, lihat format biner transaksi.

Akun dalam legacy

Setiap akun ditulis sebagai kunci publik 32-byte penuh dalam account_keys, dan instruksi mereferensikannya dengan indeks 1-byte ke dalam array tersebut. Tidak ada cara untuk mereferensikan akun yang tidak tercantum dalam transaksi, itulah yang membatasi transaksi legacy pada sekitar 32 akun sebelum kapasitas 1.232 byte habis.

Batas sumber daya dalam legacy

Batas unit komputasi, batas ukuran data akun yang dimuat, ukuran heap, dan biaya prioritas semuanya diminta dengan menyertakan instruksi program ComputeBudget dalam transaksi. Masing-masing memerlukan satu slot instruksi dan 150 unit komputasi. Menghilangkan nya aman: runtime akan menggunakan default 200.000 CU per instruksi (dibatasi hingga 1,4M), batas ukuran data 64 MiB, heap 32 KiB, dan biaya prioritas nol.

Format v0

v0 adalah pesan legacy ditambah dua hal: byte prefiks versi 0x80 dan array address_table_lookups yang ditambahkan setelah instruksi. Semua yang ada sebelumnya byte-identik dengan legacy.

Tata letak wire v0

FieldUkuranDeskripsi
num_signaturescompact-u16Jumlah tanda tangan
signaturesnum_signatures x 64 byteTanda tangan Ed25519
0x801 byteByte prefiks versi — byte pertama dari pesan
header3 byteMessageHeader (sama dengan legacy)
num_account_keyscompact-u16Jumlah kunci akun statis
static_account_keysnum_account_keys x 32 byteKunci yang muncul secara literal dalam transaksi
recent_blockhash32 bytesPenentu masa berlaku
num_instructionscompact-u16Jumlah instruksi
instructionsvariabelFormat sama dengan legacy
address_table_lookupscompact-u16 + variabelReferensi ALT (lihat di bawah)

Setiap entri pencarian tabel alamat berisi:

FieldSizeDescription
account_key32 byteKunci publik akun ALT
writable_indexescompact-u16 + N x 1 byteIndeks ke dalam ALT untuk akun yang dapat ditulis
readonly_indexescompact-u16 + N x 1 byteIndeks ke dalam ALT untuk akun read-only

Address lookup table

ALT adalah akun onchain yang menyimpan hingga 256 kunci publik. Dengan mereferensikan ALT, sebuah transaksi dapat menyertakan akun tambahan menggunakan indeks 1-byte alih-alih kunci publik 32-byte, sehingga secara signifikan mengurangi overhead per akun.

Saat runtime, sebelum eksekusi dimulai, validator menyelesaikan semua referensi ALT menjadi kunci publik lengkap. Alamat yang telah diselesaikan ditambahkan ke kunci akun statis untuk membentuk daftar kunci akun yang lengkap. Akun yang diselesaikan melalui ALT mengikuti urutan yang sama dengan akun statis: pencarian yang dapat ditulis (writable lookups) muncul sebelum pencarian read-only.

Tabel pencarian alamat hanya memengaruhi cara akun direferensikan dalam transaksi on-wire. Pada waktu eksekusi, runtime menyelesaikan semua indeks menjadi alamat akun lengkap. Akun yang diselesaikan melalui ALT hanya dapat bersifat writable atau read-only (non-signer); mereka tidak dapat menjadi signer.

Batas sumber daya dalam v0

Tidak berubah dari legacy: instruksi ComputeBudget, dengan default yang sama ketika mereka dihilangkan.

Format v1

v1 meningkatkan batas ukuran menjadi 4.096 byte dan merestrukturisasi pesan di sekitar konfigurasi transaksi: batas sumber daya dipindahkan dari instruksi ComputeBudget ke field berposisi tetap dalam pesan itu sendiri. Hal ini memungkinkan jaringan mengurutkan transaksi berdasarkan biaya prioritas dengan satu pembacaan offset tetap alih-alih memindai dan mendeserialisasi daftar instruksinya.

Tata letak wire v1

FieldUkuranDeskripsi
0x811 byteByte prefiks versi — byte pertama dari transaksi
header3 byteMessageHeader (sama seperti legacy)
config_mask4 byteBitmask u32 LE yang menandai nilai konfigurasi mana yang ada
recent_blockhash32 bytePenentu masa berlaku
num_instructions1 byteHitungan lebar tetap, maksimal 64
num_addresses1 byteHitungan lebar tetap, maksimal 64
addressesN x 32 byteAlamat akun, semua inline — tanpa referensi lookup table
config_values0–20 byteSatu nilai per bit mask yang disetel, dalam urutan bit (lihat di bawah)
instruction_headersN x 4 bytePer instruksi: program_id_index (u8), num_accounts (u8), data_len (u16 LE)
instruction_payloadsvariabelPer instruksi: indeks akun, lalu instruction data
signaturesN x 64 byteDi bagian akhir, tanpa prefiks panjang — hitungannya berasal dari header

Dua perbedaan struktural dari legacy dan v0 perlu diperhatikan saat menulis dekoder. Hitungannya adalah field u8 lebar tetap, bukan compact-u16, dan instruksi dibagi menjadi dua bagian: semua header berukuran tetap terlebih dahulu, kemudian semua payload dengan panjang variabel, alih-alih setiap instruksi bersifat berurutan.

Akun dalam v1: tanpa address lookup table

v1 menghapus dukungan ALT secara sengaja. 64 alamat mentah adalah 2.048 byte, masih nyaman di dalam batas 4.096 byte, sehingga setiap alamat bersifat inline seperti dalam legacy. Jika aplikasi Anda bergantung pada lookup table, beralih ke v1 berarti menginline alamat-alamat tersebut.

Batas sumber daya dalam v1: konfigurasi transaksi

Konfigurasi adalah bitmask u32 diikuti oleh nilai lebar tetap untuk setiap field yang bitnya disetel:

BitFieldLebarCatatan
0–1Biaya prioritasu64Total lamport — kedua bit disetel bersamaan
2Batas unit komputasiu32
3Batas ukuran data akun yang dimuatu32
4Ukuran heap yang dimintau32

Bit yang tidak dikenal akan ditolak. Karena pesan ditandatangani, field konfigurasi yang tidak dikenal tidak dapat diabaikan secara diam-diam.

Biaya prioritas adalah total lamport, bukan harga

Dalam legacy dan v0, biaya prioritas ditetapkan melalui SetComputeUnitPrice sebagai micro-lamport per unit komputasi, dikalikan dengan batas unit komputasi. Dalam v1, nilainya adalah total absolut dalam lamport — tanpa perkalian, tanpa pembulatan. Jangan membawa aritmetika per-CU tersebut. Formula total biaya tidak berubah: (signatures × lamports_per_signature) + priority_fee.

Instruksi ComputeBudget adalah no-op dalam v1

Transaksi v1 tidak menolak instruksi ComputeBudget — instruksi tersebut diabaikan untuk konfigurasi. Instruksi tersebut tetap dieksekusi sebagai no-op yang berhasil, mengonsumsi 150 unit komputasi dan satu dari 64 slot instruksi tanpa memberikan efek apa pun pada anggaran. Hilangkan instruksi tersebut saat membangun transaksi v1, dan hentikan pemindaian terhadapnya saat membaca transaksi v1: nilainya ada dalam konfigurasi pesan.

Field konfigurasi harus disetel secara eksplisit

Perubahan perilaku terpenting bagi pengirim: tidak seperti legacy dan v0, transaksi v1 harus menetapkan batas unit komputasi dan batas ukuran data akun yang dimuat secara eksplisit, atau transaksi Anda akan gagal.

Field yang tidak disetellegacy / v0v1Gejala jika dihilangkan
Batas unit komputasi200k per instruksi, maks 1,4M0 CULangsung gagal, anggaran habis
Ukuran data akun yang dimuat64 MiB0 byteMaxLoadedAccountsDataSizeExceeded pada akun pertama yang dimuat
Biaya prioritas00
Ukuran heap32 KiB32 KiB

Pendekatan yang direkomendasikan adalah melakukan simulasi sekali dengan kedua batas dimaksimalkan, lalu menulis nilai unitsConsumed dan loadedAccountsDataSize yang dikembalikan ke dalam konfigurasi, membulatkan ukuran data ke atas ke halaman 32 KiB berikutnya untuk cadangan (model biaya blok menghitung dalam halaman 32 KiB, sehingga cadangan di bawah batas halaman berikutnya gratis).

Persiapan untuk v1

v1 mengubah cara membaca transaksi, bukan hanya mengirimnya. Ketika v1 diaktifkan, setiap klien yang memanggil getTransaction atau getBlock tanpa mengaktifkan dukungannya akan mulai gagal pada transaksi v1:

  • Berikan maxSupportedTransactionVersion: 1integer JSON 1, bukan string "1" — ke getTransaction dan getBlock. Memberikan 0 akan gagal pada transaksi v1 sama seperti menghilangkan parameter tersebut, sehingga kode yang diperbarui saat peluncuran v0 masih perlu mengubah nilainya.
  • getTransaction gagal pada transaksi v1 dengan error -32015, dan satu transaksi v1 membuat seluruh respons getBlock gagal dengan error yang sama — tidak ada hasil parsial.
  • blockSubscribe mengembalikan block: null dan berhenti maju, sehingga konsumen yang membaca itu sebagai blok kosong secara diam-diam akan tertinggal sejak slot v1 pertama dan seterusnya.
  • getSignaturesForAddress tidak pernah memeriksa isi transaksi, sehingga tanda tangan v1 terdaftar seperti biasa.
  • Respons yang sudah diaktifkan menyertakan objek transactionConfig dalam pesan untuk transaksi v1 (tidak ada sama sekali untuk legacy dan v0). Pipeline yang menurunkan biaya prioritas atau batas komputasi dengan memindai instruksi ComputeBudget akan melaporkan nol secara diam-diam untuk setiap transaksi v1.
  • Gunakan encoding: 'base64' saat mendekode transaksi di sisi klien, dan untuk sendTransaction/simulateTransaction dengan transaksi di atas 1.232 byte — encoding base58 tetap dibatasi pada ukuran lama.
  • Dukungan library klien memerlukan versi terbaru: @solana/kit 8.0+, crate Rust generasi Agave 4.2.x, atau web3.js v3. web3.js v1 membaca v1 mulai dari 1.99.0 ke atas, tetapi tidak dapat membangun atau mengirimnya.

Untuk panduan migrasi lengkap — termasuk dukungan library klien, deteksi versi streaming (Geyser/gRPC), dan perilaku simulasi — lihat halaman upgrade Format Transaksi v1.

Is this page helpful?

© 2026 Yayasan Solana. Semua hak dilindungi.