Bitcoin-Core

比特幣何時更新 UTXO 集?

  • November 5, 2020

我有點困惑。我希望你能幫我澄清一下……

假設我想做一筆交易。所以我的交換錢包為我做了這件事。它這樣做的方式是首先獲取 UTXO 列表(假設它在磁碟 D上有),獲取可以使用的列表,然後使用這些 UTXO 創建具有有效輸入的交易。然後,該交易進入節點的記憶體池。然後,當開始探勘一個塊時,節點會抓取這些交易,將它們放入一個塊中並開始探勘。

問題1) D盤上的UTXO列表什麼時候更新?在將交易放入記憶體池之前,或者在礦工解決一個塊之後,或者在礦工從記憶體池中獲取交易的時候?

如果答案是:在將交易放入記憶體池之前,那麼事情會變得複雜,因為如果該節點沒有解決該塊,則可能不會發生更新 UTXO,因此這意味著該節點將恢復utxo 回到原來的樣子。

如果答案是:在礦工解決了一個塊之後,那麼我的節點可能會讓我執行兩次相同的交易,因為在創建交易之前,它會檢查 UTXO 列表。

如果答案是:當礦工從記憶體池中獲取交易時,這是非常錯誤的,因為記憶體池已經包含經過驗證的交易。

你怎麼看?

更新問題:

假設我有 1 BTC 並在節點 A 上向 Bob 發布了 1BTC 交易,在節點 B 上向 Alice 發布了相同的 1BTC 交易。

所以,假設交易廣播沒有發生,所以他們(nodeA,nodeB)不知道彼此的交易。

現在,nodeA 先挖了一個區塊並廣播了這個區塊。nodeB 收到了這個塊。現在,正如您所說,nodeB 使用了許多不同的 UTXO。完成的一項檢查是 nodeB 循環遍歷 nodeA 的塊的交易,如果可以在其記憶體池中找到任何交易(比較交易 id),它將刪除它。現在,nodeB 將如何刪除對 Alice 的交易(現在是雙花)?它是怎麼得出這個結論的?

這取決於實現,但在比特幣核心中不只有一個 UTXO 集:

  1. chainstate/數據庫目錄中磁碟上**的 UTXO 集。**它對應於上次刷新塊的狀態(不包括任何記憶體池事務的影響,或自上次刷新以來的任何塊的影響)。
  2. 記憶體中的硬幣記憶體是磁碟 (1) 上 UTXO 集頂部的記憶體,應用了來自最近未刷新塊的花費/創建。它僅物理儲存更改的值;查詢其他 UTXO 將導致從磁碟數據庫 (1) 讀取。
  3. mempool在 (2) 之上隱式定義了另一個 UTXO 集。這根本沒有實現:查詢時,我們只檢查 (2) 或 mempool 是否有要求的交易輸出,以及是否沒有 mempool 交易花費它。記憶體池始終與區塊鏈保持一致(例如,如果確認交易與記憶體池交易衝突,則刪除該記憶體池交易)。
  4. 在處理塊期間,會維護 UTXO 更改的臨時記憶體,作為 (2) 之上的更新檔。這允許塊花費自己創建的輸出,而如果一個塊由於某種原因無效,則可以直接丟棄該臨時記憶體而無需做額外的工作。只有當塊實際上完全有效時,才會將來自這個臨時記憶體的更改合併到 (2) 中,並更新 mempool (3) 以與結果一致。
  5. 錢包在概念上也維護自己的一組 UTXO(由所有者監視和/或花費),儘管它們在程式碼庫中不使用相同的介面。這是必要的,因為錢包可能包含未經確認且不在記憶體池中的交易(例如,因為它們因驅逐而被刪除,但我們仍想重試插入它們)。

最後,重要的是要注意每個節點都有自己的 UTXO 集。當礦工(哪一個?)開始將您的交易包含在他們的候選區塊中時,您自己的錢包/節點不會更新任何內容——您甚至無法知道他們正在這樣做。

引用自:https://bitcoin.stackexchange.com/questions/99826