ビットコインの情報サイトの運営者ブログ

サイトには掲載していない仮想通貨に関する時事的な情報や個人的な感想など。中級者以上向け。

Segwitとは何か?

最近話題のSegwitとは何なのでしょうか?
一言でいってしまえば、ビットコインの取引データ内に従来含まれていた署名を分離して別の領域に格納する、ということなのですが少しだけ細かく説明してみたいと思います。

前提知識

Segwitについて理解するには、ビットコインのトランザクション(取引データ)に関する基礎知識がある程度必要です。

inputとoutput

ビットコインのトランザクションはinput(入力)とoutput(出力)という二つの要素に分けられます。inputには、送信元の情報が含まれ、outputには、送信先の情報が含まれます。一つのトランザクション内にinputやoutputが複数存在することもあります。

inputとoutputのビットコイン量の差(input-output)は取引手数料となります。取引手数料はcoinbaseと呼ばれる特殊なトランザクションによって、ブロックを生成したマイナーにブロック生成報酬(現在は25BTC)とともに付与されます。

scriptSigとscriptPubKey

inputにはscriptSigと呼ばれるスクリプト(単純なプログラムコード)が含まれています。scriptSigは、取引の署名及び公開鍵などから構成されています。署名は、送信元のビットコインアドレスの秘密鍵を使用して作成される、アドレスの所有権を証明するためのデータです。署名と公開鍵を利用することで誰でもその署名が正しいことを検証できます。

一方、outputにはscriptPubKeyと呼ばれるスクリプトが含まれています。scriptPubKeyは、送信先アドレスの公開鍵のハッシュ 値などから構成されています(送信先の相手に教えてもらったアドレスから公開鍵そのものを直接生成することはできません。ビットコインアドレスは公開鍵の ハッシュ値を人間の目でも判別できる文字列に変換したものです。)。

scriptPubKeyは「ロックスクリプト」とも呼ばれ、「次のトランザクションのscriptSig内に対応する署名が含まれていなければならない」という意味のコードが書かれており、秘密鍵の所有者以外ビットコインを使用できないようにロックする役割があります。ロックという観点でいうと、scriptSigは「ロック解除スクリプト」です。秘密鍵の所有者のみがscriptSig内に署名データを入れてビットコインのロックを解除することができます。

Segregated Witnessとは何か?

Segwit(Segregated Witness)とは、従来scriptSigに含まれていたデータを、分離して全く別の領域に格納することです。この新しいデータ領域のことはwitnessと呼ばれており、取引データとは別に署名データとしてまとめられ、まとめられたwitnessはcoinbaseトランザクション内に格納されます。

従来のscriptPubKeyの内容を、「scriptSig内に対応する署名が含まれていなければならない」という意味のスクリプトから、「witness内に対応する署名が含まれていなければならない」という意味のスクリプトに変更するものでもあります。

Segregated Witnessのメリット

トランザクション展性の修正

現在、ビットコインには「トランザクション展性」と呼ばれる脆弱性があります。そもそもビットコインでは各トランザクションを識別するために、トランザクションID(txid)と呼ばれるトランザクションのデータ全体のハッシュ値が使われます。取引の内容(送信先・送信元アドレスとビットコイン量)を変更することなく、このトランザクションIDだけを変更できる脆弱性をトランザクション展性と呼びます。

トランザクション展性を利用した攻撃方法は主に二つに分けられます。一つ目は単純に秘密鍵の所有者が署名データを作り直すことで、署名以外は同じ取引内容 を保ったままトランザクションIDを変更する方法です。二つ目は、第三者がトランザクションIDを変更する方法です。ビットコインのトランザクションには 署名そのものや取引内容以外にあまり重要でない誰でも変更できるデータが含まれており、このデータを変更することで誰でもトランザクションIDが変更でき てしまいます。

このトランザクション展性は、トランザクションIDのみをトランザクションの識別に利用しているウォレットで特に問題が発生します。IDを改ざんされたトランザクションがブロックに取り込まれ確認された場合、取引(改ざん後)が完了しているのに、最初にウォレットから送信された取引(改ざん前)とはトランザクションIDとは違うために、ウォレット内では取引(改ざん前)が完了したと見なされず、ウォレット内の残高の不一致が発生してしまいます。最初の改ざん前のトランザクションはノードから二重支払いとみなされ、無効な取引として弾かれてしまうためです。

Segregated Witnessでは、署名その他のトランザクションIDの計算に使われるデータをトランザクションとは別の領域に格納することで、トランザクションIDの変更ができなくなります。

これによって、取引所やウォレットの開発者にとっては取引の追跡に単純にトランザクションIDのみを利用すれば良くなりコードが単純になるという利点の他 にも、トランザクション展性を利用した二重支払いのリスクがなくなる利点や、Lightning Networkという新しい技術の実装が容易になるという利点なども挙げられています。

トランザクション展性を利用した二重支払いというのは、約10分かかる「確認」前の状態の未確認のビットコインを使用する場合などに発生します。例えば、取引所Aから攻撃者Bに1BTCを引き出した後、未確認の状態ですぐに攻撃者Bから店舗Cにその1BTCを商品代金として送信したとします。この時、店舗Cが未確認状態のトランザクションであっても送金完了とみなしている場合、攻撃者Bは取引所Aからの引き出しのトランザクションIDを変更することで、店舗Cへの支払いのトランザクションが無効と見なされ、支払い完了として扱ってしまったのに実際には店舗Cへ支払われないという状況になります。(トランザクションもブロックと同様にチェーン状になっているため、前のトランザクションが改ざんされると後のトランザクションも無効と見なされます。)

Segwitにより不可能になるのはこのタイプの二重支払いのみであり、他にも未確認状態での二重支払いの方法は存在するので、未確認のトランザクションを送金完了とみなすことにリスクが伴うことはSegwitの採用後も変わりません。

ブロックサイズ制限の実質的な上昇

現在ビットコインのブロックには1MBというブロック制限があり、この制限が原因でスケーラビリティ問題として最近のビットコインの最重要課題となっています。

そのスケーラビリティ問題の一つの対応策となるのがSegwitです。署名を分離することで、その署名分のサイズがブロックサイズの制限(1MB)には考慮されず、実質的に1MB以上の取引をブロックに含めることができるようになります。

Segwitの導入と同時に新たなブロックサイズの制限の様式も導入される予定であり、以下の式で表されます。

witnessを除いたブロック + witness/4 ≦ 1MB

旧バージョンからみた場合は、ブロック≦1MBというかたちを変更することなくSegwitを実装することになります。

もしも取引データがすべてwitnessであれば、最大4MBの取引データが格納できることになります。しかし、これはあくまでも理論的な話であり、取引データのすべてが署名データということは現実的にないため、実際にはせいぜい1.6~2MB程度になると考えられています。なお、ブロックにおける署名データのサイズの割合が増えるほどより多くのサイズが格納できることになるため、いわゆる署名が複数となるマルチシグネチャアドレスからの送信が増えるほど、実質的なブロックサイズ制限が上昇します。

witnessのデータ量は4分の1のみが取引データの総サイズとして考慮されるため、Segwitには副次的に取引手数料が減る効果もあるとされています(ビットコインの必要取引手数料は取引データのサイズが大きいほど高くなります。)。

その他のメリット

主なメリットは上記二つですが、その他にも新しい技術の実装が容易になるとか、軽量ウォレット(SPVクライアント)のセキュリティが増すとか、様々なメリットがあると言われています。

全てについて詳しく書こうとすると、専門的で難しい内容も多いのでとりあえずはここまでにしたいと思います。

参考リンク

bips/bip-0141.mediawiki at master · bitcoin/bips · GitHub

Bitcoin Core :: Segregated Witness Benefits

Bitcoin Core :: Bitcoin Capacity Increases FAQ