国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

以太坊源碼學習—RLP編碼

leanote / 2441人閱讀

摘要:,中文翻譯過來叫遞歸長度前綴編碼,它是以太坊序列化所采用的編碼方式。所以,以太坊需要設計一種結果更小的編碼方法。例編碼結果是,其中,依次是。以上解釋了什么叫遞歸長度前綴編碼,這個名字本身很好的解釋了編碼規則。

RLP(Recursive Length Prefix),中文翻譯過來叫遞歸長度前綴編碼,它是以太坊序列化所采用的編碼方式。RLP主要用于以太坊中數據的網絡傳輸和持久化存儲。

為什么又要造輪子

對象序列化方法有很多種,常見的像JSON編碼,但是JSON有個明顯的缺點:編碼結果比較大。例如有如下的結構:

type Student struct{
    Name string `json:"name"`
    Sex string `json:"sex"`
}
s := Student{Name:"icattlecoder",Sex:"male"}
bs,_ := json.Marsal(&s)
print(string(bs))
// {"name":"icattlecoder","sex":"male"}

變量s序列化的結果是{"name":"icattlecoder","sex":"male"},字符串長度35,實際有效數據是icattlecodermale,共計16個字節,我們可以看到JSON的序列化時引入了太多的冗余信息。假設以太坊采用JSON來序列化,那么本來50GB的區塊鏈可能現在就要100GB,當然實際沒這么簡單。

所以,以太坊需要設計一種結果更小的編碼方法。

RLP編碼定義

RLP實際只給以下兩種類型數據編碼:

1. byte數組

2. byte數組的數組,稱之為列表

規則1:對于值在[0, 127]之間的單個字節,其編碼是其本身。

例1:a的編碼是97

規則2:如果byte數組長度l <= 55,編碼的結果是數組本身,再加上128+l作為前綴。

例2:空字符串編碼是128,即128 = 128 + 0

例3:abc編碼結果是131 97 98 99,其中131=128+len("abc")97 98 99依次是a b c
  

規則3:如果數組長度大于55, 編碼結果第一個是183加數組長度的編碼的長度,然后是數組長度的本身的編碼,最后是byte數組的編碼。

請把上面的規則多讀幾篇,特別是數組長度的編碼的長度

例4:編碼下面這段字符串:

The length of this sentence is more than 55 bytes, I know it because I pre-designed it

這段字符串共86個字節,而86的編碼只需要一個字節,那就是它自己,因此,編碼的結果如下:

184 86 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前三個字節的計算方式如下:

184 = 183 + 1,因為數組長度86編碼后僅占用一個字節。

86即數組長度86

84T的編碼

例5:編碼一個重復1024次"a"的字符串,其結果為:185 4 0 97 97 97 97 97 97 ...
1024按 big endian編碼為0 0 4 0,省略掉前面的零,長度為2,因此185 = 183 + 2

規則1~3定義了byte數組的編碼方案,下面介紹列表的編碼規則。在此之前,我們先定義列表長度是指子列表編碼后的長度之和。

規則4:如果列表長度小于55,編碼結果第一位是192加列表長度的編碼的長度,然后依次連接各子列表的編碼。

注意規則4本身是遞歸定義的。
例6:["abc", "def"]的編碼結果是200 131 97 98 99 131 100 101 102
其中abc的編碼為131 97 98 99,def的編碼為131 100 101 102。兩個子字符串的編碼后總長度是8,因此編碼結果第一位計算得出:192 + 8 = 200

規則5:如果列表長度超過55,編碼結果第一位是247加列表長度的編碼長度,然后是列表長度本身的編碼,最后依次連接各子列表的編碼。

規則5本身也是遞歸定義的,和規則3相似。

例7:

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]

的編碼結果是:

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前兩個字節的計算方式如下:

248 = 247 +1

88 = 86 + 2,在規則3的示例中,長度為86,而在此例中,由于有兩個子字符串,每個子字符串本身的長度的編碼各占1字節,因此總共占2字節。
第3個字節179依據規則2得出179 = 128 + 51

第55個字節163同樣依據規則2得出163 = 128 + 35

例8:最后我們再來看個稍復雜點的例子以加深理解遞歸長度前綴,

["abc",["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]]

編碼結果是:

248 94 131 97 98 99 248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

列表第一項字符串abc根據規則2,編碼結果為131 97 98 99,長度為4。
列表第二項也是一個列表項:

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]

根據規則5,結果為

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

長度為90,因此,整個列表的編碼結果第二位是90 + 4 = 94, 占用1個字節,第一位247 + 1 = 248

以上5條就是RPL的全部編碼規則。

語言實現

各語言在具體實現RLP編碼時,首先需要將對像映射成byte數組或列表兩種形式。以go語言編碼struct為例,會將其映射為列表,例如Student這個對象處理成列表["icattlecoder","male"]

type Student struct{
    Name string
    Sex string
}
s := Student{Name:"icattlecoder",Sex:"male"}
buff := bytes.Buffer{}
rpl.Encode(&buff, &s)
print(buff.Bytes())
// [210 140 105 99 97 116 116 108 101 99 111 100 101 114 132 109 97 108 101]

如果編碼map類型,可以采用以下列表形式:

[["",""],["",""],["",""]]
RLP解碼

解碼時,首先根據編碼結果第一個字節f的大小,執行以下的規則判斷:

1. 如果f∈ [0,128), 那么它是一個字節本身。

2. 如果f∈[128,184),那么它是一個長度不超過55的byte數組,數組的長度為 l=f-128

3. 如果f∈[184,192),那么它是一個長度超過55的數組,長度本身的編碼長度ll=f-183,然后從第二個字節開始讀取長度為ll的bytes,按照BigEndian編碼成整數l,l即為數組的長度。

4. 如果f∈(192,247],那么它是一個編碼后總長度不超過55的列表,列表長度為l=f-192。遞歸使用規則1~4進行解碼。

5. 如果f∈(247,256],那么它是編碼后長度大于55的列表,其長度本身的編碼長度ll=f-247,然后從第二個字節讀取長度為ll的bytes,按BigEndian編碼成整數l,l即為子列表長度。然后遞歸根據解碼規則進行解碼。

以上解釋了什么叫遞歸長度前綴編碼,這個名字本身很好的解釋了編碼規則。

參考

https://github.com/ethereum/w...

http://hidskes.com/blog/2014/...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/23941.html

相關文章

  • 以太源碼分析--RLP編碼

    摘要:,遞歸長度前綴編碼,它是以太坊序列化所采用的序列化和反序列化的主要方式。其中的編碼為的編碼為。兩個子字符串的編碼后總長度是,因此編碼結果第一位計算得出。上面就是的編碼定義,下面開始我們來看一下以太坊中的實現源碼。 RLP(Recursive Length Prefix),遞歸長度前綴編碼,它是以太坊序列化所采用的序列化和反序列化的主要方式。區塊、交易等數據結構在 網絡傳輸和持久化時會先...

    2bdenny 評論0 收藏0
  • 以太源碼分析--MPT樹

    摘要:是以太坊中存儲區塊數據的核心數據結構,它和融合一個樹形結構,理解結構對之后學習以太坊區塊以及智能合約狀態存儲結構的模塊源碼很有幫助。 MPT(Merkle Patricia Tries)是以太坊中存儲區塊數據的核心數據結構,它Merkle Tree和Patricia Tree融合一個樹形結構,理解MPT結構對之后學習以太坊區塊header以及智能合約狀態存儲結構的模塊源碼很有幫助。 首...

    roadtogeek 評論0 收藏0
  • 以太數據結構MPT

    摘要:是以太坊存儲數據的核心數據結構,它是由和結合的一種樹形結構,理解有助于我們更好的理解以太坊的數據存儲。所以就有了樹壓縮前綴樹,后面會介紹到,也被稱為,中文名稱默克爾樹,主要用于數據集較大時的文件校驗。 ??MPT(Merkle Patricia Tries)是以太坊存儲數據的核心數據結構,它是由Merkle Tree和Patricia Tree結合的一種樹形結構,理解MPT有助于我們更...

    Honwhy 評論0 收藏0
  • EIP-191(關于如何在以太合約中處理簽名數據的詳細說明)

    摘要:改標準試圖拓展以太坊的簽名規則,為簽名內容的可讀化提供的重要的基礎。摘要這個提議了一個關于如何在以太坊合約中處理簽名數據的詳細說明。如果對沒有句法約束,這就意味著可以用作句法有效的交易。 本文翻譯了官網EIP-191的相關內容。改標準試圖拓展以太坊的簽名規則,為簽名內容的可讀化提供的重要的基礎。 摘要 這個ERC提議了一個關于如何在以太坊合約中處理簽名數據的詳細說明。 動機 一些接受p...

    curlyCheng 評論0 收藏0
  • 是的我想說的技術!

    摘要:有效的數字簽名使收件人有理由相信該信息是由已知的發件人認證創建的,發件人不能否認已發送的信息不可否認,并且信息在傳輸過程中未被更改完整性。當我們說簽署交易時,我們實際上是指簽署序列化交易數據的哈希。 特殊交易:合約注冊 有一種特殊的帶有data,沒有value的交易。表示注冊一個新的合約。合約登記交易被發送到一個特殊的目的地地址,即零地址。簡而言之,合約注冊交易中的+to+字段包含地址...

    focusj 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<