---
title: "التسلسل البسيط"
description: "شرح لتنسيق ⁦SSZ⁩ الخاص بإيثيريوم."
lang: ar
sidebarDepth: 2
---

**التسلسل البسيط (<span dir="ltr">SSZ</span>)** هو طريقة التسلسل المستخدمة في سلسلة المنارة. وهو يحل محل تسلسل <span dir="ltr">RLP</span> المستخدم في طبقة التنفيذ في كل مكان عبر طبقة الإجماع باستثناء بروتوكول اكتشاف النظراء. لمعرفة المزيد حول تسلسل <span dir="ltr">RLP</span>، راجع [بادئة الطول العودي (<span dir="ltr">RLP</span>)](/developers/docs/data-structures-and-encoding/rlp/). تم تصميم <span dir="ltr">SSZ</span> ليكون حتميًا وللتحويل إلى شجرة ميركل بكفاءة. يمكن اعتبار أن <span dir="ltr">SSZ</span> يتكون من مكونين: مخطط التسلسل ومخطط التحويل إلى شجرة ميركل المصمم للعمل بكفاءة مع بنية البيانات المتسلسلة.

## كيف يعمل <span dir="ltr">SSZ</span>؟ {#how-does-ssz-work}

### التسلسل {#serialization}

<span dir="ltr">SSZ</span> هو مخطط تسلسل لا يصف نفسه - بل يعتمد على مخطط (<span dir="ltr">schema</span>) يجب أن يكون معروفًا مسبقًا. الهدف من تسلسل <span dir="ltr">SSZ</span> هو تمثيل الكائنات ذات التعقيد العشوائي كسلاسل من البايتات. هذه عملية بسيطة جدًا لـ "الأنواع الأساسية". يتم ببساطة تحويل العنصر إلى بايتات سداسية عشرية. تشمل الأنواع الأساسية ما يلي:

- الأعداد الصحيحة غير الموقعة
- القيم المنطقية (<span dir="ltr">Booleans</span>)

بالنسبة للأنواع "المركبة" المعقدة، يكون التسلسل أكثر تعقيدًا لأن النوع المركب يحتوي على عناصر متعددة قد تكون لها أنواع مختلفة أو أحجام مختلفة، أو كلاهما. عندما يكون لهذه الكائنات جميعًا أطوال ثابتة (أي أن حجم العناصر سيكون دائمًا ثابتًا بغض النظر عن قيمها الفعلية)، فإن التسلسل هو ببساطة تحويل لكل عنصر في النوع المركب مرتبًا في سلاسل بايتات صغيرة النهاية (<span dir="ltr">little-endian</span>). يتم ضم سلاسل البايتات هذه معًا. يحتوي الكائن المتسلسل على تمثيل قائمة البايتات للعناصر ذات الطول الثابت بنفس الترتيب الذي تظهر به في الكائن غير المتسلسل.

بالنسبة للأنواع ذات الأطوال المتغيرة، يتم استبدال البيانات الفعلية بقيمة "إزاحة" (<span dir="ltr">offset</span>) في موضع ذلك العنصر في الكائن المتسلسل. تتم إضافة البيانات الفعلية إلى كومة (<span dir="ltr">heap</span>) في نهاية الكائن المتسلسل. قيمة الإزاحة هي المؤشر لبداية البيانات الفعلية في الكومة، وتعمل كمؤشر (<span dir="ltr">pointer</span>) للبايتات ذات الصلة.

يوضح المثال أدناه كيف تعمل الإزاحة لحاوية تحتوي على عناصر ثابتة ومتغيرة الطول:

```Rust

    struct Dummy {

        number1: u64,
        number2: u64,
        vector: Vec<u8>,
        number3: u64
    }

    dummy = Dummy{

        number1: 37,
        number2: 55,
        vector: vec![1,2,3,4],
        number3: 22,
    }

    serialized = ssz.serialize(dummy)

```

سيكون لـ `serialized` البنية التالية (مبطنة إلى <span dir="ltr">4 bits</span> فقط هنا، ومبطنة إلى <span dir="ltr">32 bits</span> في الواقع، مع الاحتفاظ بتمثيل `int` للتوضيح):

```
[37, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 1, 2, 3, 4]
------------  -----------  -----------  -----------  ----------
      |             |            |           |            |
   الرقم 1       الرقم 2       إزاحة      الرقم 3       قيمة
                               المتجه                   المتجه
```

مقسمة على أسطر للتوضيح:

```
[
  37, 0, 0, 0,  # ترميز النهاية الصغيرة (little-endian) لـ `number1`.
  55, 0, 0, 0,  # ترميز النهاية الصغيرة لـ `number2`.
  16, 0, 0, 0,  # "الإزاحة" التي تشير إلى مكان بدء قيمة `vector` (النهاية الصغيرة 16).
  22, 0, 0, 0,  # ترميز النهاية الصغيرة لـ `number3`.
  1, 2, 3, 4,   # القيم الفعلية في `vector`.
]
```

هذا لا يزال تبسيطًا - الأعداد الصحيحة والأصفار في المخططات أعلاه سيتم تخزينها في الواقع كقوائم بايتات، هكذا:

```
[
  10100101000000000000000000000000  # ترميز النهاية الصغيرة لـ `number1`
  10110111000000000000000000000000  # ترميز النهاية الصغيرة لـ `number2`.
  10010000000000000000000000000000  # "الإزاحة" التي تشير إلى مكان بدء قيمة `vector` (النهاية الصغيرة 16).
  10010110000000000000000000000000  # ترميز النهاية الصغيرة لـ `number3`.
  10000001100000101000001110000100   # القيمة الفعلية لحقل `bytes`.
]
```

لذا يتم تخزين القيم الفعلية للأنواع متغيرة الطول في كومة في نهاية الكائن المتسلسل مع تخزين إزاحاتها في مواضعها الصحيحة في القائمة المرتبة للحقول.

هناك أيضًا بعض الحالات الخاصة التي تتطلب معالجة محددة، مثل نوع `BitList` الذي يتطلب إضافة حد أقصى للطول أثناء التسلسل وإزالته أثناء إلغاء التسلسل. التفاصيل الكاملة متاحة في [مواصفات <span dir="ltr">SSZ</span>](https://github.com/ethereum/consensus-specs/blob/master/ssz/simple-serialize.md).

يتطلب إلغاء تسلسل هذا الكائن وجود <b>المخطط</b>. يحدد المخطط التخطيط الدقيق للبيانات المتسلسلة بحيث يمكن إلغاء تسلسل كل عنصر محدد من كتلة بيانات من البايتات إلى كائن ذي معنى بحيث تمتلك العناصر النوع والقيمة والحجم والموضع الصحيح. المخطط هو الذي يخبر أداة إلغاء التسلسل بالقيم التي تمثل قيمًا فعلية وتلك التي تمثل إزاحات. تختفي جميع أسماء الحقول عند تسلسل كائن، ولكن تتم إعادة إنشائها عند إلغاء التسلسل وفقًا للمخطط.
## التحويل إلى شجرة ميركل {#merkleization}

يمكن بعد ذلك تحويل كائن <span dir="ltr">SSZ</span> المتسلسل هذا إلى شجرة ميركل - أي تحويله إلى تمثيل شجرة ميركل لنفس البيانات. أولاً، يتم تحديد عدد القطع المكونة من <span dir="ltr">32-byte</span> في الكائن المتسلسل. هذه هي "أوراق" الشجرة. يجب أن يكون العدد الإجمالي للأوراق من مضاعفات العدد 2 بحيث تؤدي عملية التجزئة للأوراق معًا في النهاية إلى جذر شجرة تجزئة واحد. إذا لم يكن هذا هو الحال بشكل طبيعي، تتم إضافة أوراق إضافية تحتوي على <span dir="ltr">32 bytes</span> من الأصفار. تخطيطيًا:

```
جذر شجرة التجزئة
            /     \
           /       \
          /         \
         /           \
   تجزئة الأوراق   تجزئة الأوراق
      1 و 2           3 و 4
      /   \            /  \
     /     \          /    \
    /       \        /      \
 الورقة 1  الورقة 2 الورقة 3  الورقة 4
```

هناك أيضًا حالات لا تتوزع فيها أوراق الشجرة بشكل متساوٍ طبيعيًا بالطريقة التي تتوزع بها في المثال أعلاه. على سبيل المثال، يمكن أن تكون الورقة 4 عبارة عن حاوية تحتوي على عناصر متعددة تتطلب إضافة "عمق" إضافي إلى شجرة ميركل، مما يؤدي إلى إنشاء شجرة غير متساوية.

بدلاً من الإشارة إلى عناصر الشجرة هذه باسم الورقة X، العقدة X وما إلى ذلك، يمكننا إعطاؤها مؤشرات معممة، بدءًا من الجذر = 1 والعد من اليسار إلى اليمين على طول كل مستوى. هذا هو المؤشر المعمم الموضح أعلاه. كل عنصر في القائمة المتسلسلة له مؤشر معمم يساوي `2**depth + idx` حيث <span dir="ltr">idx</span> هو موضعه المفهرس بالصفر في الكائن المتسلسل والعمق هو عدد المستويات في شجرة ميركل، والذي يمكن تحديده على أنه اللوغاريتم ذو الأساس 2 لعدد العناصر (الأوراق).

## المؤشرات المعممة {#generalized-indices}

المؤشر المعمم هو عدد صحيح يمثل عقدة في شجرة ميركل ثنائية حيث يكون لكل عقدة مؤشر معمم `2 ** depth + index in row`.

```
1           --العمق = 0  2**0 + 0 = 1
    2       3       --العمق = 1  2**1 + 0 = 2, 2**1+1 = 3
  4   5   6   7     --العمق = 2  2**2 + 0 = 4, 2**2 + 1 = 5...
```

ينتج عن هذا التمثيل مؤشر عقدة لكل جزء من البيانات في شجرة ميركل.

## الإثباتات المتعددة (Multiproofs) {#multiproofs}

يتيح لنا توفير قائمة المؤشرات المعممة التي تمثل عنصرًا معينًا التحقق منه مقابل جذر شجرة التجزئة. هذا الجذر هو نسختنا المقبولة من الواقع. يمكن التحقق من أي بيانات يتم تزويدنا بها مقابل هذا الواقع عن طريق إدراجها في المكان الصحيح في شجرة ميركل (يتم تحديده بواسطة مؤشرها المعمم) وملاحظة أن الجذر يظل ثابتًا. توجد دوال في المواصفات [هنا](https://github.com/ethereum/consensus-specs/blob/master/ssz/merkle-proofs.md#merkle-multiproofs) توضح كيفية حساب الحد الأدنى من مجموعة العقد المطلوبة للتحقق من محتويات مجموعة معينة من المؤشرات المعممة.

على سبيل المثال، للتحقق من البيانات في المؤشر 9 في الشجرة أدناه، نحتاج إلى تجزئة البيانات في المؤشرات 8 و 9 و 5 و 3 و 1.
يجب أن تساوي تجزئة (8،9) تجزئة (4)، والتي يتم تجزئتها مع 5 لإنتاج 2، والتي يتم تجزئتها مع 3 لإنتاج جذر الشجرة 1. إذا تم توفير بيانات غير صحيحة لـ 9، فسيتغير الجذر - وسنكتشف ذلك ونفشل في التحقق من الفرع.

```
* = البيانات المطلوبة لإنشاء الإثبات

                    1*
          2                      3*
    4          5*          6          7
8*     9*   10    11   12    13    14    15
```

- [ترقية إيثيريوم: <span dir="ltr">SSZ</span>](https://eth2book.info/altair/part2/building_blocks/ssz)
- [ترقية إيثيريوم: التحويل إلى شجرة ميركل](https://eth2book.info/altair/part2/building_blocks/merkleization)
- [تنفيذات <span dir="ltr">SSZ</span>](https://github.com/ethereum/consensus-specs/issues/2138)
- [حاسبة <span dir="ltr">SSZ</span>](https://simpleserialize.com/)
