浅析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字母。


代码分析

目录
相关文章
|
开发工具 git
在码云上新建一个仓库,并且使用git上传代码步骤
在码云上新建一个仓库,并且使用git上传代码步骤
1237 0
|
小程序 开发工具 开发者
微信开发者工具使用教程
微信开发者工具使用教程
|
11月前
|
安全 开发工具 数据安全/隐私保护
HarmonyOS应用安全全攻略:从系统到代码的全面防护
本文全面解析HarmonyOS应用安全开发,涵盖系统到代码的防护策略。首先介绍HarmonyOS三层安全体系:系统安全层、开发工具层与应用生态层。接着详解设备与数据安全等级划分,提供分级加密实战代码,包括文件读写与HUKS高级加密案例。最后总结开发最佳实践,强调数据分类、最小权限、加密常态及传输安全保障,助你构建更安全的应用。保护用户数据不仅是功能需求,更是开发者责任!
|
存储 监控 算法
在进行精度控制时,如何避免舍入误差的累积?
【10月更文挑战第29天】通过选择合适的精度控制方法、优化计算顺序和方式、运用误差补偿技术以及建立数据验证与监控机制等多种手段的综合运用,可以有效地避免舍入误差的累积,提高计算结果的精度和可靠性,满足各种对精度要求较高的应用场景的需求。
|
安全 网络协议 Linux
在安卓Termux上搭建apache服务创建个人站点并且结合cpolar内网穿透
在安卓Termux上搭建apache服务创建个人站点并且结合cpolar内网穿透工具实现公网访问。
在安卓Termux上搭建apache服务创建个人站点并且结合cpolar内网穿透
|
运维 Cloud Native 开发工具
智能运维:云原生大规模集群GitOps实践
智能运维:云原生大规模集群GitOps实践,由阿里云运维专家钟炯恩分享。内容涵盖云原生运维挑战、管理实践、GitOps实践及智能运维体系。通过OAM模型和GitOps优化方案,解决大规模集群的发布效率与稳定性问题,推动智能运维工程演进。适用于云原生环境下的高效运维管理。
602 8
|
存储 安全 数据中心
【Docker 专栏】Docker 容器与宿主机的资源隔离机制
【5月更文挑战第8天】Docker容器利用Namespace和Cgroups实现资源隔离,保证CPU、内存、网络和存储的独立,提升资源利用率和系统安全性。资源隔离有助于简化应用部署与管理,但也带来资源竞争、监控管理及安全挑战。理解并善用资源隔离机制能实现更高效、安全的容器运行。随着技术进步,Docker容器资源隔离将持续优化。
1530 2
【Docker 专栏】Docker 容器与宿主机的资源隔离机制
|
存储 安全 算法
静态路由与动态路由的区别及应用场景
【8月更文挑战第25天】
1011 0
|
C语言 计算机视觉
OpenCV使用CMake和MinGW-w64的编译安装
OpenCV使用CMake和MinGW-w64的编译安装
439 0
|
网络安全 数据安全/隐私保护
解决git@github.com: Permission denied (publickey). fatal: Could not read from remote repository. Pleas
解决git@github.com: Permission denied (publickey). fatal: Could not read from remote repository. Pleas
3499 0

热门文章

最新文章