以太坊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進制,如一、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。
相關文章
相關標籤/搜索