以太坊虛擬機
世界狀態樹
世界狀態是以太坊在某個區塊上「誰擁有什麼」的完整快照:每個帳戶的餘額與程式碼,以及每份合約儲存的內容。世界狀態樹是承載這份快照、並把它壓縮成單一 32 位元組指紋的密碼學資料結構,這個指紋就是狀態根,記在每個區塊頭裡。只要改動一個帳戶的餘額,這個指紋就會改變,因此一個區塊頭便悄然提交了整條鏈的全部狀態。
具體而言,它是一棵以帳戶地址(確切說是 20 位元組地址的 Keccak-256 雜湊)為鍵的默克爾帕特里夏字典樹。每個葉子是一個帳戶,含四個欄位:nonce(已送出的交易或已建立的合約數)、以 wei 計的餘額、storageRoot、以及 codeHash。對合約而言,storageRoot 本身又是另一棵默克爾帕特里夏字典樹的根,承載該合約的儲存槽,於是結構層層相套:一棵全域帳戶樹,每個合約帳戶各指向自己的儲存樹。
這套設計一舉買到兩樣東西:精簡的承諾與高效的證明。由於整個狀態坍縮成一個根,節點能以 32 位元組宣告其當前狀態。由於這棵樹經默克爾認證,只知道狀態根的輕用戶端能收到一段簡短的證明——一條兄弟雜湊構成的路徑——確鑿地證明「帳戶 X 餘額為 Y、儲存值為 Z」,而不必下載數百 GB 的狀態。任何竄改都會弄破路徑上的某個雜湊。
EVM 執行的每筆交易,本質上都是對這棵樹的一次編輯,而在每個區塊後重算新的狀態根,是執行用戶端的核心工作之一。這棵樹的深度與雜湊也使狀態存取成為實打實的成本——這正是計畫從十六進位的默克爾帕特里夏字典樹遷移到較扁平的 Verkle 樹的一大動機,後者能把證明縮到足以讓無狀態用戶端變得可行。
其實每個區塊提交了三棵樹:狀態樹(帳戶)、交易樹、收據樹。只有狀態樹會持久存在並變動;另兩棵每個區塊都重新建立。
另见