在以太坊区块链的复杂世界中,数据的高效、安全传输与存储至关重要,无论是账户状态、交易信息还是区块数据,都需要一种可靠的方式来编码和解码,RLP(Recursive Length Prefix,递归长度前缀)正是以太坊中用于序列化对象(如字符串、字节数组、列表等)的核心编码方法,它以其简洁、高效和可扩展的特性,成为了以太坊数据结构的基石。

什么是RLP?

RLP,全称Recursive Length Prefix,即“递归长度前缀”,它的主要目标是将任意嵌套的数据结构(一个包含多个字段和子列表的交易对象)转换成一个线性的字节数组(byte array),以便在网络中传输或存储在区块链上,同样,它也能将这些字节数组准确地还原成原始的数据结构。

RLP的设计遵循了两个基本原则:

  1. 唯一性:任意两个不同的数据结构,通过RLP编码后,得到的字节数组必须是不同的,反之亦然,确保了数据序列化和反序列化的无损和准确。
  2. 简洁性:编码后的字节数组应尽可能短,以减少存储和网络传输的开销。

RLP的核心编码规则

RLP的编码规则并不复杂,主要针对两类数据:字符串(包括字节数组,下同)和列表。

  1. 字符串(String)的编码: 字符串是指一串字节的集合,RLP对字符串的编码取决于其长度:

    • 如果字符串长度为0-127字节(即单字节,最高位为0): 直接将该字节作为编码结果,字符串 "dog" (ASCII: 0x64, 0x6f, 0x67) 的RLP编码就是其本身 0x646f67
    • 如果字符串长度大于127字节(即单字节,最高位为1)或前缀字节本身是0(即字符串以0x00开头): 编码格式为:[前缀字节] + [字符串长度] + [字符串内容]
      • 前缀字节:计算字符串长度的字节长度(L),然后设置前缀字节为 0x80 + L
        • 如果字符串长度在128-255字节之间,长度L用1字节表示,前缀字节为 0x80 + 1 = 0x81
        • 如果字符串长度在256-65535字节之间,长度L用2字节表示,前缀字节为 0x80 + 2 = 0x82
        • 以此类推,最长支持到 0xb8 + 8(即长度用8字节表示,字符串长度可达2^64-1字节)。
      • 字符串长度:以大端序表示的字符串长度。
      • :原始字符串的字节。 一个长度为128字节的字符串S:
      • 前缀字节:0x81 (因为长度128需要1字节表示,0x80 + 1 = 0x81)
      • 字符串长度:0x80 (128的大端单字节表示)
      • S本身
      • RLP编码:0x81 + 0x80 + S
  2. 列表(List)的编码: 列表是指一个包含其他字符串或列表的有序集合,RLP对列表的编码规则是:

    • 编码格式为:[前缀字节] + [总长度] + [串联后的RLP编码元素]
      • 前缀字节:计算列表所有元素RLP编码后的总长度(T),然后设置前缀字节为 0xc0 + T的字节长度
        • 如果总长度T在0-55字节之间,前缀字节为 0xc0 + T
        • 如果总长度T大于55字节,前缀字节为 0xc0 + T的字节长度,然后是大端序的T值。
      • 总长度:列表所有元素RLP编码后拼接在一起的总字节数。
      • 串联后的RLP编码元素:将列表中每个元素分别进行RLP编码,然后将这些编码结果按顺序拼接起来。
    • 示例:一个包含两个字符串 "cat" (RLP: 随机配图