Bitcoin: Lightning Networkによるマイクロペイメント

【本文】
---

Bitcoinネットワークのoff-chainの一種であるLightning Networkを利用したマイクロペイメント（少額決済）についてコマンドの流れを追っていく。

【主な参考文献】
---

構築手順及びコマンドは、"ElementsProject/lightning (Github)"に掲載されているのでそちらを参考。

>+ [ElementsProject/lightning (Github)](https://github.com/ElementsProject/lightning)
+ [lightning networkでビットコインを送金してみた(Coincheck技術ブログ)](https://coincheck.com/blog/2946)

【前提及び環境】
---

>+ OS: lubuntu(v16.10) ※軽量版Ubuntu。（Mac OSでも良い。）
+ Bitcoin Core(v0.15以上)が導入済みであること。 
+ Lightning Network（以下、LN）が導入済みであること。
+ テストネットを使用。
+ テストネットでテスト用BTCを手にする。
+ 1satoshi = 0.00000001BTC

テストネット用にBitcoinを超たするには以下サイトから。
↓↓↓
[Kiwi's testnet faucet.](https://testnet.manu.backend.hamburg/faucet)

【今回の流れ】
---

>+ bitcoin coreを起動
+ LNを起動
+ LN用アドレスを新規発行
+ LN用アドレスに適当な量のsatoshi（Bitcoinの単位）を送金（1confirmations待つ）
+ LNノードにチャネルオープン（fundが必要。ここでも1confirmations待つ）
+ LN上でマイクロペイメント実行
+ LNノードとのチャネルクローズ

【Bitcoin Core起動】
---

**1. Bitcoin Core起動**

コンソール起動し、以下コマンドを実行。
（printtoconsoleの代わりにdaemonでも良い。）

>```
$ bitcoind -testnet -printtoconsole
>```

**2. Bitcoinの残高確認**

新たにコンソール起動し、以下コマンドを実行。

>```
$ bitcoin-cli --getinfo
{
  "version": 159900,
  "protocolversion": 70015,
  "walletversion": 159900,
  "balance": 1.51194898,
  "blocks": 1260888,
  "timeoffset": 0,
  "connections": 5,
  "proxy": "",
  "difficulty": 1,
  "testnet": true,
  "keypoololdest": 1512216424,
  "keypoolsize": 1000,
  "unlocked_until": 0,
  "paytxfee": 0.00000000,
  "relayfee": 0.00001000,
  "warnings": "Warning: unknown new rules activated (versionbit 28)"
}
>```

【LN起動】
---

**3. LN起動**

新たにコンソール起動し、ディレクトリ移動

>```
$ cd lightning/
>```

port:42480。ディレクトリもテストネット用に分けておく（と便利）。

>```
$ lightningd/lightningd --network=testnet --log-level=debug --port 42480  --lightning-dir ~/.LN-test
>```

【LN用アドレス発行】
---

**4. LN起動状態確認**

新たにコンソール起動し、ディレクトリ移動

>```
$ cd lightning/
>```

起動状態を確認
idやport、テストネットに繋がっているか等を確認できる。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test getinfo
{ "id" : "02826a9ce98c34d50cfd94767a210cf2c62ba957b75d6e424a9a616a96e4d301bd", "port" : 42480, "address" : 
	[  ], "version" : "v0.5.2-2016-11-21-1646-g73c3175", "blockheight" : 1260888, "network" : "testnet" }
>```

**5. LN用アドレス新規発行**

新規にアドレスが発行される。こちらにBitcoinを入金することになる。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test newaddr
{ "address" : "2NErWgNbBQtVGXDe6YBLkk4TJDB6dHiuNQi" }
>```

【LN用アドレスにBitcoin送金】
---

いったん、Bitcoin Core側での作業となる。

**6. walletのパスワード解除**

*'注）walletにパスワードをかけていない場合、手順6の作業はスキップ'*

>```
$ bitcoin-cli walletpassphrase ●●● 60
>```

**7. LN用アドレスにBitcoin送金**

発行しておいたLN用アドレス（"2NErWgNbBQtVGXDe6YBLkk4TJDB6dHiuNQi"）に任意のamount送金（3000000satoshi = 0.03BTC)

>```
$ bitcoin-cli sendtoaddress 2NErWgNbBQtVGXDe6YBLkk4TJDB6dHiuNQi 0.03
20e8f200c8e5066329f05d6ea5c1c976dac4a8a62f8dcc419fcb61599ef9a670
>```

LN用アドレス宛に送金後、実際にLN用アドレスでfundが可能になるまで1confirmations(マイニングでTxがブロックに取り込まれる。）待つ必要がある。

【LNノードとのチャネルオープン】
---

fundが現状ないことを確認

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listfunds
{ "outputs" : 
	[  ] }
>```

**8.  LNノードにチャネルオープン**

任意のLNノードにconnect(Yallsへconnect)

Y'allsの接続情報
>+ id: 02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b
+ ip: 52.3.235.238
+ port: 9735

注）fundが出来るようになるまでにLN用アドレスに入金後、1confirmations経過しておく必要がある。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test connect 02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b 52.3.235.238
{ "id" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b" }
>```

一度、接続確認（fundしてないので、この段階では完全にはチャネルオープンしていないはず）
（"GOSSIPING"状態。fundが必要。）

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listpeers
{ "peers" : 
	[ 
		{ "state" : "GOSSIPING", "id" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "netaddr" : 
			[ "52.3.235.238:9735" ], "connected" : true, "owner" : "lightning_gossipd" } ] }
>```

※LN用アドレスに入金後、1confirmation経過すると、以下作業が可能になる。
fundを使いチャネルオープン（200000satoshi)
Yallsの接続id（"02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b"）を指定。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test fundchannel 02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b 200000 
{ "tx" : "0200000000010170a6f99e5961cb9f41cc8d2fa6a8c4da76c9c1a56e5df0296306e5c800f2e82001000000171600147e95f54b986d68db733516a2a4b3ab08dedf49ffffffffff02400d030000000000220020e8b183278c2a0d5833deace94753e6bbfdb9c649fbff43c168d8a272bf6fb119ceb82a0000000000160014d82aaa52078523b4d3d5f78e9d8febf77ffb3df402483045022100b9b1374ea3cf39b79efb00f7747052674b19a6af0f93a40d9e7925fca41db07e0220721f33233ff969aa41578d8841253ecdac3df8dc5038e85d0f587b76032d48c00121026de3a91cac8e3b1ea05852f9c5a09948caf8ae90bca32776a48b811d0a158a6900000000", "txid" : "01eca14f6b01a9d3ac985d461fb877f4407ccbb87ded81a1ad2157fce4b6ac2a" }
>```

再度、接続確認
"CHANNELD_AWAITING_LOCKIN"状態。この段階はまだ接続中で、チャネルオープンまで1confirmations待つ必要がある。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listpeers
{ "peers" : 
	[ 
		{ "id" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "connected" : true, "netaddr" : 
			[ "52.3.235.238:9735" ], "channels" : 
			[ 
				{ "state" : "CHANNELD_AWAITING_LOCKIN", "owner" : "lightning_channeld", "funding_txid" : "01eca14f6b01a9d3ac985d461fb877f4407ccbb87ded81a1ad2157fce4b6ac2a", "msatoshi_to_us" : 200000000, "msatoshi_total" : 200000000, "dust_limit_satoshis" : 546, "max_htlc_value_in_flight_msat" : 18446744073709551615, "channel_reserve_satoshis" : 0, "htlc_minimum_msat" : 0, "to_self_delay" : 6, "max_accepted_htlcs" : 483 } ] } ] }
>```

1confirmations後、再度、接続確認
"CHANNELD_NORMAL"状態。これで正常にチャネルオープンしたことになる。
200000000msatoshi = 200000satoshiなので、指定したfundが入っていることを確認。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listpeers
{ "peers" : 
	[ 
		{ "id" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "connected" : true, "netaddr" : 
			[ "52.3.235.238:9735" ], "channels" : 
			[ 
				{ "state" : "CHANNELD_NORMAL", "owner" : "lightning_channeld", "short_channel_id" : "1260892:77:0", "funding_txid" : "01eca14f6b01a9d3ac985d461fb877f4407ccbb87ded81a1ad2157fce4b6ac2a", "msatoshi_to_us" : 200000000, "msatoshi_total" : 200000000, "dust_limit_satoshis" : 546, "max_htlc_value_in_flight_msat" : 18446744073709551615, "channel_reserve_satoshis" : 0, "htlc_minimum_msat" : 0, "to_self_delay" : 6, "max_accepted_htlcs" : 483 } ] } ] }
>```

以上でチャネルオープン完了。
続いて実際にLNを利用してマイクロペイメントを実施する。

【LNでのマイクロペイメント】
---

**9.  マイクロペイメント**

実際に、Y'allsサイトでLN支払いをしてみる。
ここでは、記事を読むのに少額課金が発生するというもの。

[Y'allsのリンク]
[Y'alls -Read and write articles, with Lightning Network micropayments.-](https://yalls.org/)

[今回購読する記事リンク]
[Lightning network explorer](https://yalls.org/articles/a1264e7f-401d-4c46-97a7-7b14e6b54193:926B20A0-5375-4E8A-BC75-D060BD930D7C/4d8152c8-621a-4b16-bb5f-8a7059c23ddb)

図1のように、記事の続きを読むためには支払いをする必要がある。

（**図1**）
![3.png](https://qiita-image-store.s3.amazonaws.com/0/167054/b52eb7cc-6ec5-0792-fca4-b47ee9a05c84.png)!

図1の[Continue...]（黄色）ボタンを押下すると、図2のように支払いに関する情報（bolt11と呼ばれるLN用invoice）が表示される。

（**図2**）
![4.png](https://qiita-image-store.s3.amazonaws.com/0/167054/a62ef25c-26af-917c-f372-5bb70b4357bb.png)

記事の続きを読むために、図2の「bolt11」と呼ばれるinvoiceをコピーして支払い
preimageの結果が返ってきたら決済完了。
（決済は1秒かからないくらいの速度。）

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test pay lntb1u1pdxmydzpp55qr4zy3z7s7xtvvy2gar43eutvd85zechnrn32npuxqwutf9zyvqdyj0v3xgg36yffx2ctyypqhyarfvdkx2w3qf35kw6r5de5kueeqdejhgam0wf4jqetcwpkx7un9wg3zcgnfygazyvfjxgukzd35v5knvvmrxvkngvpsxcknjwryx5knvepnxqexyepcx5enjv3z05cqzysd3hzytzn4sc8vrtzzu3asr0am5plgnqswhzycm0m23r8epqmqjkxd4yfxact2e374mlkdcqe6z0uql5wyqnh4pz0v9ynk9ktdt6v3xqq5a3gtl
{ "preimage" : "59e498c411bd6bec4e0dda7e1b4be2b81c8b41611462246d3dee3aa3ac61e28d" }
>```

図3のように記事の続きが表示される。

（**図3**）
![5.png](https://qiita-image-store.s3.amazonaws.com/0/167054/6bfef6f1-c5a6-bad4-5b8a-b90645a84a32.png)

ついでなので、記事に対するコメント（Comments）も入れてみる。
"Good Job!"のコメントを入れて「post」すると、図4のように「bolt11」が発行されるのでこちらを利用して支払い。

（**図4**）
![7.png](https://qiita-image-store.s3.amazonaws.com/0/167054/4af5366a-894e-c31d-4d0a-ff019a9851c2.png)

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test pay lntb200n1pdxmy4lpp5s0rkudkxlpsx5gudup73wm2mefpv7u8p92hg6ycc2w56eayyzedqdr80v3xgg36yfqkgepqvysxxmmdd4jkuapz9s3xjg36yfnxzd34xyenycfdvfskye3dxscxvd3d8yunswpdxqersd3c89nrzenz8qcjylgcqzysj7cqe4cge9aqsk2f5uhxu7mj9lsvcv5m30c98cr92jhqurhkv5fqq3rc2eww0e376xp8ya3y7fwjer6s8pz7vr2ecgq8wl75wps9ufgqx4fan0
{ "preimage" : "f877187e88753b771c03f0e2c78baaa3b1d51617473fd66fffe9d1dff051dff6" }
>```

図5の通り、実際にコメント欄に「Good Job!」のコメントが追加されている。

（**図5**）
![8.png](https://qiita-image-store.s3.amazonaws.com/0/167054/a7397f8a-381d-70e9-a314-75c54baf2757.png)


**10.  決済情報確認**

自分が決済した情報を確認する。
実は、最初の決済（"id" : 1）は、上記の記事を見る為のpayコマンドを誤って2回実行してしまった人為的なミスによるもの。なので、決済情報としては正常。

決済総額は、100000(id:1) + 100000(id:2) + 20000(id:3) = 220000(msathoshi)

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listpayments
{ "payments" : 
	[ 
		{ "id" : 1, "payment_hash" : "e5d95a192f660e258ee03c31e2715864e94dd938f0fd22fc96cf6e40c07b40bd", "destination" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "msatoshi" : 100000, "timestamp" : 1517130083, "created_at" : 1517130083, "status" : "complete", "payment_preimage" : "8fa4d689c4fe08da1992e05f8bec84e36d6e5bc47061916e7f3fc4e335e2823a" }, 
		{ "id" : 2, "payment_hash" : "a007511222f43c65b184523a3ac73c5b1a7a0b38bcc738aa61e180ee2d251118", "destination" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "msatoshi" : 100000, "timestamp" : 1517130196, "created_at" : 1517130196, "status" : "complete", "payment_preimage" : "59e498c411bd6bec4e0dda7e1b4be2b81c8b41611462246d3dee3aa3ac61e28d" }, 
		{ "id" : 3, "payment_hash" : "83c76e36c6f8606a238de07d176d5bca42cf70e12aae8d131853a9acf484165a", "destination" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "msatoshi" : 20000, "timestamp" : 1517130475, "created_at" : 1517130475, "status" : "complete", "payment_preimage" : "f877187e88753b771c03f0e2c78baaa3b1d51617473fd66fffe9d1dff051dff6" } ] }
>```

**11.  fund情報確認**

自分の残高を確認。
"msatoshi_to_us" : 199780000 （自分）
"msatoshi_total" : 200000000 （fund総額）
なので、差額は220000(msatoshi)となり、No.10で確認した決済情報総額と一致する。
（ご参考： 220000msatoshi = 0.000022BTC）

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listpeers
{ "peers" : 
	[ 
		{ "id" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "connected" : true, "netaddr" : 
			[ "52.3.235.238:9735" ], "channels" : 
			[ 
				{ "state" : "CHANNELD_NORMAL", "owner" : "lightning_channeld", "short_channel_id" : "1260892:77:0", "funding_txid" : "01eca14f6b01a9d3ac985d461fb877f4407ccbb87ded81a1ad2157fce4b6ac2a", "msatoshi_to_us" : 199780000, "msatoshi_total" : 200000000, "dust_limit_satoshis" : 546, "max_htlc_value_in_flight_msat" : 18446744073709551615, "channel_reserve_satoshis" : 0, "htlc_minimum_msat" : 0, "to_self_delay" : 6, "max_accepted_htlcs" : 483 } ] } ] }
>```

fundの状態変化確認

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listfunds
{ "outputs" : 
	[ 
		{ "txid" : "01eca14f6b01a9d3ac985d461fb877f4407ccbb87ded81a1ad2157fce4b6ac2a", "output" : 1, "value" : 2799822 }, 
		{ "txid" : "eaf9562ee170867fca11ebc2ff5ee894dc0fa0d6e69247a62585da74c02eb912", "output" : 0, "value" : 199596 } ] }
>```

LN用アドレス残高：　2799822 (fee: 178)
fund残高：　199596 (fee: 404)
合計：　2999418
差額(fee)：　582 (3000000 - 2999418)

【LNノードとのチャネルクローズ】
---

最後にチャネルをクローズしてみる。

**12.  チャネルクローズ**

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test close 02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b
{  }
>```

**13.  接続状況確認**

”ONCHAIND_MUTUAL"状態となり、Y'allsとの間でチャネルクローズしたことが分かる。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test listpeers
{ "peers" : 
	[ 
		{ "id" : "02d041e838da7decc58ac47cd2ff01cd3774f00f172953b4d82429ada29216a40b", "connected" : false, "channels" : 
			[ 
				{ "state" : "ONCHAIND_MUTUAL", "owner" : "lightning_onchaind", "short_channel_id" : "1260892:77:0", "funding_txid" : "01eca14f6b01a9d3ac985d461fb877f4407ccbb87ded81a1ad2157fce4b6ac2a", "msatoshi_to_us" : 199780000, "msatoshi_total" : 200000000, "dust_limit_satoshis" : 546, "max_htlc_value_in_flight_msat" : 18446744073709551615, "channel_reserve_satoshis" : 0, "htlc_minimum_msat" : 0, "to_self_delay" : 6, "max_accepted_htlcs" : 483 } ] } ] }
>```

**14.  fundからの資金引き上げ**

おそらく、この段階ではまだfundに残金が残っていると思われるので、最終的にBitcoinアドレスに送金（引き出し）する必要がある。
この辺りの仕組みが自分の中で未だ良く分かっておらず、確信は持てないが、一応、LN用コマンドには"withdraw"がある。
今回、この"withdraw"コマンドを使用してBitcoinアドレスにfund残高を戻す。

<font color="Red">"withdraw"コマンドについて</font>
以下、リンクにリクエストとして挙がっている。（2018/4/26）
>+ [lightning-withdraw.7.txt (Github)](https://github.com/fixone/lightning/blob/deb7ed066ba598ae38c893cd754e8e4cf287a4f0/doc/lightning-withdraw.7.txt)


Bitcoin Core上でrefund用の新規アドレスを発行

>```
$ bitcoin-cli getnewaddress
mqEVHaro9myyivNGYZ5SojcdaBAQUoqSUx
>```

発行したrefund用アドレスにbitcoinを全額分戻す。

>```
$ cli/lightning-cli --lightning-dir ~/.LN-test withdraw mqEVHaro9myyivNGYZ5SojcdaBAQUoqSUx all
{ "tx" : "0200000000010212b92ec074da8525a64792e6d6a00fdc94e85effc2eb11ca7f8670e12e56f9ea0000000000ffffffff2aacb6e4fc5721ada181ed7db8cb7c40f477b81f465d98acd3a9016b4fa1ec010100000000ffffffff01c3c32d00000000001976a9146a940ea67c5d7dfab5de49289ad92f808a8ba6d388ac02473044022052a69dc1e6f3339fc6b7e723da358e401abd744c1c3e1e542c803ba28af43d28022012da574a62edbbe464a1604e08e580b8b26163ca78bafcdfcbe0bb452384332a0121030e39664ec5a75bc471d51ce33c8b75ec44ceec78823f445c011700f47306b7cc02483045022100d2114c7dd2e4bfcacf79ed66ee5957e4f8569abd3d734bf48737589e8aea300f022021e53e0e814993e9d18705186b4fc2b591563ff43c27a9714fb6963817a029f50121039f6ecdd9afc735753b91c6d0a0cb6b142564471872214c515ef7a4e307562ffd00000000", "txid" : "ff984b4aaf52a58a02782568428349db903c7d1e05695158eee9ec3b2fe008f3" }
>```

fund確認(全額引き出したため、fund残高がなくなっている。）

>```
tomo-hata@tomohata-VirtualBox:~/lightning$ cli/lightning-cli --lightning-dir ~/.LN-test listfunds
{ "outputs" : 
	[  ] }
>```


【終わりに】
---

Lightning NetworkはBitcoinのレイヤー2に当たるもので、Bitcoinが抱えるスケーラビリティ問題をon-chainではなくoff-chain等で解決しようとする試みの一つである。
特に、Lightning Networkは不特定多数のものと双方向・多対多のマイクロペイメント（少額決済）を実現可能とするもので、今回見てきたように、接続先ノードにfundすると言う点においてもLightning Networkノードの運用が肝になる。
一方、チャネルオープンからクローズまでの間はマイニングによる影響を受けることがなく決済可能となる為、少額決済（理論上は1satoshiでも可能。）及び高速決済が実現できることになる。

Ethereumでも同様の試みが行われており、例えば、Raiden NetworkもOff-chain上で多対多の決済を可能にし、Plasmaと言うEthereumネットワークとは別だがし少し重なるように独自のon-chainを構築することで、EthereumネットワークとPlasma上を行き来しながらスマートコントラクトを高速処理する試みもある。なお、PlasmaはLightning Networkの考案者であるJoseph PoonとEthereum FoundationのVitalikによる共同提案によるもの。

パブリック型（アナーキー型）ブロックチェーンは、一時期、高速かつ少額決済には向いていないとされ、特に企業向けにプライベート型の開発が主流になりつつある時期もあったが、最近のBitcoinやEthereum及びその周辺プロジェクトの進展を見ていると、再びパブリック型が重要視される可能性も十分に考えられる。

ブロックチェーンと一口に言っても、様々な基盤が存在し、それぞれの思想や解決したい課題に応じて日々研究や開発が行われている。パブリック型でもプライベート型でもそれぞれに長所・短所があるので、より広い視野を持ってこれからも勉強していきたいと思う。