ビットコインについて調べていると「segwit」という言葉をよく目にします。
その目的として以下の2つが挙げられています。
- スケーラビリティ問題の解決(改善)
- トランザクション展性(マリアビリティ攻撃)の問題の問題の解決
あるいはスケーラビリティ問題の解決策の一つとしてSegwitが紹介されているかもしれません。
しかし、スケーラビリティ問題については多くの解説を見つけることができますがトランザクション展性についてのわかりやすい説明はなかなか見つけることができません。
この記事ではトランザクション展性と,Segwitがトランザクション展性の問題がどのように解決したのかをわかりやすく説明します。
トランザクション展性(transaction malleability)とは?
ビットコインの脆弱性の一つとして語られてきたトランザクション展性(transaction malleability)とは何なのでしょうか。
展性(malleability)とは軟らかい金属などに見られる性質のことで物体が破壊されることなく薄く広げられることです。
トランザクション展性とは、トランザクション(取引)の内容自体は変更されることなくトランザクションのIDが変更されうることです。
もう少し詳しく見ていきましょう。
ビットコインのトランザクションはアウトプットとインプットで構成されています。
アウトプット(送信)は
- コインの額
- それを使えるようにする条件(ほとんどの場合が送り先の電子署名)
インプット(受信)は
- 過去のトランザクション
- 署名(送られたコインを使えるようにする条件)
からできています。
トランザクションIDはアウトプットとインプットで構成されるトランザクション全体のハッシュをとることで計算されます。
ハッシュの特徴として、ほんの少しでも内容が違えば値が全く違ったものになるという性質がありました。
トランザクション展性とは、署名の部分に微妙な変更を加えることでトランザクションの内容(取引額、送り主、送り先などの情報)を変えずにトランザクションIDを変えてしまうことができることです。
実際に起こる問題 -マリアビリティ攻撃とは?-
内容が変わらずに取引が成功するなら何も問題はなさそうです。
トランザクションの内容を変えずにIDだけを変更できることの何が問題なのでしょうか?
ビットコインの取引がブロックに取り込まれるには少し時間がかかります。
よって、普通は取引が終わった後にそれが正しく記録されているか確認することになります。
もしもその確認をトランザクションIDで行っていたらどうなるでしょうか?
取引が行われた時のIDと、ブロックに取り込まれた時のIDが変わっていたら・・・。
取引の確認が難しくなってしまいますよね。
取引がブロックに取り込まれていないと思ってしまったら、同じ取引を繰り返してしまうかもしれません。
実際にこの性質を利用した攻撃が行われた例がいくつかあります。
超有名なものに「Goxする」という言葉の語源にもなったビットコイン取引所のMt.Gox事件があります。
巨額のビットコインが消失した事件で、最初はサイバー攻撃によるものと説明されていましたが実際はそのほとんどが社長の横領によるものだった、という事件です。
しかし、消失した分のうち1%は実際にサイバー攻撃によるもので、その手口がトランザクション展性につけこんだマリアビリティ攻撃だったと言われています。
Mt.Goxではビットコインの送金確認にトランザクションIDのみを用いており、ビットコインのブロックを探して当該のIDが無ければ送金に失敗したとみなして自動的に再送金する仕組みを作っていました。
トランザクション展性を利用すれば何度もMt.Goxにビットコインを送金させることができますね。
Segwitによるトランザクション展性の解決
トランザクション展性はSegwitという方法によって解決されました。
Segwitとはトランザクションの署名部分のデータをWitnessという別の部分に移してしまうことです。
それによって署名部分を改ざんしてIDを変えるということができなくなりました。
Segwitの利点としてスケーラビリティ問題の解決(改善)も挙げられています。
もともと署名のデータはトランザクションのデータの約6割を占めていました。
署名データをブロック容量にカウントされない領域(Witness)に移すことでトランザクション一つ一つが軽くなり、一つのブロックに取り込めるトランザクションの数が増える、という仕組みです。
ちなみに、Witnessはcoinbaseという各ブロックの一番最初のトランザクションのアウトプットの中に格納されています。
署名がWitnessに移されてトランザクション一つ一つが軽くなっても署名が無くなるわけではないので、ブロックに取り込まれるトランザクションの数が増えればブロック内の実際のデータ量は増えます。
つまり、現在のブロックに取り込める容量を変更するハードフォークを行わずに実質容量を増やすことができる、というわけです。
データを圧縮しているわけではない、というのがお分かりいただけると思います。
まとめ トランザクション展性とは?
トランザクション展性とは
トランザクションの内容を変えずに署名部分を変えてしまうことができることでした。
マリアビリティ攻撃とは
トランザクション展性を利用して、トランザクションIDを変えてしまうこと同じ処理を繰り返させる攻撃でした。
Segwitによって
署名部分が別の場所に移されて改変できなくなったのでトランザクション展性は解決しました。
加えて、トランザクション一つ一つのデータ量が小さくなり、スケーラビリティも改善しました。