概覽
隔離見證(segwit)即將發布。本文提供一些背景資訊、關於如何測試 segwit 的詳細資訊、關於升級預期如何進行的資訊,以及 segwit 使實作變得更容易的一些未來功能的描述。
背景
Segwit 是一個提案,允許生產交易的軟體將交易簽名(見證)與交易中的其餘資料分離(隔離),並允許礦工將這些見證放置在傳統區塊結構之外。這提供了兩個直接好處:
-
消除可塑性:隔離見證允許接收交易的現有軟體和升級軟體在不參照見證的情況下計算使用 segwit 的交易的交易識別碼(txid)。這解決了所有已知的不需要的第三方交易可塑性情況,這是一個使 Bitcoin 錢包軟體程式設計更加困難的問題,並嚴重複雜化了 Bitcoin 智慧合約的設計。
-
容量增加:將見證資料移至傳統區塊結構之外(但仍在新式區塊結構內)意味著新式區塊可以容納比舊式區塊更多的資料,允許交易資料量的適度增加。
Segwit 還簡化了向 Bitcoin 新增新功能的能力,並提高了完整節點的效率,這提供了長期好處,將在本文件後面更詳細地描述。
有關 segwit 的更多資訊,請參閱我們的 FAQ 或 BIP 141、143 和 144。
如何測試 segwit
Segwit 變更了 Bitcoin 系統的幾個部分,最值得注意的是完整驗證節點用來就 Bitcoin 帳本狀態達成一致的共識規則。如果節點停止就帳本狀態達成一致,那麼接收新的 Bitcoin 交易就變得不安全,因此 Bitcoin 開發者應該謹慎進行任何此類變更,並對任何此類提議的變更進行廣泛的測試。
同樣重要的是用於中繼區塊和交易的點對點網路程式碼的變更。由於 segwit 交易和區塊的組織方式與早期交易和區塊版本不同,因此確保網路實作既可以向 segwit 節點中繼 segwit 資料,也可以向舊節點中繼舊式資料很重要。
這些對共識規則和 P2P 網路程式碼的組合變更包含 1,486 行新增或修改的程式碼。segwit 補丁還包括單元和整合測試中的額外 3,338 行新增或修改的程式碼,這些測試有助於確保 segwit 在 Bitcoin Core 程式的每次完整建置時都能按預期運作。
除了超過 3,000 行新增的自動化測試程式碼外,segwit 還經過 Bitcoin 開發者的廣泛測試。本節僅描述他們在過去一年對不同版本的 segwit 進行的一些嚴格測試。
-
Segwit 最初由 Pieter Wuille 和其他幾位 Blockstream 開發者在 2015 年 4 月至 6 月在 Elements Project 側鏈上實作,作為不打算與先前 Bitcoin 軟體相容的「從頭開始」版本。這個版本已用於基於 Elements 的側鏈上的每一筆交易。
-
2015 年 10 月下旬,Luke Dashjr 描述了一種允許在 Bitcoin 中將 segwit 作為軟分叉實作的方法,Wuille 利用他在 Elements 版本方面的經驗開始開發這個新的實作,該實作與所有現有 Bitcoin 軟體向後相容(儘管程式確實需要升級才能完全理解 segwit)。
-
程式碼在 2015 年 12 月下旬在特殊的 segwit 專用測試網(稱為 segnet)上完全運作,允許實作者和測試者在多使用者環境中執行程式碼,也允許錢包作者測試他們生成 segwit 交易的程式碼。Segnet 經歷了幾次迭代,因為發現並修復了問題,並發現和實作了改進。
-
2016 年 4 月,經過四個月的積極開發和測試後,Wuille 向 Bitcoin Core 專案提交了一個拉取請求以供審查。
-
2016 年 5 月,Segwit 在 Bitcoin 的常規測試網上啟用,在那裡它不僅針對預期與 segwit 互動的其他軟體進行測試,還針對在 Bitcoin 測試網上定期測試且尚未為 segwit 升級的所有其他程式進行測試。
-
同樣在 2016 年 5 月,二十位 Bitcoin Core 開發者在瑞士會面進行(除其他事項外)segwit 程式碼的面對面審查,並確保測試覆蓋率足夠。
-
2016 年 6 月,在對原始拉取請求進行了近兩個月的非常積極的審查以及在 segnet 和測試網上的擴展運作後,Wuille 建立了一個第二個拉取請求,其中包含對原始拉取請求進行的所有改進,重新基於 Bitcoin Core 開發分支的最新版本,並專門格式化以使最終審查變得容易,並確保對原始拉取請求進行的所有審查保持有效。
隨著 segwit 的原始側鏈實作在過去一年中被許多審查者使用,Bitcoin 軟分叉實作在六個月內獲得嚴格的測試和審查,Bitcoin Core 開發者相信它現在已準備好投入生產。
緊湊區塊
Segwit 將允許 Bitcoin 礦工在他們建立的區塊中包含比現在更多的交易資料。這將增加中繼所有這些資料的 Bitcoin 完整節點的頻寬需求,並增加新區塊發布和節點接收之間的延遲(因為較大的資料量通常需要更長的時間來傳播)。為了幫助減少這些負面副作用,Bitcoin Core 開發者計劃為 Bitcoin Core 0.13 及更高版本提供緊湊區塊中繼。
Bitcoin 完整節點目前下載許多交易兩次:一次是當它們單獨接收交易時,第二次是當交易作為區塊的一部分接收時。緊湊區塊中繼可以透過僅向節點發送它們使用已接收的交易重建區塊所需的資訊來消除大部分(有時是全部)這種重複。
在樂觀情況下,這將節點使用的頻寬減少了近一半。由於 segwit 預期將最大容量增加到大約兩倍,這兩個改進大致相互平衡,使節點頻寬使用保持在大致與現在相同的水平。
更重要的是,緊湊區塊中繼有助於減少峰值頻寬負載。目前,必須一次下載大約 1 兆位元組的新接收區塊;當部署 segwit 時,這意味著可能需要下載 2 兆位元組或更大的區塊。在除最快的連接之外的所有連接上,這些頻寬峰值會損害使用者同時執行的其他服務的效能,例如遊戲或影片串流。使用緊湊區塊,使用者可以以穩定的流接收交易,然後使用區塊的小描述重建每個區塊,消除了給許多使用者帶來不便的頻寬峰值。
最後,透過減少宣布新區塊時需要發送的資料量,緊湊區塊中繼還實現了更好的區塊傳播速度。緊湊區塊中繼透過支援兩種運作模式來特別利用這一點,一種低頻寬模式針對減少頻寬進行了最佳化(儘管在大多數情況下它也提高了速度),一種高頻寬模式顯著提高了速度,並且仍然設法透過僅需要比低頻寬模式平均多 20 千位元組來大大減少峰值頻寬使用。
高頻寬模式被用作點對點區塊中繼最佳化的進一步開發的基礎。它特別適用於需要盡快接收區塊的礦工(特別是如果其他非點對點區塊中繼方法失敗),但具有額外頻寬的使用者也可以啟用此模式,以幫助更快地向礦工中繼區塊,並透過使哪些高頻寬節點由礦工執行和哪些由普通對等方執行變得不那麼明顯來幫助阻止拒絕服務攻擊。
部署計劃
以下計劃描述了 segwit 預期的部署方式。
合併到 master(不含主網啟動程式碼):在 Bitcoin Core 開發者「ACK」(批准)最終 segwit 拉取請求後,它將被合併到 Bitcoin Core master Git 儲存庫分支中。正在合併的程式碼將包含 segwit 中的所有內容,除了啟動程式碼。這將使開發者可以輕鬆地在 segwit 之上測試其他功能,例如緊湊區塊。測試網上的啟動已經發生,因此使用者和開發者可以在測試網上實驗和測試 segwit。
回移到 0.12 分支:未啟動的程式碼將回移到 0.12 維護分支,回移將獲得自己的測試。
選擇 BIP9 參數:BIP9 是一種軟分叉部署機制,允許礦工發出他們準備好強制執行新共識規則的訊號。使用 BIP9 進行的每個軟分叉選擇礦工何時可以開始為軟分叉發出訊號,如果沒有足夠的礦工為其發出訊號則何時認為軟分叉不成功,以及區塊標頭版本欄位中的哪個位元將由礦工用於發出他們的準備訊號。這些參數將在此時選擇並與在 master 和 0.12 分支上啟動 segwit 的程式碼一起實作。
候選版本階段:在所有開發者測試成功完成後,將向願意測試程式碼的任何人公開提供候選版本(可能命名為 0.12.2RC1)。特別鼓勵礦工、商家和錢包供應商進行測試。如果發現任何問題,將進行修復並發布新的候選版本。這將根據需要重複,直到找到沒有已知問題的候選版本。
二進位發布:最終候選版本將其版本變更為最終發布版本(預期為 0.12.2),並將發布供所有使用者閒暇下載和開始執行(segwit 是軟分叉,因此僅當他們計劃使用 segwit 功能時才需要升級)。
礦工升級:選擇升級到 0.12.2 的礦工將能夠在達到定義為 segwit 的 BIP9 開始日期後開始生成發出準備強制執行 segwit 訊號的區塊。
鎖定:一旦在 2,016 個區塊長的重新定向期間中有 95% 的區塊發出其礦工準備好強制執行 segwit 的訊號,segwit 將鎖定 – 這意味著除非此時區塊鏈回滾,否則 segwit 將變為活躍(見下一點)。
啟動:segwit 鎖定後 2,016 個區塊(約兩週)後,它將啟動。這意味著所有執行 segwit 感知程式碼的完整節點將開始要求礦工強制執行新的 segwit 共識規則。
錢包升級:與 2012 年的 P2SH 軟分叉類似,在 segwit 啟動後,錢包立即升級以支援 segwit 並不安全。那是因為來自 segwit 交易的花費對舊節點來說看起來像不安全的交易,所以如果 segwit 啟動後不久區塊鏈被分叉,這些花費可能會被放置在不受 segwit 規則約束的較早區塊中。因此,建議錢包在 segwit 啟動後幾週內避免升級。允許額外時間過去為錢包使用者提供了額外的安全性,儘管任何想要用他們可以承受損失的少量錢進行測試的人都可以在 segwit 啟動後立即開始花費。使用者也可以使用測試網或 regtest 立即開始測試提議的 segwit 程式碼或(可用時)任何包含 segwit 的版本。
segwit 將如何影響您
-
礦工選擇執行 segwit 將有責任確保他們準備好透過將其完整驗證節點升級到 segwit 強制執行程式碼來強制執行它。當他們完成此操作並執行他們認為謹慎的任何測試時,他們可以開始發出支援 segwit 的訊號。
-
完整節點運營商可以繼續使用他們現有的節點,但建議他們升級到 segwit 強制執行版本。如果任何礦工最終在 segwit 啟動後根據 segwit 規則生成無效的區塊,升級的完整節點將自動拒絕這些區塊,確保這些升級的完整節點使用者看到準確的確認計數。
對於任何接受低確認數交易的人(例如企業)來說,此升級特別重要。
-
Bitcoin Core 錢包使用者可以繼續使用他們現有的節點。即使您升級,除了上述變更外,您也不會看到任何變更。預期在 0.12.2 中發布的程式碼預設不會開始生成 segwit 接收地址。
-
其他錢包的使用者可以繼續使用他們現有的錢包。建議輕量級錢包使用者在接收大量金錢時總是等待幾次確認,因此這裡不預期需要額外的等待。
當您有機會升級到支援 segwit 的錢包版本時,您可能會發現當您花費升級到 segwit 後收到的 bitcoin 時,您必須支付的交易費用稍低,因為見證是外部的,因此交易大小被計為較小。
segwit 使未來升級更容易
Segwit 是改善 Bitcoin 系統運作的重要一步。除了上述第三方可塑性修復和容量增加外,它還提供了一種機制,允許更輕鬆地升級 Bitcoin 的腳本語言。
自 Bitcoin 0.3.6 以來,腳本語言一直支援十個特殊的 NOP 操作碼,其行為可以在以後的版本中以某些方式重新定義。這十個特殊 NOP 操作碼中的兩個已經用於向系統新增新功能:NOP2 根據 BIP65 變更為 OP_CHECKLOCKTIMEVERIFY (CLTV),NOP3 根據 BIP112 變更為 OP_CHECKSEQUENCEVERIFY (CSV)。
這些操作需要非常仔細地實作以保留舊節點使用的 NOP 語義,這限制了軟分叉可以做什麼,並可能使以這種方式新增功能變得有點混亂。例如,因為 CLTV 和 CSV 都接受參數,所以每次使用它們時,還必須使用 OP_DROP 操作碼以保持與它們原始 NOP 行為的相容性。這使得使用它們編寫和閱讀腳本都變得更加困難。
Segwit 透過允許 segwit 使用者指定要使用的 Bitcoin 腳本語言的版本來消除所有這些問題。每個版本可以是早期版本的小改進,也可以是完全新的語言 – 而且多個版本可以共存在一起,允許個別使用者指定他們想要用於保護其交易的版本。
例如,segwit 隨附了對 OP_CHECKSIG、OP_CHECKMULTISIG 和相關簽名檢查操作碼的改進,消除了可以透過這些操作碼利用的已知拒絕服務漏洞向量。這不是對該問題的完整解決方案,因為 CHECKSIG 操作碼的先前版本仍可用於非 segwit 交易,但它確實有助於使 segwit 交易比非 segwit 交易更難以濫用。
以下描述了使用此機制進行未來升級的一些想法:
Schnorr 簽名
Bitcoin 使用橢圓曲線數位簽名演算法(ECDSA)。有一種更簡單的數位簽名演算法也使用橢圓曲線,但在 Bitcoin 最初發布前不久之前一直受專利保護。這種演算法稱為 Schnorr,它支援 Bitcoin 使用的 ECDSA 中的所有功能,包括建立安全簽名的能力以及建立 HD 錢包的能力。
Schnorr 簽名已經在 Bitcoin 之外使用。例如,著名的 Ed25519 簽名方案 基於 Schnorr。
Schnorr 簽名的驗證比 ECDSA 簽名稍快(這使得執行完整節點更方便),並且簽名可以做得更小,因為目前用於 ECDSA 簽名的 DER 編碼不需要用於 Schnorr(提供適度的容量增加)。
Schnorr 還允許在所有參與者需要簽名的情況下(例如 2-of-2、3-of-3 或任何 n-of-n)進行「原生多重簽名」,允許將所有 n 個公鑰組合成單個總體公鑰,並將所有 n 個簽名組合成單個總體簽名。總體公鑰和簽名的大小與單個原始公鑰和簽名的大小相同,因此可以建立與 1-of-1 交易大小相同的 100-of-100 多重簽名交易。這將非常有用,因為預期網路將看到 n-of-n 多重簽名交易的使用增加(例如,2-of-2 用於許多支付通道交易)。
Schnorr 支援已經在 Bitcoin Core 用於建立和驗證簽名的 libsecp256k1 程式庫中可用,儘管 Bitcoin 目前不以任何方式使用 Schnorr,並且開發者希望在開始使用它之前對程式庫的 Schnorr 部分進行一些變更。這與 segwit 對 Bitcoin 腳本版本控制的支援相結合,應該使新增上述功能變得相當容易。
Schnorr 支援的一個更難新增的功能是簽名聚合。這將變更簽名驗證的工作方式,並允許需要 1-of-2、2-of-3 或任何 m-of-n 簽名的多重簽名交易僅為每個交易建立一個簽名,前提是所有簽名者同時線上。這還允許為每個交易建立一個簽名,無論它有多少輸入(同樣,如果所有簽名者同時線上)。
由於簽名通常是交易的最大單個部分,並且許多交易有兩個或更多輸入,每個輸入至少需要一個簽名,這將顯著減少許多交易的大小,並加快驗證速度(因為總共只需要驗證一個簽名,而不是每個輸入一個簽名)。
一旦實作,簽名聚合可以與 coinjoin 隱私增強技術結合,為使用 coinjoin 花費您的 bitcoin 建立顯著的財務激勵。目前,使用 coinjoin 有輕微的財務激勵,因為將來自不同人的多個個別交易組合在一起的 coinjoin 交易比所有這些個別交易的總大小稍小。使用簽名聚合,組合交易將顯著更小,因為它只需要一個簽名而不是許多簽名。
儘管簽名聚合仍在設計中,但使用 segwit 對不同版本的 Bitcoin 腳本評估語言的支援將很容易為協定新增對它的支援。
MAST
Merkelized Abstract Syntax Trees (MAST) 允許建立 Bitcoin 腳本具有許多不同的條件,但可能只允許將相對少量的資料放入交易中。
它們的工作方式是取一個程式並將其每個條件部分拆分為單獨的片段,然後將這些片段中的每一個放入默克爾樹中。Bitcoin 被花費(encumbered)到默克爾樹的默克爾根。
需要用於最終驗證的最小條件集可以透露給所有完整驗證節點,但不執行的程式碼可以由簡單的雜湊替換,作為部分默克爾分支的一部分,允許腳本的所有部分連接到 encumbrance 中使用的默克爾根,以便可以完成驗證。
這不僅節省空間,而且還可能有助於改善隱私。例如,如果 Alice 希望能夠每天正常花費她的 bitcoin,但也希望她的遺產律師 Bob 能夠在它們閒置一年後花費她的 bitcoin,她可以將這兩個條件放在不同的分支中。當 Alice 進行正常花費時,沒有人可以僅透過查看交易來看到第二個條件是什麼。
可以使用 segwit 啟用的 Bitcoin 腳本版本控制來啟用 MAST。
