Lightning Network Daemon(Lnd)で遊んでみた ~Tutorial編(Stage1)~

はじめに
今回は[LND Developer Site](https://dev.lightning.community/)の[Stage1](https://dev.lightning.community/tutorial/01-lncli/index.html)をやってみる。
特に詰まることもないので今回はさっくりすすめる。
このチュートリアルを進めていてよく遭遇するエラーを下にまとめているのでそちらも参考に.
[LND Developer SiteのTutorialでよく起こるエラー](https://qiita.com/wokashi_/items/566bbf01b6d01cb870a1)


備考：`alice $` `bob $` `charlie $`と書いてあるのはそれぞれ`aliceのターミナルで`、`bobのターミナルで`、`charlieのターミナルで`コマンドを入力する、という意味なので、`alice $`の部分は省略して入力してください。

# 環境
PC: Thikpad X1 Carbon
OS: Ubuntu 18.04 LTS

#セットアップ
ターミナルをひらいて以下のコマンドを入力。

```
btcd --txindex --simnet --rpcuser=kek --rpcpass=kek
```

以後このターミナルはしばらくの間放置。
作業用のディレクトリを作る。
新しいターミナルで

```
cd $GOPATH
mkdir dev
cd dev

mkdir alice bob charlie
```
を入力。GOPATH上にdevディレクトリを作り、その上に`alice`, `bob`, `charlie`のディレクトリを作った
そのままこのターミナルでaliceのノードを動かしたいと思う。

```
cd $GOPATH/dev/alice

lnd --rpclisten=localhost:10001 --listen=localhost:10011 --restlisten=localhost:8001 --datadir=data --logdir=log --debuglevel=info --bitcoin.simnet --bitcoin.active --bitcoin.node=btcd --btcd.rpcuser=kek --btcd.rpcpass=kek
```

これで大量のログが図れると同時にノードが起動できた。
通常ノードの起動には`lnd`で十分なのだが、今回はたくさんのオプションを指定した。
内容は公式のチュートリアルに書いてあるし、`lnd --help`で確認できるので今回は省略する。


新しいターミナルを開きbobのノードを起動する。

```
cd $GOPATH/dev/bob
lnd --rpclisten=localhost:10002 --listen=localhost:10012 --restlisten=localhost:8002 --datadir=data --logdir=log --debuglevel=info --bitcoin.simnet --bitcoin.active --bitcoin.node=btcd --btcd.rpcuser=kek --btcd.rpcpass=kek 
```
これでbobの準備はできた。
つぎにcharleのノードを準備する。
新しいターミナルで、

```
cd $GOPATH/dev/charlie
lnd --rpclisten=localhost:10003 --listen=localhost:10013 --restlisten=localhost:8003 --datadir=data --logdir=log --debuglevel=info --bitcoin.simnet --bitcoin.active --bitcoin.node=btcd --btcd.rpcuser=kek --btcd.rpcpass=kek
```

###楽に起動したい場合
今回は`lnd`にたくさんオプションを指定した。これを毎回入力するのはめんどくさいという場合`lnd.conf`でオプションを予めファイルに記載しておく。
`lnd.conf`の場所と中身は以下の通り。

- MacOS: /Users/[username]/Library/Application\ Support/Lnd/lnd.conf
- Linux: ~/.lnd/lnd.conf

```lnd.conf
[Application Options]
datadir=data
logdir=log
debuglevel=info

[Bitcoin]
bitcoin.simnet=1
bitcoin.active=1
bitcoin.node=btcd

[btcd]
btcd.rpcuser=kek
btcd.rpcpass=kek
```
これらを指定することでalice, bob, charleはそれぞれ

```
alice$ lnd --rpclisten=localhost:10001 --listen=localhost:10011 --restlisten=localhost:8001
bob$ lnd --rpclisten=localhost:10002 --listen=localhost:10012 --restlisten=localhost:8002
charlie$ lnd --rpclisten=localhost:10003 --listen=localhost:10013 --restlisten=localhost:8003
```
で起動できるようになる。

#lncliと認証機能をうごかす
lncliでwalletを作り、macaroonの認証を済ませる。

公式には以下のように書いてあるが、この`macaroon-path`は正しくない。

```
cd $GOPATH/dev/alice
alice$ lncli --rpcserver=localhost:10001 --macaroonpath=data/admin.macaroon create
```

これを入力すると、以下のリンク先にまとめようなエラーが出る。
[LND Developer SiteのTutorialでよく起こるエラー](https://qiita.com/wokashi_/items/566bbf01b6d01cb870a1)

今回はsimnetなのでこう入力する。
新しいターミナルを開き、

```
cd $GOPATH/dev/alice
alice$ lncli --rpcserver=localhost:10001 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon create
```
`macaroon-path`を変えただけだ。
これを入力するとパスワードを設定しろと言われるので、
passwordと確認用にもう一度同じpasswordを入力した後、

```
Do you have an existing cipher seed mnemonic you want to use? (Enter y/n): 
```
と聞かれるが今回は`n`を入力。

```
Input your passphrase if you wish to encrypt it (or press enter to proceed without a cipher seed passphrase): 
```
と入力を求められるが、何も入力しないでそのままenterを押す。
これでwalletが準備できた。
同じ他アーミナルでwalletの情報を確認する。

```
cd $GOPATH/dev/alice
lncli --rpcserver=localhost:10001 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon getinfo
```

###　ちなみに
公式には書いていないが、次回以降このwalletを使うときは

```
lncli --rpcserver=localhost:10001 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon unlock
```
で認証をする。

新しいターミナルでbobでも同じことをする。

```
cd $GOPATH/dev/bob
lncli --rpcserver=localhost:10002 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon create
```

次に新しいターミナルでcharalieで同じことをする。

```
cd $GOPATH/dev/charlie
lncli --rpcserver=localhost:10003 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon create
```

毎回rpcserverとmacaroonpathのオプションを入力するのはめんどくさいので、
aliasを登録する。
`~`ディレクトリに`.bashrc`ファイルを開き（なければ作る）
最後の行に、

```
alias lncli-alice="lncli --rpcserver=localhost:10001 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon"
alias lncli-bob="lncli --rpcserver=localhost:10002 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon"
alias lncli-charlie="lncli --rpcserver=localhost:10003 --macaroonpath=data/chain/bitcoin/simnet/admin.macaroon"
```
alice、bob、charlieのディレクトリでそれぞれ

```
 source ~/.bashrc
```
と入力。これで`.bashrc`が読み込めた。


アリスのアドレスを調べる。
アリスのターミナルで`alice$ `以降の一行のコマンドを入力。

```
alice$ lncli-alice newaddress np2wkh
{
    "address": <ALICE_ADDRESS>
}
```

bobとchalieのアドレスもそれぞれ確認しておく。

```
bob$ lncli-bob newaddress np2wkh
{
    "address": <BOB_ADDRESS>
}

charlie$ lncli-charlie newaddress np2wkh
{
    "address": <CHARLIE_ADDRESS>
}
```

`{}`内にaliceのadderssが表示されたはずだ。
一番最初に`btcd`を入力し放置していたターミナルを開く。
一度`Ctrl + C`停止し、

```
btcd --simnet --txindex --rpcuser=kek --rpcpass=kek --miningaddr=<ALICE_ADDRESS>
```
を入力。`<ALICE_ADDRESS>`の部分はaliceのアドレスを入れてください。
そしてaliceのターミナルでマイニングを行う。
```
btcctl --simnet --rpcuser=kek --rpcpass=kek generate 400
```
配列形式でハッシュ値が400生成されたのが確認できただろうか。
つぎにそのままsegwitがactiveになっているかを確認する。

```
btcctl --simnet --rpcuser=kek --rpcpass=kek getblockchaininfo | grep -A 1 segwit
```
つぎにそのままアリスのターミナルでwalletのbalanceを確認。

```
lncli-alice walletbalance
```
いくらかコインが入っているはず。
今度はchalieでコインを稼ぐ。
もう一度`btcd`を動かしているターミナルを開き再び`Ctrl + C`停止し、

```
btcd --txindex --simnet --rpcuser=kek --rpcpass=kek --miningaddr=<CHARLIE_ADDRESS>
```

`<CHARLIE_ADDRESS>`はchalieのアドレス。
どのターミナルでもいいのだがchalieのターミナルを開き、

```
btcctl --simnet --rpcuser=kek --rpcpass=kek generate 100
```
でマイニングをし、balanceを確認。

```
lncli-charlie walletbalance
```

# Peerに接続する
bobのターミナルでbobの情報を確認。

```
lncli-bob getinfo
{
--->"identity_pubkey": <BOB_PUBKEY>,
    "alias": "",
    "num_pending_channels": 0,
    "num_active_channels": 0,
    "num_peers": 0,
    "block_height": 450,
    "block_hash": "2a84b7a2c3be81536ef92cf382e37ab77f7cfbcf229f7d553bb2abff3e86231c",
    "synced_to_chain": true,
    "testnet": false,
    "chains": [
        "bitcoin"
    ],
    "uris": [
    ],
    "best_header_timestamp": "1533350134",
    "version":  "0.4.2-beta commit=7a5a824d179c6ef16bd78bcb7a4763fda5f3f498"
}
```

`{}`内にbobの情報がずらりと表示された。
"identity_pubkey"に表示されたハッシュ値を使っていく。

aliceのターミナルで

```
lncli-alice connect <BOB_PUBKEY>@localhost:10012
```
 <BOB_PUBKEY>にはさっきのbobの"identity_pubkey"を入れる。
すると

```
{

}
```
と空の`{}`が表示されたはずだ。

peerのリストを確認する。
aliceのターミナルで

```
lncli-alice listpeers
{
    "peers": [
        {
            "pub_key": <BOB_PUBKEY>,
            "address": "127.0.0.1:10012",
            "bytes_sent": "7",
            "bytes_recv": "7",
            "sat_sent": "0",
            "sat_recv": "0",
            "inbound": false,
            "ping_time": "0"
        }
    ]
}
```
続いてbobのターミナルで、

```
 lncli-bob listpeers
{
    "peers": [
        {
            "pub_key": <ALICE_PUBKEY>,
            "address": "127.0.0.1:60104",
            "bytes_sent": "318",
            "bytes_recv": "318",
            "sat_sent": "0",
            "sat_recv": "0",
            "inbound": true,
            "ping_time": "5788"
        }
    ]
}
```

今度はcharlieでbobに接続する。

```
lncli-charlie connect <BOB_PUBKEY>@localhost:10012
```
ついにaliceのターミナルでbobとチャンネルを開設する

```
lncli-alice openchannel --node_key=<BOB_PUBKEY> --local_amt=1000000
```

この状態ではまだブロードキャストしたものがブロックチェーンに記録されていいのでchannelは開設できていない。
なのでマイニングを行う。

```
btcctl --simnet --rpcuser=kek --rpcpass=kek generate 6
```

開設できたかをaliceでchannelを確認する。

```
lncli-alice listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": <BOB_PUBKEY>,
            "channel_point": "2622b779a8acca471a738b0796cd62e4457b79b33265cbfa687aadccc329023a:0",
            "chan_id": "495879744192512",
            "capacity": "1000000",
            "local_balance": "991312",
            "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": 144,
            "private": false
        }
    ]
}
```

bobでinvoice(請求書)を発行する

```
 lncli-bob addinvoice --amt=10000
{
        "r_hash": "<a_random_rhash_value>",
        "pay_req": "<encoded_invoice>",
        "add_index": 1
}
```
10000satshiのinvoiceを発行した。
<encoded_invoice>は送金のときに使う。
続いてaliceの側でこのinvoiceに送金する。

```
lncli-alice sendpayment --pay_req=<encoded_invoice>
{
	"payment_error": "",
	"payment_preimage": "baf6929fc95b3824fb774a4b75f6c8a1ad3aaef04efbf26cc064904729a21e28",
	"payment_route": {
		"total_time_lock": 650,
		"total_amt": 10000,
		"hops": [
			{
				"chan_id": 495879744192512,
				"chan_capacity": 1000000,
				"amt_to_forward": 10000,
                "expiry": 650,
                "amt_to_forward_msat": 10000000
			}
		],
		"total_amt_msat": 10000000
	}
}
```

aliceの側でchannelに10000satoshiが送金されていることを確認する。

```
lncli-alice listchannels
```
bobの側でも

```
lncli-bob listchannels
```

#マルチホップペイメント

charlieでbobとchannelを開設する。

```
lncli-charlie addinvoice --amt=10000
```

aliceで同じように送金。

```
lncli-alice sendpayment --pay_req=<encoded_invoice>
```

キャロルで送金を確認する。

```
lncli-charlie listchannels
```
# channelを閉じて送金をかんりょうする。

lightningでの送金は、channelを閉じてそれがマイニング処理されてようやく完了する。
aliceで`channel_point`を確認する。

```
lncli-alice listchannels
{
    "channels": [
        {
            "active": true,
            "remote_pubkey": "0343bc80b914aebf8e50eb0b8e445fc79b9e6e8e5e018fa8c5f85c7d429c117b38",
       ---->"channel_point": "3511ae8a52c97d957eaf65f828504e68d0991f0276adff94c6ba91c7f6cd4275:0",
            "chan_id": "1337006139441152",
            "capacity": "1005000",
            "local_balance": "990000",
            "remote_balance": "10000",
            "unsettled_balance": "0",
            "total_satoshis_sent": "10000",
            "total_satoshis_received": "0",
            "num_updates": "2"
        }
    ]
}
```

channel_pointの値をよく見ると`:`で区切られているはずだ。前半分が`funding_txid`にあたり、後ろが`output_index`だ。
aliceのターミナルで,

```
lncli-alice closechannel --funding_txid=<funding_txid> --output_index=<output_index>
```

まだ送金は完了していない。マイニングで完全に送金を完了させる。

```
btcctl --simnet --rpcuser=kek --rpcpass=kek generate 1
```
bobのターミナルを開き送金を確認する。

```
 lncli-bob walletbalance
{
    "total_balance": "20001",
    "confirmed_balance": "20001",
    "unconfirmed_balance": "0"
}
```
balanceが増えている
これでStage1は完了。

続き：
[Lightning Network Daemon(Lnd)で遊んでみた ~Tutorial編(Stage2)~](https://qiita.com/wokashi_/items/5ab00b17cf50fd9076b8)