Ana içeriğe geç
Change page

Basit serileştirme

Sayfanın son güncellenmesi: 1 Şubat 2026

Basit serileştirme (SSZ), İşaret Zinciri'nde kullanılan serileştirme yöntemidir. Bu, yürütüm katmanında kullanılan RLP serileştirmesini, eş keşif protokolü hariç fikir birliği katmanının tamamında değiştirir. RLP serileştirmesi hakkında daha fazla bilgi edinmek için Özyinelemeli uzunluk ön eki (RLP) konusuna bakın. SSZ, belirleyici ve aynı zamanda Merkle işlemini verimli bir şekilde gerçekleştirebilecek şekilde tasarlanmıştır. SSZ'nin iki bileşeni olduğu düşünülebilir: bir serileştirme şeması ve serileştirilmiş veri yapısıyla etkili bir şekilde çalışacak şekilde tasarlanmış bir Merkle işlemi şeması.

SSZ nasıl çalışır?

Serileştirme

SSZ, kendini tanımlamayan bir serileştirme şemasıdır; aksine önceden bilinmesi gereken bir şemaya dayanır. SSZ serileştirmesinin amacı, nesneleri keyfi karmaşıklıkta bayt dizeleri olarak temsil etmektir. Bu, "temel tipler" için oldukça basit bir süreçtir. Öğe, onaltılık baytlara dönüştürülür. Temel tipler şunlardır:

  • işaretsiz tam sayılar
  • Boole değerleri

Karmaşık "bileşik" tipler için serileştirme daha karmaşıktır çünkü bileşik tip, farklı türleri veya farklı boyutları olan birden çok öğeyi veya her ikisini birden içerebilir. Bu nesnelerin tümünün sabit uzunluklara sahip olduğu durumlarda (yani, öğelerin boyutu gerçek değerlerinden bağımsız olarak her zaman sabitse), serileştirme, bileşik türdeki her bir öğenin sıralı olarak little-endian bayt dizelerine dönüştürülmesinden ibarettir. Bu bayt dizileri bir araya getirilir. Serileştirilmiş nesne, sabit uzunluktaki öğelerin bayt listesi temsilini, seri halden çıkarılan nesnede görünen sıra ile aynı düzende içerir.

Değişken uzunluğa sahip tipler için gerçek veri, serileştirilmiş nesnede o öğenin konumunda bir "kayma" değeri ile değiştirilir. Gerçek veri, serileştirilmiş nesnenin sonunda bir yığına eklenir. Kayma değeri, gerçek verinin yığındaki başlangıç noktasının indeksi olup ilgili baytları gösteren bir işaretçi olarak görev yapar.

Aşağıdaki örnek, hem sabit hem de değişken uzunluktaki öğelere sahip bir kapsayıcı için dengelemenin nasıl çalıştığını gösterir:

1
2 struct Dummy {
3
4 number1: u64,
5 number2: u64,
6 vector: Vec<u8>,
7 number3: u64
8 }
9
10 dummy = Dummy{
11
12 number1: 37,
13 number2: 55,
14 vector: vec![1,2,3,4],
15 number3: 22,
16 }
17
18 serialized = ssz.serialize(dummy)
19
Tümünü göster

serialized aşağıdaki yapıya sahip olacaktır (burada sadece 4 bite doldurulmuş, gerçekte 32 bite doldurulur ve int gösterimi açıklık amacıyla tutulur):

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 vektör için number3 vektör için
5 ofset değer
6

açıklık sağlamak için çizgilere bölünmüştür:

1[
2 37, 0, 0, 0, # `number1`'in little-endian kodlaması.
3 55, 0, 0, 0, # `number2`'nin little-endian kodlaması.
4 16, 0, 0, 0, # `vector` değerinin nerede başladığını gösteren "ofset" (little-endian 16).
5 22, 0, 0, 0, # `number3`'ün little-endian kodlaması.
6 1, 2, 3, 4, # `vector` içindeki gerçek değerler.
7]

Bu hala bir basitleştirmedir; yukarıdaki şemaladaki tam sayılar ve sıfırlar aslında aşağıdaki gibi bayt listeleri olarak depolanır:

1[
2 10100101000000000000000000000000 # `number1`'in little-endian kodlaması
3 10110111000000000000000000000000 # `number2`'nin little-endian kodlaması.
4 10010000000000000000000000000000 # `vector` değerinin nerede başladığını gösteren "ofset" (little-endian 16).
5 10010110000000000000000000000000 # `number3`'ün little-endian kodlaması.
6 10000001100000101000001110000100 # `bytes` alanının gerçek değeri.
7]

Bu nedenle, değişken uzunluktaki tiplerin gerçek değerleri, serileştirilmiş nesnenin sonunda bir yığında saklanır ve kaymaları, sıralı alan listesinde doğru pozisyonlarında depolanır.

Ayrıca, serileştirme sırasında bir uzunluk sınırı eklenmesini ve seri halden çıkarma sırasında kaldırılmasını gerektiren BitList türü gibi özel işlem gerektiren bazı durumlar da bulunur. Tüm ayrıntılar SSZ belirtiminde (opens in a new tab) mevcuttur.

Seriden Çıkarma

Bu nesneyi seri durumdan çıkarmak için şema gereklidir. Şema, serileştirilmiş verinin kesin düzenini tanımlar, böylece her bir özel öğe, bayt grubundan anlamlı bir nesneye, öğelerin doğru türüne, değerine, boyutuna ve konumuna sahip şekilde seri halden çıkarılabilir. Şema, hangi değerlerin gerçek değerler olduğunu ve hangi değerlerin kayma olduğunu seri durumdan çıkarıcıya bildiren unsurdur. Bir nesne serileştirildiğinde tüm alan adları kaybolur ancak bunlar, seri halden çıkarma sırasında şemaya göre tekrar oluşturulur.

Bu konuyla ilgili etkileşimli bir açıklama için ssz.dev (opens in a new tab) adresine bakın.

Merkle'laştırma

Bu SSZ serileştirilmiş nesnesi, daha sonra aynı verinin bir Merkle ağacı gösterimine dönüştürülebilir. İlk olarak, serileştirilmiş nesnedeki 32 baytlık parçaların sayısı belirlenir. Bunlar, ağacın "yaprakları"dır. Toplam yaprak sayısı, yaprakları karma hale getirerek sonunda tek bir karma ağaç kökü üretmek için 2'nin bir katı olmalıdır. Eğer bu doğal olarak böyle değilse, 32 baytlık sıfırlar içeren ekstra yapraklar eklenir. Diyagram olarak ifade etmek gerekirse:

1 hash tree root
2 / \
3 / \
4 / \
5 / \
6 hash of leaves hash of leaves
7 1 and 2 3 and 4
8 / \ / \
9 / \ / \
10 / \ / \
11 leaf1 leaf2 leaf3 leaf4
Tümünü göster

Ağacın yapraklarının, yukarıdaki örnekte olduğu gibi doğal olarak eşit şekilde dağılmadığı durumlar da vardır. Örneğin yaprak 4, Merkle ağacına ilave "derinlik" eklenmesini gerektiren ve dolayısıyla eşit olmayan bir ağaç oluşmasına yol açan birden fazla öğeye sahip bir kapsayıcı olabilir.

Bu ağaç öğelerine yaprak X, düğüm X gibi isimler yerine genelleştirilmiş indeksler verebiliriz. Bu, kök = 1 ile başlayan ve her seviyede soldan sağa sayılan genelleştirilmiş indekslerle yapılır. Bu, yukarıda açıklanan genelleştirilmiş indekstir. Serileştirilmiş listedeki her öğenin 2**depth + idx'e eşit bir genelleştirilmiş dizini vardır. Burada idx, serileştirilmiş nesnedeki sıfır dizinli konumunu, depth ise Merkle ağacındaki seviye sayısını belirtir. Derinlik, öğe (yaprak) sayısının iki tabanlı logaritması olarak belirlenebilir.

Genelleştirilmiş dizinler

Genelleştirilmiş dizin, ikili bir Merkle ağacındaki bir düğümü temsil eden bir tam sayıdır; bu ağaçta her düğümün 2 ** depth + sıradaki dizin şeklinde bir genelleştirilmiş dizini vardır.

1 1 --derinlik = 0 2**0 + 0 = 1
2 2 3 --derinlik = 1 2**1 + 0 = 2, 2**1+1 = 3
3 4 5 6 7 --derinlik = 2 2**2 + 0 = 4, 2**2 + 1 = 5...
4

Bu gösterim, Merkle ağacındaki her bir veri parçası için bir düğüm oluşturur.

Çoklu kanıtlar

Belirli bir öğeyi temsil eden genelleştirilmiş endekslerin listesini sağlamak, onu karma ağaç kökü ile karşılaştırarak doğrulamamıza olanak tanır. Bu kök, gerçekliğin kabul edilmiş versiyonudur. Sağladığımız herhangi bir veri, Merkle ağacında (genelleştirilmiş indeksi tarafından belirlenir) doğru yere yerleştirilerek ve kökün sabit kaldığı gözlemlenerek bu gerçekliğe karşı doğrulanabilir. Belirtimde burada (opens in a new tab), belirli bir genelleştirilmiş dizinler kümesinin içeriğini doğrulamak için gereken en küçük düğüm kümesinin nasıl hesaplanacağını gösteren işlevler bulunmaktadır.

Örneğin, aşağıdaki ağaçta indeks 9'daki verileri doğrulamak için 8, 9, 5, 3, 1 indekslerindeki verilerin özetine ihtiyacımız vardır. (8,9) karmasının karma (4) ile eşit olması gerekir, bu, 5 ile karma hale getirilerek 2 elde edilir ve bu da 3 ile karma hale getirilerek ağaç kökü 1 elde edilir. 9 için yanlış veri sağlanırsa, kök de değişir; bunu tespit eder ve dalı doğrulayamayız.

1* = kanıt oluşturmak için gereken veriler
2
3 1*
4 2 3*
5 4 5* 6 7
68* 9* 10 11 12 13 14 15
7

Daha fazla kaynak

Bu makale yararlı oldu mu?