チャネルバックアップなしでLNの資金をオンチェーンへ回収する方法 [Umbrel対応]
Lightning Networkのノードを運用していて、ディスク障害などでサーバーの復旧をする際、オンチェーン資金はシード(秘密鍵)から復旧できますが、オフチェーン資金はチャネルバックアップなどを使って復旧する必要があることは以前の記事で何度か紹介しました。チャネルバックアップ(LNDの場合、Static Channel Backup、SCBと呼ばれるもの)がない場合は、相手ノードへチャネルの強制閉鎖を要求してチャネルを閉じることで資金を復旧できます。ただし、チャネルの強制閉鎖後に、こちら側でもある手順を踏む必要がり、その手順はあまり知られていません。今回はその手順を紹介したいと思います。
今回使うツールは以下で、LNDのみ対応しています。c-lightningでの復旧方法はこちらを参照ください。
・・・
最初にチャネルの相手方へチャネルの強制閉鎖を依頼します。その後、自身のUmbrelの復旧をしましょう。復旧手順はUmbrelを再構築してセットアップ時にバックアップしていた24個のシードを入力することで復旧できます。
次にUmbrelへSSHログインをします(参考記事)。
その後、以下のコマンドでchantoolsをインストールします。以下ではchantools@v0.7.1を使っていますが、ここから最新のバージョンを確認してください。
$ cd /tmp
$ wget -O chantools.tar.gz https://github.com/guggero/chantools/releases/download/v0.7.1/chantools-linux-amd64-v0.7.1.tar.gz
$ tar -zxvf chantools.tar.gz
$ sudo mv chantools-*/chantools /usr/local/bin/
実際にリストアをするコマンドは以下となります。
※[追記①]部分にもっと簡単に資金回収できるコマンドを記載したので、そちらを先に参照することをおススメします。
$ chantools genimportscript --lndpaths --format bitcoin-cli
そうすると、以下のように24個のシードをスペース区切りで入力するように求められるので、入力します。さらにパスワードがある場合はパスワードも入力します。ない場合はエンターを押下します。Umbrelの場合はシードに対してはパスワードをかけていないと思うのでエンターを押下で良いと思います。
$ chantools genimportscript --lndpaths --format bitcoin-cli
2021-10-03 15:00:15.335 [INF] CHAN: chantools version v0.7.1 commit v0.7.1
Input your 24-word mnemonic separated by spaces:
Input your cipher seed passphrase (press enter if your seed doesn't have a passphrase):
そうすると以下のように総当たりでプライベートキーを出力してくれます。この記事を書いている時点の最新v0.9.3では以下の出力をファイルとして保存してくれるみたいです。また、保存されたファイルの先頭行へ #! /bin/sh -x
を1行付け加えると、あとでファイルを実行した時、その実行状況が出力され分かりやすいです。
bitcoin-cli importprivkey Kx1TrrQJ7NgKYwppfe9ZtajzMPJrdaqCy9ffYkxLgaVjwvkLJNSG "m/1017'/0'/3'/1/1/" false
bitcoin-cli importprivkey KxcozbjpMu6M5mnMqrZ1iwLkJGNcMyWDPbmX384adBsjsNBEu8MW "m/1017'/0'/3'/1/2/" false
(途中省略)
bitcoin-cli importprivkey KymjKuj9qBqLz8GEkTbTVm5nXh4AKoNiCNoiRFc3XXhyF3gMpKzE "m/1017'/0'/9'/1/2498/" false
bitcoin-cli importprivkey L4ztSKxh18pX8HzLjRaYsYBBh3Zq8wtVFjQ7sWyhomMyAVbTvDnn "m/1017'/0'/9'/1/2499/" false
bitcoin-cli rescanblockchain 2097000
プライベートキーの生成後、ブロックチェーンをリスキャンが完了したら、Umbrelのダッシュボードへ戻り資金が回収できているか確認してみましょう。
上記の結果をファイルなどへ保存し、bitcoin-cliが実行できる環境で実行することでbitcoin coreのウォレット上で残高を確認することができます。Umbrelの場合、以下のコマンドでbitcoinのDockerコンテナへファイルをコピーして、コンテナへ入ることができます。
$ sudo docker cp [保存したファイル] bitcoin:/data #bitcoinコンテナへファイルをコピー
$ sudo docker exec -it bitcoin /bin/sh #bitcoinコンテナへログイン
コンテナへログインできたら、以下のコマンドでファイルを実行します。
/ $ cd data
/ $ ls #保存したファイルがあるか確認
/ $ chmod +x [保存したファイル] #ファイルを実行形式へ変更
/ $ ./[保存したファイル] #ファイルの実行
/ $ bitcoin-cli importprivkey Kx1TrrQJ7NgKYwppfe9ZtajzMPJrdaqCy9ffYkxLgaVjwvkLJNSG "m/1017'/0'/3'/1/1/" false
/ $ bitcoin-cli importprivkey KxcozbjpMu6M5mnMqrZ1iwLkJGNcMyWDPbmX384adBsjsNBEu8MW "m/1017'/0'/3'/1/2/" false
(途中省略)
/ $ bitcoin-cli importprivkey KymjKuj9qBqLz8GEkTbTVm5nXh4AKoNiCNoiRFc3XXhyF3gMpKzE "m/1017'/0'/9'/1/2498/" false
/ $ bitcoin-cli importprivkey L4ztSKxh18pX8HzLjRaYsYBBh3Zq8wtVFjQ7sWyhomMyAVbTvDnn "m/1017'/0'/9'/1/2499/" false
/ $ bitcoin-cli rescanblockchain 2097000
{
"start_height": 2097000,
"stop_height": 2097889
}
#再スキャンが完了したら、以下のコマンドでウォレット残高を確認してみましょう。
/ $ bitcoin-cli getbalance
0.01361853
Umbrelの場合、ファイルを実行すると以下のようなエラーが表示されると思います。
error code: -18
error message:
No wallet is loaded. Load a wallet using loadwallet or create a new one with createwallet. (Note: A default wallet is no longer automatically created)
その場合は、以下のコマンドでbitcoin coreのウォレットを作成しましょう。作成したら再度ファイルの実行をしてみてください。
$ bitcoin-cli createwallet "recovery"
{
"name": "recovery",
"warning": ""
}
以上がチャネルバックアップなしでの資金回収方法でした。
ただし、UmbrelのダッシュボードにはLNDのオンチェーンウォレット残高しか表示されず、bitcoin coreのウォレット残高は表示されないので注意してください。bitcoin coreのウォレットからLNDのウォレットへ資金を移動したい場合は以下のコマンドで送金しましょう。<bitcoin_address>はUmbrelダッシュボードで生成したビットコインアドレスを、<amount>には上記bitcoin-cli getbalance
で表示された金額をセットしてください。
$ bitcoin-cli -named sendtoaddress address="<bitcoin_address>" amount=<amount> subtractfeefromamount=true
・・・
1点気になったのは、アンカーアウトプットと呼ばれる仕様が入ると、commitment_tx
のto_remote
アウトプットはP2WPKではなくP2WSHになります(詳細はこちら)。そのため上記のようにただ鍵ペアの生成だけではダメで、以下のロックスクリプトを解除するためのTxを生成しないといけなさそうです。
<remote_pubkey> OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFY
・・・
[追記① 2021/10/6]
本記事で紹介したchantoolsの最新版を見ると強制閉鎖されたチャネルの資金のみを対象に救出するコマンドが追加されていることが分かりました。上記ではgenimportscript
コマンドですべてのパスに対して秘密鍵を出力していましたが、以下のコマンドだと強制閉鎖されたチャネルのアドレス(厳密にはm/1017'/0'/3')のみを対象にできるみたいです。さらに資金回収のアドレス先をsweepaddrで指定できるので、そこへUmbrelダッシュボードで生成したBTCアドレスをセットすれば、上記で紹介したbitcoin coreを使用せずに資金を回収できそうです。
chantools sweepremoteclosed \
--feerate 10 \
--sweepaddr bc1q..... \
実際にテストネットを指定してコマンド実行したものが以下になります。強制閉鎖されたTxを見つけて、資金回収するための生Txを生成してくれました。--publishをオプションでつけるとTxの送信まで行ってくれます。
$ chantools -t sweepremoteclosed \
--feerate 2 \
--sweepaddr tb1q8t7sxfgmvgx0vgzh7df7vykkvexqnd79l0wrvx \
--apiurl "https://blockstream.info/testnet/api"
2021-10-06 02:42:34.325 [INF] CHAN: chantools version v0.9.3 commit
Input your 24-word mnemonic separated by spaces:
Input your cipher seed passphrase (press enter if your seed doesn't have a passphrase):
2021-10-06 02:42:42.433 [INF] CHAN: Found 1 unspent outputs for address tb1qrxuwu2hkk785728yp5jrlxxneedk5p0856gmh6n7xctlf6dl3myqsjxn2w
2021-10-06 02:43:39.678 [INF] CHAN: Fee 221 sats of 6530 total amount (estimated weight 443)
2021-10-06 02:43:39.679 [INF] CHAN: Transaction: 020000000001019a0ebb20b91c82d823b7762b49598622f22d1262ada56de250ac20197d76d32902000000000100000001a5180000000000001600143afd03251b620cf62057f353e612d6664c09b7c502483045022100e315dfbc60f58dbf989fb9c5c6979ef4d754316318748ef67f2b93ef418fa73a022066f73ab29c39cdeb0c0fea3d3a8bc972032c8784616bc6bf7bff3dc4486c2a1f01252102fed7e9260f7ea98063bfd1b3232a506ce93e12b05d7df2fd0c1a3e54bdaf512cad51b200000000
AWS EC2にLNDを実行させたまま不注意でインスタンスを削除してしまった。ニーモニックは控えていたがSCBはコピーしてなかった。そのLNDのチャネルは私の他ノードのみだったので、そちらで強制閉鎖。
そのTXが承認された後以下コマンドを実行。
chantools sweepremoteclosed --feerate 3 --sweepaddr <私のウォレットアドレス> --publish
mempool.spaceでTXを確認、confを得た後無事ウォレットにお金が戻ってきた!