目录

@

RLP序列化

什么是序列化?

序列化将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化机制的核心作用就是对象状态的保存与重建

为什么要序列化?

1、以某种存储形式使自定义对象持久化。->便于对象持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里)
2、将对象从一个地方传递到另一个地方。->便于网络传输,利用序列化实现远程通信,即在网络上传送对象的字节序列
3、使程序更具维护性。->便于维护,程序员依照相同的序列化规则,进行序列化及反序列化。

序列化的方法:Json序列化、FastJson序列化、xml序列化..等等,RLP正是序列化方法的一种,以太坊中使用了大量的RLP序列化

RLP序列化处理的两项数据

区块、交易等数据结构在持久化时会先经过RLP编码后再存储到数据库中,RLP编码的定义只处理两类数据:

  1. 一类是byte数组。
  2. 一类byte数组的数组,称之为列表。(递归定义)
    这里的递归定义就比较相似与JSON,可以很容易的表示出一个树的结构。

RLP序列化采取的5项规则:

  1. 对于值在[0, 127]之间的单个字节,其编码是其本身。
    例1:a的编码是97。
  2. 如果byte数组长度l <= 55,编码的结果是数组本身,再加上128+l作为前缀。
    例2:abc编码结果是131 97 98 99.其中131=128+len("abc"),97 98 99依次是a b c。
  3. 如果数组长度大于55,编码结果第一个是183加数组长度的编码的长度,然后是数组长度的本身的编码,最后是byte数组的编码。
    例3:“The length of this sentence is more than 55 bytes, I know it because I pre-designed it” = [183 + 1,86, ‘T’, ‘h’, ‘e’, ‘ ’, ’l’, ‘e’, … , ‘d’, ‘ ’, ‘i’, ’t’]
    这里一定要注意的是:加上的数组长度的编码,86是数组的长度,86编码之后占用1个字节(在1到128之间),所以才加上1
  4. 如果列表长度小于55,编码结果第一位是192加列表长度的编码的长度,然后依次连接各子列表的编码。
    例4: ["abc", "def"]的编码结果是200 131 97 98 99 131 100 101 102。其中abc的编码为131 97 98 99,def的编码为131 100 101 102。两个子字符串的编码后总长度是8,因此编码结果第一位计算得出:192 + 8 = 200。
  5. 如果列表长度超过55,编码结果第一位是247加列表长度的编码长度,然后是列表长度本身的编码,最后依次连接各子列表的编码。
    这里一定要注意的是:加上的是列表长度的编码长度!类似于规则3

ps:

  • 列表长度是指子列表编码后的长度之和。
  • 规则1~3定义了byte数组的编码方案(也就是第一种数据结构)下面介绍列表(第二种数据结构)的编码规则

现在我们看一个较复杂的例子:

利用python写的RLP

def rlp_encode(input):
    if isinstance(input,str):
        if len(input) == 1 and chr(input) < 128: return input    #规则一
        else: return encode_length(len(input),128) + input    #规则二和规则三
    elif isinstance(input,list):
        output = ''
        for item in input: output += rlp_encode(item)       #递归的去遍历
        return encode_length(len(output),192) + output    #规则四和规则五

def encode_length(L,offset):
    if L < 56:
         return chr(L + offset)
    elif L < 256**8:
         BL = to_binary(L)
         return chr(len(BL) + offset + 55) + BL
    else:
         raise Exception("input too long")

def to_binary(x):
    return '' if x == 0 else to_binary(int(x / 256)) + chr(x % 256)

实际中的使用是个怎么样子?

在具体实现RLP编码时,首先需要将对像映射成byte数组或列表两种形式。以go语言编码struct为例,会将其映射为列表,例如Student这个对象处理成列表["icattlecoder","male"]
RLP(转发注明出处)-LMLPHP
实际中的,不同,就是讲的没用16进制表示,正常来讲,是16进制表示。

RLP分析

  1. RLP最大的优点是在充分利用字节的情况下,同时支持列表结构,也就是说可以很轻易的利用RLP存储一个树状结构。

  2. 程序处理RLP编码时也非常容易。

  3. 所以理论上RLP可以编码任何数据。

参考目录

[1]. RLP编码和解码
[2]. 以太坊RLP用法-以太坊源码学习
[3]. 简单分析RLP编码原理
[4]. 以太坊源码学习—RLP编码

如果我的工作为您带来了少许帮助,帮忙点一波关注或者收藏吧~(#^.^#)

11-29 16:11