RLP编码原理

RLP编码原理RLP RecursiveLen 递归长度前缀 是一种编码算法 用于编码任意的嵌套结构的二进制数据 它是以太坊中数据序列化 反序列化的主要方法 区块 交易等数据结构在持久化时会先经过 RLP 编码后再存储到数据库中 定义 RLP 编码的定义只处理两类数据 一类是字符串 例如字节数组 一类是列表 字符串指的是一串二进制数据 列表是一个嵌套递归的结构 里面可以包含字符串和列表

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,它的二进制形式是,这个二进制形式的长度是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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/217121.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午10:18
下一篇 2026年3月18日 上午10:18


相关推荐

  • Poetry(2)Poetry的基本使用方式「建议收藏」

    Poetry(2)Poetry的基本使用方式「建议收藏」Poetry的基本使用准备工作如果你是在一个已有的项目里使用Poetry,你只需要执行poetryinit命令来创建一个pyproject.toml文件:poetryinit可看到

    2022年8月7日
    6
  • implicitly declaring library_no such object available

    implicitly declaring library_no such object availableAPAP论文源码中全局单应GH的部分!

    2026年2月20日
    7
  • 阿里云设置端口访问、使用_阿里云服务器端口号

    阿里云设置端口访问、使用_阿里云服务器端口号登录阿里云账号后,点击控制台点击自定义视图→再点击云服务器ECS点击实例id进入实例:点击本实例安全组:点击安全组id或者配置规则进入安全组规则配置界面,可以选择添加方式,这里以手动添加作为演示点击手动添加后,会出现添加栏,我们配置521端口,源选择0.0.0.0/0(意思是开放给所有人),最后点击保存放行端口就设置完毕了此外也可以从另一个地方进入本地实例安全组:(1)点击云服务器ECS后(上述步骤3)进入实例页面后,可以直接点击实例(2)选择自..

    2022年10月3日
    3
  • qtabwidget 样式_标注样式怎么设置合理

    qtabwidget 样式_标注样式怎么设置合理个人使用qt,感觉QTabwidget是个非常好用的控件,但有时候总是感觉其tab样式不好控制或说不够灵活,从而导致放弃使用该控件。比如说,标签横向显示的时候,文字随之也横着显示了,这样还需要指定自定义样式,继承QProxyStyle类并重写drawControl虚函数。然而这样过于麻烦,关于软件主菜单不同的界面切换,个人还是比较喜欢按键组合+STackedWidget控件。对于一遍的小界面来说,QTabWidget其实完全满足你的使用要求,所以本文主要简述QTabwidget样式的常用使用方法,配合标

    2025年11月29日
    9
  • C语言中fprintf_c语言gets函数用法

    C语言中fprintf_c语言gets函数用法c语言中fprintf函数C中的fprintf()函数(fprintf()functioninC)Prototype:原型:intfprintf(FILE*filename,constchar*string,….);Parameters:参数:FILE*filename,constchar*stringetc….

    2022年8月30日
    6
  • 『Python笔记』python中的for循环总结(enumerate)

    『Python笔记』python中的for循环总结(enumerate)目录 1 可以明确循环的次数 2 iteratle object 可迭代对象 3 enumerate 使用方法为 4 补充 统计文件行数可以这样写 1 可以明确循环的次数遍历一个数据集内的成员 在列表解析中使用 生成器表达式中使用 2 iteratle object 可迭代对象 String 字符串 List 列表 Tuple 元组 Dictionary

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号