相手ノードとのネゴシエーションが終わり、initメッセージの交換が終わると、BOLTメッセージが交換できるようになる。
通常は、ノード間に開設したチャネルを使って送受金を行うため、開設するための「Channel Establish」について説明していく。
まず、ノードのどちらかが出資者(funder)になり、このチャネルでやりとりする総額を決定する。現在のBOLT仕様では、送受金はこの額の範囲内でしか行えない。
送金する場合は送金額を自分に割り当てられた額から減らして相手の割当額に加えるし、着金の場合はその逆になる。
それを繰り返し、チャネルを閉鎖したくなったときに、最後に残った配分をブロックチェーンに展開する。
Channel Establishは大きく2つに分かれる(BOLTでは前半・後半の呼び名はなく、ここでの説明のために分けている)。
- funding transaction展開前(前半)
- funding transaction展開後(後半)
“funding transaction“というのは、上の図でいう橙色に当たる。
funderが出資したトランザクションで、その出力先はAさんとBさんのMultiSigになっている。
チャネルの双方が出資し合うように思ってしまうが、BOLT仕様では片方しか出資しない。
このトランザクションをブロックチェーンに展開し、相手が指定したブロック時間だけ経過すると、funding transactionとして有効と見なすことになっている。
今回は、前半だけ解説する。
まず、funder(シーケンス図の左)が open_channel メッセージを送信する。
メッセージに問題が無ければ、fundee(シーケンス図の右)が accept_channel メッセージを送信する。
どちらもパラメータが多いが、ここで出資するための情報や条件がほぼ表されている。
主なパラメータを以下に示す(主に、と書いたが、無視できるパラメータは無い)。
- MultiSigのための公開鍵 : funding_pubkey
- 前章に出てきた、鍵生成のためのパラメータ : xxx_basepoint
- 出資額 : open_channel.funding_satoshis
- 出資額のうち、相手に渡す額 : open_channel.push_msat
- funding transaction展開後、トランザクションが安定したと見なす最短ブロック時間 : accept_channel.minimum_depth
Bitcoinの額は、最小単位がsatoshiである。
しかし、BOLTでの最小単位はmilli-satoshi(msat)で、1000分の1 satoshiである。
ここでは、push_msatがmsatになる。
push_msatは、単に配分として相手に渡すという仕様があるだけで、それを渡すための条件はBOLTで決められていない。
もしpush_msatに値がある状態でチャネルを開設し、そのまま取引をせずにチャネルを閉鎖しても、相手にはpush_msatをsatoshiに変換した額が渡されてしまうので、扱いについては注意が必要である。
accept_channelをチェックして問題が無ければ、 funding_createdメッセージを送信する。
この時点で、チャネルを閉鎖した際、funderとfundeeにいくらずつ配分すべきかのトランザクションを決定することができる。
これはfunding transactionの出力となるトランザクションで、BOLTでは “commitment transaction”と呼ぶ。
以降、commitment transactionでfunderとfundeeの配分を変化させていくことで送受金処理を行っていく。
BOLTではトランザクションの構成を細かく決めることで、トランザクション自体の情報を交換せず、ブロックチェーンに展開する際の署名だけを渡すことが多い(funding transactionが2-of-2 MultiSigのため、その出力であるcommitment transactionを展開するためにはお互いが署名する必要がある)。
ブロックチェーンに見える部分だけの署名関係を簡易図にすると、以下のようになる(txはトランザクションの略)。
commitment transaction(commit_tx)の送金先は、実際はもう少し複雑であるが、基本的にはこうなる。
funding_createdメッセージでは、funderが初回のcommitment transactionに署名して、相手に渡す。
また、込みいっていることに、commitment transactionの構成はAさんとBさんで異なる。
これは、funderとfundeeで異なる訳ではなく、トランザクションの項目に”local”と”remote”があり、自分が作るトランザクションの場合は「local=自分」「remote=相手」になり、相手が作るトランザクションの場合は「local=相手」「remote=自分」になるためである。
トランザクションの展開には手数料(fee)も必要になるが、手数料はトランザクションを展開する人の額から差し引くことになっているため、額についてもどちらが展開するかによって変わってくることになる。
以上を踏まえて図を修正すると、以下のようになる。
そして、funding_createdで送信する署名は、相手が展開するcommitment transactionに対する署名である。
よって、commitment transactionは自分用と相手用の両方を作り、メッセージで送信する場合は相手のcommitment transactionに対しての署名を送信し、メッセージで受信した署名は自分のcommitment transactionでチェックすることになる。
funding_signedを受信して問題が無かった場合、funding_signedメッセージを送信する。
このメッセージも署名を含んでいるが、funding_createdと同様に「相手の持つcommitment transaction」に行った署名になる。
ここまでメッセージを交換すると、funding transactionを展開してから相手が不在になったとしても、自分に取り戻すcommitment transactionを展開することができる状況になったので、funding transactionをブロックチェーンに公開する。
ここまでがEstablish Channelの前半である。