文档章节

RLP编码原理

dophin459
 dophin459
发布于 2017/05/06 21:56
字数 1068
阅读 1121
收藏 2

RLP(Recursive Length Prefix,递归长度前缀)是一种编码算法,用于编码任意的嵌套结构的二进制数据,它是以太坊中数据序列化/反序列化的主要方法,区块、交易等数据结构在持久化时会先经过RLP编码后再存储到数据库中。

定义

RLP编码的定义只处理两类数据:一类是字符串(例如字节数组),一类是列表。字符串指的是一串二进制数据,列表是一个嵌套递归的结构,里面可以包含字符串和列表,例如["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]就是一个复杂的列表。其他类型的数据需要转成以上的两类,转换的规则不是RLP编码定义的,可以根据自己的规则转换,例如struct可以转成列表,int可以转成二进制(属于字符串一类),以太坊中整数都以大端形式存储。

从RLP编码的名字可以看出它的特点:一个是递归,被编码的数据是递归的结构,编码算法也是递归进行处理的;二是长度前缀,也就是RLP编码都带有一个前缀,这个前缀是跟被编码数据的长度相关的,从下面的编码规则中可以看出这一点。

RLP编码规则

  • 对于单个字节,如果它的值范围是[0x00, 0x7f],它的RLP编码就是它本身。
  • 否则,如果一个字符串的长度是0-55字节,它的RLP编码包含一个单字节的前缀,后面跟着字符串本身,这个前缀的值是**0x80**加上字符串的长度。由于被编码的字符串最大长度是55=0x37,因此单字节前缀的最大值是0x80+0x37=0xb7,即编码的第一个字节的取值范围是[0x80, 0xb7]
  • 如果字符串的长度大于55个字节,它的RLP编码包含一个单字节的前缀,后面跟着字符串的长度,后面再跟着字符串本身。这个前缀的值是**0xb7**加上字符串长度的二进制形式的字节长度,说的有点绕,举个例子就明白了,例如一个字符串的长度是1024,它的二进制形式是10000000000,这个二进制形式的长度是2个字节,所以前缀应该是0xb7+2=0xb9,字符串长度1024=0x400,因此整个RLP编码应该是\xb9\x04\x00再跟上字符串本身。编码的第一个字节即前缀的取值范围是[0xb8, 0xbf],因为字符串长度二进制形式最少是1个字节,因此最小值是0xb7+1=0xb8,字符串长度二进制最大是8个字节,因此最大值是0xb7+8=0xbf
  • 如果一个列表的总长度(列表的总长度指的是它包含的项的数量加它包含的各项的长度之和)是0-55字节,它的RLP编码包含一个单字节的前缀,后面跟着列表中各元素项的RLP编码,这个前缀的值是**0xc0**加上列表的总长度。编码的第一个字节的取值范围是[0xc0, 0xf7]
  • 如果一个列表的总长度大于55字节,它的RLP编码包含一个单字节的前缀,后面跟着列表的长度,后面再跟着列表中各元素项的RLP编码,这个前缀的值是**0xf7**加上列表总长度的二进制形式的字节长度。编码的第一个字节的取值范围是[0xf8, 0xff]

RLP编码例子

  • 字符串 "dog" = [0x83, 'd', 'o', 'g' ] (规则二)
  • 列表 ["cat","dog"] = [0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ] (规则四)
  • 空字符串 "" = 0x80 (规则二)
  • 空列表 [] = [0xc0] (规则四)
  • 整数 15('\x0f') = 0x0f (规则一)
  • 整数 1024('\x04\00') = [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'] (规则三)

本文大部分翻译自以太坊github wiki文档,并加入自己的理解。

参考资料:https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP

© 著作权归作者所有

共有 人打赏支持
dophin459
粉丝 10
博文 15
码字总数 15489
作品 0
西城
程序员
深入讲解以太坊的数据存储

前言:本文的目的是打算深入浅出讲讲以太坊的整体结构以及存储相关的内容,会聚焦在存储上,同时会结合源码讲解,整个过程也可以体会到作者的设计思想之精妙。 一,区块 block是最重要的数据...

01/08
0
1
Python从头实现以太坊(一):Ping

以太坊是一种可以在区块链上执行代码的加密货币。这个功能允许人们编写可以自动运行的“智能合约”。大概一年前,一个叫做DAO的智能合约炸锅了,有人找到方法操纵它去获取当时价值4100万美元...

JonHuang
2017/08/18
0
0
java 以太坊开发利器web3j

为了给希望使用web3j的开发人员提供更大的灵活性,项目由多个模块组成。 根据依赖顺序,列一下: org.web3j.utils :最小实用模块。 org.web3j.rlp :递归长度前缀(RLP)编码器。 org.web3...

智能合约
07/03
0
0
Ethereum学习(1)—— 基本介绍

1 开发环境安装 安装Ethereum 协议的Go语言的最新实现。 2 Ethereum组成 Ethereum包含以下几大模块。 模块 介绍 基于命令行的Ethereum客户端。使用JSON RPC格式,基于HTTP、WebSocket或者IPC...

翻书
09/11
0
0
PoW挖矿算法原理及其在比特币、以太坊中的实现

  PoW,全称Proof of Work,即工作量证明,又称挖矿。大部分公有链或虚拟货币,如比特币、以太坊,均基于PoW算法,来实现其共识机制。即根据挖矿贡献的有效工作,来决定货币的分配。 比特币...

莫名2013
06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Docker和Kubernetes如何让DevOps更具效力

缩短time-to-makrt对于任何一家企业都至关重要,这直接决定了客户满意度、市场竞争力乃至盈利能力。但在部署应用时,大多数企业内的IT团队都或多或少会遇到Dev和Ops之间的问题,这两个部门围...

好雨云帮
13分钟前
0
0
OSChina 周一乱弹 —— 嫂子我帮你们照顾放心吧

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @clouddyy :#每日一歌# 《绿光 - 孙燕姿》 《绿光》 - 孙燕姿 手机党少年们想听歌,请使劲儿戳(这里) @凝小紫:又到周日了,按照惯例吐槽一...

小小编辑
34分钟前
41
5
可爱的python测试开发库(python测试开发工具库汇总)

欢迎转载,转载请注明来源: github地址 谢谢点赞 本文地址 相关书籍下载 测试开发 Web UI测试自动化 splinter - web UI测试工具,基于selnium封装。 链接 selenium - web UI自动化测试。 链...

python测试开发人工智能安全
今天
2
0
Shiro | 实现权限验证完整版

写在前面的话 提及权限,就会想到安全,是一个十分棘手的话题。这里只是作为学校Shiro的一个记录,而不是,权限就应该这样设计之类的。 Shiro框架 1、Shiro是基于Apache开源的强大灵活的开源...

冯文议
今天
1
0
linux 系统的运行级别

运行级别 运行级别 | 含义 0 关机 1 单用户模式,可以想象为windows 的安全模式,主要用于修复系统 2 不完全的命令模式,不含NFS服务 3 完全的命令行模式,就是标准的字符界面 4 系统保留 5 ...

Linux学习笔记
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部