はじめに
今回は翻訳ではなくて実際にWorking with LND and Dockerを実際に試してみた様子をレポート。
Working with LND and Dockerとは
Dockerのコンテナ上でlndとbtcdを動かすチュートリアル的なもの。
BitcoinのテストネットでLightningの動きを確認できるので、Lightning Networkがよくわからないって人はこれを試して見ると実際の動きが見れるのでより理解しやすくなる。
基本的に書いてある通りにコマンド叩いていれば簡単にサクサク進められるのでまず本家を見て見るのをオススメする。
環境
私の環境は以下の通り。
- PC : Macbook Pro
- Docker: 19.03.1
- docker-compose: 1.24.1
githubからソースコードを落として、中のdockerディレクトリに移動したら準備完了
では始めます。
備考: ターミナルを3つ使います。どのターミナルでどのコマンドを打てばいいのかわからなくならないようにaliceのターミナルで打つべきコマンドはalice$
、Bobはbob$
、その他は$
で始まっています。
ライトニングネットワーククラスタを作る
Bitcoin Coreのregtestモードに似たsimnetを使う。
このチュートリアルではシンプルに1つのBitcoinノードを
Bitcoinネットワークとして扱う。実際の環境では
アリスとボブは異なるBitcoinノードに繋がっている。
ワークフロー
- プライベートsimnetで動くbtcdノードを作る。
- シミュレーションネットワークにlndノードとしてのAlice作る
- シミュレーションネットワークにlndノードとしてのBob作る
- Aliceにビットコインを送るためにブロックをマイニングする
- AliceとBobのチャンネルを開設する
- アリスからボブへ送金する
- AliceとBobのチャンネルを閉じる
- オンチェーンでBobのバランスが変わったのを確認する。
以下のコマンドを実行
# ビットコインネットワーク環境を初期化
$ export NETWORK="simnet"
# アリスのコンテナを実行
$ docker-compose run -d --name alice lnd_btc
$ docker exec -i -t alice bash
bash-5.0#
と表示された。
以降、alice$
で始まるコマンドはここに打っていく
# Aliceのp2shアドレスを生成
alice$ lncli --network=simnet newaddress np2wkh
これを打つとP2SH(Pay To Script Hash)アドレスが表示される。Pay To Script Hashってなんぞって人はググってみるといい。
次は別ターミナルを開いて以下を実行。
# btcdノードをもう一度作りマイニングアドレスとしてアリスのアドレスを設定
$ MINING_ADDRESS=<alice_address> docker-compose up -d btcd
<alice_address>
ってとこにはさっき生成したアリスのp2shアドレスを入れる
# ブロックを400生成
$ docker-compose run btcctl generate 400
実行するとズラーッとhashgが配列で帰ってくる。
ブロックの成熟に最低100ブロック必要で、さらにsegwitを有効にするために300以上必要らしい。
segwitってなんぞって人もググってみてください。
# Segwitがアクティブになってるか確認
$ docker-compose run btcctl getblockchaininfo | grep -A 1 segwit
"status":"active"
と返って来るはず。
Aliceのターミナルに移動してBalanceを確認します
alice$ lncli --network=simnet walletbalance
"total_balance"
、 "confirmed_balance"
、"unconfirmed_balance"
が表示される。
ではBobのノードをAliceのノードに繋ぎます。
また新しいターミナルを開いて、
$ docker-compose run -d --name bob lnd_btc
$ docker exec -i -t bob bash
また、bash-5.0#
と表示されます。
以降、bob$
で始まるコマンドはここに打っていく
bob$ lncli --network=simnet get-info
を打つと
{
"identity_pubkey": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38",
"alias": "",
"num_pending_channels": 0,
"num_active_channels": 0,
"num_inactive_channels": 0,
"num_peers": 0,
"block_height": 1215,
"block_hash": "7d0bc86ea4151ed3b5be908ea883d2ac3073263537bcf8ca2dca4bec22e79d50",
"synced_to_chain": true,
"testnet": false
"chains": [
"bitcoin"
]
}
こんな感じのが返って来るはずです。
次にボブのIPアドレスを取得します。
$ docker inspect bob | grep IPAddress
次にアリスのターミナルでBobに接続します。
alice$ lncli --network=simnet connect <bob_pubkey>@<bob_host>
<bob_pubkey>
の所には先ほどgetinfo
したBobの”identity_pubkey”
をいれます。
<bob_host>
の所にはボブのIPアドレスをいれます。
空の中括弧が返ってきます。
アリスのpeerを確認します。
alice$ lncli --network=simnet listpeers
すると、
{
"peers": [
{
"pub_key": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38",
"address": "172.19.0.4:9735",
"bytes_sent": "357",
"bytes_recv": "357",
"sat_sent": "0",
"sat_recv": "0",
"inbound": true,
"ping_time": "0"
}
]
}
みたいなのが返ってきます。
今度はBobのpeerを確認します。
bob$ lncli --network=simnet listpeers
{
"peers": [
{
"pub_key": "03d0cd35b761f789983f3cfe82c68170cd1c3266b39220c24f7dd72ef4be0883eb",
"address": "172.19.0.3:51932",
"bytes_sent": "357",
"bytes_recv": "357",
"sat_sent": "0",
"sat_recv": "0",
"inbound": false,
"ping_time": "0"
}
]
}
が返ってきたでしょうか。
お互いにpeerとして設定されたことがわかります。
次にAliceとBobのチャンネルを作ります。
alice$ lncli --network=simnet openchannel --node_key=<bob_identity_pubkey> --local_amt=1000000
には、Bobの"identity_pubkey"
をいれます。
"funding_txid"が返ってきます。
funding transactionをブロックに入れてチャンネルを開設します。
$ docker-compose run btcctl generate 3
Bobとのチャンネルが開設されているか確認します.
alice$ lncli --network=simnet listchannels
{
"channels": [
{
"active": true,
"remote_pubkey": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38",
"channel_point": "3511ae8a52c97d957eaf65f828504e68d0991f0276adff94c6ba91c7f6cd4275:0",
"chan_id": "1337006139441152",
"capacity": "1005000",
"local_balance": "1000000",
"remote_balance": "0",
"commit_fee": "8688",
"commit_weight": "600",
"fee_per_kw": "12000",
"unsettled_balance": "0",
"total_satoshis_sent": "0",
"total_satoshis_received": "0",
"num_updates": "0",
"pending_htlcs": [
],
"csv_delay": 4
}
]
}
が返ってきます。
次にAliceからBobに送金します。
まずはBob側でinvoiceを発行します。
bob$ lncli --network=simnet addinvoice --amt=10000
{
"r_hash": "<your_random_rhash_here>",
"pay_req": "<encoded_invoice>",
}
が返ってきます。
aliceからボブへ送金を行います。
alice$ lncli --network=simnet sendpayment --pay_req=<encoded_invoice>
<encoded_invoice>
はinvoice発行時のpay_reqの値を入れます。
入力すると送金の確認がされるのでyes
とうつ。
すると送金が完了します。
では、Aliceのチャンネルのbalanceを確認します。
alice$ lncli --network=simnet channelbalance
次に、Bobのチャンネルのbalanceを確認します。
bob$ lncli --network=simnet channelbalance
Aliceのチャンネルポイントの確認をします。
alice$ lncli --network=simnet listchannels
{
"channels": [
{
"active": true,
"remote_pubkey": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38",
"channel_point": "3511ae8a52c97d957eaf65f828504e68d0991f0276adff94c6ba91c7f6cd4275:0",
"chan_id": "1337006139441152",
"capacity": "1005000",
"local_balance": "990000",
"remote_balance": "10000",
"commit_fee": "8688",
"commit_weight": "724",
"fee_per_kw": "12000",
"unsettled_balance": "0",
"total_satoshis_sent": "10000",
"total_satoshis_received": "0",
"num_updates": "2",
"pending_htlcs": [
],
"csv_delay": 4
}
]
}
ここで
ではチャンネルを閉じます。"channel_point"
の値をよく確認してください。:
で区切られているのがわかります。:
の前がfunding_txid
で後ろがoutput_index
です。
alice$ lncli --network=simnet closechannel --funding_txid=<funding_txid> --output_index=<output_index>
とをに先ほどのfunding_txid
とoutput_index
を入れ、入力すると"closing_txid"
が表示されます。
そしてトランザクションを終えます。
$ docker-compose run btcctl generate 3
チャンネルが閉じられました。
AliceとBobのオンチェーンバランスを確認します。
alice$ lncli --network=simnet walletbalance
bob$ lncli --network=simnet walletbalance
するとBobの方で、
{
"total_balance": "10000",
"confirmed_balance": "10000",
"unconfirmed_balance": "0"
}
となっていることが確認できますでしょうか。
Lightning Networkを使った送金に成功したということになります。
faucetのlightningノードを作る
このセクションではBitcoinを送金できるfaucetノードを作って接続します。
構成は以下の通り。

(1)新しく加えたノードをBobに繋げ、 Alice->Faucet->Bobなmultihop paymentを作る
(2)"Faucet", "Alice", "Bob"はビットコインネットワークを元に相互に結びついたチャンネルを持つLightning Network daemonである。
(3)このシナリオでは"Alice"と"Faucet"は異なるBitcoinノードに結びついたLightning Networkである。もし、"Bob"に"Faucet"をしようとしても、btcdはすでにそれを行ってくれている。
ビットコインネットワークの環境変数を"testnet"
に変更してbtcdを起動します。
$ export NETWORK="testnet"
$ docker-compose up -d "btcd"
btcdが同期できたらAliceをFaucetノードに繋ぎます。
FaucetノードのアドレスはFaucet Lightning Community webpageにあります。
Aliceのコンテナを起動。
$ docker-compose up -d "alice"; docker exec -i -t "alice" bash
Aliceを Faucetノードに接続
alice$ lncli --network=simnet connect <faucet_identity_address>@<faucet_host>
接続できたらFaucetノードはチャンネルを開設しアリスにいくらかのBitcoinを送金します。
次にすべきことは?
What you may do next?ということで課題が与えられています。
- いくらかfaucetノードに送金してみる。
- faucetにBobのノードを繋いでmultihop paymentを実装して見る(Alice->Faucet->Bob)
- Faucetチャンネルを閉じてオンチェーンbalanceを確認する。
以上で完了となります。
お疲れ様でした!