作者:AdamISZ
來源:https://reyify.com/blog/lightning-unchained/
原文發表於 2025 年 2 月。
閃電網絡有一個問題,在工程師之間算得上人盡皆知,但可能用戶和錢包開發者們很少思考過(沒準大家都想過,真希望我是錯的!),那就是,閃電網絡的用戶不得不公開自己用來開設通道的 UTXO 。設想如果可以不這樣做,作為一名用戶,你的隱私性可以好多少。
閃電網絡的鏈上軟肋
為了解釋清楚,我要先岔開以下話題,還要介紹閃電網絡工作原理的一個重要方面。就從一個叫做 short-channel-id(通道短 ID)的東西開始。
“通道短 ID” 是編碼了一個 UTXO 的 8 字節字符串。在比特幣協議內,一個 UTXO 可以用一個元組 (outpoint, index) 來指代,其中的 “輸出點(outpoint)” 是創造這個 UTXO 的交易的標識符(txid),而 “索引號(index)” 則是這個 UTXO 在該交易的輸出中的位置。這種方法雖然不會產生歧義,卻使用了 36 個字節(32 + 4 ;雖然用 4 個字節來表示一個索引號有點大材小用,但木已成舟)。稍後我們會明白,閃電網絡協議的設計者們專門創建了一種更高效的編碼方式(只使用 8 個字節,不需要 36 個字節)。要是你想知道為什麼只需要 8 個字節,就想想,為了指明一個 UTXO ,你只需要指明哪些東西:一個(它在其中創建出來的)區塊號、一個交易編號(因為區塊包含的是 有序的 交易列表),最後是這個交易的一個輸出。這三個整數,每一個都有最大數值,所以你可以對每一個整數使用合理的編碼(分別用到 3 個、3 個、2 個字節)。
這樣做有啥意思呢?來,我們再回想一下。“閃電網絡”,我常常說,有兩部分。第一部分是 “閃電(通道)”,意味著兩方之間的 Poon-Dryja 式支付通道;第二部分是 “網絡”,意味著在多條首尾連接的通道(貨幣通路)中強制執行的哈希時間鎖合約(HTLC)。這裡的第二部分 —— “網絡” —— 就是關鍵。為了構造通路,你需要先知道這些通道存在(甚至還有更難的,你必須知道或者猜測這些通道內、在你需要的方向上,有多少餘額可用!)。為 此 ,你必須讓別人告訴你它們存在。這就是為什麼我們要有 “閃電網絡 gossip 協議”,這些消息中的絕大部分,都是在告訴對等節點:某些通道存在。
那麼問題來了:在一個互不信任的環境中,人們可能會說謊 —— 我完全可以胡說八道嘛。我發現了 10000 條通道,每條通道都有 1 BTC 的容量,這裡是一份完整的名單,你自個兒找去吧 …… 這完全可以用來浪費你的時間、讓你的 CPU 做無用功;而且,最後,你可能會得到一個全然無用的通道圖景,每當你對照這個圖來嘗試在 “網絡” 中轉發金錢,結果總是失敗。
所以,我們用上了通道短 ID;如前所述,它是 UTXO 的緊湊表示方式。UTXO 並不能免費創建,雖然創建一個是非常便宜的(在區塊鏈內手續費率極低的時候,只需要 1 ~ 2 聰/vB 的費率就能發送交易、創建 UTXO,按照今天的匯率,大概是 10 ~ 30 美分),但代價會隨著創建的數量線性增長;而且,如果你想要 很快地 創造出 10 萬個 UTXO,代價甚至可能是無窮大的。
我認為,這是一個鮮有人討論、但非常重要的點:由比特幣的極高哈希率,為 UTXO 的創生速度(每秒可創造的 UTXO 輸出)帶來的天然剎車,讓 UTXO 的創造成本不僅不是線性的,還幾乎有個爆炸點(singularity) —— 這正是你在搭建公開服務時所需要的良好抗 DoS 措施.
現在可以回答問題了:需要緊湊地編碼 UTXO, 是因為這些編碼需要廣播。如果有 1 萬條甚至 10 萬條通道,那就有一大堆需要傳播的 UTXO 數據,要是每一個都需要 36 字節,那情形就會比現狀(使用通道短 ID )糟糕得多。
問題的細節
問題用一個詞就能說清楚:隱私型。向整個網絡宣佈你持有哪些 UTXO,就意味著向全世界宣佈 —— 尤其是,你通過一個公開的、明文的 IPv4/6 網絡地址來發送宣佈消息(許多 “嚴肅的” 節點都這麼幹哦);這簡直是邀請間諜來分析你在區塊鏈內的活動。這可能不會變成商業風險,但 絕對 是一種安全風險。這些信息可以跟其它信息交叉關聯起來,比如,連接到你的 IP 地址、開始打探你是誰、你住在哪裡、你持有多少比特幣,等等。
基本上,這就是 P2P 網絡典型衝突的又一次顯現。什麼 “典型衝突”?很簡單:
在開放的點對點網絡中,保護資源要求我們抵禦分身攻擊(Sybil attacks),這跟用戶希望匿名的安全性要求相沖突
(譯者注:“Sybil attacks” 指的是攻擊者可以輕易偽造出許多身份來消耗受害者的資源;舊譯為直譯 “女巫攻擊”。)
如果說這種 “典型衝突” 有什麼 “典型解決方案”,從我的角度看,那就是要求用戶使用一種稀缺資源來參與點對點網絡。(另一種 “解決方案” 是強制要求非匿名性,但這是一種脆弱的方法,時間一長總會失敗。 —— 這是我個人的觀點,但正因為純粹是個人觀點,所以但說無妨。)
這種衝突和解決,在最近 Tor 洋蔥網絡的服務故障中也上演了 —— 分身消耗了大量資源,而解決方法是工作量證明。基於計算循環的工作量證明是不是真的能解決這個問題,我改天再討論,因為我想回到閃電網絡 gossip 的問題!
好了,通道短 ID 會直接揭曉 UTXO 。我們已經知道這是壞事了。那我們能做什麼呢?至少我們可以嘗試這樣做:
我有一條通道。我準備證明,我用來開啟通道的 UTXO 的價值是 X 聰(或者至少有 X 聰),但我一點也不想告訴你們哪一條擁有這麼多聰的通道是我的。
這個想法,首先,很吸引人,但聽起來也瘋瘋癲癲的 —— 如果你不是 “零知識證明(ZKP)” 的愛好者的話。在深入瞭解 ZKP 之前,我們先要解決一個非常討巧的邏輯問題:
一個 UTXO 是否真的被用來開啟一條通道,這個事實會是一個公開知識嗎?在當前使用 P2WSH 輸出來開啟通道的情形中,從技術上來說,即使到關閉的時候,也不會揭曉這樣的事實,儘管有明顯的信號(閃電網絡的工程師們請大膽糾正我)。至於 taproot 通道,至少在 MuSig2 發展起來之後,我們可以指望或者說預期,通道們將永遠不會暴露它們是 2-2 多簽名的,更不用說它是一條通道了。提醒一下,這場討論是關於施加成本來防止 DOS 攻擊的,所以我要斷言,嘗試證明 “這是一條通道” 是一個錯誤的方向。只需證明 UTXO 所有權就夠了。
(不同意?沒問題,我們想得再仔細一些。我聲稱存在一條通道,我公開它(或者說 gossip 它)。為了支持我的聲明,我給出一個通道短 ID;這個通道短 ID 指向區塊鏈內的一個真實的 UTXO ,但你怎麼知道這個 UTXO 真的指向一條通道呢?如果我就是要說謊,我只需要讓這個 UTXO “看起來像是一條通道”。如我們前面所說的,在有些情況下,所有的 UTXO 看起來都會像通道(使用 taproot 輸出、MuSig2 得到廣泛採用)。甚至,作為一個攻擊者,我可以 真的製作出一條真實的通道,然後讓它完全不工作而不違反協議要求。在 gossip 消息中使用通道短 ID 來 “證明一條通道” 的最終意義,只是 “證明我創造了一個 UTXO”。)
但我們還可以討論得更細一些。你想要讓誰承擔代價、讓什麼樣的行為承擔代價?在這篇舊文章中,Rusty Russel 提議在節點層面施加成本,而不是在通道層面。不論其中的技術難度(對此我可以說幾乎一無所知),我同意這種視角的主要原因在於,解除代價與對你有益的資源的關聯,可以進一步提高各通道的實際隱私性(例如,假設你創建了一條容量非常大的通道,然後立即發佈一個零知識證據來證明它存在,而這個證據意味著 “我證明我擁有一條通道,它的容量至少是 2 BTC”,可是剛好就有一個價值 2.2 BTC 的 UTXO 出現在鏈上;這只是一個例子,你應該能理解我的意思)。
但是這還不是故事的結局:“到底是,還是不是通道 UTXO?” 想必你可以在本博客的評論區瞭解更多。
好,我承認你說的它的用處,但這能夠實現嗎?用 ZKP 之類的東西?
所以,到底有沒有可能呢?總結上文,我們要證明的是:
當前存在的、面額在一定範圍內的 UTXO 中,有一個是我的;我們可以假設是 taproot 通道,但並不限制 “通道的類型”(理想情況下你甚至不會知道它的類型);但我不會告訴你到底是哪一個
可是在合理的數值範圍,可能有幾十萬到幾千萬個 UTXO 。這能做到嗎?顯然不是那麼簡單。
我研究這個問題 3 年了,反反覆覆(雖然,我要澄清,我並不是只關注閃電網絡,我關注的是廣義的隱私型抗分身方案)。最早,我關注的是 “環簽名(ring signatures)”,我意識到, 這樣的構造存在,但(證據的) 體積 可能是 O(log N)(以字節計)。問題在於,證據的驗證和計算時間都是 O(N) 。Bulletproofs 也有這個問題。沒有這個問題是默克爾樹 —— 這是 Andrew Poelstra 給我的一個洞見 —— 默克爾證據的驗證時間是 O(log N) ;大約是同一時間(2022),“曲線樹(Curve Trees)” 出現了,它實現了兩者的組合:你可以使用 bulletproofs 來生成緊湊的證據,然後用一種代數版本的默克爾樹(使用極其特殊的 secp-secq 曲線循環)來實現驗證的對數擴容。務實的結果是,對於 100 萬個 UTXO 所組成的集合,你可以在 50 到 100 毫秒內驗證證據(使用我的代碼就可以做到,而且應該能做得更好!),可以用 1 ~ 2 秒來生成一個證據,證據的體積在 2 到 3 kB 之間。再提醒一次,這些證據證明的是 “我持有這 100 萬個 UTXO 的其中之一,但我不會告訴你到底是哪一個 ”。要了解同一想法的一個更加完備的版本,可見 FCMP++ 項目,雖然那是 Monero 區塊鏈上的。
最近,J T Halseth 發佈了 output-zero ,它是解決同一個問題的迥然有別的辦法。它用到了另一種 ZKP,具體來說是 zkSTARKs,不是 Bulletproofs(實現的細節見 risc0),然後使用了一個 Groth16 封裝器來創造緊湊的證據。
如果你感興趣,我強烈建議你看看 Delving Bitcoin 論壇上關於他的 項目/想法 的討論。
我目前的總結如下(不確定是否準確):output-zero 的主要優勢在於,它產生的證據的大小是 O(1) 級別(也即是恆定的)(得益於 Groth16),我記得大概是 260 字節。這顯然比我的方法(證據體積在 3kB 左右)要好得多。但另一方面,從我自己測試它的結果(在此處)以及作者提供的概述來看,我並不相信它的證據生成時間是可以接受的。作者的論證是這樣的:路由節點的設備通常配置很高,而且,更重要的是,證明並不是一個實時的操作,所以哪怕花上幾分鐘也無妨(似乎如果有 GPU 加速的話,那會快得多,但也許是我太老派了,我不覺得這種優勢應該考慮在內(為什麼呢?));至於驗證,兩種 ZKP 都要花上 50 到 200 毫秒。我懷疑在實踐中,超過 10 秒的證據生成時間,就已經有點 “落伍” 了。也許我是錯的。
但最後我要說,我認為這裡最吸引人的地方在於,對於這些零知識證據應不應該跟具體的 通道 UTXO 相綁定,人們有不同的意見。如果你讀了上面的 Delving Bitcoin 論壇上的討論,你會發現我在這一點上也搖擺不定。我認為,不要嘗試使用通道 UTXO,對隱私性會好得多;但是,從另一個角度看,為什麼你想要使用並非通道的 UTXO 呢(你本來就已經給通道投入了流動性,為什麼不使用它)?此外,如果你想在 ZKP 中使用通道 UTXO,那麼你 應該/必須 支持這個證據要從 MuSig2 UTXO 中生成出來,這不僅要在 ZKP 的設計中考慮到(顯然,如果 UTXO 不是隻有一個主人的話,會更加棘手),還會引發一個問題:誰 可以/應該 使用這個 ZKP 作為一個資源憑證呢?關於這裡的 ZKP 會如何受到影響,僅舉一例,請看 output-zero 當前的設計,使用
hash(bitcoin-pubkey-1||bitcoin-pubkey-2)作為它的 “密鑰鏡像”(用來防止你一遍又一遍重複使用同一個 UTXO 的東西,迥異於常見設計: “密鑰鏡像是私鑰的不可反算的哈希值”)。我知道這對大多數讀者來說過於苛求了,但只是為了演示其中的不確定性。
(完)

