以太坊源碼剖析(1)-RLP編碼

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

前言

RLP(Recursive Length Prefix,遞迴長度首碼)是一種編碼演算法,用於編碼任意的嵌套結構的位元據,它是以太坊中資料序列化/還原序列化的主要方法,區塊、交易等資料結構在持久化時會先經過RLP編碼後再儲存到資料庫中,RLP編碼的定義只處理兩類資料:一類是字串(例如位元組數組),一類是列表。

RLP與JSON的比較

話不多說,直接上代碼

package mainimport (    "encoding/json"    "fmt"    "rlp")type Pig struct {    Name    string    Gender  uint8    Address string}func main() {    pig := &Pig{Name: "piggy", Gender: 2, Address: "England"}    json_bytes, _ := json.Marshal(pig)    fmt.Println(json_bytes)    fmt.Println(string(json_bytes))    fmt.Println("length:", len(json_bytes))    //output    //[123 34 78 97 109 101 34 58 34 112 105 103 103 121 34 44 34 71 101 110 100 101 114 34 58 50 44 34 65 100 100 114 101 115 115 34 58 34 69 110 103 108 97 110 100 34 125]    //{"Name":"piggy","Gender":2,"Address":"England"}    //length: 47    rlp_bytes, _ := rlp.EncodeToBytes(pig)    fmt.Println(rlp_bytes)    fmt.Println("length:", len(rlp_bytes))    //output    //[207 133 112 105 103 103 121 2 135 69 110 103 108 97 110 100]    //length: 16}

從上面的輸出我們可以看到,同一個結構體,JSON編碼需要47個位元組,而RLP編碼只需要16個位元組,{"Name":"piggy","Gender":2,"Address":"England"}中的Name,Gender,Address都是不需要的。當然JSON編碼也有自己的優點,這裡不展開說明。

定義

RLP 編碼函數接受一個item。定義如下:

  • 將一個字串作為一個item(比如,一個 byte 數組)
  • 一組item列表(list)作為一個item

例如,一個Null 字元串可以是一個item,一個字串"cat"也可以是一個item,一個含有多個字串的列表也行,列表裡面嵌套列表也可以,比如這樣的["monkey",["tony","kong"],"horse",[[]],"pig",[""],"fish"]。

RLP 編碼定義如下:

類型 首位元組範圍 編碼內容
[0x00, 0x7f]的單個位元組 [0x00, 0x7f] 位元組內容本身
0-55 位元組長的字串 [0x80, 0xb7] 0x80加上字串長度,後跟字串二進位內容
超過55個位元組的字串 [0xb8, 0xbf] 0xb7加上字串長度的長度,後跟字串二進位內容
0-55個位元組長的列表(所有項的組合長度) [0xc0, 0xf7] 0xc0加上所有的項的RLP編碼串聯起來的長度得到的單個位元組,後跟所有的項的RLP編碼的串聯組成。
列表的內容超過55位元組 [0xf8, 0xff] 0xC0加上所有的項的RLP編碼串聯起來的長度的長度得到的單個位元組,後跟所有的項的RLP編碼串聯起來的長度的長度,再後跟所有的項的RLP編碼的串聯組成

例子

  • 字串 "pig" = [ 0x83, 'p', 'i', 'g' ]
  • 列表 [ "pig", "dog" ] = [ 0xc8, 0x83, 'p', 'i', 'g', 0x83, 'd', 'o', 'g' ]
  • Null 字元串 ('null') = [ 0x80 ]
  • 空列表 = [ 0xc0 ]
  • 數字12 ('x0c') = [ 0x0c ]
  • 數字 1024 ('x04x00') = [ 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' ]

RLP分析

以上我們可以看出RLP編碼的設計思想,就是通過首位元組快速判斷一串編碼的類型,充分利用了一個位元組的儲存空間,將0x7f以後的值賦予了新的含義,RLP最大的優點是在充分利用位元組的情況下,同時支援列表結構,也就是說可以很輕易的利用RLP儲存一個樹狀結構。

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

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.