作者:Shinobi
“隔離見證(Segregated Witness)”(其 BIP 作者是 Pieter Wuile、Eric Lombrozo和 Johnson Lau)和 “Taproot”(其 BIP 作者是 Pieter Wuille、Jonas Nick、Tim Ruffing 和 Anthony Towns)是比特幣協議迄今為止最大的兩項變更。
前者在根本上改變了比特幣交易的結構(並因此改變了比特幣區塊),以解決以往的交易結構的內在侷限性。後者則重構了比特幣的腳本編程語言的一些方面(構造和驗證複雜腳本的方式),並加入了一種新的生成密碼學簽名的方案。
兩者都屬 巨大的 變更;相較之下,增加一個像 CHECKTIMELOCKVERIFY(CLTV)這樣的操作碼,只是允許收款方選擇防止自己在特定時間點之前花費一筆支付,沒什麼大不了的。(譯者注:CLTV 是腳本層面的相對時間鎖,在 2015 年的 BIP65 軟分叉中加入比特幣協議。)
這些變更是為了解決比特幣作為一個系統的最根本短板和侷限性。作為一個維護比特幣的整體狀態(即所有未花費的錢幣)的全局共識的基礎層,比特幣協議是一項價值不可估量的天才創新。但想讓每個人都能直接與這些錢幣交易,它還遠遠不能勝任。
在隔離見證和 Taproot 激活之後的這些年,它們解決的許多短板也已經被遺忘。而它們的設計抉擇背後的這些理由和哲學,也隨著時間推移在口口相傳中逐漸歪曲。
這兩項變更都是對比特幣協議的大問題的解決方案,但它們也都為解決其它問題、未來作出其它優化,打下了基礎。
值此許多新人加入比特幣網絡之時,值得回顧這兩項變更,並敘述它們的設計抉擇的上下文。
隔離見證(BIP 141 1)
當一筆比特幣交易花費一些錢幣時,它會通過創建這些錢幣的交易的標識符(TXID)、以及這些錢幣在輸出隊列中的索引號,來索引這些錢幣。這保證了交易的輸出都可以唯一地標識,並且以絕對的確定性驗證它們此前沒有被花費過。
在隔離見證升級以前,比特幣交易的結構是這樣的:
[Version] [Inputs] [Outputs] [Locktime]交易版本號輸入輸出交易鎖定時間交易標識符是這些數據的一個哈希值。問題在於,輸入的 “腳本簽名(ScriptSig)”(簽名、哈希值原像,等等),其作用是用來證明這筆交易(花費操作)是有效的,也被當成輸入的一部分。你可以稍微改變一個腳本簽名中的程序指令,甚至改變其中的密碼學簽名,都不會使它失效。
這些 “熔融操作” 會改變 TXID 。這就給預先簽名的交易帶來的大麻煩。
閃電網絡、Ark、Spark、BitVM、謹慎日誌合約(DLC),所有這些擴容工具都依賴於預先簽名的交易。它們要求參與者先創建一筆待簽名的注資交易、預先簽名保證合約妥善執行和資金安全的所有交易,然後才簽名和確認注資交易。所有這些系統,也都使用多簽名的身份認證,來保證資金不會被重複花費(這一點很重要,我們後面還會提到)。
如果注資交易被熔鑄了,並且它的交易 ID 在它得到區塊確認之前就改變了,那麼所有保護二層資金的預先簽名的交易都會作廢。如果在你的注資交易傳播期間,任何人都能改變它的 TXID,那麼上述所有工具都毫無用武之地。
隔離見證使用一個未定義的操作碼作為一種遮掩,替換了以往放在輸入的腳本簽名中的數據,並將所有這些數據都移到了交易的一個新的叫做 “見證(witness)” 的字段中。新的交易結構是這樣的:
[Version] [Marker/Flag] [Inputs] [Outputs] [Witness] [Locktime]交易版本號標記輸入輸出見證交易鎖定時間輸入中的這個 “百葉窗”,讓舊的節點(沒有使用隔離見證規則的節點)可以默認把與它相關的東西都當成有效的,而新的節點(使用隔離見證規則的節點)則會時機應用相應的驗證邏輯。傳統意義上的 TXID,將不再因為見證中的數據改變而發生改變。這就為預先簽名的交易解決了問題,併為今天得到開發的各種擴容解決方案開啟了大門。
但是,區塊頭中的交易默克爾樹僅僅承諾進入該區塊的各交易的傳統 TXID,這又產生了一個新問題:區塊沒有對見證數據的任何承諾。所以,我們需要見證承諾,以及 “見證交易 ID(WTXID)”。就跟常規的 TXID 的默克爾樹構造一樣,各交易的 WTXID 會形成一棵默克爾樹,並將承諾放到 coinabse 交易的見證中。(譯者注:應有誤,WTXID 的默克爾樹根應該是放在 coinbase 交易的一個輸出的腳本公鑰中的。)
唯一的區別在於,這棵樹的樹根是跟一個保留數值一起哈希的,並且這個保留數值會放在 coinbase 交易的見證中。這讓這個數值在未來可用於承諾共識規則中的其它新數據字段。在這種見證樹承諾(想法來自 Luke Dashjr)發明以前,人們以為隔離見證需要一次硬分叉 ,因為交易結構改變了、而且區塊頭中需要一個專門的見證承諾。
這種 “百葉窗” 設計,也讓對腳本編程系統的任何升級都成為可能,因為所有新型的數據都會被不使用新規則的節點無視,也不會由它們驗證。這允許我們設計一種新的腳本系統,繞過老式腳本系統的所有限制。這種升級路徑的靈活性,也讓集成 Schnorr 簽名成為可能,並且允許我們加入抵抗量子計算的簽名方案(如果有必要的話)(量子抗性簽名方案的公鑰體積一般都大於老式腳本對單個數據對象的 520 字節體積限制,簽名也是如此)。
隔離見證解決了交易 ID 熔融性的根本問題,讓可擴展的二層協議可以放開手腳,把比特幣帶給更多用戶;但同時,它也為有必要支持和能夠提升這些二層協議的任何腳本系統優化都打下了基礎。
Schnorr 簽名 2
“Schnorr 簽名方案” 是 Claus Schnorr 在 1991 年發明的, 並且他馬上就獲得了專利。事實上,正是因為 Schnorr 簽名有專利權,人們才發明了 ECDSA 簽名方案。Schnorr 簽名的專利在 2010 年 2 月過期,就在比特幣網絡啟動的一年多以後。
如果沒有那項專利,也許中本聰(以及世界上的其他人)一開始就會使用 Schnorr 簽名。
相較 ECDSA,Schnorr 簽名有幾個主要優勢:
- Schnorr 簽名是可證明安全的。證明 Schnorr 簽名 不可偽造/無法打破的數學證據要更強,用到的假設也更少(相比 ECDSA)。讓比特幣的心臟中的密碼學擁有更強的安全性保證,顯然是一個巨大的好處。
- Schnorr 簽名是天然無法熔鑄的,這就意味著,能夠替換掉簽名而不會使交易作廢這樣的問題,在使用 ECDSA 時會存在,在使用 Schnorr 簽名卻是完全不可能的。
- Schnorr 簽名擁有一種 “線段性”,允許簡單且高效的加法密碼構造、分佈式密鑰生成以及分佈式簽名生成。這讓用戶可以直接把單個的 Schnorr 公鑰 “加起來”,然後作為一個團隊,製作出這個聚合公鑰的簽名。
Schnorr 簽名相比 ECDSA 更安全、無法被第三方熔鑄,並且打開了大門,讓我們可以用所有類型的高效而靈活的密碼學方案來提升多簽名的身份認證。
在前文討論交易熔融性時,我提到,所有使用預先簽名的交易的鏈外協議都依賴於多簽名身份認證來保護用戶的資金。這種做法是共享資金控制權時的安全措施,卻隱含了由此帶來的擴容效果的天花板。傳統的多簽名無法縮小。交易的體積本身面臨限制;對於版本 0 的(隔離見證的)見證數據,其體積也有限制。如果一個多簽名地址只能允許這麼多參與者,那就暗含了只有這麼多參與者能夠分享對資金的控制權(因此為擴容效果帶來了上限)。
基於 Schnorr 簽名的簽名方案通過聚合多個公鑰為一個集體公鑰,放寬了這個限制:從此我們不再需要構造出每個成員的公鑰都顯式包含在內的腳本。在隔離見證升級以前,一個多簽名地址只能有 15 個參與者;在隔離見證之後,擴大的限制可以容納 20 個參與者。
而使用 “MuSig”5 和 “FROST”6 這樣的基於 Schnorr 的簽名方案,這些限制完全不存在了(至少在共識規則層面是不存在了)。參與一個多簽名裝置的人群可以想要多大就有多大,只要這群人能夠協調簽名流程,不會因為總是有人拒絕簽名或退出而無法完成簽名。
(譯者注:MuSig 為基於 Schnorr 的多重簽名方案,每一個參與了公鑰聚合的人都要參與簽名;而 FROST 是一種閾值簽名方案,參與簽名的公鑰數量只要達到預先設定的閾值就可以製作出簽名。
同樣的屬性,既允許我們像這樣聚合密鑰,也允許實現高效的適配器簽名(adaptor signatures):在這類方案中,我們可以製作出暫時無效、一旦某一段秘密信息暴露就會生效的簽名。這些屬性也讓一些基於零知識證據的方案成為可能,簽名人可以簽名自己沒有看到的消息。
Taproot 3 4
“Taproot” 是一種叫做 “默克爾化抽象語法樹(MAST)” 7 的舊概念的升級版。MAST 自身只是 “支付到腳本哈希值(P2SH)” 腳本的一種插件 8。P2SH 的出現是為了處理兩個大問題:
- 在使用大體積的定製化鎖定腳本時,(如果要將這樣的腳本直接放在交易的輸出中),產生的未花費輸出會有更大的體積(相比於使用小體積的鎖定腳本),也就需要更多空間來存儲 UTXO 集(也就是比特幣網絡的最新狀態)。
- 在使用大體積的定製化鎖定腳本時,發送者要支付更高的費用,因為 TA 發起的交易的體積更大,這會勸退人們給可能更安全的定製化腳本支付。
P2SH 的想法是,與其在交易的輸出中顯式地包含整個腳本,不如僅包含這樣的腳本的一個哈希值;在花費這個輸出時,再由輸出的主人(前一筆的交易中的收款方)在輸入中提供完整的腳本,可以用哈希值來驗證。這就解決了未花費的輸出佔用存儲空間的問題,並讓使用較大體積腳本的經濟負擔由使用者自己承擔(而不是讓給他們支付的人來承擔)。
不過,這裡還留下了一個問題。定製化的腳本可能包含了多種花費方法,但是,在花費的時候,花費者依然需要揭曉整個腳本,其中也包含了對於驗證本次花費操作有效性無關的腳本分支。因此,定製化腳本的空間效率會隨著腳本的大小而不斷下降,並且讓花費者承擔超出必要水平的代價。
MAST 背後的想法在於,我們可以將一個多分支腳本分拆為單個單個的花費條件,然後用這些花費條件構造出一棵默克爾樹。每個花費條件都會經過哈希,而默克爾樹的樹根就是用戶的地址。在花費的時候,用戶只需提供自己用到的花費條件,以及證明該條件存在於樹上的默克爾證據,然後是滿足這個花費條件的必要數據。
這種默克爾樹構造,不僅解決了 P2SH 嘗試解決的所有問題,還優化了使用者的花費成本(同時提升了他們的隱私性!)。
Taproot 採用了這個概念,並且利用 Schnorr 簽名的線段性、以更加保護隱私的方式集成了這個概念。在人們想要的絕大部分合約中,都有一個樂觀結果,就是所有用戶都對如何分割資金達成了一致。在這種情況下,他們可以直接簽名交易。Taproot 使用 MAST 的根來 “微調” 一個 Schnorr 公鑰,從而產生一個新的公鑰;只需使用同一個 MAST 的根來 “微調” 私鑰,就能得到這個新公鑰的對應私鑰。
這樣一來,用戶既可以使用這個調整後的密鑰直接花費他們的輸出、不留下其中存在一棵 MAST 的任何痕跡;也可以揭曉原本的公鑰、MAST 樹根以及一個存放在樹上的花費條件。此外,如果你完全不希望直接使用調整後的密鑰,還可以使用一個特殊的 NUMS(此中無後門)點作為原始公鑰,這個點是可以證明無法花費的(沒人知道它背後的私鑰),從而只留下 MAST 上的腳本作為有效的花費路徑。
除了利用隔離見證的設計抉擇,Taproot 也引入了 “tapscript”,一種新的腳本編程系統。相比於以前的腳本編程系統,它的主要變化在於:放棄了 OP_CHECKMULTISIG 和 OP_CHECKMULTISIGVERIFY(它們是原本用於驗證多簽名的操作碼),代之以 OP_CHECKSIGADD,它可以更高效地驗證多個簽名。結合 Schnorr 密鑰聚合,這就產生了跟老式腳本一樣的多簽名功能。
此外,tapscript 還將 OP_CHECKSIG 和 OP_CHECKSIGVERIFY 修改成只能驗證 Schnorr 簽名,並加入了 OP_SUCESS 作為對 OP_NOP(老式腳本中的未定義操作碼)的替代。OP_SUCCESS 被設計成允許更加乾淨、更加安全的操作碼升級(相比 OP_NOP)。
見證數據體積限制
行文至此,還有兩個方面沒有得到討論,那就是在隔離見證升級中加入的 “區塊重量(blockweight)” 限制,以及在 Taproot 升級中得以提高的 “見證數據體積限制(witness size limit)”。
這兩個決定,都在生態中的一小群非常活躍的資深用戶那裡引發了爭議。我不會討論區塊體積的增加,這是加入區塊重量限制的一部分,是那時候向持有不同意見的用戶的妥協(他們正在推動一次提高區塊體積限制的硬分叉),而且那時候也被網絡的參與者們認為是安全的;但是見證數據折扣(witness discount)這個機制是重要的。
比特幣交易手續費的橫向比較基於一筆交易所包含的數據量,而與這筆交易轉移的價值多少無關,它完全是由輸入、輸出(以及見證)的數量以及它們的體積(以字節計)決定的。前面我已經提到,在隔離見證升級以前,腳本簽名(或者說簽名和其它數據)是包含在交易的輸出中的。這是一大塊的數據,在輸入中有,在輸出中沒有。
這就意味著,從一筆交易的角度看,輸入比輸出更貴,而且貴上不少。這就產生了一種長期的激勵因素,讓用戶也傾向於花費面額較大的輸出、創造出找零輸出,而不是花費大量積累起來的小面額輸出。也就是說,這是一種長期的經濟激勵,鼓勵用戶持續地讓 UTXO 集膨脹 —— 而存儲 UTXO 集是所有全節點驗證交易和區塊的前提。
見證數據折扣的出發點就糾正這種價格差異,縮小它而不是增大它。為了在經濟上激勵負責任的 UTXO 管理,這是極為重要的,至少在理論上,對於只想使用比特幣協議的經濟理性用戶來說是如此。
Taproot 升級則移除了對一筆交易的見證字段的數據體積限制。在隔離見證升級後,這個限制是 10,000 字節。這樣做是因為,Taproot 的設計已經緩解了構造出難以驗證的交易的可能性,而在 tapscript 中嘗試加入這樣的體積限制,會給 “Miniscript” 帶來大量的複雜性。這個限制所要防止的問題並不影響 Taproot ,而它又會給一個意圖讓定製化腳本更加安全、更平易近人的工具增加複雜性(所以開發者們決定移除它)。
(譯者注:Miniscript 是一種編程語言,可以結構化地組合比特幣腳本的片段,從而讓整個鎖定腳本更容易分析,也更安全。)
全景
這兩項變更,都為拓展比特幣、讓更多人能以自主保管方式使用比特幣,搬開了巨大的路障;但為了做到這一點,它們必然要大量變更協議的基礎部分。
我希望以往不熟悉這些設計抉擇以及背後哲學的讀者,可以理解這些關切,並進一步思考它們的設計方式。比特幣是一個動人心魄的創造,這毫無疑問,但它無法將好處播撒到可觀比例的人群。
隔離見證和 Taproot 奠定了兩個基石,為了解決比特幣的可擴展性短板,它們是絕對必要的。如果沒有這兩項提議(或者解決相同的問題的替代性協議變更),我們今天擁有的所有這些成長中的可擴展性協議和系統都只是夢幻泡影。
Ark、Spark、BitVM、DLC —— 沒有任何一個有可能出現。
這就是全景。今天的比特幣也不是完美的,但它開始有很好的機會擴展到足夠多的人群、對世界產生真實的影響、為嘗試離場的人提供真正的替代方案。這都是因為這兩項協議升級:它們消除了那些根本的障礙。
(完)
腳註
1. https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki ↩
2. https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki ↩
3. https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki ↩
4. https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki ↩
5. https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki ↩
6. https://github.com/siv2r/bip-frost-signing ↩
7. https://github.com/bitcoin/bips/blob/master/bip-0114.mediawiki ↩
8. https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki ↩

