type
status
date
slug
summary
tags
category
icon
password
Sub-item
Last edited time
Oct 15, 2023 08:58 AM
Parent item
领域
RLP (递归长度前缀)是以太坊中数据序列化/反序列化的主要方法,区块、交易等数据结构在网络传输和数据库持久化时都会先经过RLP编码压缩。RLP适用于任意二进制数据数组的编码。
RLP编码相比JSON编码来说,占用空间小,几乎没有冗余信息。不过这个因为压缩空间小,无冗余字段,在提取数据时,需要全部解压才能读取指定的数据,在极端情况下会影响性能,在FISCO-BCOS中,对RLP协议做了一定的改进,可以不解码全部数据的前提下就看提取到指定的数据。
RLP编码的定义只处理两类数据:
- 二进制数据的数组(字符串,字节数组,整形等);
- 列表(二进制数据的数组的数组,即一个嵌套递归的结构,里面可以包含字符串和列表);
例如下面的例子就是一个复杂的列表:
如果要对其他类型的数据进行RLP编码,那么需要先转换成以上的2类结构,例如struct可以转成列表,int可以转成字符串(也可以不转,使用字节数组表示),字典可以转换成例如 :
[[k1,v1],[k2,v2]...]
。RLP编码规则根据数据内容的长度可以概括如下:
- 单字节数据。数据内容的值的ASCII值在 [0x00, 0x7f] 范围内,RLP 编码内容就是字节内容本身:
- 单个字符:
‘b’ = 0x62
- 整数:
15('\x0f') = 0x0f
例如:
- 字符串的长度小于55(0x47),则编码为:
- 字符串
"abc"
编码结果是0x83 0x61 0x62 0x63
,其中0x83=0x80+len("abc")
; - 整数
1024('\x04\00')
编码结果是[0x82, 0x04, 0x00]
; - 空字符串
""
编码为0x80
;
其中前缀的计算方法为
0x80+len(待编码数据)
例如:- 字符串的长度大于55(0x47),则编码为:
- 字符串
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
编码结果为:[0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't']
; - 列表总长度(列表的总长度指的是它包含的项的数量加它包含的各项的长度之和)小于55(0x47),它的RLP编码是:
其中前缀为
0xb7+字符串长度数值的长度
,即: 数据 → [0xb7+len(len(字符串))) || len(字符串) || 字符串内容]
。
例如:前缀取值范围是
[0xc0, 0xf7]
。
例子:- 列表
["cate","dog"]
编码为:[0xc9, 0x84, 'c', 'a', 't', 'e',0x83, 'd', 'o', 'g' ]
其中0xc9 = 0xc0+1+4+1+3
(
1+4
:1是字符串cate长度的长度; 4是字符串长度,; 1+3
:1是字符串dog长度的长度;3是字符串长度);- 空列表
[ [], [[]], [ [], [[]] ] ]
编码为:[0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0]
;
- 列表总长度大于55(0x47),它的RLP编码是 :
其中前缀取值范围是
[0xf8, 0xff]
。
例子:列表
["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]
编码为: [0xf8 0x58 0xb3 'T','h','e',..., 0xa3,'I',' ','k',...,'t']
其中:
0xf8=0xf7+1
(1:列表总长度的长度
0x58=0x56+1+1
(0x56:列表总长度,1+1是2个字符串长度的长度)
0xb3=0x80+0x33
(0x33: 第一个字符串的长度)
0xa3=0x80+0x23
(0x23: 第二个字符串的长度)
再来看一个综合编码的例子,待编码数据为:
["abc",["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]]
,包含2个列表,3个字符串。编码结果为:
[0xf8 0x5e 0x83 0x61 0x62 0x63 0xf8 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]
其中:
0xf8=0xf7+1
(1:列表总长度的长度)0x5e=(1+3)+(1+51)+(1+35)+2
(列表总长度。1+3:第一个字符串编码后的长度值,1+51:子列表中第一个字符串编码后的长度值,1+35:子列表中第二个字符串编码后的长度值,2:子列表编码后占用的前缀(1个字节)和长度字段(1个字节))0x83
开始是字符串"abc"
的编码(为0x83 0x61 0x62 0x63
)0xf8
开始是后面子列表的编码