如何在 CKB 上實現閃電網絡(一)

本文作者: yaning-u2

閃電網絡主要解決了比特幣的可擴展性問題,閃電網絡可以分爲兩部分:雙向支付通道和通道間支付,本文主要介紹如何在 CKB 上實現雙向支付通道。

雙向通道的主要分爲以下幾個流程:通道建立、餘額更新、通道關閉。

其中交易包括以下幾種:

  • Funding Transaction,用於通道建立。
  • Commit Transaction,用於更新餘額。
  • Exercise Settlement Transaction,用於關閉交易通道。

通道建立

通道建立是通過在鏈上廣播 Funding Transaction 完成,Funding Transaction 是一個 2-2 的簽名交易,爲了方便我們將參與雙方命名爲 Alice 和 Bob。通道建立的步驟如下:

  1. 新建 Funding Transaction
  2. 新建 Commit Transaction
  3. 各自對 Commit Transaction 簽名
  4. 交換 Commit Transaction 簽名
  5. 各自對 Funding Transaction 簽名
  6. 交換 Funding Transaction 簽名
  7. 到鏈上廣播 Funding Transaction

這裏爲什麼要首先構造出 Commit Transaction 呢?因爲如果 Alice 和 Bob 都對 Funding Transaction 簽名後,任何一方都可以將交易廣播到鏈上,但是花費 Funding Transaction 的 Output 需要雙方的簽名,如果任何一方不合作則會導致資金永遠鎖在 Funding Transaction 中,所以這裏首先先構造出可以消費 Funding Transaction 的 First commitment Transaction 再對 Funding Transaction 簽名,這樣任何一方都可以從Funding Transaction中取出自己的資金,而不需要對手方去進行配合。

舉例,Alice 提供一個 300 ckb 的 Input,Bob 提供一個 300 ckb 的 Input,然後 Output 爲600 ckb,鎖定腳本爲 2-2 的多籤腳本,需要 Alice 和 Bob 的簽名才能花費 Output。

clipboard.png

(閃電網絡白皮書中的一張圖,將就看)

由於 Funding Transaction 的 Output 是一個 2-2 的多籤腳本鎖定,所以我們可以先部署一個 2-2 的多籤合約。

合約代碼如下:

https://github.com/u2/lightni...

我們可以看到 CKB 是可以用 C 語言寫合約的。在部署 Funding Transaction 之前,我們可以先部署 2-2 的鎖定腳本,這樣 Funding Transaction 直接引用 2-2 多籤合約即可。這樣如果在 CKB 中有很多雙向支付通道,可以共享一個多籤腳本,而不必每個支付通道單獨在合約中包含多籤合約,減少合約的交易手續費,降低 CKB 的存儲空間的佔用。

閃電網絡實現的一個前提是,必須要解決交易延展性問題,否則交易的Hash是不確定的,可能導致 Funding Transaction 的資金無法解鎖。比如 Alice 和 Bob 構造完成 First commitment Transaction(1a, 1b)並廣播 Signed Funding Transaction,但是這個時候礦工修改了 Signed Funding Transaction 中 Input 的簽名腳本,Funding Transaction 最終上鍊,但是交易 Hash和原來不一致。由於 First commitment Transaction 通過交易 Hash 來引用 Funding Transaction,此時找不到合法的 Funding Transaction,First commitment Transaction 將無法被消費,如果 Alice 或者 Bob 其中的任何一方採取不合作的方式,另一方將無法取出自己的資金。

比特幣通過實現隔離見證解決了交易延展性問題,CKB 也實現了自己的隔離見證。在 CKB 中,用戶只需要選擇將簽名等解鎖參數放入交易中的witnesses中即可:

https://github.com/nervosnetw...

由於交易hash不包括用戶解鎖參數,

https://github.com/nervosnetw...

這樣就可以是交易hash只包含Inputs和Outputs等交易處理的相關信息而不包含解鎖腳本,解決交易延展性問題。

更新餘額

Funding Transaction 被廣播到鏈上之後,雙向支付通道就成功建立了,後續 Alice 和 Bob 就可以構造離線的 Commitment Transaction 來更新雙方的金額了。閃電網絡的每一筆 Commitment Transaction 交易都是建立在 Funding Transaction 之上的。

在構造 Commitment Transaction 時,需要解決以下兩個問題:

  • 追責問題。因爲每筆 Commitment Transaction 都是合法的,而且都是建立在 Funding Transaction 之上。Alice 和 Bob 都各有一份不同 commitment transaction,如果其中任何一方將歷史 commitment transaction 發送到鏈上,可以對其進行罰沒。
  • 罰沒機制。如果任何一方不遵循雙向通道的機制,將歷史交易發送到鏈上,則需要能將其資金進行罰沒。

追責問題。解決追責問題,需要Alice和Bob構造兩個不同的交易,我們可以將這兩個交易分別命名爲 2a,2b。假設最新的餘額爲 Alice 400,Bob 200,commitment transaction 具體的流程如下:

  1. 對於 Alice,其創建新的 Commitment Transaction 結構爲,Output-0 爲 400,花費條件爲 Alice 需要在 10 個高度可以花費或者擁有 Alice2(Alice2 的新私鑰)+ Bob 的簽名可以立即花費。Output-1爲 200,需要 Bob 的簽名可以立刻花費。
  2. 雙方交換籤名。

通過這種機制,可以構造一種交易,Alice 如果廣播其交易 a1 交易,則 Alice 可以在 10 個高度之後花費 Output-0,Bob 可以立刻花費其 Output-1。

在介紹罰沒機制之前,我們先介紹下比特幣中的時間鎖機制。在比特幣中使用 nLocktime 來對交易進行時間限制,使交易必須在某個絕對高度或者時間之後纔可以被記錄到鏈上,CHECKLOCKTIMEVERIFY 指令可以配合 nLockTime 一起使用。交易 Inputs 中的 nSequence 可以用來對相對時間進行限制,是某個 Input 必須在 Output 上鍊一定時間後,其所在交易纔可以被打包,CHECKSEQUENCEVERIFY 可以配合 nSequence 來使用。

在 CKB 中使用 Transaction Valid Since 機制,即可以表示相對時間或者區塊,也可以表示絕對值,所以可以起到 Bitcoin 中的 nSequence 和 nLocktime 作用,設計上更簡潔。由於 CKB VM 可以通過 syscall 獲取到交易 Input 中的 since 值:

https://github.com/nervosnetw...

所以可以在不增加任何指令的情況下實現相對時間鎖的作用。

例如代碼

https://github.com/u2/lightni...

表示取出 Input 中的 since,並判斷其是否是使用相對塊高度,且必須在相對塊高度大於 10 是才驗證通過。這裏保證了交易 Input 在當前條件下,只有在 10 個高度以後,才能被消費。

我們現在回到罰沒機制上來,在上面的基礎上,又加入了 Breach Remedy Transaction 機制,用來防止 Alice 或者 Bob 發送歷史交易到鏈上。這樣從建立通道到更新餘額的完整流程爲:

  1. Alice & Bob 構造完成各自的First commitment Transaction(1a,1b),結構如上所示
  2. 廣播 Funding Transaction 到鏈上。
  3. Alice & Bob 更新餘額,構造各自新的 commitment transaction (2a, 2b),並交換籤名
  4. Alice & Bob 分別向對方揭示 Alice2,Bob2 私鑰(上一個 commitment transaction 中所用解鎖output的私鑰)。

在這種情況下,因爲 Alice 擁有 Bob 的 Bob2 私鑰,而 Bob 擁有 Alice 的 Alice2 私鑰。如果 Alice 廣播歷史交易 a1,其交易 Output-0 可以被 Alice2 + Bob 的簽名理解花費,或者可以被 Alice 在 10 個高度後消費。在這種情況下,因爲 Bob 已經擁有 Alice2 的私鑰,所以 Alice 沒有動機去廣播歷史交易 a1。同理對於 Bob 也適用。我們稱這種 commitment transaction 爲可以撤銷的 commitment transaction(Revocable commitment transaction)。其 commitment transaction 的鎖定腳本可以稱爲 revocable maturity script,代碼:https://github.com/u2/lightni...

Alice 和 Bob 每次更新餘額,都會構造一個新的可以撤銷的 commitment transaction,並向對方揭示自己上一個 commitment transaction 的 output-0 的私鑰,這樣自己的歷史 commitment transaction 不需要保存,只需要保存對方揭示的私鑰即可。雙方都有檢測鏈上對方是否有廣播歷史交易,如果對方有廣播歷史交易,可以使用自己的私鑰和對方揭示的私鑰構造 Breach Remedy Transaction 立即花費對方的 Output,這樣可以將罰沒對方的資金。

clipboard.png

(閃電網絡白皮書中的圖,可以將就看)

關閉通道

Alice 和 Bob 可以選擇合作構造 Exercise Settlement Transaction(ES transaction)來選擇關閉通道。ES transaction 是沒有任何時間鎖的交易,這樣 Alice 和 Bob 可以選擇直接廣播交易來花費 Funding transaciton。

總結

在作者第一次實現的時候,和以上方案略有不同,並沒有 revocable maturity 腳本,而是在構造每個 commitment transaction 時,雙方各自事先構造好其上一個交易的 Breach Remedy Transaction 並互相交換籤名。這種情況下,Alice 和 Bob 不需要生成很多私鑰,但是缺點是 Alice 和 Bob 需要保留歷史的 Breach Remedy Transaction,因爲交易比私鑰更佔空間,相對而言這種方案並不夠合理。

在 CKB 中,實現了隔離見證以及靈活的時間鎖機制,且用戶可以通過提前部署閃電網絡的相關合約,用更低成本來建立雙向支付通道。對實現細節感興趣的讀者可以閱讀下面項目中的代碼。另外 CKB 中可以通過定義 Type Script 而實現 User defined Token 的閃電網絡,這裏不再贅述。

項目地址:https://github.com/u2/lightning

相關文章:《漫談閃電網絡》

比特幣時間鎖機制相關 Bips:

CKB 的時間鎖機制:https://github.com/nervosnetw...

閃電網絡白皮書:https://lightning.network/lig...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章