Özyinelemeli uzunluk ön eki (RLP) serileştirmesi
Sayfanın son güncellenmesi: 23 Şubat 2026
Özyinelemeli Uzunluk Ön Eki (RLP), Ethereum'un yürütüm istemcilerinde yaygın şekilde kullanılan bir serileştirme yoludur. RLP, düğümler arasında veri transferini, alan açısından verimli bir biçimde standartlaştırır. RLP'nin amacı, rastgele iç içe geçmiş ikili veri dizilerini kodlamaktır. RLP, Ethereum'un yürütüm katmanında nesneleri serileştirmek için kullanılan temel kodlama yöntemidir. RLP'nin ana amacı yapıyı kodlamaktır; pozitif tam sayılar hariç olmak üzere RLP, belirli veri türlerinin (ör. dizeler, kayan noktalı sayılar) kodlanmasını daha üst düzey protokollere devreder. Pozitif tamsayılar, başlarında sıfır olmadan big-endian ikili biçiminde gösterilmelidir (böylece sıfır tamsayı değeri boş bayt dizisine eşdeğer olur). Başında sıfır bulunan seri duruma getirilmiş pozitif tamsayılar, RLP kullanan herhangi bir üst düzey protokol tarafından geçersiz olarak değerlendirilmelidir.
Ethereum sarı bülteninde (Ek B) (opens in a new tab) daha fazla bilgi bulabilirsiniz.
Bir sözlüğü kodlamak için RLP kullanmanın iki kabul edilmiş yolu:
- sözlüksel sırada anahtarlarla
[[k1,v1],[k2,v2]...]kullanın - Ethereum'un yaptığı gibi kodlama için üst düzey Patricia Ağacını kullanmak
Tanım
RLP kodlama fonksiyonu bir öğeyi içine alır. Bir öğe aşağıdaki gibi tanımlanır:
- bir dize (yani bayt dizisi) bir öğedir
- öğelerin listesi, bir öğedir
- bir pozitif tamsayı bir öğedir
Örneğin, aşağıdakilerin tümü öğelerdir:
- boş dize;
- "cat" kelimesini içeren dize;
- herhangi bir sayıda dize içeren bir liste;
- ve
["cat", ["puppy", "cow"], "horse", [[]], "pig", [""], "sheep"]gibi daha karmaşık veri yapıları. 100sayısı
Bu sayfanın geri kalanı bağlamında "dize", "belirli sayıda ikili veri baytı" anlamına gelir; hiçbir özel kodlama kullanılmaz ve dizelerin içeriği hakkında hiçbir bilgiye sahip olunduğu ima edilmez (minimum olmayan pozitif tamsayılara karşın kuralın gerektirdiği durumlar hariç).
RLP kodlaması şu şekilde tanımlanır:
- Pozitif bir tamsayı için big-endian yorumu tam sayı olan en kısa bayt dizisine dönüştürülür ve ardından aşağıdaki kurallar uyarınca bir dize olarak kodlanır.
- Değeri
[0x00, 0x7f](ondalık[0, 127]) aralığında olan tek bir bayt için bu bayt kendi RLP kodlamasıdır. - Aksi takdirde, bir dize 0-55 bayt uzunluğundaysa, RLP kodlaması 0x80 (onl. 128) değerindeki tek bir bayt artı dizenin uzunluğu ve ardından dizenin kendisinden oluşur. Böylece ilk baytın aralığı
[0x80, 0xb7](onl.[128, 183]) olur. - Bir dize 55 bayttan uzunsa, RLP kodlaması şunlardan oluşur: 0xb7 (onl. 183) değerinde tek bir bayt, artı ikili biçimdeki dizenin uzunluğunun bayt cinsinden uzunluğu, ardından dizenin uzunluğu ve son olarak dizenin kendisi. Örneğin, 1024 bayt uzunluğunda bir dize,
\xb9\x04\x00(onl.185, 4, 0) olarak kodlanır ve ardından dize gelir. Burada, ilk bayt olarak0xb9(183 + 2 = 185), ardından gerçek dizenin uzunluğunu belirten 2 baytlık0x0400(onl. 1024) gelir. Böylece ilk baytın aralığı[0xb8, 0xbf](onl.[184, 191]) olur. - Bir dize 2^64 bayt uzunluğunda veya daha uzunsa kodlanamayabilir.
- Bir listenin toplam yükü (yani RLP kodlu tüm öğelerinin birleşik uzunluğu) 0-55 bayt uzunluğundaysa, RLP kodlaması, değeri 0xc0 olan tek bir bayt artı yükün uzunluğu ve ardından öğelerin RLP kodlamalarının birleşiminden oluşur. Böylece ilk baytın aralığı
[0xc0, 0xf7](onl.[192, 247]) olur. - Bir listenin toplam yükü 55 bayttan uzunsa RLP kodlaması; 0xf7 değerinde tek bir bayt, artı ikili formdaki yük uzunluğunun bayt cinsinden uzunluğu, ardından yükün uzunluğu ve son olarak da öğelerin RLP kodlamalarının birleşiminden oluşur. Böylece ilk baytın aralığı
[0xf8, 0xff](onl.[248, 255]) olur.
Kodda, bu:
1def rlp_encode(input):2 if isinstance(input,str):3 if len(input) == 1 and ord(input) < 0x80:4 return input5 return encode_length(len(input), 0x80) + input6 elif isinstance(input, list):7 output = ''8 for item in input:9 output += rlp_encode(item)10 return encode_length(len(output), 0xc0) + output1112def encode_length(L, offset):13 if L < 56:14 return chr(L + offset)15 elif L < 256**8:16 BL = to_binary(L)17 return chr(len(BL) + offset + 55) + BL18 raise Exception("girdi çok uzun")1920def to_binary(x):21 if x == 0:22 return ''23 return to_binary(int(x / 256)) + chr(x % 256)Tümünü gösterÖrnekler
- "dog" dizesi = = [ 0x83, 'd', 'o', 'g' ]
[ "cat", "dog" ]listesi =[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]- boş dize ('null') =
[ 0x80 ] - boş liste =
[ 0xc0 ] - 0 tamsayısı =
[ 0x80 ] \x00baytı =[ 0x00 ]\x0fbaytı =[ 0x0f ]\x04\x00baytları =[ 0x82, 0x04, 0x00 ]- üçün küme kuramsal temsili (opens in a new tab),
[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ] "Lorem ipsum dolor sit amet, consectetur adipisicing elit"dizesi =[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ..., 'e', 'l', 'i', 't' ]`
RLP kod çözme
RLP'nin kodlaması kurallarına ve sürecine göre RLP kod çözme girdisi, bir ikili veri dizisi olarak kabul edilir. RLP kod çözme süreci aşağıdaki gibidir:
-
girdi verisinin ilk baytına (yani önekine) göre veri türü, gerçek veri uzunluğu ve ofsetin kodunu çözme;
-
verilerin türüne ve kaymasına göre, pozitif tamsayılar için minimum kodlama kuralına uyarak, verilerin kodunu uygun şekilde çözün;
-
girdinin geri kalanını çözmeye devam edin;
Bunların yanında veri tiplerini ve kaymaları kodlamanın kuralları şu şekildedir:
-
ilk baytın (yani önekin) aralığı [0x00, 0x7f] ise, veri bir dizedir ve dize doğrudan ilk baytın kendisidir;
-
i̇lk baytın aralığı [0x80, 0xb7] ise veri bir dizedir ve dizenin uzunluğu ilk bayttan 0x80 çıkarıldığında elde edilen değere eşit uzunluktadır;
-
veri, ilk baytın aralığı [0xf8, 0xff] ise ve uzunluğu ilk bayt eksi 0xf7'ye eşit olan listenin toplam yükü ilk baytı takip ediyorsa ve hepsini kodlamalarının birleşimi bir listedir. listenin öğeleri, listenin toplam yükünü takip eder;
-
ilk bayt aralığı [0xc0, 0xf7] ise veriler bir listedir ve toplam yükün ilk bayta eşit olduğu listenin tüm öğelerinin RLP kodlamalarının sıralanması eksi 0xc0 ilk baytı takip eder;
-
ilk baytın aralığı [0xf8, 0xff] ise veri bir listedir ve uzunluğu ilk bayt eksi 0xf7'ye eşit olan listenin toplam yükü ilk baytı takip eder ve tümünün RLP kodlamalarının birleşimi listenin öğeleri listenin toplam yükünü takip eder;
Kodda, bu:
1def rlp_decode(input):2 if len(input) == 0:3 return4 output = ''5 (offset, dataLen, type) = decode_length(input)6 if type is str:7 output = instantiate_str(substr(input, offset, dataLen))8 elif type is list:9 output = instantiate_list(substr(input, offset, dataLen))10 output += rlp_decode(substr(input, offset + dataLen))11 return output1213def decode_length(input):14 length = len(input)15 if length == 0:16 raise Exception("girdi boş")17 prefix = ord(input[0])18 if prefix <= 0x7f:19 return (0, 1, str)20 elif prefix <= 0xb7 and length > prefix - 0x80:21 strLen = prefix - 0x8022 return (1, strLen, str)23 elif prefix <= 0xbf and length > prefix - 0xb7 and length > prefix - 0xb7 + to_integer(substr(input, 1, prefix - 0xb7)):24 lenOfStrLen = prefix - 0xb725 strLen = to_integer(substr(input, 1, lenOfStrLen))26 return (1 + lenOfStrLen, strLen, str)27 elif prefix <= 0xf7 and length > prefix - 0xc0:28 listLen = prefix - 0xc0;29 return (1, listLen, list)30 elif prefix <= 0xff and length > prefix - 0xf7 and length > prefix - 0xf7 + to_integer(substr(input, 1, prefix - 0xf7)):31 lenOfListLen = prefix - 0xf732 listLen = to_integer(substr(input, 1, lenOfListLen))33 return (1 + lenOfListLen, listLen, list)34 raise Exception("girdi RLP kodlama biçimine uymuyor")3536def to_integer(b):37 length = len(b)38 if length == 0:39 raise Exception("girdi boş")40 elif length == 1:41 return ord(b[0])42 return ord(substr(b, -1)) + to_integer(substr(b, 0, -1)) * 256Tümünü gösterDaha fazla kaynak
- Ethereum'da RLP (opens in a new tab)
- Perde arkasında Ethereum: RLP (opens in a new tab)
- Coglio, A. (2020). Ethereum ACL2'deki Özyinelemeli Uzunluk Ön Eki. arXiv preprint arXiv:2009.13769. (opens in a new tab)