MacにLightningNetworkノードを3本たてて直接繋がっていない2ノード間での支払いを体験した後、Satoshi's Placeに支払いをやっていきます。testnetで行います。
Satoshi's Placeとは100万pxのキャンバスを用意して、1px=1satoshi(=1億分の1BTC)で塗ることができるWebサービスです。1度塗られたピクセルはもう一度支払えば誰でも何回でも塗り替えることができます。
LightningNetworkでの支払いのみ受けつけています。
色々前提の説明
- macOS High Sierra
- go (1.9.2)
- btcd (0.12.0-beta)
- bitcoinのクライアントの一つ
- goで実装されている
- testnet
- bitcionではpublicなネットワークとしてmainnetとtestnetがある
- mainnetが本物のBTCが動いているネットワーク
- testnetはいわゆるテスト環境
- LightningNetwork
- bitcoinの2ndレイヤー技術のひとつ
- スケール問題の有力な解決策になりたいやつ
- bitcoinフルノードと常に通信する必要があるので単体では成立しない
- bitcoin以外にLitecoinとmonaでも実現されている
- 以後、LNと略します
-
lnd (0.4.2-beta)
- LNの実装の一つ
- goで実装されている
- チャネル
- LNは2者間でチャネルを開く
- 実態は両者のpublicKeyで作られたマルチシグアドレスに、いくらか送金してそれがブロックに取り込まれている状態のこと
- チャネルが張られいている間は両者で最初に送金した額を上限として、かつ手数料0で何回でも送金しあえる
- LNは2者間でチャネルを開く
- マルチホップペイメント
- 直接チャネルが開かれていないけれどいくつかのノードを介して繋がっている状態の2者間で行われる支払いのこと
- 支払いを中継したノードは手数料を課すことができる
-
Satoshi's Place
- mainnet版とtestnet版がある。今回はtestnet版使います。
btcdとlndの用意
こちらに従ってインストールしていきます。
https://github.com/lightningnetwork/lnd/blob/master/docs/INSTALL.md
goがまだ入ってない場合は入れ下さい。GOPATHなどの設定は済んでいるものとして始めます。
lndがgoの依存管理ツールdepを使うので入れます
$ go get -u github.com/golang/dep/cmd/dep
lndリポジトリをgo get&makeしたらbtcdもインストールされます。
$ go get -d github.com/lightningnetwork/lnd
$ cd $GOPATH/src/github.com/lightningnetwork/lnd
$ make && make install
btcdをtestnetでたちあげる
$ btcd --testnet --txindex --rpcuser=rpcuser --rpcpass=rpcpasswd
btcdとはrpcでコミュニケーションをとります。
上手く立ち上がるとネットワークとブロックを同期し始めます。
毎回オプションを指定したくない場合は設定ファイルに書いておくことで省略できます。
Macの場合のデフォルトの設定ファイルのパスは /Users/${USER}/Library/Application Support/Btcd/btcd.conf
です。
btcd.conf
testnet=1
txindex=1
rpcuser=rpcuser
rpcpass=rpcpasswd
btcctlでapiをたたく
btcctlはbtcdインストール時に同時にインストールされるコマンドラインツールです。
ブロックの同期が進んでいるか確認
$ btcctl --testnet --rpcuser=rpcuser --rpcpass=rpcpasswd getinfo
{
"version": 120000,
"protocolversion": 70002,
"blocks": 1353458,
"timeoffset": -4,
"connections": 8,
"proxy": "",
"difficulty": 44426516.52938943,
"testnet": true,
"relayfee": 0.00001,
"errors": ""
}
btcctlもconfを設定することで実行時オプション指定を省略できます。
Macの場合のデフォルトの設定ファイルのパスは /Users/${USER}/Library/Application Support/Btcctl/btcctl.conf
です。
btcctl.conf
rpcuser=bitcoinrpc
rpcpass=passwd
testnet=1
testnetの最新のブロック高は Bitcoin Testnet Block Explorer | BlockCypher で確認できます。
最新のブロックに追いつくまで待ちます。1から始めて2〜3時間、調子わるいときは10時間くらいかかりました。
LNノードを動かす
こちらを見ながら進めていきます。
Stage 1 - Setting up a local cluster
lndを起動する前にlnd.confを調整します。Macのデフォルトの場所は /Users/${USER}/Library/Application Support/Lnd/lnd.conf
lnd.conf
# lnd.conf
[Application Options]
debuglevel=trace
debughtlc=true
maxpendingchannels=10
no-macaroons=true # lndに対してmacaroonでの認証がデフォルト。ID/PASSで認証する場合に指定する
noencryptwallet=1 # デフォルトでウォレットは暗号化される。今回はローカルでの遊びなのでoff
[Bitcoin]
bitcoin.active=1
bitcoin.testnet=1
bitcoin.node=btcd # bitcoinノードの指定、bitcoindやnutorinoも可
[Btcd]
# btcd<->lnd間もrpcでやり取りするのでアカウント情報が必要。
btcd.rpcuser=rpcuser
btcd.rpcpass=rpcpasswd
lndを3ノード立ち上げる
$GOPATH/dev/
にalice
,bob
,charie
の3ディレクトリを作ってそこでlndを実行する。
lndは立ち上がるとbtcdと同期を始め、ブロック(のメタデータ?)を実行ディレクトリに溜めていきます。なので3ノードはそれぞれ別ディレクトリで立ち上げます。めちゃくちゃファンが回ります。
$ cd $GOPATH
$ mkdir dev
$ cd dev
$ mkdir alice bob charlie
// バックグラウンドで実行していきます
$ cd alice
$ nohup lnd --rpclisten=localhost:10001 --listen=localhost:10011 --restlisten=localhost:8001 --datadir=data --logdir=log &
$ cd ../bob
$ nohup lnd --rpclisten=localhost:10002 --listen=localhost:10012 --restlisten=localhost:8002 --datadir=data --logdir=log &
$ cd ../charlie
$ nohup lnd --rpclisten=localhost:10003 --listen=localhost:10013 --restlisten=localhost:8003 --datadir=data --logdir=log &
rpclisten
はrpcをリッスンするポート、listen
は他のノードからのコネクションをリッスンするポートです。
lncliでlndに問い合わせ
lndへの問い合わせはlncliコマンドで行う。lndをインストールするとついてくる。
lndのrpcサーバーへの認証にはmacaroon使うけどここでは--no-macaroonsで認証をスルー。
$ lncli --rpcserver=localhost:10001 --no-macaroons getinfo
{
"identity_pubkey": "02d457db9ce501e2254bbd778c0c86ad6bd91caafdb3f38c32de29286a47fc76d5",
"alias": "02d457db9ce501e2254b",
"num_pending_channels": 0,
"num_active_channels": 0,
"num_peers": 4,
"block_height": 1353464,
"block_hash": "0000000000000038bf20004f6aae232a8fac5cd8defa392526e337b82f0f074e",
"synced_to_chain": true,
"testnet": true,
"chains": [
"bitcoin"
],
"uris": [
],
"best_header_timestamp": "1531553546",
"version": "0.4.2-beta commit=e13f96e64bd5a0d49ff7fc9fbed20cfa1d2ddfa8"
}
オプション指定が面倒なのでalias設定する。
// ~/.bashrc
alias lncli-alice="lncli --rpcserver=localhost:10001 --no-macaroons"
alias lncli-bob="lncli --rpcserver=localhost:10002 --no-macaroons"
alias lncli-charlie="lncli --rpcserver=localhost:10003 --no-macaroons"
それぞれのノードでアドレス作成
$ lncli-alice newaddress np2wkh
{
"address": "2MsmZEmJeaovzrsUjw2PR5MoAxTm2Rbv4QY"
}
$ lncli-bob newaddress np2wkh
{
"address": "2N1Ym3n3uHNZb5h6A9foqTbte8PnL3h1sbU"
}
$ lncli-charlie newaddress np2wkh
{
"address": "2Mszero8eeZZ86rZ9j1M6eNN9fBBez8LQKK"
}
FaucetからBTCをもらう
下記サイトにアドレスを入れるとtestnetのBTCをいくらかもらえる。
※)2018/09/03現在どちらも停止しています。他に利用できるFaucetサービスをご存知でしたら教えていただけると幸いです><
testnetとは言え実際のネットワークなので承認まで時間がかります。待ちましょう。しばらくしたら残高を確認します。confirmed_balanceに数字が入っていればOKです。
$ lncli-alice walletbalance
{
"total_balance": "129975466",
"confirmed_balance": "129975466",
"unconfirmed_balance": "0"
}
$ lncli-charlie walletbalance
{
"total_balance": "xxxxxxxxxxxxxxx",
"confirmed_balance": "xxxxxxxxxxxxxxxx",
"unconfirmed_balance": "0"
}
ノードを繋ぐ
コネクションを張るには相手のLNノードのpublicKeyとIP(場合によってポート)が必要です。
今は全てローカルでやっているのでIPはlocalhostでOKです。
bobのpub_keyを調べてaliceとcharlieからそれぞれ繋いでみましょう。
// bobのノードの情報を調べる
$ lncli-bob getinfo
{
"identity_pubkey": "035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d",
"alias": "035c4beb21be0d577cc4",
"num_pending_channels": 0,
"num_active_channels": 0,
"num_peers": 3,
"block_height": 1353468,
"block_hash": "0000000000000026429d046a964b0e447515f2618cf63475d8e3fc5a79b7c260",
"synced_to_chain": true,
"testnet": true,
"chains": [
"bitcoin"
],
"uris": [
],
"best_header_timestamp": "1531555098",
"version": "0.4.2-beta commit=e13f96e64bd5a0d49ff7fc9fbed20cfa1d2ddfa8"
}
// identity_pubkeyの値とbobノードを立ち上げるときに指定したlisten:10012を使ってコネクションを張る
$ lncli-alice connect 035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d@localhost:10012
aliceのpeerリストを確認します。
なんかボブ以外のノードともpeerになってしまってるんですが一旦置いときましょう・・。
リストにbobのpublicKeyがあることが確認できます。
$ lncli-alice listpeers
{
"peers": [
{
"pub_key": "03370405f1d3dacbf14b067c184ff63552c689e06b9a9c430864ca789080a83a2f",
"address": "81.107.214.119:9735",
"bytes_sent": "7465464",
"bytes_recv": "4109636",
"sat_sent": "0",
"sat_recv": "0",
"inbound": false,
"ping_time": "264194"
},
{
"pub_key": "03236a685d30096b26692dce0cf0fa7c8528bdf61dbf5363a3ef6d5c92733a3016",
"address": "50.116.3.223:9735",
"bytes_sent": "208904",
"bytes_recv": "878890",
"sat_sent": "0",
"sat_recv": "0",
"inbound": false,
"ping_time": "138130"
},
// bob node
{
"pub_key": "035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d",
"address": "127.0.0.1:10012",
"bytes_sent": "472671",
"bytes_recv": "315587",
"sat_sent": "0",
"sat_recv": "0",
"inbound": false,
"ping_time": "0"
}
]
}
今度はbobのpeerリストを確認してみます。
リストにaliceのpublicKeyがあることが確認できます。片方からコネクションを張れば相手から見ても繋がっている状態になります(当然か)。
$ lncli-bob listpeers
{
"peers": [
{
"pub_key": "02b2536894b76cfe1cc57c93f6323e456a76a99bc29027b871fbf13abe70630c9e",
"address": "35.204.26.235:9735",
"bytes_sent": "2731208",
"bytes_recv": "4095146",
"sat_sent": "0",
"sat_recv": "0",
"inbound": false,
"ping_time": "239184"
},
// alice node
{
"pub_key": "02d457db9ce501e2254bbd778c0c86ad6bd91caafdb3f38c32de29286a47fc76d5",
"address": "127.0.0.1:52247",
"bytes_sent": "316549",
"bytes_recv": "474283",
"sat_sent": "0",
"sat_recv": "0",
"inbound": true,
"ping_time": "429"
}
]
}
同様にcharlieもbobにつなぎます。(操作ログは省略)
チャネルを開く
aliceからbobに対してチャネルを開いてみます。
$ lncli-alice openchannel --node_key=035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d --local_amt=1000000
{
"funding_txid": "f72f392e4ee85506a33571f601b7aa83f9a21e7e0935f161b99fb4c1363a3271"
}
node_key
に開く相手ノードのpublicKeyを指定します。
「チャネルを開く」とはお互いの秘密鍵でアンロックできる2of2マルチシグアドレスに対する送金をブロードキャストすることです。
ここでの送金額をデポジットとして、この範囲内でお互いに振り分けることで送金を実現します。
local_amt
はこのデポジットの額です。
funding_txid
はブロードキャストされたTxのidです。このTxをオープニングトランザクションと呼びます。このTxが3Confirmを得たらチャネルの開通です。
charlieからbobへのチャネルのオープンもやります。
$ lncli-charlie openchannel --node_key=035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d --local_amt=800000 --push_amt=200000
{
"funding_txid": "98358221e656aff18b8898f6b46a646c6918bd615bbe6340c3affcba7f6ba501"
}
新しくpush_amt
を指定しています。これはチャネルオープン時点ですでに自分のデポジット額から相手ノードに支払っている状態です。
なぜこれをしているかと言うと、もうちょっと後で直接繋がっていないaliceとcharlieがbobを経由しての送金を行いますが、bob->charlie間で予めbob側にBTCがないとaliceからの送金を中継できないためです。この辺の仕組みはHTLCを調べるとわかります。
チャネルの確認
先程のTxが3confirmした頃にaliceのチャネル状況を確認します。
$ lncli-alice listchannels
{
"channels": [
{
"active": true,
"remote_pubkey": "035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d",
"channel_point": "f72f392e4ee85506a33571f601b7aa83f9a21e7e0935f161b99fb4c1363a3271:0",
"chan_id": "1488154903381540864",
"capacity": "1000000",
"local_balance": "999817",
"remote_balance": "0",
"commit_fee": "183",
"commit_weight": "600",
"fee_per_kw": "253",
"unsettled_balance": "0",
"total_satoshis_sent": "0",
"total_satoshis_received": "0",
"num_updates": "0",
"pending_htlcs": [
],
"csv_delay": 144,
"private": false
}
]
}
remote_pubkey
にbobノードのpublicKeyを確認できます。
channel_point
はコロンの前がオープニングTxIdで、後ろがOUTPUTのインデックスです。
local_balance
が実際にデポジットされたBTCの量です。
commit_fee
はオープニングTxの送金手数料ですね。最初に1000000satoshiをデポジット額としてチャネルをオープンしましたがTx手数料があるためそれを差し引いた額が残りました。
マイクロペイメントしてみる(single hop)
bobで10000satoshiのinvoceを作成してaliceから支払います。LNでは支払い先が請求情報を発行するところからスタートします。
$ lncli-bob addinvoice --amt=10000
{
"r_hash": "ee1a08932c22bc66394ba01b3702accfe4c36ce59120d2cff7319e9a45d8ba3a",
"pay_req": "lntb100u1pd5n024pp5acdq3yevy27xvw2t5qdnwq4veljvxm89jysd9nlhxx0f53wchgaqdqqcqzyse2c4dytrtfurvqznl084cs5hsknmvss2hwdq7vqnwaglw2pnv3wj8eh8eeavxwg4ldvt43dy2n3c0ed2tl8cssqudh2er5pwljwufqqqh2mwme"
}
pay_req
がinvoice(請求情報)です。
続いて支払いです。
$ lncli-alice sendpayment --pay_req=lntb100u1pd5n024pp5acdq3yevy27xvw2t5qdnwq4veljvxm89jysd9nlhxx0f53wchgaqdqqcqzyse2c4dytrtfurvqznl084cs5hsknmvss2hwdq7vqnwaglw2pnv3wj8eh8eeavxwg4ldvt43dy2n3c0ed2tl8cssqudh2er5pwljwufqqqh2mwme
{
"payment_error": "",
"payment_preimage": "ad897d92f98111bb8537bd3a16c194d4fff493cab9061229b57380429afd87cc",
"payment_route": {
"total_time_lock": 1353619,
"total_amt": 10000,
"hops": [
{
"chan_id": 1488154903381540864,
"chan_capacity": 989817,
"amt_to_forward": 10000,
"expiry": 1353619,
"amt_to_forward_msat": 10000000
}
],
"total_amt_msat": 10000000
}
}
成功しました。ちなみにpay_req
をdecodeしてみると支払い先と額が入っていることがわかります。
lncli decodepayreq lntb100u1pd5n024pp5acdq3yevy27xvw2t5qdnwq4veljvxm89jysd9nlhxx0f53wchgaqdqqcqzyse2c4dytrtfurvqznl084cs5hsknmvss2hwdq7vqnwaglw2pnv3wj8eh8eeavxwg4ldvt43dy2n3c0ed2tl8cssqudh2er5pwljwufqqqh2mwme
{
"destination": "035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d",
"payment_hash": "ee1a08932c22bc66394ba01b3702accfe4c36ce59120d2cff7319e9a45d8ba3a",
"num_satoshis": "10000",
"timestamp": "1531559253",
"expiry": "3600",
"description": "",
"description_hash": "",
"fallback_addr": "",
"cltv_expiry": "144",
"route_hints": [
]
}
マイクロペイメントしてみる(multi hop)
charlieで10000satoshiのinvoceを作成。
$ lncli-charlie addinvoice --amt=10000
{
"r_hash": "667b40fbc6d61fb37b71b5a411a5a62bf1f58eced4938c582bce099e11c5157f",
"pay_req": "lntb100u1pd5nw5gpp5vea5p77x6c0mx7m3kkjprfdx90cltrkw6jfcckptecyeuyw9z4lsdqqcqzysslh4julrl0mzhf4v4jhddnt6fv0p89xusxr36e89w33uurjn0atkdfjry89d4rfvl655dt476lx45zht07rmehqj45hcdwv96x9aeegqq03g5k"
}
aliceで支払い
$ lncli-alice sendpayment --pay_req=lntb100u1pd5nw5gpp5vea5p77x6c0mx7m3kkjprfdx90cltrkw6jfcckptecyeuyw9z4lsdqqcqzysslh4julrl0mzhf4v4jhddnt6fv0p89xusxr36e89w33uurjn0atkdfjry89d4rfvl655dt476lx45zht07rmehqj45hcdwv96x9aeegqq03g5k
{
"payment_error": "",
"payment_preimage": "7c5e8240f01e582972f18911b51f7556c19a729681f908d7db7c75c06adaf289",
"payment_route": {
"total_time_lock": 1353763,
"total_fees": 1,
"total_amt": 10001,
"hops": [
{
"chan_id": 1488154903381540864,
"chan_capacity": 979817,
"amt_to_forward": 10000,
"fee": 1,
"expiry": 1353619,
"amt_to_forward_msat": 10000000,
"fee_msat": 1010
},
{
"chan_id": 1488156002849914880,
"chan_capacity": 800000,
"amt_to_forward": 10000,
"expiry": 1353619,
"amt_to_forward_msat": 10000000
}
],
"total_fees_msat": 1010,
"total_amt_msat": 10001010
}
}
成功しちゃいました。aliceとcharlieはチャネル以前にpeerでもありませんでしたがbobを介して送金することができました。
先程のalice<->bobではhops
の配列の要素が一つでしたが今回は2つです。これは終点を含めた経由ノードを表しています。
hopsの1つ目でfee:1
が発生しています。これが中継手数料です。
satoshi's place(testnet)に支払ってみる
testnetのpubKeyは035fc91a8ba32729da031bde4543c7f247de3c8e67b483825ea64b32fd9664233d@51.15.113.51:9735
なのでまずはcharlieからチャネル開きます。
$ lncli-charlie connect 035fc91a8ba32729da031bde4543c7f247de3c8e67b483825ea64b32fd9664233d@51.15.113.51:9735
$ lncli-charlie openchannel --node_key=035fc91a8ba32729da031bde4543c7f247de3c8e67b483825ea64b32fd9664233d --local_amt=1000000
3confirm待ってチャネルの開通を確認します。
$ lncli-charlie listchannels
{
"channels": [
{
"active": true,
"remote_pubkey": "035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d",
"channel_point": "eef70726b80fac79ce59e472177bc82bc25a94a8a327b54bfaebab3d4e923d58:0",
"chan_id": "1552620369813176320",
"capacity": "1000000",
"local_balance": "78172",
"remote_balance": "200000",
"commit_fee": "721828",
"commit_weight": "724",
"fee_per_kw": "997000",
"unsettled_balance": "0",
"total_satoshis_sent": "0",
"total_satoshis_received": "0",
"num_updates": "3",
"pending_htlcs": [
],
"csv_delay": 144,
"private": false
},
{
"active": true,
"remote_pubkey": "035fc91a8ba32729da031bde4543c7f247de3c8e67b483825ea64b32fd9664233d",
"channel_point": "74c813b183ef8df225da1a67cc5f3eb9d320a3b65d6b86dbd2e06d05729784b3:0",
"chan_id": "1552656653489602560",
"capacity": "1000000",
"local_balance": "277334",
"remote_balance": "838",
"commit_fee": "721828",
"commit_weight": "724",
"fee_per_kw": "997000",
"unsettled_balance": "0",
"total_satoshis_sent": "838",
"total_satoshis_received": "0",
"num_updates": "6",
"pending_htlcs": [
],
"csv_delay": 6,
"private": false
}
]
}
bobとsatoshi's place(testnet)と2つチャネルが開いています。
さて、実際にお絵かきしてinvoiceを発行してみます。
せっかくなんで「Qiita」と描いてみます。
右下のsubmitを押してinvoiceを発行します。
このinvoiceに対して直接繋がっていないbobから支払いをしてみます。
$ lncli-bob sendpayment --pay_req=lntb8380n1pdc6vgtpp5vpec4q2n70z0t62lklnd6gg53a2upvmuapr3tzlkppzzw8u8zzmqdzz2pshjmt9de6zqen0wgsrsvecypcxj7r9d3ejqct5ypekzar0wd5xjuewwpkxzcm99cxqzjccqp2qtd84yjxr2uspfx3k2j0j7l9w3jfzz2v4zlmxa4jtn9c94hcjxap7p2ugkqv0vgxaheayf5qt94xmy08m5365vtjqhwqevr7mcs4ghsp850spc
{
"payment_error": "",
"payment_preimage": "4f15820788eca8f34a1aef1dc1071b72daa3d355872f6c4ff0cf9efdcc35e5a6",
"payment_route": {
"total_time_lock": 1412346,
"total_fees": 1,
"total_amt": 839,
"hops": [
{
"chan_id": 1552620369813176320,
"chan_capacity": 190000,
"amt_to_forward": 838,
"fee": 1,
"expiry": 1412202,
"amt_to_forward_msat": 838000,
"fee_msat": 1000
},
{
"chan_id": 1552656653489602560,
"chan_capacity": 1000000,
"amt_to_forward": 838,
"expiry": 1412202,
"amt_to_forward_msat": 838000
}
],
"total_fees_msat": 1000,
"total_amt_msat": 839000
}
}
一瞬で支払いが完了しました。charlieを介しているのでhopsが2個になっていますね。支払い後のスクショを取りそこねましたが、画面をリロードするとQiitaの文字が描き込まれてました。
チャネルのクローズ
charlieが開いているチャネルをクローズしてみます。
// チャネル情報の確認
$ lncli-charlie listchannels
{
"channels": [
{
"active": true,
"remote_pubkey": "035c4beb21be0d577cc4b23a9a5184380eeb89380f9569af8b091c2320677a540d",
"channel_point": "eef70726b80fac79ce59e472177bc82bc25a94a8a327b54bfaebab3d4e923d58:0",
"chan_id": "1552620369813176320",
"capacity": "1000000",
"local_balance": "79011",
"remote_balance": "199161",
"commit_fee": "721828",
"commit_weight": "724",
"fee_per_kw": "997000",
"unsettled_balance": "0",
"total_satoshis_sent": "0",
"total_satoshis_received": "839",
"num_updates": "5",
"pending_htlcs": [
],
"csv_delay": 144,
"private": false
},
{
"active": true,
"remote_pubkey": "035fc91a8ba32729da031bde4543c7f247de3c8e67b483825ea64b32fd9664233d",
"channel_point": "74c813b183ef8df225da1a67cc5f3eb9d320a3b65d6b86dbd2e06d05729784b3:0",
"chan_id": "1552656653489602560",
"capacity": "1000000",
"local_balance": "273128",
"remote_balance": "5044",
"commit_fee": "721828",
"commit_weight": "724",
"fee_per_kw": "997000",
"unsettled_balance": "0",
"total_satoshis_sent": "5044",
"total_satoshis_received": "0",
"num_updates": "10",
"pending_htlcs": [
],
"csv_delay": 6,
"private": false
}
]
}
// 2つともクローズ
$ lncli-charlie closechannel --funding_txid=74c813b183ef8df225da1a67cc5f3eb9d320a3b65d6b86dbd2e06d05729784b3 --output_index=0
{
"closing_txid": "6b47822912f9a90dc7e9bf7fd3c3863911907a202ffbd461482f5e0e222cbdff"
}
$ lncli-charlie closechannel --funding_txid=eef70726b80fac79ce59e472177bc82bc25a94a8a327b54bfaebab3d4e923d58 --output_index=0
{
"closing_txid": "67211b5182c822630186b56796d18da2241b6890715afcb0057fc4d4e3b35924"
}
funding_txid
はオープニングトランザクションのTxIdで、output_index
はマルチシグアドレスへのアウトプットがどのindexかです。
charlieのチャネルを確認します。
$ lncli-charlie listchannels
{
"channels": [
]
}
LN上のチャネルはクローズされました。ただしクローズTxがブロックに取り込まれるまではLN上の資金は戻ってきません。
まとめ
ということでローカルでLNを動かして外部のWebサービスへの即時決済を体験してみました。
今回支払った額は800satoshiくらいなのでこれを書いている時点の相場で6円相当の支払いでした。LN上での手数料は1satoshiとかなので0.008円相当でした。(今回はtestnetで行いましたがmainnetで行ってもほぼ同じです)
予め入金するという手間がありますが、ネットワーク越しに少額を超少額の手数料で支払うことができました。