تسلسل بسيط
آخر تحديث للصفحة: 1 فبراير 2026
التسلسل البسيط (SSZ) هو أسلوب التسلسل المستخدم في سلسلة المنارة. إنه يحل محل التسلسل RLP المستخدم في طبقة التنفيذ في كل مكان عبر طبقة الإجماع باستثناء بروتوكول اكتشاف الأقران. لمعرفة المزيد حول تسلسل RLP، راجع بادئة الطول العودي (RLP). تم تصميم SSZ ليكون حتميًا وأيضًا لـ Merkleize بكفاءة. يمكن اعتبار SSZ على أنه يتكون من عنصرين: مخطط تسلسل ومخطط Merkleization المصمم للعمل بكفاءة مع بنية البيانات التسلسلية.
كيف يعمل SSZ؟
تسلسل
SSZ عبارة عن مخطط تسلسل لا يصف نفسه بنفسه - بل يعتمد على مخطط يجب معرفته مسبقًا. الهدف من تسلسل SSZ هو تمثيل الكائنات ذات التعقيد التعسفي كسلاسل من البايتات. هذه عملية بسيطة جدًا بالنسبة لـ "الأنواع الأساسية". يتم تحويل العنصر ببساطة إلى بايتات سداسية عشرية. الأنواع الأساسية تشمل:
- أعداد صحيحة غير موقعة
- القيم المنطقية
بالنسبة للأنواع "المركبة" المعقدة، يكون التسلسل أكثر تعقيدًا لأن النوع المركب يحتوي على عناصر متعددة قد يكون لها أنواع أو أحجام مختلفة، أو كليهما. حيثما يكون لكل هذه الكائنات أطوال ثابتة (أي أن حجم العناصر سيكون ثابتًا دائمًا بغض النظر عن قيمها الفعلية)، فإن التسلسل هو ببساطة تحويل لكل عنصر في النوع المركب مرتبًا في سلاسل بايتات little-endian. تم ربط سلاسل البايتات هذه معًا. يحتوي الكائن التسلسلي على تمثيل بايتلي للعناصر ذات الطول الثابت بنفس الترتيب الذي تظهر به في الكائن غير التسلسلي.
بالنسبة للأنواع ذات الأطوال المتغيرة، يتم استبدال البيانات الفعلية بقيمة "الإزاحة" في موضع هذا العنصر في الكائن التسلسلي. يتم إضافة البيانات الفعلية إلى كومة في نهاية الكائن التسلسلي. قيمة الإزاحة هي المؤشر لبداية البيانات الفعلية في الكومة، وتعمل كمؤشر للبايتات ذات الصلة.
يوضح المثال أدناه كيفية عمل الإزاحة للحاوية التي تحتوي على عناصر ذات طول ثابت ومتغير:
12 struct Dummy {34 number1: u64,5 number2: u64,6 vector: Vec<u8>,7 number3: u648 }910 dummy = Dummy{1112 number1: 37,13 number2: 55,14 vector: vec![1,2,3,4],15 number3: 22,16 }1718 serialized = ssz.serialize(dummy)19إظهار الكلسيكون لـ serialized البنية التالية (مبطنة إلى 4 بتات فقط هنا، ومبطنة إلى 32 بتًا في الواقع، مع الحفاظ على تمثيل int للوضوح):
1[37, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 1, 2, 3, 4]2------------ ----------- ----------- ----------- ----------3 | | | | |4 number1 number2 إزاحة لـ number 3 قيمة لـ5 vector vector6مقسمة على خطوط من أجل الوضوح:
1[2 37, 0, 0, 0, # ترميز little-endian لـ `number1`.3 55, 0, 0, 0, # ترميز little-endian لـ `number2`.4 16, 0, 0, 0, # الـ "إزاحة" التي تشير إلى مكان بدء قيمة `vector` (little-endian 16).5 22, 0, 0, 0, # ترميز little-endian لـ `number3`.6 1, 2, 3, 4, # القيم الفعلية في `vector`.7]لا يزال هذا مجرد تبسيط - سيتم تخزين الأعداد الصحيحة والأصفار في المخططات أعلاه في الواقع كقوائم بايتلية، مثل هذا:
1[2 10100101000000000000000000000000 # ترميز little-endian لـ `number1`3 10110111000000000000000000000000 # ترميز little-endian لـ `number2`.4 10010000000000000000000000000000 # الـ "إزاحة" التي تشير إلى مكان بدء قيمة `vector` (little-endian 16).5 10010110000000000000000000000000 # ترميز little-endian لـ `number3`.6 10000001100000101000001110000100 # القيمة الفعلية لحقل `bytes`.7]وبالتالي، يتم تخزين القيم الفعلية لأنواع الطول المتغير في كومة في نهاية الكائن التسلسلي مع تخزين إزاحاتها في مواضعها الصحيحة في القائمة المرتبة من الحقول.
هناك أيضًا بعض الحالات الخاصة التي تتطلب معالجة محددة، مثل نوع BitList الذي يتطلب إضافة حد أقصى للطول أثناء التسلسل وإزالته أثناء إلغاء التسلسل. التفاصيل الكاملة متاحة في مواصفات SSZ (opens in a new tab).
إلغاء التسلسل
يتطلب إلغاء تسلسل هذا الكائن المخطط. يعرف المخطط التخطيط الدقيق للبيانات التسلسلية بحيث يمكن إلغاء تسلسل كل عنصر محدد من كتلة من البايتات إلى بعض الكائنات ذات المعنى مع وجود العناصر بالنوع والقيمة والحجم والموضع الصحيح. إنه المخطط الذي يخبر برنامج إلغاء التسلسل ما هي القيم التي هي قيم فعلية وأيها هي إزاحات. تختفي جميع أسماء الحقول عند تسلسل الكائن، ولكن يتم إعادة إنشائها عند إلغاء التسلسل وفقًا للمخطط.
راجع ssz.dev (opens in a new tab) للحصول على شرح تفاعلي حول هذا الموضوع.
المركلة
يمكن بعد ذلك تحويل هذا الكائن التسلسلي SSZ إلى Merkleized - أي تحويله إلى تمثيل شجرة Merkle لنفس البيانات. أولاً، يتم تحديد عدد الأجزاء المكونة من 32 بايت في الكائن التسلسلي. هذه هي "أوراق" الشجرة. يجب أن يكون العدد الإجمالي للأوراق قوة للرقم 2 حتى يؤدي تجميع الأوراق معًا في النهاية إلى إنتاج جذر شجرة تجزئة واحد. إذا لم يكن هذا هو الحال بشكل طبيعي، تتم إضافة أوراق إضافية تحتوي على 32 بايتًا من الأصفار. تخطيطيا:
1 جذر شجرة الهاش2 / \3 / \4 / \5 / \6 هاش الأوراق هاش الأوراق7 1 و 2 3 و 48 / \ / \9 / \ / \10 / \ / \11 leaf1 leaf2 leaf3 leaf4إظهار الكلهناك أيضًا حالات لا تتوزع فيها أوراق الشجرة بشكل طبيعي بالتساوي بالطريقة التي حدثت في المثال أعلاه. على سبيل المثال، يمكن أن تكون الورقة 4 عبارة عن حاوية تحتوي على عناصر متعددة تتطلب إضافة "عمق" إضافي إلى شجرة Merkle، مما يؤدي إلى إنشاء شجرة غير مستوية.
بدلاً من الإشارة إلى عناصر الشجرة هذه على أنها ورقة X أو عقدة X وما إلى ذلك، يمكننا أن نعطيها مؤشرات معممة، بدءًا من الجذر = 1 والعد من اليسار إلى اليمين على طول كل مستوى. هذا هو المؤشر المعمم الذي تم شرحه أعلاه. يحتوي كل عنصر في القائمة المتسلسلة على فهرس معمَّم يساوي 2**depth + idx حيث idx هو موضعه المفهرس بالصفر في الكائن المتسلسل، والعمق هو عدد المستويات في شجرة ميركل، والذي يمكن تحديده على أنه اللوغاريتم ذو الأساس اثنين لعدد العناصر (الأوراق).
الفهارس المعمَّمة
الفهرس المعمَّم هو عدد صحيح يمثل عقدة في شجرة ميركل الثنائية حيث يكون لكل عقدة فهرس معمَّم 2 ** depth + index in row.
1 1 --العمق = 0 2**0 + 0 = 12 2 3 --العمق = 1 2**1 + 0 = 2, 2**1+1 = 33 4 5 6 7 --العمق = 2 2**2 + 0 = 4, 2**2 + 1 = 5...4يؤدي هذا التمثيل إلى إنشاء فهرس عقدة لكل قطعة بيانات في شجرة Merkle.
البراهين المتعددة
إن توفير قائمة المؤشرات المعممة التي تمثل عنصرًا محددًا يسمح لنا بالتحقق منه مقابل جذر شجرة التجزئة. هذا الجذر هو نسختنا المقبولة من الواقع. يمكن التحقق من أي بيانات يتم تقديمها لنا مقابل هذا الواقع عن طريق إدخالها في المكان الصحيح في شجرة ميركل (التي يتم تحديدها من خلال مؤشرها المعمم) وملاحظة أن الجذر يظل ثابتًا. توجد دوال في المواصفات هنا (opens in a new tab) توضح كيفية حساب المجموعة الدنيا من العقد المطلوبة للتحقق من محتويات مجموعة معينة من الفهارس المعمَّمة.
على سبيل المثال، للتحقق من البيانات في الفهرس 9 في الشجرة أدناه، نحتاج إلى تجزئة البيانات في الفهارس 8، 9، 5، 3، 1. يجب أن يساوي تجزئة (8،9) تجزئة (4)، والتي تجزئ مع 5 لإنتاج 2، والتي تجزئ مع 3 لإنتاج جذر الشجرة 1. إذا تم تقديم بيانات غير صحيحة لـ 9، فسيتغير الجذر - سنكتشف ذلك ونفشل في التحقق من الفرع.
1* = البيانات المطلوبة لإنشاء البرهان23 1*4 2 3*5 4 5* 6 768* 9* 10 11 12 13 14 157