Mi

日常をさらさらと

eltoo と SIGHASH_NOINPUT

Off-chain Scaling

Payment Channel

2人のユーザーがいた場合に、お互いが資金を出し合って、お互いの署名がないとunlockができないようなマルチシグに送金するトランザクションを生成し、それをblockchainにbroadcastし、そのfunding transactionをinputとし、お互いの残高を更新していく

この仕組みは資金をブロックチェーンに固定し、固定した金額を上限として、trustlessにoff-chainで決済を切り返すためのプロトコル

どのようなコントラクトで行われるのか

  1. AとBは、Payment Channelをセットアップするためにチャネル決済に使用するコインをblockchain常にlockするFunding Transactionを生成する(この段階では、生成をしただけで、署名をしていないので、broadcastはされていない)
  2. AとBは、それぞれ秘密の値(Secret)とその値のHashを生成する.その中でHashのみを相手に伝える
  3. AとBは相手から受け取ったHashを使って、Funding TransactionのOutputをInputにしたCommitment Transactionをそれぞれ作り、自分の署名を付与して相手に送る.この時点で、お互いに相手が作成した相手の署名が付与されたCommitment Transactionを持っている.これにTransactionを付与すれば、Transactionは完成する.かつこのTransactionがBroadcastされれば、Broadcastしたユーザーが1000ブロック(条件(仮))待てば、コインを入手できる
  4. 最初のCommitment Transactionの交換が完了したら、1で作成したFunding Transactionに署名して、ネットワークにBroadcastして、Channelをオーブンできる

Channelがオープンしたら、そのChannelの範囲内でお互いにオフライン決済ができるようになる

Off-chain Payment

off-chain paymentは新しいシークレットの作成・交換を行い、決済の結果で残高を更新したCommitment Transactionを作り、自分の署名を加えて、相手に送る

着目すべきところは、Commitment Transactionを作る際に、前回のCommitment Transactionを生成する時に生成したSecretの値を相手に明らかにするということ

不正を働いた場合のペナルティ

Bが自分の取り分の多い過去のCommitment Transactionを Broadcastしようとしたとする その場合、AはBが1000ブロック(仮条件)を待っている間にA宛のTransactionを入手でき、かつ新規のTransactionのSecretも知っているので、全資金を入手できる しかし、そのためには、古いCommitment TransactionがBroadcastされていないかChainの監視をする必要がある

eltoo

Setup

1. Channlを開く前に各参加者はUpdate用(Au, Bu)とSettlement用(As, Bs)のキーペアを生成し、各公開鍵を相手と交換する - Update用の鍵 Channelの状態を更新する(新しい支払いをする)際に使用する鍵 - Settlement用の鍵 Channelを最終残高で閉じる際に使用する鍵

※ eltooでは、Channelの最新状態を表したTransactionを保持しておけば、古い状態がBoradcastされても、そのTransactionを最新状態を表すTransactionに置換することができる

  1. Aの資金を2-of-2のマルチシグにlockするFunding Transactionを生成する
  2. Funding TransactionのUTXOをInputにしたTrigger Transactionを作成
  3. Trigger TransactionをInputとしたSettlement Transactionを作成する.setupフェーズでは払い戻し用として機能し、Outputは5BTCがそのままAのアドレスにいく(Bが途中で消えてもいいように)
  4. AはFunding Transactionに署名し、Broadcastする

着目すべき点は、Lightning Networkの ContractはCommitment Transaction 1つでお互いの残高を管理していたが、eltooではTrigger Transaction(Update Transaction) と Settlement Transactionの2つでChannelの残高を管理する

Payment(1回目)

  1. A -> B に1BTCを支払うために、Trigger TransactionをInputとして、新しいUpdate Transactionを生成する
  2. Update TransactionのUTXOをInputとして、Outputに残高を反映してSettlement Transactionを生成する

Payment(2回目)

  1. B -> A に0.5BTCを支払うため、Trigger TransactionをInputとして、新しいUpdate Transactionを生成する
  2. Update TransactionのUTXOをInputとして、Output

eltooを可能にするSIGHASH_NOINPUT

通常、Transaction Dataが署名対象のメッセージダイジェストとなるため、Transaction Dataが1部でも変更されるとその署名は無効になる.そのため、現時点でのBTCの使用では実現不可能.

SIGHASH_NOINPUT

インプットが参照する前のTransactionのOutputの情報は全て空になる.署名はTransactionのOutPintにcommitしなくなり、署名後にInputが参照するOutPointの変更が可能になる

eltooのポイント: セトルメント鍵のローテーション

Settlement Transactionに署名する際に、SIGHASH_NOINPUTが使用される.不正があった場合に、対応するUpdate Transactionの参照先が変わると、Update TransactionのTXIDも変わり、Settlement TransactionのInputの参照先も変更する必要がある.

Update Transactionの条件で、セトルメント鍵でunlockする場合、その鍵は各状態ごとに異なる鍵を使用する.キーペアの導出自体はHDウォレット等と同様に、決定論的に導入される.これによりSettlement Transactionは対応するUpdate Transactionのみにbindされる

まとめ

eltooはPayment Channelで旧状態でBroadcastされた際に、罰ではなく、最新の状態を後から置換可能にするコントラストをベースにした 新しい Payment Channelの提案になる