如何驗證比特幣交易?
在進行比特幣交易時,我真的很難理解比特幣網路如何驗證我1)擁有我想要發送的比特幣,以及 2)尚未將其發送給其他人。
如果我的帳戶餘額被跟踪,那將很容易。在我花錢之前,節點會做一個簡單的 if 檢查來測試我的賬戶中是否有足夠的餘額。但據我所知,比特幣交易會破壞比特幣並生成新的比特幣(UTXO)。所以交易看起來像:
FromAddress, ToAddress, Id_of_Bitcoin_being_destroyed, Id_of_bitcoin_being_created
以上假設我有我想要支付的確切零錢 - 因為這足以解決我的問題。
所以現在在送出這個事務之前,節點需要驗證:
isDestroyed(Id_of_Bitcoin_being_destroyed) == false; i.e. coin has not been spent already Owner(Id_of_Bitcoin_being_destroyed) == me; i.e., coin belongs to me
有人可以詳細解釋這是怎麼回事嗎?
一個節點是否在進行反向表掃描(即,從最近的交易開始掃描區塊鏈到最舊的交易)直到它找到
Id_of_Bitcoin_being_destroyed
?然後它可以回答上面的兩個問題。**然而,這個算法根本無法擴展,**是我試圖理解的關鍵。為了使其具體,讓我們說
Id_of_Bitcoin_being_destroyed = 1234
。發生反向表掃描並找到以下記錄:From:Me, To:Brian, 1234, 5678
節點檢測到我已經花費了硬幣並且交易失敗。
另一個例子。在這種情況下,反向表掃描會發現:
From:Brian, To:Me, 5678, 1234
節點可以自信地說我擁有代幣並且它沒有被花費。
我真誠地努力理解這一點並在網上找到答案,包括查看[1 , [2]](https://www.coindesk.com/information/how-do-bitcoin-transactions-work)但沒有成功。例如,1只是這樣說:
這筆交易可以通過插入簽名和我的公鑰(每個人都知道) 進入比特幣程序。
但這讓我無法解釋。
節點維護多個數據庫,它們不只是儲存區塊鏈並在每次想要做某事時對其進行掃描。這些數據庫包括一個塊索引(以便它知道在哪裡可以找到一個塊)和 UTXO 集。包含 UTXO 集的數據庫在這裡很重要。該數據庫包含每個 UTXO 和 UTXO 本身的標識符。一個 UTXO 由一個支出條件(稱為 scriptPubKey)和一個金額組成。
當開始同步區塊鏈時,節點將開始建構其 UTXO 數據庫。在驗證區塊時,它會遍歷該區塊中的每筆交易,並將每筆交易創建的輸出添加到其 UTXO 數據庫中。它還刪除了事務花費的每個 UTXO。因此,一旦一個節點完全同步,UTXO 數據庫就會以一種易於查找的方式包含每個未使用的交易輸出。
因此,在驗證交易時,為了確定輸入是否尚未被花費,節點將嘗試使用其 UTXO 數據庫中的 txid 和輸出索引(UTXO 的唯一標識符)來查找 UTXO。如果它成功並且恰好得到一個結果,那麼它就知道 UTXO 沒有被花費。如果沒有結果,則 UTXO 已經被花費,因此可以將交易標記為無效。
一旦節點擁有輸入的 UTXO,它就可以繼續驗證輸入是否滿足支出條件。支出條件包含在 UTXO 中稱為 scriptPubKey 的欄位中。scriptPubKey 是用比特幣交易腳本語言編寫的腳本。這是一個程序的一半。當與交易輸入中提供的 scriptSig 結合使用時,程序應該是完整且可執行的。
所以節點將(本質上)獲取 scriptSig,將 scriptPubKey 附加到它的末尾,然後執行生成的程序。如果該程序完成執行並返回 true,則腳本有效且已滿足支出條件。因此該輸入是有效的。如果所有輸入都有效,並且其餘交易檢查通過(鎖定時間檢查、輸出具有有效金額等),則整個交易被接受為有效。
如果你注意到了,我提到 UTXO 有支出限制,而不是所有者。這是因為 UTXO 沒有所有者。有些人可以被任何人花費,因為支出約束表明任何人都可以花費產出。節點關心的只是滿足支出限制。
但是我們人類關心所有者,因此有一部分支出約束通常用於表示某人是 UTXO 的“所有者”並且是唯一被允許使用它的人。這些支出限制基本上說明了以下內容:
“為了花費這個輸出,花費者必須提供一個與這個特定雜湊匹配的公鑰和一個使用上述雜湊的公鑰的私鑰產生的支出交易的簽名”
這種支出條件可以抽象為人類術語,即“擁有與腳本中散列的公鑰相對應的私鑰的人擁有該輸出”。