トランザクション・マリアビリティとは? ビットコインの脆弱性について探る
<この記事(ページ)は 9分で読めます>
ビットコインの脆弱性としてよく挙げられるのが、トランザクション・マリアビリティです。
malleability(マリアビリティ)は、malleable(鍛えられる、順応性のある)という形容詞の名詞形で、トランザクション・マリアビリティとはトランザクション展性と呼ばれることもあります。しかし、トランザクションに展性があるといわれてもしっくりきません。
そこで、ここではトランザクション・マリアビリティの意味について、技術的な観点から説明します。
トランザクションとは
そもそも、トランザクションとなんなのか整理しましょう。
トランザクションとは、一言でいうとブロックチェーン上に書き込まれる取引の記録のことです。つまり、ビットコインを介した取引が行われる際にトランザクションが作成されます。
具体的にはトランザクションとは、簿記の個々の取引行のようなもので、インプットの項とアウトプットの項から構成されています。インプットは支払い、対してアウトプットは受け取りで、インプットの項は「お金をその本当の持ち主が送信する(または送信した)」という内容を表し、アウトプットの項は「お金を誰がいくら受け取る(または受け取った)」という内容を表します。
インプット
取引においてインプット、すなわち送金する側のウォレットでは、まず初めにそれ以前のトランザクションの中から自身へのアウトプットで未使用のアウトプットを含むトランザクションを探し出す作業を行います。これは送金しようとしている人が実際にその支払い能力があるかを確認するためです。これにより支払い能力の裏付けが取れると、送金者宛の未使用のアウトプットの一部を用いてインプットを行います。
トランザクションのインプットの項では、このように送金者の支払い能力を示す過去のアウトプット(以降ではUnspent Transaction Outputの略称をとってUTXOと呼ぶことにします)が示されます。具体的にはUTXOのトランザクションIDと呼ばれる32桁の文字列とUTXOの索引番号と呼ばれる4桁の通し番号で指定されます。なお、トランザクションIDとは、トランザクションのインプットとアウトプットとを合わせたものをハッシュ関数に入力した出力値として得られます。
さらに、これだけでは送金しようとしているユーザーがそのお金の正当な持ち主なのかサーバーが判断できないため、自分が持ち主だと証明するための電子署名を行います。そして電子署名により自分が本人であることを誰でも確認できるようにするため、公開鍵を同封します。こういったトランザクション自体に関わらない、認証に関わる情報が含まれるscriptSigと呼ばれる領域があります。
アウトプット
一方、アウトプットの項には、送金をアウトプットすなわち受け取る人についての情報、そして送金されたコインの額が含まれます。そしてさらに、送金を受け取った本人以外がそのコインを使うことができないようにするためこのコインに鍵をかけます。具体的には、送られたコインを次回使用するときには本人であることを認証するためにどのような手法を用いるか、ということを指定します。たいていの場合は電子署名が用いられるのですが、このようなコインの解錠条件を指定する領域のことをscriptPubKeyと呼びます。
このscriptPubKeyと、インプットのところで説明したscriptSigが施錠と解錠の関係になっています。以上が、トランザクションについての説明です。
具体化
少し抽象的な話になったので、具体例で考えてみましょう。
過去に5Bitコイン入金したAさんがBさんに4Bitコイン送金する場合、どのような流れになるか追ってみましょう。
送金主であるAさんのウォレットは、Aさんから4Bitコイン送金したいという指示を受けると、Aさんが4Bitコイン持っているかどうかを過去のトランザクションを遡って調べます。すると、過去にAさんが5Bitコイン入金した(もしくはCさんに円を支払ってBitコインを得た)というトランザクションが見つかります。そのトランザクションを証拠にするため、トランザクションIDと索引番号でトランザクションのインプットの項の上に記録します。
次に取引を実行するには支払いを要求しているのがAさん本人であるという確認をとることが必要になります。Aさんが5Bitコイン入金したトランザクションのアウトプットの項のscriptPubKeyを参照するとAさんの電子署名が要求されるので、Aさんは電子署名を行います。そして自分自身だという証明のために公開鍵を同封して、これをscriptSigに記録します。
また、電子署名によりAさん本人であることが確認されるとAさんの送金が可能となり、Bさんを指定する情報、Bさんに4Bitコイン送るということ、そしてBさんがここでのアウトプットを次回インプットするときの本人確認として電子署名を求めるscriptPubKeyで鍵をかけるということをアウトプットの項に記録してトランザクションの完成です。
トランザクションIDの発行
それでは、具体例で理解を深めたところで、本題のトランザクション・マリアビリティの話に入りましょう。まずは、トランザクション・マリアビリティという問題の責任の一端を担っているビットコインの特徴を紹介します。
その特徴とは、トランザクションIDの発行主体が存在しないということです。このこと自体は致命的な欠陥でもありませんし、そもそもこれ自体はハッシュ関数の性質を考えると全然問題ないのですが、別の欠点と絡むとトランザクション・マリアビリティという問題を生じます。順を追って説明します。
トランザクションIDは発行主体がないため、必要になるとトランザクションのデータをハッシュ関数に入力することで計算されます。
まず、送金主が電子署名により取引が有効なものとして認識されると、インプットとアウトプットのデータからトランザクションIDが計算され、送金主は自分のウォレット上でトランザクションIDを計算することができます。
その後、このトランザクションがP2P通信を介してマイナーのもとに伝えられ、マイナーがマイニングによりこのトランザクションをブロックに取り込むと、マイナーはトランザクションIDを計算してブロックに取り込まれたトランザクションのトランザクションIDを報告します。
ユーザーはこの報告を確認することで自分の行った取引が確実にブロックに取り込まれたのか確認することができます。送金主がトランザクションIDを計算するときに用いるトランザクションのデータと、マイナーがトランザクションIDを計算するときに用いるトランザクションのデータが完全に一致していれば、ハッシュ関数の出力値も当然同じものになるので、このようなシステムでなんら問題はありません。
改ざんの可能性
しかし、ビットコインにもある欠点があります。それはP2P通信を介してマイナーのもとに伝えられる途中でトランザクションの一部の領域がハッカーによる改ざんを受ける可能性があるのです。その領域とは、トランザクションの説明の中で出てきた、scriptSigです。
これは、トランザクションの内容を改変するとマイナーたちにより簡単に検出されるのですが、取引が成立している時点で有効だと保証されたscriptSigに対して改変を検出するのが難しいためです。このようにしてハッカーによりscriptSigが改変されると、衝突耐性をもつハッシュ関数に入力して得られるトランザクションIDも元のトランザクションのトランザクションIDとは異なったものになります。
この結果、送金主の認識しているトランザクションID(以降「純トランザクションID」と呼びます)とハッカーにより改変されたトランザクションID(以降「改変トランザクションID」と呼びます)とが二重に存在します。このように同じトランザクションに対して複数のトランザクションが存在しうる、ということをトランザクション・マリアビリティといいます。
そして、もし仮にマイナーのもとに改変トランザクションIDが純トランザクションIDよりも先に伝えられると、マイナーは改変トランザクションIDをこのトランザクションの正規のトランザクションIDとして認識するので、純トランザクションIDが伝えられたときには二重支払いと認識されて支払いが拒否されます。送金主は、実際にはトランザクションが成立しているにもかかわらず、自分の知っている純トランザクションIDのトランザクションが拒否されているため、出金が拒否されたと勘違いしてしまいます。
そして、多くのウォレットでは、ウォレット上で認識されているトランザクションIDをもつ取引が拒否されると、自動で同じ取引を繰り返すようになっています(改ざんを受けた場合に限らず取引が拒否されることは起こりうるため)。そのため、実際には済んでいる取引をまだ済まされていないものと認識して何度も繰り返してしまう、ということが起こり得ます。これがトランザクション・マリアビリティの大きな問題点です。
トランザクション・マリアビリティの解決策
このように重大な問題を生じ得るトランザクション・マリアビリティですが、なんと解決策があります。
それは8月1日危機をめぐって大きな争点となったSegWitです。8月1日危機ではビッグブロックとSegWitというブロックサイズ問題の解決策として対比されたため、SegWitというとブロックサイズ問題の解決策やASIC BOOSTを防ぐなどといった特徴が有名ですが、SegWitにはトランザクション・マリアビリティの解決策という側面もあります。SegWitのブロックサイズの問題についてはこちらの記事をご覧下さい。
SegWitというのは、簡潔にいうと、インプットのうちscriptSigを別物として扱い、ビットコインのメインのブロックチェーンに記録するのではなく、サイドチェーンに記録するという技術です。これによってハッカーによる改ざん可能なscriptSigを除いた領域がトランザクションIDを指定するため、トランザクションIDが一意的に決定します。すなわち、送金主の認識しているトランザクションIDとマイナーに報告するトランザクションIDにズレが生じる可能性がなくなります。
まとめ
トランザクション・マリアビリティとは、トランザクションのうち取引結果に直接的に関係しないscriptSigという領域が、直接関係しないがためにハッカーからの攻撃を受けやすく、1つのトランザクションにつき複数のトランザクションIDが発生し得るということです。
その結果、送金主が本当は完了されたトランザクションを完了されていないかのように誤認する可能性がある、さらにはウォレット自身がそのような誤認をすると同じ払込を複数繰り返すことにより送金主の知らないうちにビットコインが大量に振り込まれる可能性もある、というのが問題点です。
トランザクション・マリアビリティはブロックサイズなど、多くの問題点を解決するSegWitにより解決されました。実は、ビットコインはLightning Networkというサイドチェーンにより小口の支払いの迅速化および手数料の低価格化を目指していたのですが、トランザクション・マリアビリティの問題から開発が行き詰まっていました。
SegWitによるトランザクション・マリアビリティ解決のおかげで、安全性の向上のみならず、Lightning Networkを始めとする新技術のさらなる発展が見込めます。