以太坊MPT树的HP(Hex-Prefix)编码
Posted zhoujunjie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以太坊MPT树的HP(Hex-Prefix)编码相关的知识,希望对你有一定的参考价值。
源码如下:
func hexToCompact(hex []byte) []byte {
terminator := byte(0)
if hasTerm(hex) {
terminator = 1
hex = hex[:len(hex)-1]
}
buf := make([]byte, len(hex)/2+1)
buf[0] = terminator << 5 // the flag byte
if len(hex)&1 == 1 {
buf[0] |= 1 << 4 // odd flag
buf[0] |= hex[0] // first nibble is contained in the first byte
hex = hex[1:]
}
decodeNibbles(hex, buf[1:])
return buf
}
MPT树存储的是键值对,需要对hex格式的Key转化成byte类型。
为什么要进行编码?(https://ethfans.org/hpcoder/articles/961)
在以太坊协议中,不管是地址还是hash,都是一个16进制串,如"0x5b3edbcf7d0a97e95e57a4554a29ea66601b71ad",数据最小的表示单位为一位16进制,如1、a等,但在编程实现中,数据的最小表示单位往往是byte(8bit,2位16进制数),这样在用byte来表示一串奇数长度的16进制串时会出现问题,如"5b3"和"5b30",直接转成byte都是5b30。还有一种简单直观的转换方式,"5b3"->"050b03",这种方式虽然简单,但是数据量会翻倍,不利于大量hash的计算,同时也会增加tree的大小,降低同步性能。Hex-Prefix Encoding能解决这些问题。
在以太坊协议中,不管是地址还是hash,都是一个16进制串,如"0x5b3edbcf7d0a97e95e57a4554a29ea66601b71ad",数据最小的表示单位为一位16进制,如1、a等,但在编程实现中,数据的最小表示单位往往是byte(8bit,2位16进制数),这样在用byte来表示一串奇数长度的16进制串时会出现问题,如"5b3"和"5b30",直接转成byte都是5b30。还有一种简单直观的转换方式,"5b3"->"050b03",这种方式虽然简单,但是数据量会翻倍,不利于大量hash的计算,同时也会增加tree的大小,降低同步性能。Hex-Prefix Encoding能解决这些问题。
- 输入 key 结尾为 0x10,则去掉这个终止符。
- key 之前补一个二进制flag四元组(Nibble), 这个四元组第 0 位区分奇偶信息,第 1 位区分节点类型。
- 如果输入 key 的长度是偶数,则再添加一个四元组 0x0 在 flag 四元组后。
- 将原来的 key 内容压缩,将分离的两个 hex(Nibble) 以高四位低四位进行合并成一个byte。
以上是关于以太坊MPT树的HP(Hex-Prefix)编码的主要内容,如果未能解决你的问题,请参考以下文章