ملخص
تمتلك سولانا ثلاث صيغ للمعاملات: legacy وv0 وv1. تضيف v0 جداول بحث العناوين (ALTs) للإشارة إلى الحسابات عبر مؤشرات أحادية البايت. أما v1 فترفع حد الحجم إلى 4,096 بايت، وتنقل حدود الموارد إلى داخل الرسالة نفسها، وتزيل دعم ALTs.
تدعم سولانا ثلاث صيغ للمعاملات: legacy وv0 وv1. يُوصف كلٌّ منها أدناه بالأجزاء الثلاثة ذاتها: كيفية ترتيب بياناته على السلك، وكيفية الإشارة إلى الحسابات، ومصدر حدود موارده.
حالة تفعيل v1
صيغة v1 غير مفعّلة بعد على أي مجموعة عقد. يُستهدف التفعيل مع
Agave v4.2. يتيح لك solana-test-validator الإصدار 4.2 وما بعده اختبار معاملات v1 محلياً.
ينبغي على التطبيقات الحالية مراجعة الاستعداد لـ v1.
مقارنة الصيغ
| الحد | legacy | v0 | v1 |
|---|---|---|---|
| الحد الأقصى لحجم المعاملة | 1,232 بايت | 1,232 بايت | 4,096 بايت |
| عناوين الحسابات | ~32، محدودة بالحجم | 64، عبر جداول البحث | 64، مضمّنة |
| جداول بحث العناوين | غير مدعومة | مدعومة | غير مدعومة |
| حدود الموارد | تعليمات ComputeBudget | تعليمات ComputeBudget | إعداد الرسالة |
صيغة Legacy
الصيغة الأصلية، ولا تزال الافتراضية في معظم الأدوات. لا تحتوي على بادئة إصدار على الإطلاق:
البايت الأول من المعاملة هو عدد compact-u16 لمصفوفة التوقيعات، والبايت الأول من
الرسالة هو num_required_signatures الذي تكون بتته العليا دائماً غير مضبوطة.
تخطيط سلك Legacy
| الحقل | الحجم | الوصف |
|---|---|---|
num_signatures | compact-u16 | عدد التوقيعات |
signatures | num_signatures × 64 بايت | توقيعات Ed25519 |
header | 3 بايتات | MessageHeader — البايت الأول لا تكون فيه بتة الإصدار مضبوطة |
num_account_keys | compact-u16 | عدد مفاتيح الحسابات |
account_keys | num_account_keys × 32 بايت | المفاتيح العامة، جميعها مضمّنة |
recent_blockhash | 32 بايت | محدد العمر الافتراضي |
num_instructions | compact-u16 | عدد التعليمات |
instructions | متغير | كل تعليمة مُسلسَلة بشكل متتالٍ |
كل مصفوفة متغيرة الطول تُسبق بطول compact-u16: بايت واحد للقيم من 0 إلى 127، و2–3 بايتات للقيم الأكبر. للاطلاع على تخطيط التعليمة الفردية وحساب حجم عملي، انظر الصيغة الثنائية للمعاملة.
الحسابات في Legacy
يُكتب كل حساب كمفتاح عام كامل بطول 32 بايت في account_keys، وتُشير إليه
التعليمات بمؤشر أحادي البايت في تلك المصفوفة. لا توجد طريقة للإشارة إلى حساب
غير مُدرج صراحةً في المعاملة، وهذا ما يحدّ معاملة legacy بحوالي 32 حساباً
قبل أن تنفد الـ 1,232 بايت.
حدود الموارد في Legacy
يُطلب تحديد حد وحدات الحوسبة، وحد حجم بيانات الحسابات المُحمَّلة، وحجم الكومة، ورسوم الأولوية، بإدراج تعليمات برنامج ComputeBudget في المعاملة. يكلّف كل منها فتحة تعليمة slot و150 وحدة حوسبة. الحذف آمن: يعود وقت التشغيل إلى القيم الافتراضية وهي 200,000 وحدة حوسبة لكل تعليمة (بحد أقصى 1.4M)، وحد حجم بيانات 64 ميبيبايت، وكومة 32 كيبيبايت، ورسوم أولوية بقيمة صفر.
صيغة V0
v0 هي رسالة legacy مضافاً إليها أمران: بايت بادئة إصدار 0x80 ومصفوفة
address_table_lookups تُلحق بعد التعليمات. كل ما قبل ذلك مطابق بالبايت لصيغة legacy.
تخطيط سلك V0
| الحقل | الحجم | الوصف |
|---|---|---|
num_signatures | compact-u16 | عدد التوقيعات |
signatures | num_signatures × 64 بايت | توقيعات Ed25519 |
0x80 | 1 بايت | بايت بادئة الإصدار — البايت الأول من الرسالة |
header | 3 بايتات | MessageHeader (نفس القديم) |
num_account_keys | compact-u16 | عدد مفاتيح الحسابات الثابتة |
static_account_keys | num_account_keys × 32 بايت | المفاتيح التي تظهر حرفياً في المعاملة |
recent_blockhash | 32 بايت | محدد العمر الافتراضي |
num_instructions | compact-u16 | عدد التعليمات |
instructions | متغير | نفس التنسيق القديم |
address_table_lookups | compact-u16 + متغير | مراجع ALT (انظر أدناه) |
يحتوي كل إدخال في جدول البحث عن العناوين على:
| الحقل | الحجم | الوصف |
|---|---|---|
account_key | 32 بايت | المفتاح العام لحساب ALT |
writable_indexes | compact-u16 + N x 1 بايت | الفهارس في ALT للحسابات القابلة للكتابة |
readonly_indexes | compact-u16 + N x 1 بايت | الفهارس في ALT للحسابات للقراءة فقط |
جداول بحث العناوين
ALT هو حساب على السلسلة يخزن ما يصل إلى 256 مفتاحاً عاماً. من خلال الإشارة إلى ALT، يمكن للمعاملة تضمين حسابات إضافية باستخدام فهارس بحجم 1 بايت بدلاً من المفاتيح العامة بحجم 32 بايت، مما يقلل بشكل كبير من العبء لكل حساب.
في وقت التشغيل، قبل بدء التنفيذ، يقوم المدقق بتحليل جميع مراجع ALT إلى مفاتيح عامة كاملة. يتم إلحاق العناوين المحللة بمفاتيح الحسابات الثابتة لتشكيل قائمة مفاتيح الحسابات الكاملة. تتبع الحسابات المحللة من ALT نفس الترتيب الخاص بالحسابات الثابتة: تأتي عمليات البحث القابلة للكتابة قبل عمليات البحث للقراءة فقط.
تؤثر جداول البحث عن العناوين فقط على كيفية الإشارة إلى الحسابات في المعاملة على الشبكة. في وقت التنفيذ، يقوم وقت التشغيل بتحليل جميع الفهارس إلى عناوين حسابات كاملة. يمكن أن تكون الحسابات المحللة من ALT قابلة للكتابة أو للقراءة فقط (غير موقّعة)؛ لا يمكن أن تكون موقّعة.
حدود الموارد في v0
لم تتغير عن legacy: تعليمات ComputeBudget، مع القيم الافتراضية ذاتها عند حذفها.
صيغة V1
ترفع v1 حد الحجم إلى 4,096 بايت وتعيد هيكلة الرسالة حول إعداد المعاملة: تنتقل حدود الموارد من تعليمات ComputeBudget إلى حقول ذات موضع ثابت في الرسالة نفسها. يتيح ذلك للشبكة ترتيب المعاملات حسب رسوم الأولوية بقراءة واحدة ذات إزاحة ثابتة بدلاً من فحص قائمة التعليمات وفك تسلسلها.
تخطيط سلك V1
| الحقل | الحجم | الوصف |
|---|---|---|
0x81 | 1 بايت | بايت بادئة الإصدار — البايت الأول من المعاملة |
header | 3 بايتات | MessageHeader (مطابق لـ legacy) |
config_mask | 4 بايتات | قناع بتات u32 LE يحدد قيم الإعداد الموجودة |
recent_blockhash | 32 بايت | محدد العمر الافتراضي |
num_instructions | 1 بايت | عدد ذو عرض ثابت، الحد الأقصى 64 |
num_addresses | 1 بايت | عدد ذو عرض ثابت، الحد الأقصى 64 |
addresses | N × 32 بايت | عناوين الحسابات، جميعها مضمّنة — بدون إشارات إلى جداول البحث |
config_values | 0–20 بايت | قيمة واحدة لكل بتة مضبوطة في القناع، بترتيب البتات (انظر أدناه) |
instruction_headers | N × 4 بايتات | لكل تعليمة: program_id_index (u8)، num_accounts (u8)، data_len (u16 LE) |
instruction_payloads | متغير | لكل تعليمة: مؤشرات الحسابات، ثم instruction data |
signatures | N × 64 بايت | في الذيل، بدون بادئة طول — يُستخرج العدد من الرأس |
ثمة فارقان هيكليان عن legacy وv0 يستحقان الانتباه عند كتابة مُفككّ ترميز.
الأعداد حقول u8 ذات عرض ثابت بدلاً من compact-u16، والتعليمات مقسّمة إلى
جريانين: كل الرؤوس ذات الحجم الثابت أولاً، ثم كل الحمولات متغيرة الطول،
بدلاً من أن تكون كل تعليمة متتالية.
الحسابات في 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 بوصفها
micro-lamports لكل وحدة حوسبة، مضروبةً في حد وحدات الحوسبة. أما في
v1 فهي إجمالي مطلق بوحدة lamport — بدون ضرب ولا تقريب.
لا تنقل حسابات الـ per-CU إلى v1. صيغة الرسوم الإجمالية لا تتغير:
(signatures × lamports_per_signature) + priority_fee.
تعليمات ComputeBudget لا تؤثر في v1
لا ترفض معاملة v1 تعليمات ComputeBudget — بل تتجاهلها للإعداد. لا تزال تُنفَّذ كعمليات ناجحة لا أثر لها، تستهلك 150 وحدة حوسبة وفتحة واحدة من فتحات التعليمات الـ 64، دون أي تأثير على الميزانية. احذفها عند بناء معاملات v1، وتوقف عن البحث عنها عند قراءة معاملات v1: القيم موجودة في إعداد الرسالة.
يجب ضبط حقول الإعداد صراحةً
أهم تغيير سلوكي للمُرسِلين: خلافاً لـ legacy وv0، يجب على معاملات v1 ضبط حد وحدات الحوسبة وحد حجم بيانات الحسابات المُحمَّلة صراحةً، وإلا فستفشل معاملتك.
| الحقل غير المضبوط | legacy / v0 | v1 | العرض عند الحذف |
|---|---|---|---|
| حد وحدات الحوسبة | 200k لكل تعليمة، الحد الأقصى 1.4M | 0 وحدة حوسبة | يفشل فوراً، نفاد الميزانية |
| حجم بيانات الحسابات المُحمَّلة | 64 ميبيبايت | 0 بايت | MaxLoadedAccountsDataSizeExceeded عند أول حساب مُحمَّل |
| رسوم الأولوية | 0 | 0 | — |
| حجم الكومة | 32 كيبيبايت | 32 كيبيبايت | — |
النهج الموصى به هو المحاكاة مرة واحدة مع رفع كلا الحدين إلى الأقصى، ثم كتابة
unitsConsumed وloadedAccountsDataSize المُعادَين في الإعداد، مع تقريب
حجم البيانات إلى أعلى صفحة 32 كيبيبايت لإبقاء هامش (يتقاضى نموذج تكلفة
الكتلة وفق صفحات 32 كيبيبايت، لذا فأي هامش دون حدود الصفحة التالية مجاني).
الاستعداد لـ v1
تُغيّر v1 طريقة قراءة المعاملات، لا إرسالها فحسب. عند تفعيل v1،
سيبدأ أي عميل يستدعي getTransaction أو getBlock دون الاشتراك في الدعم
بالفشل عند معاملات v1:
- مرّر
maxSupportedTransactionVersion: 1— العدد الصحيح JSON الصحيح1، لا السلسلة النصية"1"— إلىgetTransactionوgetBlock. تمرير0يُفشل معاملات v1 تماماً كحذف المعامل، لذا قد تحتاج قاعدة التعليمات البرمجية المحدَّثة إبان طرح v0 إلى تغيير القيمة. getTransactionيفشل عند معاملة v1 بالخطأ-32015، ومعاملة v1 واحدة تُفشل استجابةgetBlockبأكملها بالخطأ ذاته — لا يوجد نتيجة جزئية.blockSubscribeيُصدرblock: nullويتوقف عن التقدم، لذا قد يُفسّر مستهلك يعتبر ذلك كتلة فارغة أنه يتأخر بصمت اعتباراً من أول slot لـ v1.getSignaturesForAddressلا يفحص أجسام المعاملات أبداً، لذا تظهر توقيعات v1 بشكل طبيعي.- تتضمن الاستجابات المُشترَكة كائن
transactionConfigفي الرسالة لمعاملات v1 (غائب كلياً لـ legacy وv0). ستُبلّغ مسارات معالجة البيانات التي تستخرج رسوم الأولوية أو حدود الحوسبة بفحص تعليمات ComputeBudget عن صفر بصمت لكل معاملة v1. - استخدم
encoding: 'base64'عند فك ترميز المعاملات من جانب العميل، وكذلك معsendTransaction/simulateTransactionللمعاملات التي تتجاوز 1,232 بايت — يظل ترميز base58 محدوداً بالحجم القديم. - دعم مكتبات العميل يتطلب إصدارات حديثة:
@solana/kitالإصدار 8.0 فأعلى، أو حزم Rust من جيل Agave 4.2.x، أو web3.js v3. يقرأ web3.js v1 معاملات v1 اعتباراً من الإصدار 1.99.0، لكنه لا يستطيع بناءها أو إرسالها.
للاطلاع على دليل الترحيل الكامل — بما في ذلك دعم مكتبات العميل، واكتشاف الإصدار في البث المباشر (Geyser/gRPC)، وسلوك المحاكاة — راجع صفحة ترقية صيغة المعاملة v1.
Is this page helpful?