《比特幣開發哲學》:升級

作者:Kalle Rosenbaum & Linnéa Rosenbaum

來源:https://bitcoindevphilosophy.com/#upgrading

前篇見此處

upgrading-banner

想要安全地給比特幣升級,是極度困難的。這樣的變更(即使內容是確定的,也)要許多年才能推出。在這一章,我們會了解圍繞比特幣升級的常見詞彙,並瞭解歷史上的幾個升級案例,以及我們能夠從中學到的教訓。最後,我們要討論 “區塊鏈鏈分裂” 以及相關的成本和風險。

想要更好地理解本章的內容,你應該先從 David Harding 論 “和諧與不和諧” 的文章開始:

比特幣的專家們經常把 “共識(consensus)” 這個詞掛在嘴上,這個意思比較抽象,難以一兩句話說清楚。但 “consensus” 的詞源是拉丁語 “concentus”,意思是 “和諧地合唱”【1】,所以,我們可以先不討論 “比特幣的共識”,而討論 “比特幣的和諧”。

和諧是讓比特幣得以運作的東西。數千個全節點,各自獨立地工作:驗證自己收到的交易是有效的,從而產生出關於比特幣賬本狀態的一個和諧的一致意見,並且無需任何一個節點運營者信任另一個運營者。它就類似於一個合唱團,每個成員都在同一時間唱同一首歌,從而產生比任何一個成員單獨歌唱要更加美妙的歌曲。

比特幣的和諧的結果是一套系統,在其中,比特幣是安全的,不僅能抵抗小偷(只要你保管好了自己的私鑰),還能抵禦無止境的通脹、大規模的以及有針對性地沒收,還能脫離傳統金融系統這樣地官僚主義泥潭。

—— David Harding,《和諧與不和諧》

本章要討論地是,比特幣如何能夠升級而不造成不和諧。保持和諧,也即維持共識,實際上是比特幣開發過程中最大的挑戰之一。升級的機制有許多細節,最好是通過研究以往升級的實際案例來理解。出於這個理由,本節在歷史案例上花費了許多篇幅;為此,我們要從瞭解一些有用的詞彙開始。

5.1 詞語

根據維基百科(Wikipedia),“向前兼容性(forward compatibility )” 指的是舊的軟件也能處理更新的軟件所產生的數據、忽略其不能理解的部分。

如果使用較早的版本編譯出來的產品,可以 “優雅地” 處理為同一標準的後續版本而設計的輸入、忽略掉其不能理解的部分,我們就說該標準支持 “前向兼容性”。

—— 向前兼容性,維基百科

反之,“向後兼容性(backward compatibility )”,則是指來自舊軟件的數據在更新的軟件上也可用。如果一項變更既是向前兼容的,又是向後兼容的,我們就說這項變更是 “完全兼容的”。

如果一項對比特幣共識規則的變更是完全兼容的,我們就說它是一個 “軟分叉”。這是升級比特幣最常見的方式,這其中的許多理由,我們會在本章後續小節中探討。如果一項對比特幣共識規則的變更至向後兼容的,但不是向前兼容的,我們就叫它 “硬分叉”。

關於軟分叉和硬分叉的技術概述,請閱讀《Grokking Bitcoin》的第十一章。該章節解釋了這些屬術語,也深入講解了升級的機制。筆者推薦讀者在往下閱讀之前,先瀏覽一下該章節,雖然這不是嚴格必要的。

5.2 歷史上的升級

今天的比特幣(協議)與它在第一個區塊產生時是不一樣的。這些年陸續發生了多次升級。在 2017 年,Eric Lombrozo 在 Breaking Bitcoin 大會上講解比特幣的不同升級機制時,指出這些升級機制也發生了許多變化。他甚至解釋了中本聰有一次如何通過硬分叉來升級比特幣。

實際上,中本聰真的用過一次硬分叉來升級比特幣 —— 我們絕不會再這樣做了,因為這是一種非常糟糕的辦法。看這個 git 提交描述【757f076】,他說這個提交是為了回滾 makefile.unix wx-config,使用版本號 0.3.6 。沒了,就是這些。他完全沒有說這是一次破壞性變更。他基本上就是把它藏起來了。他也在 bitcoin talk 論壇上發帖,呼籲所有用戶儘快升級到 0.3.6 版本;如果你不能立即升級,那麼最好是先關閉自己的比特幣節點。基於上述信息,我不知道他為什麼要這樣做 —— 他同時決定在同一段代碼中加入一些優化,修復 Bug 和添加一些優化。

—— Eric Lombrozo,《改變共識規則而不破壞比特幣》,Breaking Bitcoin 大會(2017)

Lombrozo 還指出,不論是有意還是無意的,這次硬分叉也為未來的軟分叉創造了機會,因為它引入了腳本操作碼(opcode)OP_NOP1 ~ OP_NOP10 。我們會在章節 9.2.1 中更多瞭解這次代碼變更。到目前為止,這些操作碼已經被用於兩次軟分叉:BIP65(OP_CHECKLOCKTIMEVERIFY)和 BIP113(OP_SEQUENCEVERIFY)。(譯者注:兩者分別是在腳本中驗證絕對時間鎖和相對時間鎖。)

Lombrozo 還簡要介紹了升級機制在這些年中的變化(截至 2017 年)。在此之後,只有一次主要升級 “Taproot” 得到部署(詳見章節 5.2.3)。這個漫長而且有些混論的激活過程,幫助我們獲得了對於比特幣升級機制的更多洞見。

5.2.1 “隔離見證” 升級

雖然 “隔離見證(Segwit)” 升級以前的所有升級,或多或少都可以說是沒有痛苦的,但它就不同了。在隔離見證激活代碼發佈的時候(2016 年 10 月),似乎比特幣的用戶中的壓倒性多數都支持它,但出於一些理由,礦工們並沒有表示對這次升級的支持,這導致激活停滯了,而且看起來沒有解決辦法。

Aaron van Wirdum 在他發表在 Bitcoin Magazine 網站的文章《走向隔離見證的長路》中描述了這道一波三折的路程。他首先解釋了 “隔離見證” 升級是什麼、它如何捲進了關於變更比特幣區塊體積限制的爭論。然後,Van Wirdum 列舉了最終導致它激活的轉折性事件。其中的關鍵是一種叫做 “用戶激活軟分叉(UASF)” 的升級機制,是由用戶 “Schaolinfry” 提出的。

Shaolinfry 提出了一種替代選擇:用戶激活的軟分叉(UASF)。它不是讓哈希算力來表態,而是設計一個 “‘激活信號日’,讓用戶從預定的未來時間點開始強制執行”。只要這樣的一次 UASF 被大多數經濟主體強制執行,應該就能說服多數礦工遵循(或者說激活)軟分叉。

—— Aaron van Wirdum,《走向隔離見證的長路》,Bitcoin Magazine(2017)

此外,Van Wirdum 還引用了 Shaolinfry 發佈在 Bitcoin-dev 郵件組中的郵件。在那裡,Shaolinfry 表示反對礦工激活的軟分叉,並列舉了這種激活方式的許多問題。

首先,它要求信任哈希算力會在激活之後誠實地驗證。但在 BIP66 軟分叉中,明明有 95% 的哈希算力表示已經就緒,實際上卻有大約半數並沒有真正驗證升級後的規則、錯誤地挖出了一個無效的區塊【1】。

其次,礦工信號有一種天然的否決機制,少量哈希算力就能否決節點的升級激活意圖,讓所有人都得不到升級。到目前為止,軟分叉利用了相對中心化的挖礦生態,只有少量的礦池在構造有效的區塊;隨著我們轉向更加去中心化的挖礦生態,我們有可能會越來越多地受困於 “升級惰性”,它會否決絕大多數升級。

—— Shaolinfry,Bitcoin-dev mailing list (2017)

Shaolinfry 還指出了對礦工信號的常見錯誤解讀:人們普遍認為,這是一種工具,由礦工來決定協議要不要升級,而不是一種幫助協調升級的行動。因為這種誤解,礦工們可能也覺得有義務在公開場合表達他們對一項軟分叉的看法,彷彿這會給這些提議增加說服力。

而 UASF 提議,簡單來說,只是一個 “信號日”,節點們開始強制執行特定的新規則。這樣一來,礦工們就不必採取集體行動來協調升級,而是 可以 在信號日之前激活升級,只要足夠多的區塊表態已經就緒。

我的建議是,讓我們集兩者之所長。因為用戶激活的軟分叉在激活之前需要一個相對長的預備期,我們可以結合 BIP9 來給出哈希算力協調激活的選項(這樣會更快),此外,還能附加一個較慢的信號日激活。不論是哪一種情況,我們都能利用 BIP9 中的警告系統。這項變化是比較簡單的,只需添加一個 “激活時間” 參數,它會在 BIP9 部署超時日期之前,將軟分叉的 BIP9 狀態轉為 “鎖定(LOCKED_IN)”。

—— Shaolinfry,Bitcoin-dev mailing list (2017)

這個想法引起了許多人的興趣,但似乎並沒有得到所有人的支持,還引起了對它可能引發區塊鏈網絡分裂的擔心。Aaron van Wirdum 的文章解釋了這些爭議最後是如何因為 BIP91 而得到解決的。這是由 James Hilliard 提出的比特幣升級提議(BIP)。

Hilliard 提出了一個複雜一些但更加聰明的解決方案,讓所有東西都能兼容:由 Bitcoin Core 開發團隊提出的隔離見證升級、BIP148 用戶激活軟分叉,以及 “紐約共識(New York Agreement)” 激活機制。他的 BIP91 可以保持比特幣不分裂 —— 至少在隔離見證激活期間。

—— Aaron van Wirdum,《走向隔離見證的長路》,Bitcoin Magazine(2017)

這裡面還涉及一些更加複雜的因素(比如,所謂的 “紐約共識”),這個 BIP 也不得不加以考慮。筆者鼓勵讀者完整地閱讀 van Wirdum 的文章,以瞭解這段故事中的許多有趣的細節。

5.2.2 隔離見證升級之後的討論

在隔離見證升級激活之後,關於激活機制的討論還在繼續。正如 Eric Lombrozo 在 Breaking Bitcoin 大會上的演講以及 Shaolinfry 所指出的(見上文 5.2.1 章節),礦工激活軟分叉並不是一種理想的升級機制。

有時候我們會想要給比特幣協議添加更多特性。這是一個我們要捫心自問的巨大的哲學問題。我們要為下一次升級使用 UASF 嗎?還是用一種混合方法?礦工自己激活(這種方法)已經出局了。我們不會再使用 BIP9 了。

—— Eric Lombrozo,《改變共識規則而不破壞比特幣》,Breaking Bitcoin 大會(2017)

在 2020 年 1 月,Matt Corallo 在 Bitcoin-dev 郵件組裡發送了一封郵件,開始了關於未來軟分叉部署機制的討論。他列舉了他認為在升級中至關重要的 5 個目標。David Harding 在一期 Bitcoin Optech 週報中總結為:

  1. 如果所提議的共識規則變更遭遇了嚴肅的反對,有能力放棄升級。
  2. 在發佈升級後的軟件之前,有足夠長的協調時間,讓絕大多數的經濟節點都能升級到強制執行這些規則。
  3. 預計在變更之前和之後(以及任何轉變期間),網絡的哈希率將大致保持相同水平。
  4. 儘可能地防止創建在新規則下無效的區塊,這樣的無效區塊會導致不升級的節點和 SPV 客戶端的區塊確認統計出錯。
  5. 確保放棄機制不會被搗亂者濫用、拖延廣受期待而沒有已知問題的升級。

—— David Harding,Bitcoin Optech newsletter #80 (2020)

Corallo 提出的是一種結合了礦工激活軟分叉和用戶激活軟分叉的機制:

因此,把事情講得更具體些,我認為,一種能夠作為正確先例、妥當地兼顧上述目標的激活方法,應該是這樣的:

1)一個標準的 BIP 9 部署流程,以一年的時間窗口準備激活,要求 95% 的礦工準備好;

2)在一年內無法激活的情形中,設定一個長度為 6 個月的靜默期,社區可以分析和討論不激活的理由;

3)在合理的情況下,在最早的部署軟件發行版中提供一個簡單的 命令行命令/配置文件參數,讓用戶可以選擇一個 BIP 8 部署流程,以 24 個月的時間窗口促成信號日激活(同時,新的 Bitcoin Core 發行版自動啟用這個標籤)。

這給更加標準的激活方法提供一個非常長的時間窗口;雖然,在保證依然能夠滿足第 5 條目標的前提下,需要顯著延長時間窗口來保證滿足第 3 條目標。開發比特幣不是一場賽跑。如果有必要,等待 42 個月可以保證我們不是在建立一個會在日後讓我們後悔的負面先例。

—— Matt Corallo,《現代軟分叉激活方法》,Bitcoin-dev 郵件組(2020)

中文譯本

5.2.3 “Taproot” 升級與 “Speedy Trial”

當 “Taproot” 在 2020 年 10 月準備好部署的時候,也就是圍繞它的共識規則的所有技術細節都已經被實現並且獲得了社區內的廣泛認可的時候,關於如何部署它的討論開始發酵。在此之前,這樣的討論一直很低調。

大量關於激活機制的提議開始浮出水面,而 David Harding 在 Bitcoin Wiki 中總結了這些提議。在他的文章中,他解釋了 BIP8 的一些屬性,那時候為了讓它更加靈活而有了一些變化:

在這份文件創制的時候,BIP8 的基礎是從 2017 年學到的教訓。跟隨 BIP 9+148 而出現的一個重大變更是,強制激活的時間度量是區塊高度,而不是過往時間中值(median time past);第二個重大變更是,強制激活是一個布爾參數,既可以在初次部署設定軟分叉的激活參數時選定,也能在後續部署中更新。

不設強制激活的 BIP8 與 BIP9(帶有超時和延遲的版本比特機制)非常相似,唯一的重大區別是,BIP8 使用區塊高度,而 BIP9 使用過往時間中值。這一設定允許升級嘗試失敗(但是可以再次嘗試)。

帶有強制激活的 BIP8 最終會有一個強制的信號表態期,期間所有產生的區塊都必須遵守它的規則 —— 必須表示已經準備好激活這次軟分叉 —— 這將使同一軟分叉在沒有強制激活的早期部署中激活。換句話說,如果已經發行的軟件版本 x 沒有強制激活機制,而後續發行的版本 y 有,並且成功迫使礦工開始在同一個時間窗口種表示已經就緒,則兩個版本的軟件都將在同一時間開始強制執行新的共識規則。

修正後的 BIP8 提議的靈活的,使得它可以表達看起來像是 BIP8 的其它想法。這提供了一種區分許多不同提議的通用元素。

—— David Harding,Taproot 激活提議,Bitcoin Wiki(2020)

從這一時間點開始,討論變得非常熱烈,尤其是圍繞 lockinontimeout 應設置為 true(從而使用用戶激活軟分叉,也就是 Harding 所說的 “帶有強制激活的 BIP8”)還是 false(從而類同於礦工激活軟分叉,也就是 Hardking 說的 “不設強制激活的 BIP8”)的討論。

在列舉出來的提議中,其中一個名為 “不妨看看會發生什麼事(Let’s see what happens)”。出於一些原因,這個提議並沒有獲得很多關注,直到幾個月之後。

在這 7 個月時間裡,討論一直在進行,而且似乎沒有辦法達成廣泛的共識(要使用哪一種部署機制)。人們分成兩大派別:一些人傾向於 lockinontimeout=true(UASF 派),而其他人傾向於 lockinontimeout=true(“試試看,要是失敗了就再想辦法” 派)。因為這兩個選項都沒有獲得壓倒性的支持,辯論一直在原地打轉,看起來沒辦法走出來了。其中一些討論是在在線聊天室(IRC)中發生的,在一個名為 “##taproot-activation” 的頻道中;但是,到了 2021 年 3 月 5 日,事情有了轉變:

06:42 < harding> roconnor: 有人提議 BIP8(3m, false)(為期 3 個月,不設強制激活的 BIP8)嗎?我之前提過這個問題,但我沒看到有人回答。 [...]06:43 < willcl_ark_> 應該有,我自己就在想,與此相比,隔離見證的激活機制是非常直接的:直接是 LOT=false ,要是沒通過,那就來一次 UASF 。06:43 < maybehuman> 有趣。如果我沒有記錯,在這個頻道剛剛創建的時候,“Let’s see what happens” (就是 false,3m)是一個熱門的選擇。06:44 < roconnor> harding: 我支持。我不知道這有沒有價值。根據我對其他人的顧慮的理解,基本上,我認為這會是一個能夠得到廣泛接受的選擇。06:44 < willcl_ark_> maybehuman: 因為每個人都想要這個升級,甚至礦工們也說自己能在大約兩週內升級(至少 f2pool 是這麼說的)06:44 < roconnor> harding: BIP8(3m,false) 加上一個延長的鎖定期。06:45 < harding> roconnor: 哦,不錯。從我 7 個月前笫一次在 wiki 上總結這些選項以來,這是我最喜歡的選項。06:45 <@michaelfolkson> UASF 無法發佈 (true,3m),但是 Core 可以發佈 (false, 3m)06:45 < willcl_ark_> harding: 對我來說它真的像是一個好方法。*如果* 它失敗了,那我們可以先想想這是為什麼,就不用浪費太多時間。

—— #taproot-activation IRC 日誌

這種 “Let’s see what happens” 方法最終似乎抓住了人們的心。這個過程,後來被說成是 “速戰速決(Speedy Trial)”,因為它的表態期很短。David Harding 在一封發佈在 Bitcoin-Dev 郵件組的郵件中向廣大社區解釋了這個想法:

這個提議的較早版本成文於 200 多天以前【3】,而 taproot 的底層代碼是在 140 多天以前合併到 Bitcoin Core 軟件中的【4】。如果我們從代碼被合併的同一時間點開始 “速戰速決”(這不太現實),我們將要麼在未來不到 2 個月的時間裡激活 taproot,要麼在 1 個多月以前就轉向再一次嘗試激活。

然而,從一年多以前我們開始討論隔離見證之後的激活方案以來,我們一直在辯論,並且看起來完全沒有更加接近於我認為可以得到廣泛接受的解決方案【5】。我認為,“速戰速決” 是一種快速推進的方法,要麼,它能終止爭論(如果激活成功,它就能終止截至目前的爭論),要麼,它給我們一些真實的數據,作為未來的 taproot 激活提議的基礎。

—— David Harding,Bitcoin-dev 郵件組

這個激活機制經過了兩個月的改進,然後發佈在了 Bitcoin Core 版本 0.21.1 裡面。礦工們很快開始表態準備好了這次升級,從而將部署狀態轉變成了 LOCKED_IN;在一段平靜的時光之後,“Taproot” 規則於 2021 年 11 月中旬,從區塊高度 709632 開始激活。

5.2.4 未來的升級機制

給定近期的軟分叉(隔離見證和 Taproot)中出現的問題,尚不清楚未來的升級會如何部署。Speedy Trial 被用來部署 Taproot,但它是因為能夠彌合 UASF 派和 MASF 派之間的分歧而被使用的,並不是因為它是我們已知最佳的部署機制。

5.3 風險

在任何分叉 —— 無論是軟分叉還是硬分叉、用戶激活還是礦工激活 —— 激活期間,都有持續存在的區塊鏈網絡分裂風險。持續數個區塊的分裂可能導致對圍繞比特幣的情緒以及價格的嚴重破壞。但最重要的是,這會造成對 “比特幣是什麼” 的極大困惑。比特幣是這條鏈、還是那條鏈?

用戶激活軟分叉的風險在於,即使大部分的哈希算力都不支持新規則,新規則還是會激活。這種情形將導致長久持續的鏈分裂,直到絕大部分哈希算力採用新規則才會停止。如果礦工們在發生分裂之後,已經在使用舊規則的鏈上挖掘了區塊,可能就很難讓他們遷移到使用新規則的鏈上。不過,這裡也值得提到一個令人印象深刻的事件(詳見 9.2.3 章節):在 2013 年 3 月,比特幣網絡因為意料之外的硬分叉而產生了長時間的區塊鏈分裂,但背反於這種激勵因素,兩個主要礦池決定放棄他們已經挖出的分支,以重建共識。

另一方面,礦工激活軟分叉的風險在於,礦工可能會發送錯誤的信號,也即是說,真正採用變更的哈希算力的佔比,可能比看起來的要小。如果實際支持變更的哈希算力並不形成大多數,我們就有可能看到類似於前面章節所說的長期持續的鏈分裂。這個問題,至少可以說是一個類似的問題,在 BIP66 部署的時候真的發生了(詳見 9.2.4 章節),只是在 6 個區塊以內就解決了。

5.3.1 分裂的代價

Jimmy Sone 在巴黎的 Breaking Bitcoin 大會上講解過跟硬分叉相關的代價,但他說的許多代價,也適用於因為失敗的軟分叉而導致的鏈分裂。他講到了 “負外部性(negative externalities )”,定義是其他人不得不為你的行動支付的代價。

“負外部性” 的一個經典例子是一家工廠。也許它是有生產力的,它是一家石油精煉廠,生產了對經濟體有好處的一種商品,但也產生了負外部性,比如汙染。它不僅是每個人都必須付出代價的東西 —— 要麼清理,要麼忍受。它還會有 2 階 和 3 階的後續效果,比如隨著更多工人要在工廠工作,就有更多的交通流量。工廠周圍可能還有野生動物。也有一些時候,並非每個人都要承擔代價,而只有一部分人,比如以前使用周邊道路的人、生活在工廠周圍的野生動物,是由他們來承擔工廠的代價的。

—— Jimmy Song,《硬分叉的社會成本》,Breaking Bitcoin 大會(20017)

在比特幣的語境下,他將使用 Bitcoin Cash(Bcash)作為負外部性的例子;Bcash 是比特幣的硬分叉,就在 2017 年 Breaking Bitcoin 大會舉辦之前不久創建。Song 還將硬分叉的負外部性區分為一次性的成本和永續的成本。

在一次性成本的許多例子中,他還提到了因為交易所而產生的成本。

市場上有許許多多的交易所,他們都必須承擔大量的一次性成本。首當其衝的是,存入和取出資金的窗口必須暫停一到兩天,因為他們無法確定會發生什麼事。由於用戶要求 Bcash,許多這樣的交易所不得不動用冷存儲。這是他們應盡的信託責任,他們必須這樣做。你還必須審計新的軟件。這是我們在 itbit 必須做的事。我們想要花費 bcash —— 但是怎麼花費呢?我們一定要下載 electron cash 軟件嗎?會不會有惡意軟件?因此必須審計。我們可能要 10 天來搞清楚它到底能不能用。然後,同樣必須決定的是,僅僅允許用戶一次性取款呢,還是要上架這種貨幣?對於交易所來說,要商家一種新的貨幣並不是簡單的事,它關聯著冷存儲、簽名、存款、取款這整套的流程。或者,你也可以搞一個一次性的活動,把 Bcash 歸還給用戶,這就一了百了了。但這樣做也有問題。最後,不論你怎麼做 —— 讓用戶取走,或是上架新幣種 —— 你都需要新的基礎設施來操作這種新的貨幣,哪怕你提供的只是一次性的取款。總得有一種辦法來歸還它們給用戶。而且,你還要搞個臨時通知,對吧?時間不多,火急火燎。

—— Jimmy Song,《硬分叉的社會成本》,Breaking Bitcoin 大會(20017)

他也列出了在商家、支付處理商、錢包軟件、礦工和用戶處發生的一次性成本,還有永續成本,比如隱私性損失以及更高的鏈重組風險。

實際上,在發生區塊鏈分裂的時候,如果使用更鬆散規則的鏈比使用更嚴格規則的鏈更加強壯,鏈重組就會發生。這對受損分支上的所有交易都會有嚴重的影響。出於這些理由,不論什麼時候,避免鏈分裂都是極為重要的。

5.4 結論

比特幣隨時間生長和演化。在此期間,多種升級機制被採用過,其學習曲線也是陡峭的。隨著我們對網絡的反應瞭解越來越多,越來越精巧和健壯的方法不斷被髮明出來。

為了保持比特幣的和諧,軟分叉被證明是前進的方向,但是,還有一個大問題依然沒有完全得到解決:我們如何能夠安全地部署軟分叉,而不引起不和諧呢?

相关赛道:
來源
免責聲明:以上內容僅為作者觀點,不代表Followin的任何立場,不構成與Followin相關的任何投資建議。
喜歡
收藏
評論