以太坊的RLP编码,理解起来其实不难

以太坊账户状态的4个组成部分:Nonce、Balance、StorageRoot、CodeHash。

其中,对于外部账户真正有效的只有Nonce和Balance两个字段,这两个字段也好理解。而对于合约账户,4个字段都有效,且后面两个字段,StorageRoot和CodeHash就比较令人费解。StorageRoot跟合约拥有的数据有关,CodeHash跟合约拥有的代码有关。

我们先来看看StorageRoot。

这其实是一棵梅克尔树(Merkle Tree)的树根,但这里的梅克尔树和比特币里的梅克尔树不一样,它是一棵经过改进的梅克尔树,称之为MPT(Merkle Patricia Tree)。

在比特币里,只有一处用到梅克尔树,就是在区块里,把该区块的所有交易用一棵梅克尔树组织起来,然后将树根存储到区块头里。

而在以太坊,我们会发现,将会有很多地方用到梅克尔树或MTP。而StorageRoot就存储了一棵MPT树的树根,它是这么来的:

1、将该合约账户包含的所有数据,用一定方式划分成一个个的32字节长的数据块,做为“value”,并且将这些数据块按顺序从0开始编号,编号也是32字节长,做为“key”,这样,key和value一一对应;

2、但这时的key和value还是原始key和原始value,需将原始key哈希一下,得到最终的key,将原始value用RLP编码处理一下,得到最终的value;

3、最后,把最终的[key, value]对用一棵MPT树存储起来。其树根就是StorageRoot。

哈希我们学过了,不再讲。MTP树和RLP编码是以太坊独创的,且在多处用到。MTP树我们明天再讲。所以,今天主要就是弄清楚RLP编码。

RLP(Recursive Length Prefix),全名叫递归长度前缀编码,很拗口,不管它,我们叫它RLP就行。RLP编码其实就是一些变换规则。

它变换的对象有两种,一种就是字符串,比如“abcde”,另一种是由多个字符串组成的列表,比如[“abc”,”bde”,”a23f”]。

RLP编码基于标准的ASCII编码,标准的ASCII编码是常用的计算机编码方式,但它只编码了字母、数字、标点等128个常用字符,一个字符占用一个字节(所以,想要在以太坊上存储些奇怪字符是不可能的?如果理解错了,请大神指出,拜谢!)。

接下来,我们来看看它的具体转换规则:

规则一: 对于值在[0, 127]之间(因为基于ASCII标准表,所以超过128就处理不了啦)的单个字符,其编码是其ASCII编码。 比如,单个字符‘0’在ASCII标准表里是48(十六进制是0x30),所以在RLP这里也是48。

规则二: 如果字符串长度是0-55个字节,那么在前面加上(128+字符串长度)作为前缀。 比如,空字符串编码就是128,即128 = 128 + 0; “0”这个字符串只有1个字符,编码就是12948; “0123”在ASCII标准表是48495051,长度是4个字节,前缀为132,那么RLP 转换后就是13248495051。

规则三: 如果字符串长度大于55, 那么在前面加上(183+字符串长度的二进制编码的长度)和(字符串长度)做前缀。(为什么是183?因为在规则二里,最大就是183(128+55)。)

比如,一个字符串长度为1024个字节,1024换成二进制是00000100 00000000,占2个字节,所以,前缀为18540,其中185得自183+2,4得自长度的第一个字节00000100转换成十进制,0得自第二个字节00000000转换成十进制。 接下来还有2条规则,是针对字符串列表的。

规则四: 如果列表中所有字符串的总长度按规则1到3编码后,小于等于55,那么在前面加上(192+该长度)做前缀。列表里的字符串编码参照规则1到3(183和192之间差了9个字节,9个字节用来表示长度,那是个非常非常大的数字了,所以,RLP几乎可以编码非常非常长的字符串)。

比如,一个列表有3个字符串,这3个字符串分别按规则1到3编码后,总长度是9个字节,那么前缀是192+9=201;

规则五: 如果列表中所有字符串的总长度按规则1到3编码后,超过55,那么在前面加上(247+该长度的二进制编码的长度)和(该长度)做前缀。列表里的字符串编码参照规则1到3(为什么是247?因为192+55=247)。

比如,一个列表有10个字符串,这10个字符串分别按规则1到3编码后,总长度是100个字节,因为100进行二进制编码,只占用1个字节,所以前缀是248(247+1)和100。

其实,像RLP这种序列化的编码已有很多,但冗余太大,占用空间太大,而区块链上的存储和计算资源都很金贵,所以太坊重新发明了一个更紧凑的。

你可能感兴趣的:(比特币,以太坊,区块链,编码,以太坊技术)