如何構(gòu)建出LightWork Web應(yīng)用程序
在這一周中,在構(gòu)建LightWork Web應(yīng)用程序的第一個版本時,我遇到了一些架構(gòu)問題,主要與處理ln節(jié)點和我的Web應(yīng)用程序之間的bolt11發(fā)票(core to ln)有關(guān)。在經(jīng)歷了(大部分)這些障礙之后,我想我會寫一些關(guān)于開發(fā)一個由LN驅(qū)動的應(yīng)用程序以及如何減少大家在開發(fā)時遇到的主要障礙。
應(yīng)用程序棧
現(xiàn)在大多數(shù)應(yīng)用程序通常分為兩個主要部分:客戶端和服務(wù)器。例如,客戶端可以是移動應(yīng)用程序或JavaScript SPA,服務(wù)器可以由NodeJS / Go / Rust后端組成,后端主要是基于RESTful或GraphQL的API。
為應(yīng)用程序添加Lightning Network支持,通常會向應(yīng)用程序堆棧引入兩個部分:比特幣節(jié)點和Lightning Network節(jié)點。
對于比特幣,有幾個節(jié)點實現(xiàn)可供使用,其中兩個最廣泛接受的方式是:
· 比特幣核心-比特幣
· BTCD-BTCD
根據(jù)社區(qū)共識、網(wǎng)絡(luò)上活動節(jié)點的數(shù)量以及各自代碼存儲庫的維護統(tǒng)計,很明顯比特幣核心是最廣泛使用和維護更好——也是我們將要使用的方式。
在Lightning Network方面,有(目前)三個兼容的客戶端都遵循相同的BOLT規(guī)范:
1. C-Lightning(用C編寫)
2. LND(用Go編寫)
3. Eclair(用Scala編寫)
你應(yīng)該評估每個客戶端,并決定那個是對你最有意義。我以前曾親自使用過C-Lightning和LND,但也聽說過有關(guān)ECLAir客戶的很多事情。對于lightwork,我決定使用lnd,因為它提供了一個友好易用的grpc/rest api,以及現(xiàn)成的Neutrino light客戶端支持(現(xiàn)在是testnet)。
是時候啟動和運行節(jié)點了。
比特幣核心設(shè)置
當前的比特幣主網(wǎng)區(qū)塊鏈大約有260GB的數(shù)據(jù),挖掘了約55萬個區(qū)塊。由于我們的lnd節(jié)點依賴于訪問底層鏈來打開和關(guān)閉通道事務(wù),因此在本地機器/筆記本電腦上運行一個完整的節(jié)點似乎是一項巨大的任務(wù)。這不僅是1/4TB的數(shù)據(jù),而且完全同步還需要幾個小時(取決于您的連接,可能需要幾天時間)。
比特幣也有一個testnet3網(wǎng)絡(luò),允許開發(fā)者在不影響主網(wǎng)的情況下測試新功能和對協(xié)議的更改。這對于開發(fā)人員在比特幣上構(gòu)建應(yīng)用程序和服務(wù)也很好,因為比特幣能夠使用無價值的TestNet BTC幣測試端到端的流量。測試網(wǎng)的容量較小大約25GB和大約有144000個區(qū)塊。如果您所要做的只是處理與閃電網(wǎng)絡(luò)接口的應(yīng)用程序,那么同步testnet3仍然是一個很大的障礙。這就是為什么比特幣核心給了我們另一個網(wǎng)絡(luò),這一個叫regtest(simnet為btcd用戶)。
RegTest是區(qū)塊鏈的一個測試應(yīng)用版本,考慮到它的唯一目的是允許在協(xié)議上進行更快的開發(fā),作為該節(jié)點的管理員,您可以即時地挖掘任意多個區(qū)塊。我在開發(fā)時使用了我的regtest網(wǎng)絡(luò),只占用了大約37MB容量。這更符合我們想要的。
安裝比特幣核心節(jié)點
以下說明用于在MacOS系統(tǒng)上運行比特幣。
如果您還沒有安裝,請運行以下命令在您的環(huán)境中安裝比特幣核心:
curl -O https://bitcoin.org/bin/bitcoin-core-0.17.0/bitcoin-0.17.0-osx64.tar.gz
如果您熟悉PGP,還建議您檢查發(fā)布的簽名哈希:01EA 5486 DE18 A882 D4C2 6845 90C8 019E 36C2 E964
現(xiàn)在,您可以使用以下方法打開tarball:
tar -zxf bitcoin-0.17.0-osx64.tar.gz
隨后使用以下方法使bitcoind二進制文件可用:
sudo mkdir -p /usr/local/bin
sudo cp bitcoin-0.17.0/bin/bitcoin* /usr/local/bin/
刪除文件,您可以刪除下載的文件夾:
rm -rf bitcoin-0.17.0*
您現(xiàn)在應(yīng)該可以完全訪問計算機上的bitcoind和bitcoin-cli命令。
節(jié)點配置
比特幣核心完整節(jié)點有許多配置選項,因此每次運行二進制文件時,不要在命令行上傳遞所有這些參數(shù),建議您使用bitcoin.conf配置文件。
有關(guān)bitcoind支持的所有命令的列表,請運行bitcoind --help。
下面是一個配置文件示例,其中包含運行regtest節(jié)點(并連接到LND節(jié)點)的(必要)參數(shù):
# Daemon Options
server=1
# Network OpTIons
regtest=1
# RPC OpTIons
rpcport=8332
rpcuser=USERNAME_HERE
rpcpassword=PASSWORD_HERE
# ZMQ OpTIons
zmqpubrawblock=tcp://127.0.0.1:28332
zmqpubrawtx=tcp://127.0.0.1:28333
為了簡單起見,您可以在完整節(jié)點在系統(tǒng)中創(chuàng)建的主比特幣文件夾中創(chuàng)建bitcoin.conf文件。在macOS系統(tǒng)中,該文件夾位于?/ Library / ApplicaTIon Support / Bitcoin。
記下您選擇的RPC用戶名和密碼,因為我們在LND節(jié)點配置期間需要它。
然后,您可以運行以下步驟進入同一個Bitcoin目錄,并使用新創(chuàng)建的配置文件啟動節(jié)點守護程序:
cd ~/Library/Application Support/Bitcoin
bitcoind -datadir=。/ -conf=。/bitcoin.conf
您應(yīng)該看到類似于的輸出:
在單獨的終端窗口中,您可以運行bitcoin-cli getblockchaininfo,您將看到來自regtest比特幣鏈的最新數(shù)據(jù)集,包括當前塊高度,難度級別和磁盤大小。有關(guān)bitcoin-cli命令的完整列表,請運行bitcoin-cli --help。
當您第一次運行bitcoind時,它會自動為您創(chuàng)建一個錢包。所以在這一點上,任何通過采礦獎勵獲得的BTC都將被發(fā)送到這個錢包。為了挖掘regtest塊,只需運行bitcoin-cli就可以生成100,其中100是要挖掘的區(qū)塊數(shù)。如果您運行bitcoin-cli getwalletinfo,您現(xiàn)在將擁有“余額”下的值。這些是regtest BTC硬幣,非常適合測試Lightning Network應(yīng)用程序?,F(xiàn)在我們已經(jīng)運行了比特幣核心守護程序并且我們知道如何挖掘regtest塊,現(xiàn)在是時候設(shè)置我們的LND節(jié)點了。
LND節(jié)點設(shè)置
要連接到閃電網(wǎng)絡(luò),您只需要一個連接到底層鏈的LND節(jié)點。但是為了可以向網(wǎng)絡(luò)周圍發(fā)送資金,您必須有另一個節(jié)點發(fā)送到或請求。一種方法是將具有不同比特幣核心和LND節(jié)點的多個VPS盒旋轉(zhuǎn)起來,然后在兩個VPS盒之間打開通道。另一個更簡單的方法是讓多個LND實例在您的機器上運行,連接到一個您完全控制的比特幣regtest節(jié)點。用戶可以在單個環(huán)境中運行他們想要的多個LND節(jié)點,只有三個要求:
每個節(jié)點都必須有自己的專用數(shù)據(jù)目錄
每個節(jié)點都必須有自己的gRPC / REST端口
每個節(jié)點必須有自己的一組TLS證書和管理Macaroon
LND創(chuàng)建在啟動時運行節(jié)點所需的所有必要數(shù)據(jù)文件,包括身份驗證macaroon文件??紤]到這一點,在啟動第一個節(jié)點后,您可以簡單地克隆它(并刪除身份驗證macaroons / TLS證書,以便在初始化第二個節(jié)點時重新創(chuàng)建它們)。對于macOS用戶,默認的LND文件夾位于?/ Library / Application Support / Lnd(NODE A),因此我將其克隆到?/ Library / Application Support / Lnd Test(NODE B)中。
節(jié)點配置
與比特幣核心類似,LND節(jié)點接收稱為lnd.conf的配置文件。為了運行兩個節(jié)點,我們需要兩個文件,放在每個相應(yīng)的數(shù)據(jù)目錄中,配置節(jié)點以連接到正確的bitcoind實例。
NODE A將在默認數(shù)據(jù)目錄和默認設(shè)置(RPC / REST / gRPC端口)上運行。我們將使用以下conf文件:
# LND Settings
debuglevel=debug
debughtlc=true
alias=YOUR_NODE_NAME
maxpendingchannels=10
color=#eeeeee
rpclisten=0.0.0.0:10009
restlisten=0.0.0.0:8080
listen=9735
externalip=127.0.0.1:9735
datadir=。/
datatlscertpath=。/tls.cert
tlskeypath=。/tls.key
adminmacaroonpath=。/data/chain/regtest/admin.macaroon
# Bitcoin
bitcoin.active=1
bitcoin.regtest=1
bitcoin.node=bitcoind
# Bitcoind
bitcoind.rpcuser=USERNAME_HERE
bitcoind.rpcpass=PASSWORD_HERE
bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332
bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333
請注意,ZMQ選項和RPC用戶名和密碼必須與先前配置的bitcoind.conf設(shè)置匹配。
除連接端口外,NODE B將具有基本相同的配置設(shè)置。更具體地說,rpclisten,restlisten,listen和externalip屬性都接收新端口。
# LND Settings
debuglevel=debug
debughtlc=true
alias=YOUR_NODE_NAME
maxpendingchannels=10
color=#eeeeee
rpclisten=0.0.0.0:10008
restlisten=0.0.0.0:8090
listen=9736
externalip=127.0.0.1:9736
datadir=。/
datatlscertpath=。/tls.cert
tlskeypath=。/tls.key
adminmacaroonpath=。/data/chain/regtest/admin.macaroon
# Bitcoin
bitcoin.active=1
bitcoin.regtest=1
bitcoin.node=bitcoind
# Bitcoind
bitcoind.rpcuser=USERNAME_HERE
bitcoind.rpcpass=PASSWORD_HERE
bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332
bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333
此時,我們有兩個LND節(jié)點在不同的數(shù)據(jù)目錄上運行,具有自己的一組TLS證書和身份驗證宏,并在不同的端口上運行。是時候啟動網(wǎng)絡(luò)了。在兩個單獨的終端shell中,使用以下命令啟動NODE A和NODE B:
lnd --configfile=。/lnd.conf
在另外兩個shell中,使用lncli工具向您的節(jié)點發(fā)送命令。運行以下命令以創(chuàng)建錢包。對于NODE A,我們只需要運行create命令,如下所示:
lncli --network=regtest create
對于NODE B,我們必須傳遞更多屬性:
lncli --network=regtest --rpcserver=localhost:10008 --lnddir=。/ --tlscertpath=。/tls.cert create
添加的屬性是為了確保第二個lncli調(diào)用與在端口10008上運行的NODE B通信。運行錢包創(chuàng)建過程并為每個錢包創(chuàng)建自己的密碼。
請注意,一旦您創(chuàng)建了錢包,您只需運行unlock命令即可開始工作。
LND節(jié)點實際上做了很多,并且要了解它的所有功能,請轉(zhuǎn)到LND的文檔或運行l(wèi)ncli --help來查看幾個命令。一些更廣泛使用的是:
# Wallet balance, in Satoshis
lncli walletbalance
# Balance of all channels combined, in Satoshis
lncli channelbalance
# Generate Invoice
lncli addinvoice --amt=1000 --memo=testing
# Pay Invoice
lncli payinvoice lnbcrt10u1pdlyp6fpp50xvlxjg.。.
# Connect to specific node URI
lncli connect 03fbe39af6166273.。.@127.0.0.1:9735
# Open channel with to specific node
lncli openchannel 03fbe39af6166273.。.1af2 100000
我們將使用這些命令中的每一個在我們的兩個節(jié)點之間發(fā)送LN發(fā)票,但在我們這樣做之前,我們需要在我們的一個錢包中使用一些實際的regtest BTC。
將regtest BTC從比特幣核心發(fā)送到LND節(jié)點
您可以使用bitcoin-cli工具將已開采的regtest BTC發(fā)送到NODE A.首先從NODE A內(nèi)部生成一個新地址:
lncli --network=regtest newaddress np2wkh
然后轉(zhuǎn)到比特幣核心并將一些regtest BTC發(fā)送到該地址。確保生成幾個區(qū)塊以進行挖掘并確認交易。
# Send 250 BTC to the LND Address
bitcoin-cli sendtoaddress 2MuKLyJQn2UQ2BaVotWpCKAfXpkrsa96eL7 250
# Mine Blocks
bitcoin-cli generate 10
現(xiàn)在回到NODE A,我們可以獲得我們的錢包余額,并看到我們的BTC已正確轉(zhuǎn)移。
在兩個lnd節(jié)點之間打開通道
既然我們在NODE A內(nèi)有了BTC,我們就可以讓NODE B為節(jié)點A創(chuàng)建一些付款請求。作為Lightning網(wǎng)絡(luò)規(guī)范的一部分,如果節(jié)點想發(fā)送和接收Satoshis,則需要與其他節(jié)點打開通道(通過其他間接節(jié)點路由發(fā)票為C我們可以在真實的網(wǎng)絡(luò)場景中使用,而不是在我們的兩節(jié)點lnd regtest網(wǎng)絡(luò)中)。
要連接兩個節(jié)點,您需要獲取節(jié)點的公共URI。在NODE B上,運行以下命令:
lncli --network=regtest --rpcserver=localhost:10008 --lnddir=。/
--tlscertpath=。/tls.cert getinfo
突出顯示的部分是我們需要用來連接到此節(jié)點的URI。如果您沒有看到列出的URI,可能是因為您沒有在LND配置文件上設(shè)置externalip屬性。
要在節(jié)點之間打開通道,首先我們需要連接它們。使用NODE B的URI在NODE A上運行以下命令。
lncli --network=regtest connect 0394ed661ff.。.92f446@127.0.0.1:9736
我們?nèi)匀粵]有開通任何渠道,因此即使我們嘗試支付發(fā)票,我們也會遇到路由問題:
作為開通渠道的一部分,LND將在鏈上創(chuàng)建一個資金交易,設(shè)置一定數(shù)量的satoshis來鎖定這個新創(chuàng)建的頻道。
lncli --network=regtest openchannel NODE_PUB_KEY amount
要使資金交易有效,您需要運行比特幣-cli生成10才能在比特幣核心中挖掘更多的區(qū)塊。此時,您可以在NODE A中運行l(wèi)istchannels以查看兩個節(jié)點之間打開的通道:
lncli --network=regtest listchannels
處理發(fā)票(BOLT11付款請求)
既然NODE A已經(jīng)獲得了一些regtest BTC的資助,并且我們在兩個節(jié)點之間有一個活躍的開放通道,我們可以創(chuàng)建一個發(fā)票來處理一些BTC。
發(fā)票是任何Lightning Network交易的核心。要了解有關(guān)LN發(fā)票(付款請求)和BOLT11規(guī)范的更多信息,請閱讀我的其他文章。
從NODE B,生成300 satoshis的發(fā)票,其中包含‘測試’的說明:
lncli --network=regtest --rpcserver=localhost:10008 --lnddir=。/
--tlscertpath=。/tls.cert addinvoice --amt=300 --memo=testing
突出顯示的部分是BOLT11付款請求哈希。要了解有關(guān)此發(fā)票的更多信息以及我們可以從中解碼的數(shù)據(jù)類型,請轉(zhuǎn)到Lightning Decoder并粘貼您的發(fā)票。
從NODE A,我們可以支付這個新創(chuàng)建的發(fā)票,并通過我們剛剛打開的通道通過Lightning Network路由付款。
lncli --network=regtest payinvoice lnbcrt3u1pdlygj221k0x.。.c0h503tpr
NODE B現(xiàn)在應(yīng)該在通道的一側(cè)列出300個satoshis。我們可以使用channelbalance命令檢查它。
lncli --network=regtest --rpcserver=localhost:10008 --lnddir=。/
--tlscertpath=。/tls.cert channelbalance
瞧,我們的300個satoshis已被轉(zhuǎn)移。
您已成功連接在同一regtest BTC網(wǎng)絡(luò)上運行的兩個LND節(jié)點,在它們之間打開了一個通道,并通過支付BOLT11發(fā)票來交易BTC。通過此設(shè)置,您可以通過這兩個LND節(jié)點創(chuàng)建無限的實際付款方案。這樣可以更輕松地對Lightning網(wǎng)絡(luò)驅(qū)動的應(yīng)用程序的后端服務(wù)器邏輯進行測試,迭代和故障排除。
現(xiàn)在,要與應(yīng)用程序內(nèi)的節(jié)點連接,請查看LND的gPRC或RESTful API。您還可以利用Alex Bosworth的抽象層,例如LN Service,它可以提供更友好的API。
LNET
在開發(fā)LN應(yīng)用程序時,通常遵循regtest→testnet→mainnet方法,但根據(jù)您的應(yīng)用程序大小和要求,添加額外步驟可能是有意義的。
在2018年Chaincode Lightning Residency的最后一天,來自Blockstream的Christian Decker演示了lnet。 lnet背后的目標是簡化初始化LN網(wǎng)絡(luò)拓撲以進行應(yīng)用程序測試的過程。您需要做的就是以graphviz點格式描述網(wǎng)絡(luò),lnet將負責其余部分。這個庫是基于C-Lightning而不是LND構(gòu)建的,并沒有(但是?)提供與旋轉(zhuǎn)您自己的節(jié)點一樣多的控制、定制和配置—但它確實有助于使用許多節(jié)點進行測試。
結(jié)論
我將繼續(xù)分享這些筆記,因為我將繼續(xù)開發(fā)LightWork并進一步了解Lightning Network。在下一篇文章中,我希望詳細介紹用于構(gòu)建LightWork對分期付款和提款的支持的實際代碼片段/實現(xiàn)——真實世界的源代碼比1000個單詞更有價值。