3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SFCAdvent Calendar 2019

Day 25

【Bitcoin】Lappsの時代が来た!

Last updated at Posted at 2019-12-24

#はじめに
 Lightning Network Application略してLappsです。
お金のやり取りの処理を実装するのは何かとめんどくさいけど、Bitcoinなら自由度高くやり取りできんるかもって話。
今回はLappsを作ってみてその過程を記事にしてみます。ちなみに初Lapps。
「SFCにはこんなニッチなことやってるやつもいるんだなー」と流し見していただくだけで十分ありがたいです。
興味持ってくれた人がいるなら是非BCALIへ。

#自己紹介
慶應SFC2年の押川拓夢、RG名 wokashi(をかし) です。
奈良県の高校卒業後、大阪に移り住みふらふらしたり専門行ったりしてたので2年遅れで大学生やってます。
大学入学後はベンチャーで約1年Webエンジニアをやって今は村井研BCALIでBitcoinのLightning Netwrokを主に勉強しています。次のお仕事探し中。

#Lightning Network?

アセット 2@3x-8.png

今のBitcoinを支払いに使ってる人なんてほとんどいませんよね。
それもそのはず、Bitcoinは今はまだメチャクチャ使いずらいです。

  • 送金内容が反映されるまで最大10分待つ必要がある
  • 手数料が高くて少額のやりとりができない

と、いうような問題があるためです。
そこで生まれたのがLightning Network。
個々の支払いを改ざん出来ない形で個別にやり取りし、最終的な支払い結果だけをBitcoinのブロックチェーンに書き込みます。
詳しくは下の記事に書いています↓

「で、Lightning Networkって何?」: https://qiita.com/ito_wokashi/items/d373c56678a518e393e3

#今回やること
今回はnode.jsでlndのgRPCクライアントを作ってみる。
gRPCでlndが使えたらlndによる送金をアプリケーションに組み込めるようになる。
Lapps製作の第一歩。
~~アリスとボブでinvoice(請求書)を発行して送金を行うとこまでやりたい。~~←失敗

#セットアップ
 まずはBitcoinノードとlightningノードを立ち上げる必要があります。Bitcoinのバックエンド実装にはbtcdを、lightningはlndを使うことにします。今回は遊びなのでsimnetというローカルのテストネットを使います。なお、btcdやlndのインストールの手順は下の記事を参考にしてみてください。

「Ubuntuでlndとbtcdの環境を構築してみる」:https://qiita.com/ito_wokashi/items/5cafb65de68a1aa3bc9e

インストールが出来たらターミナルでbtcdを起動します。

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

次にアリスとボブの作業用ディレクトリを作成します。
別のターミナルを開いて以下のコマンドを入力します。
ここら辺は下の記事でやったのとほぼ同じです。

「Lightning Network Daemon(Lnd)で遊んでみた ~Tutorial編(Stage1)~」: https://qiita.com/ito_wokashi/items/83f1894ee321649296aa

$ cd $GOPATH
$ mkdir dev
$ cd dev

$ mkdir alice bob

アリスのノードを起動します。

$ 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

次に、ボブ。

$ 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 

本来Lappsを作るならチャンネル開設やクローズなどもアプリケーションの機能としてつけるべきですが、今回はあくまで遊びなのでそこらへんはコンソールでやってしまいます。

lndのconfigファイルを作ります。
lnd.conf

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

作り、lightningノードの起動を行います。

(アリス)$ lnd --rpclisten=localhost:10001 --listen=localhost:10011 --restlisten=localhost:8001
(ボブ)$ lnd --rpclisten=localhost:10002 --listen=localhost:10012 --restlisten=localhost:8002

アリスのwalletを作ります。

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

今度はボブの。

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

#Lapps開発開始
ここからは公式のやり方で進めてもなかなかすんなりいかない。
実はgRPCを使わないでWebsocketを使う方法を数日かけて試したのだが、なぜか上手くいかず、Lapps関連は記事が少ないのでどうしようもなかった。
なので最近勉強してはいるもののまだ身についてはいないgRPCを使うことにした。
この辺で俺はクリスマスイブに何をやっているんだと気づき始める。

まずは適当なディレクトリを作り、npm init
grpc周りのパッケージもインストールする。
ついでにserver.jsも作っておきます

$ mkdir lapps
$ cd lapps
$ npm init
$ npm install grpc --save
$ touch server.js

lnd/lnrpc/rpc.protoを使う必要があるため持ってきます。

$ curl -o rpc.proto -s https://raw.githubusercontent.com/lightningnetwork/lnd/master/lnrpc/rpc.proto

コンパイルするためにgoogleapisが必要です。

$ git clone https://github.com/googleapis/googleapis.git

そしてコンパイル。

$  protoc --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` --proto_path googleapis:. --js_out=. --grpc_out=. rpc.proto

大量のファイルができるはず。
ここからserver.jsを書いていくのですが、私の環境ではこのまま進めると、

DeprecationWarning: grpc.load: Use the @grpc/proto-loader module with grpc.loadPackageDefinition instead

と表示さ、それ以外の処理を実行してくれなかったので、@grpc/proto-loaderをインストールし、それを踏まえたコードを書きます。

server.js
const fs = require('fs');
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');

process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA'

const lndCert = fs.readFileSync(" # tls.certのpathを記述 ");
const sslCreds = grpc.credentials.createSsl(lndCert);
const macaroonCreds = grpc.credentials.createFromMetadataGenerator(function(args, callback) {
  const macaroon = fs.readFileSync("# macaroon.adminのpathを記述").toString('hex');
  const metadata = new grpc.Metadata()
  metadata.add('macaroon', macaroon);
  callback(null, metadata);
});

const credentials = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
const packageDefinition  = protoLoader.loadSync("rpc.proto");
const rpcProto = grpc.loadPackageDefinition(packageDefinition);

const lnrpc = rpcProto.lnrpc;
const lightning = new lnrpc.Lightning('localhost:10001', credentials);

だいぶごちゃってますがこれでいけるはず。
試しにwalletbalanceを喋らせます。
最終行に以下を追加

server.js
let request = {} 
lightning.walletBalance(request, function(err, response) {
  console.log(response);
})

ではserverを起動!

$ node server.js
{}

・・・。
これ以上何をやっても{}しか帰ってきませんでした。

ここでタイムアップ。SFC AdventCalenderの担当日になってしまった。
もうちょっと勉強してから再チャレンジします。
また記事にするんでよかったら是非読んでください。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?