福岡ブロックチェーンエコノミー勉強会vol.3「segregated witness」
TRANSCRIPT
Copyright ©2017 HAW International Inc. all rights reserved.
福岡ブロックチェーンエコノミー勉強会(Vol.03)
Segregated Witness2017 / 08 / 25
株式会社ハウインターナショナル安土 茂亨
Copyright ©2017 HAW International Inc. all rights reserved.
ハウインターナショナル
•Blockchainに関する取り組み
‣2nd Layer技術を中心に研究開発
‣Open Assets Protocolの実装の一つである
openassets-rubyを実装https://github.com/haw-itn/openassets-ruby
‣BitcoinプロトコルのRuby実装(WIP)https://github.com/haw-itn/bitcoinrb
•製品・サービス開発
‣Congrechain
‣ブロックチェーンPoC
‣Open Assets Explorer
Copyright ©2017 HAW International Inc. all rights reserved.
Bitcoinの送金の仕組みと問題
Copyright ©2017 HAW International Inc. all rights reserved.
Bitcoinのトランザクションの構造
Transaction
Input
OutputInput
Output
Output
Transaction
InputOutput
Output
Transaction
Input
OutputInput
Output
Transaction
Input
Input …
入力は既存のトランザクション
の出力と1対1になる
入力に使われていない出力(UTXO)が
使用可能なBitcoinの量
複数の入力と出力から構成される取引の連鎖
入力のBitcoinの合計=出力のBitcoin合計(+手数料)
Copyright ©2017 HAW International Inc. all rights reserved.
Bitcoinを送る(使用する)のに必要なこと
Transaction
InputOutput
Output
Transaction
Input
Output
Output
Output
各出力はBitcoinの量と、そのBitcoinを使用するための
解除条件を記載したスクリプト(script_pubkey)を持つ
出力のBitcoinを使うためには、出力に記載された
解除条件を満たすロック解除スクリプト(script_sig)を持つ
script_pubKeyscript_sig
参照する出力のscript_pubkeyと入力のscript_sigのスクリプトを
結合し実行した結果がTRUEであれば、そのBitcoinの使用条件を満たす
有効なトランザクションと判断される。
Copyright ©2017 HAW International Inc. all rights reserved.
P2PKH = Pay to Pubkey Hash(公開鍵ハッシュへの支払い)
【Bitcoinのもらい方】
1. 受取用にキーペア(秘密鍵・公開鍵のペア)を作成
2. 公開鍵のハッシュからスクリプト(script_pubkey)を生成
3. スクリプトをエンコードしアドレスを生成し相手に伝える
4. 相手はそのアドレス宛にBitcoinを送る
【Bitcoinの送り方】
送金の際の一般的なスクリプト
Transaction
InputOutput
Output
Transaction
Input Output
Output
script_pubKey
script_sig(署名スクリプト)
ある公開鍵のハッシュにロックされたコイン
1. 未使用のOutputをInputにセットし、相手の公開鍵ハッシュに
送る出力を持つトランザクションを作成
2. トランザクションデータからメッセージダイジェストを作成
3. script_pubkeyにセットされている公開鍵ハッシュの元となった
公開鍵に対応する秘密鍵で作成したメッセージダイジェストに
署名する
4. 署名と公開鍵をその入力のscript_sigにセットする
5. トランザクションをP2Pネットワークにブロードキャストする
OP_DUP OP_HASH160 公開鍵ハッシュ OP_EQUALVERIFY OP_CHECKSIG
Copyright ©2017 HAW International Inc. all rights reserved.
トランザクションのmalleability問題
version txincount
txins txoutcount
txoutslocktime
outpoint script_sig sequence script_pubkey value
署名対象
署名データの格納場所は署名されない(改竄ポイント)
TXID = トランザクションの全データから計算
トランザクションデータの一部でも変わると TXIDも別の値になる
署名スクリプト(script_sig)の改竄ポイント
● バイト表現の異なるPUSHDATAへの置き換え
● 余計な空データプッシュの追加
● ECDSA署名の正負を入れ替え。 (R, S)→(R, -S mod N)でもECDSAの署名検証はパスする
悪意あるリレーノードもしくはマイナー
Tx Block
Tx …Tx
ブロードキャスト リレー
改竄
…ブロードキャストした時点の Txとブロックに入ったTxでTXIDが異なる
Copyright ©2017 HAW International Inc. all rights reserved.
Segwitの仕組みと解決する問題
Copyright ©2017 HAW International Inc. all rights reserved.
Segwitで変わるトランザクションの構造
version txincount
txins txoutcount
txoutslocktime
outpoint script_sig sequence script_pubkey value
署名対象
version merker flag txincount
txins txoutcount
txoutswitness locktime
outpoint script_sig sequence script_pubkey value
署名スクリプトの格納場所を新たに設けたwitnessに移動し、script_sigは空に
従来のトランザクション構造
Segwitのトランザクション構造(太字が新規追加フィールド)
TXIDの計算は従来のトランザクション構造のフィールドが使用され、かつ scirpt_sigは空であるため、
署名スクリプトが改竄されても TXIDは変わらない。
未署名でもTXIDが決まるということは、未署名のトランザクションチェーンが
作れるということを意味し、双方向のオフチェーン決済が可能になる。重要なポイント
Copyright ©2017 HAW International Inc. all rights reserved.
新しいシリアライゼーションフォーマットの導入
version merker0
flag1 Inputs Outputs witness locktime
新しく追加されたmarker、flag、witnessフィールドを含むシリアライゼーションフォーマットを定義。
Segwit対応Node
Segwit非対応Node
● TXID従来のシリアライゼーションフォーマットでシリアライズして算出
● WTXID新しいシリアライゼーションフォーマットでシリアライズして算出
witnessデータを含むため、署名データへのコミットメントになる
ノードはリモートノードと接続する際に、自身がサポートする service bitを通知する。
Segwitに対応したノードは を service bitに適用する。
Segwit対応Node
handshake handshake
NODE_WITNESS = ( 1 << 3 )
tx relay tx relay
新フォーマットTx 旧フォーマットTxSegwit対応ノード間では
新フォーマットを使用
Segwitに対応していないノードに対しては旧
フォーマットを使用。
※ witnessの署名データは含まれず、
CLEANSTACKチェックにより非標準Txとし
て扱われるため、このTxを他のノードにリレー
することはない。
Copyright ©2017 HAW International Inc. all rights reserved.
新しい署名検証の仕組み
署名に使用するメッセージダイジェストの生成方法が変わる。
Segiwtトランザクションのメッセージダイジェスト項目
nVersion
hashPrevouts(全入力のOutpointから生成したハッシュ)
hashSequence(全入力のsequenceから生成したハッシュ)
outpoint(署名対象の入力のOutpoint)
scriptCode
value(署名対象の入力が持つコインの量)
nSequence(署名対象の入力のsequence)
hashOutputs(全出力から生成したハッシュ)
nLocktime
sighash type
従来のメッセージダイジェスト項目
nVersion
nInputs(全入力の数)
全入力のペイロード(Outpoint,sequence,script含む)
nOutputs(全出力の数)
全出力のペイロード(script_pubkey, value)
nLocktime
sighash type
入力が使用するコインの量を明示的にダイジェストに
組み込むことで、ハードウェアウォレットのようなオフライン
デバイスでも、支払いに使用するBitcoinの量を認識した上
で署名をすることができるようになる。追加・変更項目
上記のデータをダブルSHA-256ハッシュした値に対し、署名をする
Copyright ©2017 HAW International Inc. all rights reserved.
Segwitのトランザクションを作る条件
● P2WPKH = Pay to Witness Pubkey HashP2PKHのSegwit版でscipt_pubkeyは以下の形式
先頭の0はwitness versionで、2つ目の要素がwitness program(↑の場合はP2WPKH)で、
P2WPKHの場合その長さは20バイト。
scipt_pubkeyがP2WPKH形式の場合、トランザクションの Inputのscript_sigは空で、署名と公開鍵を
witnessフィールドに配置する。
● P2WSH = Pay to Witness Script HashP2SHのSegwit版でscript_pubkeyは
P2WSHの場合witness programはredeem scriptのハッシュで、その長さは 32バイト。
トランザクションのscript_sigは空で、redeem scriptとそのスクリプトを満たすのに必要なアイテムを
witnessフィールドに配置する。
0 公開鍵ハッシュ
version merker flag txincount
txins txoutcount
txoutswitness locktime
outpoint script_sig sequence script_pubkey value
0 スクリプトハッシュ
Copyright ©2017 HAW International Inc. all rights reserved.
Segwitのトランザクションを作る条件
【注意事項】
Segwitがアクティベートされても全てのトランザクションがwitnessに署名スクリプトを
配置するわけではない(そうすると後方互換性が無くなるので)
● 従来のP2PKHやP2SHのUTXOを使用する場合は今までどおり、script_sigに
署名スクリプトを配置する必要がある
● トランザクションを作成する際、全入力のうち1つでもP2WPKH、P2WSH以外の
script_pubkeyでロックされたコインがあると、その入力の署名スクリプトは
script_sigに配置されるので、malleabilityによりTXIDが変えられる可能性がある。
● P2WPKHやP2WSHで使用できる公開鍵は圧縮公開鍵のみで非圧縮公開鍵は使
用できない。
Copyright ©2017 HAW International Inc. all rights reserved.
SegwitのアドレスフォーマットBech32
新たなエンコード仕様Bech32とそれを利用したアドレスフォーマットを定義
https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
● BCH符号を採用しており、エラー訂正が可能Segwitのアドレスではチェックサムが 6文字で最大4文字のエラー訂正が可能
● 大文字小文字の区別が無い音声読み上げが可能で、QRコードも大文字の英数字モードで作成出来るためコンパクトになる
human-readable separator(1固定) data
人間が識別するためのフィールドでASCIIコード33〜126で構成される。
Segwitアドレスの場合はmainnetはbc、testnetはtb
データとチェックサム(ラスト6文字)で構成される。
Segwitアドレスの場合、witness versionとwitness programの
データを変換してエンコードしたデータで構成される。
BC 1 QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4
00 751e76e8199196d454941c45d1b3a323f1433bd6witness programwitness version
ビット列に変換し、5つにグルーピングし、変換表を元にアドレス文字列に変換
SegwitのトランザクションにするにはBech32に対応したウォレットが必要
Copyright ©2017 HAW International Inc. all rights reserved.
witnessの署名へのコミットメント
Blockブロックヘッダ
バージョン
前のブロックのハッシュ
マークルルート
ブロックの生成時刻
difficulty(bits)
Nonce
ハッシュ 12 ハッシュ 34
マークルート
ブロックにはそのブロックに含まれる全トランザクションのTXIDから算出したマーク
ルツリーのマークルルートが格納されており、これがブロックが保持する全トランザ
クションのデータに対するコミットメントになる。
TXID1 TXID2 TXID3 TXID4
※ TXIDを元に算出されているので、witnessフィールドの
署名スクリプトに対してはコミットできてない。
ハッシュ 12 ハッシュ 34
マークルート
0x00...0 WTXID2 WTXID3 WTXID4
【witnessを含むコミットメントの追加】
witnessの署名データを含むWTXIDをベースにマークルツリーを構築し、
そのマークルルートを、コインベーストランザクションの出力の1つに
格納することでwitnessのデータまで含めたコミットメントとする。
※ 既存のマークルルートと同様、ブロックヘッダに項目を追加すると
ハードフォークになってしまうため↑の形に。
witnessまで含めたコミットメント
Copyright ©2017 HAW International Inc. all rights reserved.
ブロックサイズの計算方法の変更
【今までの計算方法】
1つのブロックに格納できるトランザクションサイズ = 1MB
【Segwitアクティベート後の計算方法】
block weight = ベースサイズ × 3 + トータルサイズ
block weight <= 4MB● ベースサイズ
従来のシリアライゼーションフォーマットでシリアライズしたデータ(witnessの署名スクリプトを含まない)
● トータルサイズ
新しいシリアライゼーションフォーマットでシリアライズしたデータ(witnessの署名スクリプトを含む)
ブロック内のトランザクションが全て既存のP2PKHやP2SHの場合、その署名スクリプトは全てsript_sigに格納され
ているため、ベースサイズとトータルサイズは変わらず、既存の1MBと同じサイズ分しかブロックには入らない。
そのためP2WPKHやP2WSHのトランザクションが主流にならないとスケールメリットは薄い。
witnessに移動したデータ分、より多くのトランザクションを
ブロックに格納できるようになる
Segwitが主流になったとしてもブロックに入れられるサイズは実質 1.6〜1.7MBくらいと思われ
る
Copyright ©2017 HAW International Inc. all rights reserved.
オフチェーン決済のために必要な機能
アリス ボブ
Opening Transaction
2-of-2 マルチシグ
アリスとボブの 10 BTC
オフチェーン決済に使用するコインを登録
Commitment Transaction
Opening Tx
4BTCをアリスに
6BTCを以下のマルチシグに■ 1000ブロック経過したらボブの鍵で入手可能■Secret B1が分かればアリスの鍵で入手可能
Commitment Transaction
Opening Tx
6BTCをボブに
4BTCを以下のマルチシグに■ 1000ブロック経過したらアリスの鍵で入手可能■Secret A1が分かればボブの鍵で入手可能
オフチェーン決済のトランザクションを作成&交換 オフチェーン決済のトランザクションを作成&交換
…① 最初Opening Txをブロードキャスト
する前にそのTXIDが確定する必要が
ある。
(TXIDが変わる可能性がある場合は、
有効期限付きのチャネルになる)
② オフチェーン決済で作成する
Commitment TxのTXIDが確定する必
要がある。(裏切りの監視のため)
双方向のオフチェーン決済のためには未署名のトランザクションチェーンが作れる必要があり、Segwitによりそれが可能に!