Συναλλαγές με έκδοση

Περίληψη

Το Solana διαθέτει τρεις μορφές συναλλαγών: legacy, v0 και v1. Η v0 προσθέτει Address Lookup Tables (ALTs) για αναφορά λογαριασμών μέσω δεικτών 1 byte. Η v1 αυξάνει το όριο μεγέθους στα 4.096 bytes, μεταφέρει τα όρια πόρων μέσα στο ίδιο το μήνυμα και αφαιρεί τα ALTs.

Το Solana υποστηρίζει τρεις μορφές συναλλαγών: legacy, v0 και v1. Η κάθε μία περιγράφεται παρακάτω με τα ίδια τρία μέρη: πώς διατάσσει τα bytes στο δίκτυο, πώς αναφέρεται σε λογαριασμούς και από πού προέρχονται τα όρια πόρων της.

Κατάσταση ενεργοποίησης v1

Η μορφή v1 δεν είναι ακόμη ενεργή σε κανένα cluster. Η ενεργοποίηση στοχεύεται με το Agave v4.2. Το solana-test-validator 4.2+ σάς επιτρέπει να δοκιμάζετε συναλλαγές v1 τοπικά. Οι υπάρχουσες εφαρμογές θα πρέπει να ανατρέξουν στο προετοιμασία για v1.

Σύγκριση μορφών

Όριοlegacyv0v1
Μέγιστο μέγεθος συναλλαγής1.232 bytes1.232 bytes4.096 bytes
Διευθύνσεις λογαριασμών~32, περιορισμός μεγέθους64, μέσω πινάκων αναζήτησης64, inline
Πίνακες αναζήτησης διευθύνσεωνδεν υποστηρίζεταιυποστηρίζεταιδεν υποστηρίζεται
Όρια πόρωνΕντολές ComputeBudgetΕντολές ComputeBudgetρύθμιση μηνύματος

Μετάβαση σε: Legacy · v0 · v1

Μορφή legacy

Η αρχική μορφή, και ακόμη η προεπιλογή στα περισσότερα εργαλεία. Δεν διαθέτει κανένα πρόθεμα έκδοσης: το πρώτο byte της συναλλαγής είναι ο αριθμός compact-u16 του πίνακα υπογραφών, και το πρώτο byte του μηνύματος είναι το num_required_signatures, του οποίου το υψηλό bit είναι πάντα απενεργοποιημένο.

Διάταξη wire μορφής legacy

ΠεδίοΜέγεθοςΠεριγραφή
num_signaturescompact-u16Αριθμός υπογραφών
signaturesnum_signatures x 64 bytesΥπογραφές Ed25519
header3 bytesMessageHeader — το πρώτο byte έχει απενεργοποιημένο το bit έκδοσης
num_account_keyscompact-u16Αριθμός κλειδιών λογαριασμού
account_keysnum_account_keys x 32 bytesΔημόσια κλειδιά, όλα inline
recent_blockhash32 bytesΠροσδιοριστής διάρκειας ζωής
num_instructionscompact-u16Αριθμός εντολών
instructionsμεταβλητόΚάθε εντολή σειριοποιημένη διαδοχικά

Κάθε πίνακας μεταβλητού μήκους έχει πρόθεμα μήκους compact-u16: 1 byte για τιμές 0–127, 2–3 bytes για μεγαλύτερες τιμές. Για τη διάταξη ανά εντολή και έναν υπολογισμό μεγέθους με παράδειγμα, δείτε δυαδική μορφή συναλλαγής.

Λογαριασμοί στη μορφή legacy

Κάθε λογαριασμός γράφεται ως πλήρες δημόσιο κλειδί 32 bytes στο account_keys, και οι εντολές τους αναφέρονται με δείκτη 1 byte σε αυτόν τον πίνακα. Δεν υπάρχει τρόπος αναφοράς λογαριασμού που δεν αναγράφεται ρητά στη συναλλαγή, κάτι που περιορίζει μια συναλλαγή legacy σε περίπου 32 λογαριασμούς πριν εξαντληθούν τα 1.232 bytes της.

Όρια πόρων στη μορφή legacy

Το όριο μονάδων υπολογισμού, το όριο μεγέθους δεδομένων φορτωμένων λογαριασμών, το μέγεθος heap και η προτεραιότητα αμοιβής ζητούνται με τη συμπερίληψη εντολών προγράμματος ComputeBudget στη συναλλαγή. Η καθεμία καταναλώνει ένα slot εντολής και 150 μονάδες υπολογισμού. Η παράλειψή τους είναι ασφαλής: το runtime χρησιμοποιεί προεπιλογές 200.000 CU ανά εντολή (μέγιστο 1,4M), όριο μεγέθους δεδομένων 64 MiB, heap 32 KiB και προτεραιότητα αμοιβής μηδέν.

Μορφή V0

Η v0 είναι ένα legacy μήνυμα με δύο επιπλέον στοιχεία: ένα byte προθέματος έκδοσης 0x80 και έναν πίνακα address_table_lookups που προστίθεται μετά τις εντολές. Όλα τα προηγούμενα είναι byte-προς-byte ίδια με το legacy.

Διάταξη wire μορφής V0

ΠεδίοΜέγεθοςΠεριγραφή
num_signaturescompact-u16Αριθμός υπογραφών
signaturesnum_signatures x 64 bytesΥπογραφές Ed25519
0x801 byteByte προθέματος έκδοσης — πρώτο byte του μηνύματος
header3 bytesMessageHeader (ίδιο με legacy)
num_account_keyscompact-u16Αριθμός στατικών κλειδιών λογαριασμού
static_account_keysnum_account_keys x 32 bytesΚλειδιά που εμφανίζονται κυριολεκτικά στη συναλλαγή
recent_blockhash32 bytesΠροσδιοριστής διάρκειας ζωής
num_instructionscompact-u16Αριθμός εντολών
instructionsμεταβλητόΊδια μορφή με legacy
address_table_lookupscompact-u16 + μεταβλητόΑναφορές ALT (δείτε παρακάτω)

Κάθε καταχώρηση αναζήτησης πίνακα διευθύνσεων περιέχει:

ΠεδίοΜέγεθοςΠεριγραφή
account_key32 bytesΤο δημόσιο κλειδί του λογαριασμού ALT
writable_indexescompact-u16 + N x 1 byteΔείκτες στο ALT για λογαριασμούς εγγραφής
readonly_indexescompact-u16 + N x 1 byteΔείκτες στο ALT για λογαριασμούς μόνο για ανάγνωση

Πίνακες αναζήτησης διευθύνσεων

Ένας ALT είναι ένας λογαριασμός onchain που αποθηκεύει έως και 256 δημόσια κλειδιά. Με την αναφορά σε έναν ALT, μια συναλλαγή μπορεί να περιλαμβάνει πρόσθετους λογαριασμούς χρησιμοποιώντας ευρετήρια 1-byte αντί για δημόσια κλειδιά 32-byte, μειώνοντας σημαντικά το overhead ανά λογαριασμό.

Κατά το runtime, πριν ξεκινήσει η εκτέλεση, ο validator επιλύει όλες τις αναφορές ALT σε πλήρη δημόσια κλειδιά. Οι επιλυμένες διευθύνσεις προστίθενται στα στατικά κλειδιά λογαριασμών για να σχηματίσουν την πλήρη λίστα κλειδιών λογαριασμών. Οι λογαριασμοί που επιλύονται μέσω ALT ακολουθούν την ίδια σειρά με τους στατικούς λογαριασμούς: οι αναζητήσεις εγγραφής προηγούνται των αναζητήσεων μόνο για ανάγνωση.

Οι πίνακες αναζήτησης διευθύνσεων επηρεάζουν μόνο τον τρόπο με τον οποίο αναφέρονται οι λογαριασμοί στη συναλλαγή on-wire. Κατά τον χρόνο εκτέλεσης, το runtime επιλύει όλους τους δείκτες σε πλήρεις διευθύνσεις λογαριασμών. Οι λογαριασμοί που επιλύονται μέσω ALT μπορούν να είναι μόνο εγγράψιμοι ή μόνο για ανάγνωση (non-signer)· δεν μπορούν να είναι υπογράφοντες.

Όρια πόρων στη μορφή v0

Αμετάβλητα σε σχέση με το legacy: εντολές ComputeBudget, με τις ίδιες προεπιλογές όταν παραλείπονται.

Μορφή V1

Η v1 αυξάνει το όριο μεγέθους στα 4.096 bytes και αναδομεί το μήνυμα γύρω από μια ρύθμιση παραμέτρων συναλλαγής: τα όρια πόρων μεταφέρονται εκτός των εντολών ComputeBudget και σε πεδία σταθερής θέσης μέσα στο ίδιο το μήνυμα. Αυτό επιτρέπει στο δίκτυο να κατατάσσει μια συναλλαγή βάσει προτεραιότητας αμοιβής με μία μόνο ανάγνωση σταθερής μετατόπισης αντί να σαρώνει και να αποσειριοποιεί τη λίστα εντολών.

Διάταξη wire μορφής V1

ΠεδίοΜέγεθοςΠεριγραφή
0x811 byteByte προθέματος έκδοσης — το πρώτο byte της συναλλαγής
header3 bytesMessageHeader (ίδιο με legacy)
config_mask4 bytesBitmask u32 LE που σηματοδοτεί ποιες τιμές ρύθμισης υπάρχουν
recent_blockhash32 bytesΠροσδιοριστής διάρκειας ζωής
num_instructions1 byteΜέτρηση σταθερού πλάτους, μέγιστο 64
num_addresses1 byteΜέτρηση σταθερού πλάτους, μέγιστο 64
addressesN x 32 bytesΔιευθύνσεις λογαριασμών, όλες inline — χωρίς αναφορές πίνακα αναζήτησης
config_values0–20 bytesΜία τιμή ανά ενεργοποιημένο bit μάσκας, με σειρά bit (βλ. παρακάτω)
instruction_headersN x 4 bytesΑνά εντολή: program_id_index (u8), num_accounts (u8), data_len (u16 LE)
instruction_payloadsμεταβλητόΑνά εντολή: δείκτες λογαριασμών, έπειτα instruction data
signaturesN x 64 bytesΣτο τέλος, χωρίς πρόθεμα μήκους — ο αριθμός προκύπτει από την κεφαλίδα

Δύο δομικές διαφορές από τα legacy και v0 αξίζει να σημειωθούν κατά τη σύνταξη αποκωδικοποιητή. Οι μετρήσεις είναι πεδία u8 σταθερού πλάτους αντί για compact-u16, και οι εντολές χωρίζονται σε δύο ενότητες: πρώτα όλες οι κεφαλίδες σταθερού μεγέθους, και έπειτα κάθε payload μεταβλητού μήκους, αντί κάθε εντολή να είναι διαδοχική.

Λογαριασμοί στη v1: χωρίς πίνακες αναζήτησης διευθύνσεων

Η v1 αφαιρεί σκόπιμα την υποστήριξη ALT. 64 ακατέργαστες διευθύνσεις αντιστοιχούν σε 2.048 bytes, άνετα εντός του ορίου των 4.096 bytes, επομένως κάθε διεύθυνση είναι inline όπως στο legacy. Εάν η εφαρμογή σας εξαρτάται από πίνακες αναζήτησης, η μετάβαση στη v1 σημαίνει ότι πρέπει να ενσωματώσετε αυτές τις διευθύνσεις inline.

Όρια πόρων στη v1: η ρύθμιση παραμέτρων συναλλαγής

Η ρύθμιση είναι μια bitmask u32 ακολουθούμενη από τιμές σταθερού πλάτους για κάθε πεδίο του οποίου το bit είναι ενεργοποιημένο:

Bit(s)ΠεδίοΠλάτοςΣημειώσεις
0–1Αμοιβή προτεραιότηταςu64Συνολικά lamports — και τα δύο bits ενεργοποιούνται μαζί
2Όριο μονάδων υπολογισμούu32
3Όριο μεγέθους δεδομένων φορτωμένων λογαριασμώνu32
4Ζητούμενο μέγεθος heapu32

Τα άγνωστα bits απορρίπτονται. Επειδή το μήνυμα είναι υπογεγραμμένο, τα μη αναγνωρισμένα πεδία ρύθμισης δεν μπορούν να αγνοηθούν σιωπηλά.

Η αμοιβή προτεραιότητας είναι συνολικά lamports, όχι τιμή

Στα legacy και v0, η αμοιβή προτεραιότητας ορίζεται μέσω του SetComputeUnitPrice ως micro-lamports ανά μονάδα υπολογισμού, πολλαπλασιασμένα επί το όριο μονάδων υπολογισμού. Στη v1 είναι ένα απόλυτο σύνολο σε lamports — χωρίς πολλαπλασιασμό, χωρίς στρογγυλοποίηση. Μην μεταφέρετε την αριθμητική ανά-CU. Ο τύπος συνολικής αμοιβής παραμένει ως έχει: (signatures × lamports_per_signature) + priority_fee.

Οι εντολές ComputeBudget είναι no-ops στη v1

Μια συναλλαγή v1 δεν απορρίπτει εντολές ComputeBudget — τις αγνοεί για ρύθμιση παραμέτρων. Εξακολουθούν να εκτελούνται ως επιτυχημένα no-ops, καταναλώνοντας 150 μονάδες υπολογισμού και ένα από τα 64 slots εντολών χωρίς να επηρεάζουν τον προϋπολογισμό. Αφαιρέστε τες κατά τη δημιουργία συναλλαγών v1, και σταματήστε να τις σαρώνετε κατά την ανάγνωση συναλλαγών v1: οι τιμές βρίσκονται στη ρύθμιση παραμέτρων του μηνύματος.

Τα πεδία ρύθμισης πρέπει να ορίζονται ρητά

Η πιο σημαντική αλλαγή συμπεριφοράς για τους αποστολείς: σε αντίθεση με τα legacy και v0, οι συναλλαγές v1 πρέπει να ορίζουν ρητά το όριο μονάδων υπολογισμού και το όριο μεγέθους δεδομένων φορτωμένων λογαριασμών, αλλιώς η συναλλαγή θα αποτύχει.

Αόριστο πεδίοlegacy / v0v1Σύμπτωμα εάν παραλειφθεί
Όριο μονάδων υπολογισμού200k ανά εντολή, μέγιστο 1,4M0 CUΑποτυγχάνει αμέσως, εκτός προϋπολογισμού
Μέγεθος δεδομένων φορτωμένων λογαριασμών64 MiB0 bytesMaxLoadedAccountsDataSizeExceeded στον πρώτο λογαριασμό που φορτώνεται
Αμοιβή προτεραιότητας00
Μέγεθος heap32 KiB32 KiB

Η συνιστώμενη προσέγγιση είναι να κάνετε προσομοίωση μία φορά με αμφότερα τα όρια στο μέγιστο, και στη συνέχεια να γράψετε το unitsConsumed και το loadedAccountsDataSize που επιστράφηκαν πίσω στη ρύθμιση, στρογγυλοποιώντας το μέγεθος δεδομένων στην επόμενη σελίδα 32 KiB για περιθώριο ασφαλείας (το μοντέλο κόστους μπλοκ χρεώνει σε σελίδες 32 KiB, οπότε το περιθώριο κάτω από το επόμενο όριο σελίδας είναι δωρεάν).

Προετοιμασία για v1

Η v1 αλλάζει την ανάγνωση συναλλαγών, όχι μόνο την αποστολή τους. Όταν ενεργοποιηθεί η v1, οποιοδήποτε client καλεί getTransaction ή getBlock χωρίς να έχει δηλώσει συμβατότητα θα αρχίσει να αποτυγχάνει στις συναλλαγές v1:

  • Περάστε maxSupportedTransactionVersion: 1 — τον JSON ακέραιο 1, όχι το string "1" — στα getTransaction και getBlock. Το πέρασμα του 0 αποτυγχάνει στις συναλλαγές v1 ακριβώς όπως η παράλειψη της παραμέτρου, επομένως μια βάση κώδικα ενημερωμένη κατά την ανάπτυξη v0 εξακολουθεί να χρειάζεται αλλαγή της τιμής.
  • Το getTransaction αποτυγχάνει σε συναλλαγή v1 με σφάλμα -32015, και μία συναλλαγή v1 αποτυγχάνει ολόκληρη την απόκριση getBlock με το ίδιο σφάλμα — δεν υπάρχει μερικό αποτέλεσμα.
  • Το blockSubscribe εκπέμπει block: null και σταματά να προχωρά, οπότε ένας καταναλωτής που το διαβάζει ως κενό μπλοκ υστερεί σιωπηλά από τον πρώτο slot v1 και μετά.
  • Το getSignaturesForAddress δεν εξετάζει ποτέ το σώμα των συναλλαγών, επομένως οι υπογραφές v1 εμφανίζονται κανονικά.
  • Οι αποκρίσεις με δηλωμένη συμβατότητα περιλαμβάνουν ένα αντικείμενο transactionConfig στο μήνυμα για τις συναλλαγές v1 (απουσιάζει εντελώς για legacy και v0). Pipelines που υπολογίζουν αμοιβές προτεραιότητας ή όρια υπολογισμού σαρώνοντας εντολές ComputeBudget θα αναφέρουν σιωπηλά μηδέν για κάθε συναλλαγή v1.
  • Χρησιμοποιήστε encoding: 'base64' όταν αποκωδικοποιείτε συναλλαγές στην πλευρά του client, και για sendTransaction/simulateTransaction με συναλλαγές άνω των 1.232 bytes — η κωδικοποίηση base58 παραμένει περιορισμένη στο παλιό μέγεθος.
  • Η υποστήριξη client library απαιτεί πρόσφατες εκδόσεις: @solana/kit 8.0+, Rust crates γενιάς Agave 4.2.x, ή web3.js v3. Το web3.js v1 διαβάζει v1 από την έκδοση 1.99.0 και μετά, αλλά δεν μπορεί να δημιουργήσει ή να αποστείλει v1 συναλλαγές.

Για τον πλήρη οδηγό μετάβασης — συμπεριλαμβανομένης της υποστήριξης client library, ανίχνευσης έκδοσης streaming (Geyser/gRPC) και συμπεριφοράς προσομοίωσης — δείτε τη σελίδα αναβάθμισης Transaction Format v1.

Is this page helpful?

© 2026 Ίδρυμα Solana. Με επιφύλαξη παντός δικαιώματος.