[以太坊源碼分析]:RLP編碼

RLP編碼

RLP編碼是以太坊對象序列化和反序列化的主要方法,可編碼任意嵌套的二進制數(shù)據(jù)。以太坊中多個地方都用到了RLP編碼,例如區(qū)塊,交易等。

RLP是 Recursive Length Prefix 三個單詞的縮寫,分別是遞歸,長度,前綴。以下是我的理解:遞歸指可以處理嵌套的數(shù)據(jù)結構,長度指編碼是對數(shù)據(jù)的長度進行處理,前綴指編碼結果是在數(shù)據(jù)前加一個前綴。

0.索引

01.為什么要使用RLP編碼
02.RLP編碼規(guī)則
03.總結

1.為什么要使用RLP編碼

使用RLP編碼的情況下,需要保存的額外數(shù)據(jù)比較少。RLP編碼結果的前綴不會超過9個字節(jié),舉個例子:

type Tests struct{
    Name string
}
t := Tests{Name:"abc"}
  • 1.采用JSON編碼,t的編碼結果為{"Name":"abc"},長度為14個字節(jié)。
  • 2.采用RLP編碼,t的編碼結果為0x83616263,直觀的表示為131 a b c,長度為4個字節(jié)。

t的有效的數(shù)據(jù)長度為3個字節(jié),采用JSON編碼的時候,額外的數(shù)據(jù)長度為11個字節(jié),而采用RLP編碼的時候,額外的數(shù)據(jù)長度為1個字節(jié)(即前綴)。由此可見,RLP編碼可以節(jié)省編碼后的數(shù)據(jù)的存儲空間,這對以太坊來說是很必要的,區(qū)塊和交易編碼后的長度跟原來的長度相差不大,節(jié)省了存儲空間的開銷。

2.RLP編碼規(guī)則

在以太坊的黃皮書附錄B中,定義了如下的兩種數(shù)據(jù)結構:



簡單的理解為,L為列表類型的數(shù)據(jù),B為字節(jié)數(shù)組,字符串類型的數(shù)據(jù)。如果是其他的數(shù)據(jù)類型,則需要先轉換為這兩種數(shù)據(jù)類型,比如說,結構體轉換為嵌套的列表,布爾類型轉換為整型。對此兩種數(shù)據(jù)類型的RLP編碼表示為:



RLP編碼的規(guī)則一共有5個,3個對于字節(jié)數(shù)組而言,剩下2個與列表有關。
字節(jié)數(shù)組
字節(jié)數(shù)組的編碼過程

Rb(x)涉及了3個規(guī)則:

  • 1.單個字節(jié),小于128,結果為該字節(jié)
  • 2.字節(jié)數(shù)組,長度小于56,結果為128+字節(jié)數(shù)組長度,各個字節(jié)的編碼兩部分
  • 3.字節(jié)數(shù)組,長度大于等于56,結果為183+字節(jié)數(shù)組長度編碼的長度,字節(jié)數(shù)組長度,各個字節(jié)的編碼三部分 (長度不能超過288)

舉個例子:

  • 1.單個字節(jié):z => “7A”
    (z的十六進制ascii碼為7A)
  • 2.長度小于56的字節(jié)數(shù)組:xyz => “8378797A”
    83為128+3的十六進制表示,xyz分別為78 79 7A)
  • 3.長度大于等于56的字節(jié)數(shù)組:“Lorem ipsum dolor sit amet, consectetur adipisicing elit” =>“B8384C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C6974”
    (B8為183+1,1為字節(jié)數(shù)組長度56的編碼長度;38為字節(jié)數(shù)組長度56十六進制;其余為各個字節(jié)的編碼)

BE(x),去掉前導零的大端表示 (bn是8個字節(jié)的,所以以8個字節(jié)為例)
例如:1024 -> 0x00 00 00 00 00 00 04 00 -> 0x0400

(a)·(b,c)·(d,e) = (a,b,c,d,e),指的是字節(jié)的拼接,類似于把字符串連接起來。

列表
列表的編碼過程

Rl(x)涉及了2個規(guī)則:

  • 1.列表,長度小于56,結果為192+列表長度,各個字節(jié)的編碼兩部分
  • 2.列表,長度大于等于56,結果為247+列表長度編碼的長度,列表長度,各個子列表的編碼三部分

舉個例子:

  • 1.長度小于56的列表:[ 1, 2, 3] => “C3010203”
    C3為192+3的十六進制表示)
  • 2.長度大于等于56的列表:["aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo“] =>“F83C836161618362626283636363836464648365656583666666836767678368686883696969836A6A6A836B6B6B836C6C6C836D6D6D836E6E6E836F6F6F”
    F8為247+1,1為總的列表長度60的編碼長度;3C為60十六進制表示;bbb為一個子列表83626262,80+3,以及b為62)

3.總結

  • 1.RLP編碼是以太坊對象序列化和反序列化的主要方法,對數(shù)據(jù)進行編碼,編碼結果為在原本的數(shù)據(jù)前增加一個前綴??晒?jié)省編碼后的數(shù)據(jù)的存儲空間。
  • 2.RLP編碼有5個規(guī)則,3個規(guī)則適用于字節(jié)數(shù)組,2個規(guī)則適用于列表。根據(jù)字節(jié)數(shù)組和列表的不同長度使用不同的編碼規(guī)則。
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 文章分為2部分, 第一部分是綜合整理已有資料而生成的參考文檔, 第二部分是python版以太坊代碼中的源碼實現(xiàn)分析...
    shi_qinfeng閱讀 3,712評論 0 3
  • 這是以太坊源碼研究的第一篇文章?;旧蟻碚f,我寫什么內(nèi)容,說明我正好在學習什么內(nèi)容,并沒有固定的順序。之所以先寫R...
    魏兆華閱讀 1,587評論 0 0
  • GitHub上介紹(解碼部分為本人編輯): https://github.com/ethereum/wiki/wi...
    AlbertGou閱讀 3,162評論 1 3
  • 文化以不同的形式生長,博學這個詞簡直像是在反諷人類的創(chuàng)造力。
    Joshua_05d6閱讀 190評論 0 0
  • 2018-01-31 ω 很棒 第三遍鬧鈴終于把我叫醒了 多跑了一個路口 穿過一群與凌晨不相符的嘈雜 我以為是垃圾...
    夏天的秘密花園閱讀 573評論 0 0

友情鏈接更多精彩內(nèi)容