1. 程式人生 > >比特幣閃電網路(Lighting Network)入門

比特幣閃電網路(Lighting Network)入門

比特幣閃電網路

什麼是支付隧道(Payment channels)

支付隧道是用於在無信任環境中進行鏈下交易比特幣的一種機制。交易雙方通過廣播並鎖定一筆由雙方共同簽名的鏈上交易。隧道(channel)只是一種虛擬的比喻,一個隧道由一個在鏈上的(on-chain)的funding transaction、一系列的鏈下(off-chain)的commitment transaction和最後一筆鏈上交易組成。因為絕大部分的交易都是在鏈下發生,所以就沒有了像比特幣一樣的交易速度的限制,極大的提高了交易的速度。

最簡單的單向支付隧道

比如一個視訊點播app,使用者(記作A)每播放1秒鐘視訊需要支付0.1個比特幣給app開發者(記作B),在app介面上提供了一個基於使用者和app開發者雙重簽名的地址,使用者向該地址傳送了360個比特幣作為該支付隧道的funding transaction

,這筆雙重交易的輸出初始狀態是t0(A:360, B:0),隨著視訊的播放,雙方每隔一秒鐘就會有一筆新的commitment transaction生產,t1(A:359.9, B:0.1), t2(A:359.8, B:0.2)···,這些承諾交易都是不廣播到鏈上的,終端使用者點選了停止播放按鈕,最後一筆交易的狀態可能是tn(A:100,B:260),最後一筆交易就廣播到了鏈上。整個交易完成,並且只在鏈上產生了兩筆交易。

這個簡單的單向支付隧道有兩個明顯的漏洞:

  • A傳送第一筆資金交易後,B直接消失,那A永遠也拿不回自己錢了。
  • A可以拿被B簽名過後的任何一筆commitment transaction進行廣播,從而減少自己費用。

這兩個問題可以通過加一個timelock來解決

加了時間鎖的單向支付隧道

在A發起funding transaction之前,A先讓B簽名一份有timelockrefund transaction,交易的輸出的高度為當前的區塊高度+3000。然後才開始接下來的funding transaction流程,如果B消失了,A可以通過refund transaction等待(3000個塊)拿回自己的錢。接下來的每一次commitment transaction都帶著時間鎖,從refund transaction設定的區塊高度遞減,比如T+3000, T+2999, T+2000, T+1500。這樣每一次簽署最新的commitment transaction

就相當於撤銷了之前的交易(因為時間離T較近,可以優先廣播出去)。這也就解決了上面說的A可以拿之前的一筆commitment transaction進行廣播,然而B看到A廣播了之前的區塊,就可以拿時間較新的交易進行廣播,從而讓A的廣播的交易失效。

簡單的加了time lock的單向支付隧道雖然解決了上面兩個問題,但還有幾個問題沒有解決:

  • 如果B故意消失的話,A只能等到3000個區塊後才能拿回自己的錢
  • 因為添加了time lock,隧道的生命週期有了限制。
  • 因為每一筆交易都是通過遞減時間鎖進行的,所以commitment transaction筆數有了限制。

為了解決這三個問題,接下來要引入叫Asymmetric Revocable Commitments

Asymmetric Revocable Commitments

和前面一樣,我們先在鏈上廣播一筆由雙方簽名的funding transacion,但接下來的commitment transaction和前面的不同,A和B雙方各自生成一個commitment transaction,像下面這樣:

A的commitment transaction:

Input: 2-of-2 funding output, signed by B

Output 0 <5 bitcoin>:
    <B's Public Key> CHECKSIG

Output 1 <5 bitcoin>:
    <1000 blocks>
    CHECKSEQUENCEVERIFY
    DROP
    <A's Public Key> CHECKSIG

B的commitment transaction:

Input: 2-of-2 funding output, signed by A

Output 0 <5 bitcoin>:
    <A's Public Key> CHECKSIG

Output 1 <5 bitcoin>:
    <1000 blocks>
    CHECKSEQUENCEVERIFY
    DROP
    <B's Public Key> CHECKSIG

因為雙方都簽名的交易可以馬上拿回自己的幣,而對方得等待1000個區塊後才能拿回自己的幣。所以雙方都很願意對交易進行簽名。接下來要加入一個新的元素:Revocation Public Key每次發起commitment transaction前雙方都會各自獨立生成該密碼的一半,把這個Key用在上面的第二個output上,變成這樣:

A的commitment transaction:

Input: 2-of-2 funding output, signed by B

Output 0 <5 bitcoin>:
    <B's Public Key> CHECKSIG

Output 1 <5 bitcoin>:
IF
    # Revocation pernalty output
    <Revocation Public Key>
ELSE
    <1000 blocks>
    CHECKSEQUENCEVERIFY
    DROP
    <A's Public Key> CHECKSIG
ENDIF
CHECKSIG

B的commitment transaction:

Input: 2-of-2 funding output, signed by A

Output 0 <5 bitcoin>:
    <A's Public Key> CHECKSIG

Output 1 <5 bitcoin>:
IF
    # Revocation pernalty output
    <Revocation Public Key>
ELSE
    <1000 blocks>
    CHECKSEQUENCEVERIFY
    DROP
    <B's Public Key> CHECKSIG
ENDIF
CHECKSIG

有了Revocation key,在每次提議commitment transaction前都會交換前面一個commitment transactionRevocation public key,如果一方發現對方廣播了前面的一筆commitment transaction就可以使用完整的Revocation Key拿到全部的幣。通過使用了相對的time lock就可以極大提高單個隧道里面的commitment transaction

Hash Time Lock Contracts(HTLC)

HTLC是一種智慧合約,它想到達到的效果就是由交易的接受人提供一個Hash過的金鑰R作為output的的條件之一,如果誰能出示金鑰R,就能獲得這個交易的output的幣。類似這樣的輸出:

IF
    # Payment if you have the secret R
    HASH160 <H> EQUALVERIFY
ELSE
    # Refund after timeout.
    <locktime> CHECKLOCKTIMEVERIFY DROP
    <Payer Public Key> CHECKSIG
ENDIF

路由的支付隧道(Lighting Network)

在HTLC的機制基礎上我們可以實現一個簡單的閃電網路,在雙方沒有建立支付隧道的情況下完成一筆交易。例子如下圖: routed_payment_channelAlice想向Eric轉賬1BTC, 因為Alice並沒有直接跟Eric建立隧道,他只知道Bob,所以他向Bob發起了一筆commitment transaction,一共1.003BTC,output指向持有Eric提供的金鑰R的收款人。因為Bob並沒有金鑰R,所以他轉而向跟他建立隧道的Carol發起一筆commitment transaction,一共1.002BTC,這樣如果Carol能向他提供金鑰R的話,他轉可以獲得1.003-1.002=0.001個BTC, 因為Carol也沒有金鑰R,所以他向Diana發起另外一筆1.001BTC的commitment transaction,期望Diana能給他金鑰R,最後到達了Eirc,他提供了金鑰R,因此所有人都獲得了對應的commitment transaciont,交易完成。這就是最簡單的閃電網路。