以太坊 RLP機制分析

2021-09-16 23:37:31 字數 3160 閱讀 4366

目錄

1 rlp 定義

2 rlp 編碼規則

3 rlp 編碼例項

4 rlp 分析

1 rlp 定義

rlp,即 recursive length prefix, 遞迴長度字首編碼,是以太坊資料序列化的主要方法, 具有較好的資料處理效率,尤其是將長度和型別統一作為字首,實際上 rlp 是基於 ascii 編碼的一種結構化擴充,既能表示長度還能表示型別,是一種非常緊湊的結構化編碼方案。 該編碼方案用於編碼任意的巢狀結構的二進位制資料,區塊、交易等資料結構在持久化時會先 經過 rlp 編碼後再儲存到資料庫中。rlp 的唯一目標就是解決結構體的編碼問題;對原子 資料型別(比如,字串,整數型,浮點型)的編碼則交給更高層的協議;以太坊中要求數 字必須是乙個大端位元組序的、沒有零佔位的儲存的格式(也就是說,乙個整數 0 和乙個空數 組是等同的)。如果要編碼乙個字典,推薦使用兩種規範的編碼格式——一是通過 key 的字 典序來組織字典[[k1,v1],[k2,v2]……],另一種是以太坊中使用的高層的 patricia tree。

rlp 編碼的定義只處理兩類資料:

一類是字串(例如位元組陣列),即一串二進位制資料(strings);

一類是列表。即乙個巢狀遞迴的結構,裡面可以包含字串和列表。

例如:[「cat」,[「puppy」,「cow」],「horse」,,「pig」,[「」],「sheep」]

其他型別的資料需要轉成以上的兩類,轉換的規則不是 rlp 編碼定義的,可以根據自己的 規則轉換,例如 struct 可以轉成列表,int 可以轉成二進位制(屬於字串一類),以太坊中整 數都以大端形式儲存。

從 rlp 編碼的名字可以看出它的特點:

一是遞迴,被編碼的資料是遞迴的結構,編碼演算法也是遞迴進行處理的;

二是長度字首,即 rlp 編碼都帶有乙個字首,這個字首是跟被編碼資料的長度相關的。

2 rlp 編碼規則

規則一:單位元組值在[0x00,0x7f]之間的,編碼就是自身。需要注意的是 0x7f 這個邊界,因為 ascii 編碼最大值就是 0x7f(即二進位制 1111,1111),也就是說在 0x7f 以內完全當做 ascii 編碼使用。

規則二:如果乙個 string 長度在 0-55 之間,編碼結果的為在 string 開頭加乙個位元組,這個字 節的值是 0x80 加上 string 的長度。由於被編碼的字串最大長度是 55=0x37,因此單位元組前 綴的最大值是 0x80+0x37=0xb7,即編碼的第乙個位元組的取值範圍是[0x80, 0xb7]。 (128—183)

(0x80+[string 的長度]) || string

規則三:如果乙個 string 長度超過了 55 個位元組,編碼結果的第 1 個位元組為 0xb7+string 的長度 值(位元組表示)的長度,後跟著string的長度,後跟著string。所以第乙個位元組的範圍為[0xb8,0xbf]。

(0xb7+string 長度值的長度) || (string 的長度) || string

比如某個 string 長度為 1024(0x0400),0x0400 的長度為 2,因此第 1 個位元組為字首應該是 0xb7+2=0xb9,後面跟著0x0400,再後面跟著string,即整個rlp編碼應該是\xb9\x0400\string。 編碼的第乙個位元組即字首的取值範圍是[0xb8, 0xbf],因為字串長度二進位制形式最少是 1個位元組,因此最小值是 0xb7+1=0xb8,字串長度二進位制最大是 8 個位元組,因此最大值是 0xb7+8=0xbf。(184—191)

規則四:如果乙個陣列中所有元素的長度之和在 0-55 之間,編碼結果的第 1 個位元組為 0xc0+ 所有元素的長度,後面跟著列表中各元素的編碼串,因此第 1 個位元組的範圍在[0xc0,0xf7]。 [192—247]

(0xc0+列表元素總長度) || 列表各元素的編碼串

規則五:如果陣列中所有元素的長度超過 55 個位元組,編碼結果的第 1 個位元組為 0xf7 加上所 有元素長度值(位元組表示)的長度,後跟所有元素長度,後面跟著陣列。第 1 個位元組的範圍是 [0xf8,0xff]。 [248—255]

(0xf7+所有元素長度值的長度) || 列表元素總長度 || 列表各元素的編碼串

3 rlp 編碼例項

字串 「dog」 = [0x83, 』d』, 『o』, 『g』 ] (規則二)

列表 [「cat」,「dog」] = [0xc8, 0x83, 『c』, 『a』, 』t』, 0x83, 』d』, 『o』, 『g』 ] (規則四)

空字串 「」 = 0x80 (規則二)

空列表 = [0xc0] (規則四)

整數 15(『\x0f』) = 0x0f (規則一)

整數 1024(『\x04\00』) = [0x82, 0x04, 0x00] (規則二)

列表 [ , , [ , ] ] = [0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0] (規則四)

字串 「lorem ipsum dolor sit amet, consectetur adipisicing elit」 = [0xb8, 0x38, 『l』, 『o』, 『r』, 『e』, 』m』, 『 』, … , 『e』, 『l』, 『i』, 』t』](規則三)

4 rlp 分析

rlp 編碼的設計思想,就是通過首位元組快速判斷一串編碼的型別,充分利用了乙個字 節的儲存空間,將 0x7f 以後的值賦予了新的含義。相比於 unicode 的對指定長度位元組進行 編碼,處理這些編碼時一般按照指定長度進行拆分解碼,最大的弊端是傳統編碼無法表現一 個結構,即列表。rlp 最大的優點是在充分利用位元組的情況下,同時支援列表結構,也就 是說可以很輕易的利用 rlp 儲存乙個樹狀結構。

程式處理 rlp 編碼時也非常容易,根據首位元組就可以判斷出這段編碼的型別,同時呼叫不 同的方法進行解碼,類似於 json 結構, rlp 支援巢狀的結構,通過遞迴呼叫可以將整個 rlp 快速還原成一顆樹,或者轉譯成乙個 json 結構,便於其他程式使用。

rlp 使用首位元組儲存長度的位數,再用後續的位元組表明整體字串的長度,根據規則二計 算,rlp 可以支援的單個最大字串長度為 2 的 64 次方,再加上巢狀規則,理論上 rlp 可 以編碼任何資料。

以太坊RLP機制分析

目錄 1 rlp 定義 2 rlp 編碼規則 3 rlp 編碼例項 4 rlp 分析 1 rlp 定義 rlp,即 recursive length prefix,遞迴長度字首編碼,是以太坊資料序列化的主要方法,具有較好的資料處理效率,尤其是將長度和型別統一作為字首,實際上 rlp 是基於 asci...

以太坊RLP機制分析

目錄 1 rlp 定義 2 rlp 編碼規則 3 rlp 編碼例項 4 rlp 分析 1 rlp 定義 rlp,即 recursive length prefix,遞迴長度字首編碼,是以太坊資料序列化的主要方法,具有較好的資料處理效率,尤其是將長度和型別統一作為字首,實際上 rlp 是基於 asci...

以太坊原始碼(06) RLP 機制分析

目錄 1 rlp 定義 4 2 rlp 編碼規則.4 3 rlp 編碼例項 5 4 rlp 分析 5 1 rlp 定義 rlp,即 recursive length prefix,遞迴長度字首編碼,是以太坊資料序列化的主要方法,具有較好的資料處理效率,尤其是將長度和型別統一作為字首,實際上 rlp ...