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

本文做者: yaning-u2git

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

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

其中交易包括如下幾種:segmentfault

  • 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中取出本身的資金,而不須要對手方去進行配合。spa

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

clipboard.png

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

因爲 Funding Transaction 的 Output 是一個 2-2 的多籤腳本鎖定,因此咱們能夠先部署一個 2-2 的多籤合約。blog

合約代碼以下:ip

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...

相關文章
相關標籤/搜索