Evm

儲存 trie - 兩個具有相同儲存內容的合約實例是否重用了 trie 節點?

  • March 2, 2018

閱讀 geth 程式碼和這裡的各種文章,我想我現在已經很好地理解了數據是如何儲存在乙太坊中的(如果我在某些時候錯了,請糾正我)。

在最低級別,我們有一個鍵值數據庫

在下一個級別,我們有一個通用的資料結構,稱為 trie

在乙太坊區塊鏈級別,我們有類似的東西(僅命名相關部分):

block -> state trie -> account* -> storage trie

$$ Q1 $$:對於 state trie,路徑代表帳戶地址。儲存樹中的路徑是什麼?儲存索引?

$$ Q2 $$:如果我們有一個簡單的契約形式:

contract C {
   uint256 public x = 100;
}

當我們實例化這個合約的兩個實例時。它們會有相同的儲存根雜湊嗎?如果是,它們是否會在數據庫中(在最低級別)共享完全相同的鍵/值對,分別在儲存 trie 中共享相同的 trie 節點?

對於 state trie,路徑代表帳戶地址。儲存樹中的路徑是什麼?儲存索引?

這是正確的,除了地址和索引在儲存到 trie 之前經過雜湊處理。這樣做是為了 DoS 保護:為什麼在 Merkle Patricia Trie 中對密鑰進行雜湊處理?

當我們實例化這個合約的兩個實例時。它們會有相同的儲存根雜湊嗎?

是的。

它們會在數據庫中共享完全相同的鍵/值對(在最低級別),分別在儲存樹中共享相同的樹節點嗎?

是的,因為兩個合約的 trie 根是相同的,它們共享底層數據庫中的鍵/值。乍一看,兩個合約“共享相同的儲存空間”似乎違反直覺或不安全,但是,因為 trie 結構是不可變的,每當向 trie 添加新條目時,都會使用它自己的根創建一個修改後的實例。舊的未修改的 trie 仍然存在於底層數據庫中,其他合約仍然可以指向它。

您可以嘗試使用相同的儲存創建 2 個合約,然後使用此 nodejs 程式碼https://ethereum.stackexchange.com/a/40280/18932讀取它們的儲存根和內容

引用自:https://ethereum.stackexchange.com/questions/41464