浅析RLP-以太坊的数据编码方式

简介: ### 概述 RLP(RecursiveLength Prefix)是以太坊中序列化数据的编码方式。 既然是编码方式,下面结合代码详细看看RLP的奥秘: 官方定义: * RLP encoding is defined as follows: * For a single byte whose value is in the [0x00, 0x7f] range, th

概述

RLP(RecursiveLength Prefix)是以太坊中序列化数据的编码方式。
既然是编码方式,下面结合代码详细看看RLP的奥秘:

官方定义:

  • RLP encoding is defined as follows:

    • For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding.
    • Otherwise, if a string is 0-55 bytes long, the RLP encoding consists of a single byte with value 0x80 plus the length of the string followed by the string. The range of the first byte is thus [0x80, 0xb7].
    • If a string is more than 55 bytes long, the RLP encoding consists of a single byte with value 0xb7 plus the length in bytes of the length of the string in binary form, followed by the length of the string, followed by the string. For example, a length-1024 string would be encoded as xb9x04x00 followed by the string. The range of the first byte is thus [0xb8, 0xbf].
    • If the total payload of a list (i.e. the combined length of all its items being RLP encoded) is 0-55 bytes long, the RLP encoding consists of a single byte with value 0xc0 plus the length of the list followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus [0xc0, 0xf7].
    • If the total payload of a list is more than 55 bytes long, the RLP encoding consists of a single byte with value 0xf7 plus the length in bytes of the length of the payload in binary form, followed by the length of the payload, followed by the concatenation of the RLP encodings of the items. The range of the first byte is thus [0xf8, 0xff].

编码规则

[0x00, 0x7f]范围内的单字节数据

字面意思: 对于[0x00, 0x7f]范围内的单字节数据,RLP编码后的数据和编码之前是一样的。

有没有想过为什么是0x7f呢? 打开ASCII编码表会惊奇的发现ASCII编码的最大值就是0x7f, 所以RLP这个编码在[0x00, 0x7f]之内复用了ASCII编码,就是把数据当成ASCII编码使用了。

下面用以太坊的Python版本看看是不是这样:

image.png


长度在55个字节以内的字符串

字面意思: RLP编码包含一个单字节的前缀,后面跟着字符串本身,这个前缀的值是0x80加上字符串的长度。
想想为什么是0xb7的上界? 0x37的10进制数就是55, 所以单字节前缀表示的最大值就是0x80+0x37=0xb7, 事实上这个前缀表示的长度是以字节为单位的。

下面依然用Python验证一下:

image.png

上面的截图中"hello"占用5个字节,所以前缀变成了: 0x85。


长度超过55字节的字符串

字面意思: RLP编码包含一个单字节的前缀,后面跟着字符串的长度,后面再跟着字符串本身; 其中前缀的值是0xb7加上字符串长度的二进制形式的字节长度。
结构像这个样子: | 前缀 | 字符串长度 | 字符串本身 |

前缀的计算举一个例子: 如果一个字符串长度是156个字节(26个英文字母连续输入6遍), 用2进制表示十进制的156==10011100, 1个字节就可以表示156了。
所以前缀是: 0xb7+1 = 0xb8
长度是: 0x9c
则结果就是 | 0xb8 | 0x9c | 重复6遍的字母表 |

下面我们用Python验证一下:

image.png


以上是对单字节 和 字符串数据的编码说明, 接下来的两项编码规则是对list而言的。
开始之前,需要定义什么是list的总长度: 包含的各项的长度之和 + 包含的项的数量
例如: ["abc","def","ghi"] 的总长度是: 3+9=12(0xc)


list总长度为0 ~ 55字节

字面意思: RLP编码包含一个单字节的前缀,后面跟着列表中各元素项的RLP编码, 前缀的值是0xc0加上列表的总长度。
前缀取值范围是[0xc0, 0xf7], 同理 0xf7== 十进制(192+55), 其中 0xc0的十进制是 192。

以["abc","def","ghi"] 为例, 其RLP编码为: | 0xcc | 三个字符串的RLP |

Python验证:

image.png


list总长度大于55字节

字面意思: RLP编码包含: 一个单字节的前缀, 后面跟list的长度,后面再跟list中各元素项的RLP编码; 前缀的值是0xf7加上list总长度的二进制形式的字节长度(和规则3表达的计算方式相同)。
第一个前缀的取值范围是: [0xf8, 0xff], 则这个规则能表示的list最大长度是: 8字节表示的最大整数(0xff = 0xf7+0x08)。

以一个总长度超过55字节的list为例:
我们看看存储了6次a~z的list怎么表达呢? ["abc....z", "abc...z", "abc...z","abc....z", "abc...z", "abc...z"]
按照上面的规则描述, list总长度是: 0xa2(16进制), 10100010(2进制,1字节可表示), 162(10进制)

则: 前缀: 0xf7+0x01=0xf8

  总长度: 0xa2

如果是12次a~z的list呢? 总长度: 324,需要2字节表示(00000001 01000100)。
则: 前缀: 0xf7+0x02=0xf9

  总长度: 0x0144

Python验证一下:

image.png

如果细致一点, 你会发现上面的测试用0x01D代表了0x0144, 没错十六进制的0x44就是对应ASCII的D字母。


代码分析

目录
相关文章
|
安全 算法 数据处理
Python 标准类库-因特网数据处理之Base64数据编码
Python 标准类库-因特网数据处理之Base64数据编码
131 1
|
存储 安全 区块链
储存比特币的钱包开发源码规则解析
储存比特币的钱包开发源码规则解析
|
存储 机器学习/深度学习 缓存
二十七、网络层概述和数据交换方式
二十七、网络层概述和数据交换方式
二十七、网络层概述和数据交换方式
|
存储 芯片 内存技术
【计算机网络--物理层】编码和调制与数据交换方式
【计算机网络--物理层】编码和调制与数据交换方式
123 0
【计算机网络--物理层】编码和调制与数据交换方式
|
网络协议 算法 网络性能优化
字节一面:如何用 UDP 实现可靠传输?
我记得之前在群里看到,有位读者字节一面的时候被问到:「如何基于 UDP 协议实现可靠传输?」 很多同学第一反应就会说把 TCP 可靠传输的特性(序列号、确认应答、超时重传、流量控制、拥塞控制)在应用层实现一遍。 实现的思路确实这样没错,但是有没有想过,既然 TCP 天然支持可靠传输,为什么还需要基于 UDP 实现可靠传输呢?这不是重复造轮子吗?
|
数据格式
网络标准之:IANA定义的传输编码
网络标准之:IANA定义的传输编码
网络标准之:IANA定义的传输编码
|
算法 安全 区块链
加密,编码三问
网络通信中最重要的就是数据部分,而保证数据的正确安全传输,就要牵扯到数据的编码和数据的加密问题,今天的三问就是关于编码和加密:
117 0
|
Rust JavaScript 前端开发
区块链开发(八)以太坊不同语言客户端地址
区块链开发(八)以太坊不同语言客户端地址
123 0
|
区块链 算法 开发者
带你读《深入理解以太坊》之一:以太坊概述
这是一本从原理和实践两个层面系统、深入讲解以太坊技术的专著,从设计理念、技术架构、共识算法、智能合约、以太坊虚拟机、开发工具、DApp开发、企业以太坊解决方案、跨链技术等近10个方面进行了详细讲解,既适合初学者系统学习以太坊的原理和应用开发,又适合有一定基础的开发者深入掌握以太坊的底层运行机制。
|
程序员 PHP 区块链
是否可以用以太坊交易EthSendTransaction发送任意文本?
是的。文本应该是ASCII编码的,并在交易的数据中以十六进制字符串的形式提供。示例如下: RawTransaction.
2564 0