精通比特幣

附錄 B比特幣白皮書勘誤表

附錄 B

比特幣白皮書勘誤表

約 7 分鐘閱讀 · 7 個小節

本 附錄包含中本聰論文「比特幣:點對點電子現金系統」中已知問題的描述,以及術語變化和比特幣實作與論文中描述的差異的說明。

本文檔最初由本書的共同作者於 2016 年發布;在此轉載並附有更新。本勘誤表中章節的名稱對應於中本聰原始論文中章節的名稱。

摘要

「最長的鏈不僅可以作為所見證事件序列的證明,而且可以證明它來自最大的 CPU 算力池。」

  • 實作細節: 如果鏈中的每個連結(在比特幣中稱為「區塊」)都使用相同數量的工作量證明(PoW)構建,則最長的鏈將是由最大計算能力池支援的鏈。然而,比特幣的實作方式使得區塊之間的 PoW 數量可以變化,因此重要的不是檢查「最長的鏈」,而是「展示最多 PoW 的鏈」;這通常縮寫為「最多工作鏈」。

    從檢查最長鏈到檢查最多工作鏈的 更改發生在 2010 年 7 月,遠在比特幣最初發布之後:

    -    if (pindexNew->nHeight > nBestHeight)
    +    if (pindexNew->bnChainWork > bnBestChainWork)
  • 術語變化: 通用 CPU 用於為最早的比特幣區塊生成 PoW,但今天 PoW 生成主要由專用應用積體電路(ASIC)執行,因此與其說「CPU 算力」,不如說「計算能力」或簡單地說用於生成 PoW 的雜湊的「雜湊率」可能更正確。

「只要多數 CPU 算力由不合作攻擊網路的節點控制,它們就會產生最長的鏈並超過攻擊者。」

  • 術語變化: 今天「節點」一詞用於指完全驗證節點,即執行系統所有規則的程式。今天擴展鏈的程式(和硬體)被稱為「礦工」,基於中本聰在論文第 6 節中對黃金礦工的類比。中本聰期望所有礦工都是節點,但他發布的軟體並不要求所有節點都是礦工。在原始軟體中,節點 GUI 中的一個簡單選單項允許打開或關閉挖礦功能。

    今天的情況是,絕大多數節點不是礦工,並且許多擁有挖礦硬體的個人不使用自己的節點(甚至那些使用自己節點挖礦的人通常在新發現的區塊之上短時間挖礦,而不確保他們的節點認為新區塊有效)。論文的早期部分主要使用「節點」而沒有修飾語,是指使用完全驗證節點進行挖礦;論文的後期部分提到「網路節點」主要是關於即使節點不進行挖礦也可以做什麼。

  • 發布後發現: 當產生新區塊時,產生該區塊的礦工可以立即開始處理其後續,但所有其他礦工都不知道新區塊,並且在它傳播到他們的網路之前無法開始處理它。這使得產生許多區塊的礦工比產生較少區塊的礦工具有優勢,這可以在所謂的自私挖礦攻擊中被利用,允許擁有約 30% 總網路雜湊率的攻擊者使其他礦工利潤降低,可能迫使他們遵循攻擊礦工的政策。因此,與其說「多數 CPU 算力由不合作攻擊網路的節點控制」,不如說「只要合作攻擊網路的節點控制少於約 30% 的網路」可能更正確。

交易

「我們 將電子貨幣定義為數位簽章鏈。每個所有者透過數位簽署前一筆交易的雜湊和下一個所有者的公鑰,並將這些添加到貨幣的末尾,將貨幣轉移給下一個所有者。」

  • 實作細節: 比特幣實作了該系統的更通用版本,其中不直接使用數位簽章,而是使用「確定性表達式」。正如與已知公鑰匹配的簽章可以用來啟用支付一樣,滿足已知表達式的資料也可以啟用支付。一般來說,在比特幣中為了花費貨幣必須滿足的表達式稱為「約束」。迄今為止,比特幣中幾乎所有約束都需要提供至少一個簽章。因此,與其說「數位簽章鏈」,不如說「約束鏈」更正確。鑑於交易通常有多個輸入和多個輸出,結構不是很像鏈;它更準確地描述為有向無環 圖(DAG)。

工作量證明

「…​我們 透過在區塊中遞增 nonce 來實作工作量證明,直到找到一個值使區塊的雜湊獲得所需的零位元。」

  • 實作細節: Adam Back 的 Hashcash 實作需要找到具有所需前導零位元數的雜湊。比特幣將雜湊視為整數,並要求它小於指定的整數,這有效地允許指定小數位元數。

「工作量證明本質上是一個 CPU 一票。」

  • 重要說明: 這裡的投票不是針對系統的規則,而僅僅是針對交易的順序,以提供「電子貨幣」不能輕易被雙重支付的保證。這在論文的第 11 節中有更詳細的描述,其中說:「我們考慮攻擊者試圖比誠實鏈更快地生成替代鏈的情境。即使完成了這一點,它也不會使系統對任意更改開放,例如憑空創造價值或拿走從未屬於攻擊者的錢。節點不會接受無效交易作為支付,誠實節點永遠不會接受包含它們的區塊。」

「…​工作量證明難度由移動平均值確定,目標是每小時平均區塊數。」

  • 實作細節: 不使用移動平均值。相反,每 2,016 個區塊將其報告的生成時間與較早區塊的生成時間進行比較,並且它們之間的差異用於計算用於調整的平均值。

    此外,比特幣中實作的平均值目標是每兩週平均區塊數(而不是文本可能暗示的每小時)。其他實作的規則可能進一步減緩調整,例如調整不能使每個週期的區塊生成速度增加超過 300%,也不能使其減慢超過 75%。

回收磁碟空間

「一旦 貨幣中的最新交易被足夠多的區塊埋在下面,其之前的已花費交易可以被丟棄以節省磁碟空間。」

  • 可能的發布後發現: 儘管本節中描述的 merkle 樹結構可以證明交易包含在特定區塊中,但目前在比特幣中沒有辦法證明交易尚未被花費,除非處理區塊鏈中的所有後續資料。這意味著這裡描述的方法不能在所有節點中普遍用於回收磁碟空間,因為所有新節點都需要處理所有交易。

簡化支付驗證

「一種 防禦策略是當網路節點檢測到無效區塊時接受來自它們的警報,提示使用者的軟體下載完整區塊和警報的交易以確認不一致。」

  • 重要說明: 儘管已經產生了實作本節某些部分並稱為簡化支付驗證(SPV)的軟體,但這些程式目前都不接受來自網路節點(完全驗證節點)的警報,當檢測到無效區塊時。這使得所謂的 SPV 錢包中的比特幣過去曾處於風險之中。

隱私

「對於 多輸入交易,某些連結仍然是不可避免的,這必然揭示它們的輸入由同一所有者擁有。」

  • 發布後發明: 如果所有者經常將他們的輸入與屬於其他所有者的輸入混合,則同一交易中的不同輸入是否有相同所有者並不清楚。例如,Alice 和 Bob 各自貢獻他們的一個輸入來支付 Charlie 和 Dan,與 Alice 單獨貢獻她的兩個輸入來支付 Charlie 和 Dan 之間沒有公開差異。

    這種技術今天被稱為 CoinJoin,實作它的軟體自 2015 年以來一直在使用。

計算

「接收者 生成新的金鑰對,並在簽署前不久將公鑰交給發送者。這防止了發送者透過持續工作來提前準備區塊鏈,直到他足夠幸運地獲得足夠的領先優勢,然後在那個時刻執行交易。」

  • 發布後發現: 接收者在花費者簽署交易前不久生成公鑰並不能防止花費者提前準備區塊鏈。早期比特幣使用者 Hal Finney 發現了這種攻擊並 描述了它:「假設攻擊者偶爾生成區塊。在他生成的每個區塊中,他包括從地址 A 到地址 B 的轉帳,這兩個地址都由他控制。

    「為了欺騙你,當他生成一個區塊時,他不會廣播它。相反,他跑到你的商店並用他的地址 A 向你的地址 C 付款。你等幾秒鐘,沒有聽到任何消息,然後轉移商品。他現在廣播他的區塊,他的交易將優先於你的交易。」

    該攻擊適用於任意數量的確認,有時被命名為 Finney 攻擊。


免責聲明: 本文檔的作者並不是第一個識別這裡描述的任何問題的人——他只是將它們收集到一個文檔中。

授權: 本勘誤文檔根據 CC0 1.0 通用公共領域貢獻發布

對於本書出版 後進行的更新,請參閱 原始文檔。