久しぶりの更新。時事ネタではなくあまり面白い内容でもないかもしれませんが、書きかけだったので今年中に投稿しておきます。
今回は主に「UTXO」という単語について解説してみたいと思います。ビットコインについて多少勉強したことがある人ならだれでも耳にしたことがある単語だと思います。
ブロックチェーンでの2つの残高管理の方法
ビットコインのような電子通貨の残高を管理するには大きく分けて二つの方法があります。
一つ目は、単純にアカウント(アドレス)の残高を直接データとして記録し管理する方法です。イーサリアムなどで採用されている方法で、特に説明の必要もないほどわかりやすい単純な方法です。
二つ目は、取引データのみをデータとして記録・管理し、残高を取引データから算出する方法です。例えば、アドレスAからBへ10BTC、アドレスBからCへ3BTC移動させるとき、二つの取引から算出してアドレスBには7BTC残っているということが分かります。二つだけの取引なら良いですが、現実的には莫大な量の取引データが存在し、そこから残高を算出しなければならないという非常に面倒な方法で、ビットコインではこの「UTXO」ベースの管理方法が採用されています。
UTXOとは
UTXOとはUnspent Transaction Outputの略で「未使用のトランザクションの出力」と訳せます。UTXOの正体はコインそのものであり、現実世界の現金と同じようなものとして考えられます。現実の財布でも、銀行口座(=残高を直接記録するアカウントベースの管理システム)のように一目で見て残高が分かるわけではなく、一個一個のコインやお札を数えないと合計の残高は分かりません。ただし、UTXOは勝手に盗まれては困るので、現金とは異なりパスワード(=秘密鍵)を知る所有者以外使えないように、所有者(アドレス)情報も付加されています。
ビットコインにおけるトランザクション(=取引データ)は入力(Input)と出力(Output)の二つから構成されています。有効なトランザクションであるためには、①入力にはUTXOとそのUTXOに対応する(秘密鍵から作成される)署名が含まれなければならない②出力部分の合計のコイン量は入力部分より少なくなければならない、という二つの条件が主にあります。①は所有者以外がコインを消費するのを防ぐためであり、②は自分が持っている以上の量のコインを消費できないための当然のルールです。
このトランザクションが送信・承認された後、入力部分に含まれていたUTXOは文字通り使用・消費されているので、もはや「未使用」ではなくUTXOでもなくなります。代わりに出力部分で指定した条件の通り、新しいコイン量と所有アドレス情報が含まれるUTXOが新しく生成します。
UTXOは、現実のお金と同様にカットしたり合体させたりすることはできませんが、トランザクションを介すことで、いわばトランザクション=両替のようなかたちで、細かいお金をまとめたりすることも可能です。
最初のUTXOは採掘者がブロック生成報酬として得たビットコインであり、最初のUTXOが消費され次の新しいUTXOになり、そのUTXOが消費されまた新しいUTXOとなり・・・というように巡り巡って世界中の人々のウォレットの中にUTXO(=コインそのもの)が届くわけです。
UTXOベースのシステムがアカウントベースよりも優れている点
プライバシー・匿名性
UTXOベースのシステムが優れているのが匿名性です。その理由は、UTXOベースのほうがアドレスの再利用が回避しやすくなっているためです。
例えば、アドレスAが所有する5BTCのUTXOを使用してアドレスBに4BTC送信したいときを考えます。このとき、ただ単にアドレスBへの4BTCの送金指示をしただけでは、アドレスAにおつりは戻ってきません。ビットコインでは、入力と出力の金額の差は取引手数料としてマイナー・採掘者に自動的にプレゼントすることになってしまうためです。この場合だと、1BTCも取引手数料として取られてしまうことになります。そのため、4BTCをアドレスBに送るだけではなく、お釣りとして1BTCを自分のアドレスを指定しなければなりません。このアドレスには元の自分のアドレスAを指定しても新しい自分のアドレスCを指定しても大した違いはないので、どうせなら追跡を難しくしようとプライバシーのために新しいアドレスCをお釣り用アドレスとして指定する動機が生まれ得ます。
一方で、イーサリアムのようなアカウントベースのシステムの場合を考えます。アカウント(アドレス)の残高が直接データとして記録されているので、アドレスAにある5ETHのうち4ETHをアドレスBに送りたい、といったとき、単純にアドレスBへの4ETHの送金指示をするだけで済みます。ここから、アドレスの再利用を防ぐために新しい自分のアドレスに送ろうとすると、余分に新たな送金先のデータを追加しなければならず、その分送金手数料も含めてコストが増加してしまい、アドレスの再利用を防ぐインセンティブが削がれてしまうのです。また、特にイーサリアムの場合は、スマートコントラクトの仕様によってはアカウントの再利用を強制させられてしまうこともあります。
ただし、アドレスの再利用さえしなければ、どちらもプライバシーの観点からは変わりません。あくまでアカウントベースは、再利用を避けるような設計になっていないというだけです。
議論が分かれる点
実装が単純
議論が分かれるという中には入れましたが、実際はアカウントベースのほうが有利とされることが多いのが、実装が単純という点です。
ウォレットの開発を考えてみましょう。アカウントベースの場合、ブロックチェーンに直接残高情報が記録されているので、そのデータを読むだけで残高を知ることができます。また送金を行う際にも、そのアカウントの残高から送金額(+手数料)を引けばいいだけなので、非常に単純に実装することができます。
一方でUTXOベースの場合を考えてみましょう。残高を知るだけでも、UTXOを集めてそこから合計の残高を算出しなければならないという作業が加わります。しかし、特に面倒なのが送金作業を考える際です。送金作業ではどのUTXOを支払いに使用するかを決めなければなりません。取引手数料やデータサイズ削減のためこのUTXOの選択作業がかなり複雑になるのです。
これは現金でのやりとりとまさに同じです。123円のような買い物で小銭で支払えるのにも関わらず、小銭をいちいち出すのが面倒だからといって、毎回千円札を出していると小銭が溢れて財布の中身が訳の分からないことになるのによく似ています。溢れた分は貯金箱・・・という人もいるかもしれませんが、ビットコインではそういう訳にはいかないので、最終的には細かくなった小銭からなんとか探し出して払うしかありません。
特にビットコインの場合、取引手数料が取引データのサイズから決定されるという特徴があります。つまり、「小銭」ばかりをまとめて使っていると手数料が大きくなってしまうというデメリットもあるのです。そのため、毎回なるべく少ない数のUTXOからなるべくお釣りが小さくならないようにUTXOを選ばなくてはなりません。さらにいえば、取引承認の優先順位は、「Coin Age」というどれだけUTXOの未使用期間が長いかという指標も考慮されるので、できるだけ古いUTXOを選んだほうが良く、(coin ageの概念は使用されなくなりました。)また、プライバシーを考えたければ異なるアドレスのUTXOはなるべく使わないようにしなければなりません。
これらの事情をすべて考慮すると多くの条件分岐のコードを書かなければならなくなってしまいます。
現実問題として、ビットコインでは実装が面倒だったり取引手数料の仕組みが初心者にはわかりづらかったりする程度で、UTXOによる複雑さはそこまで大きな問題にはなっていないのですが、イーサリアムのように通貨情報だけではなくスマートコントラクトのために他の情報を付加する必要があるような複雑なシステムの場合は、複雑さが大きなデメリットとなり得ます。実際に、イーサリアムだけでなく、NxtやNEMのような通貨機能だけにはとどまらないプラットフォームの多くが同様のアカウントベースのシステムを採用しています。
しかし、アカウントベースのシステムが単純で万々歳かというとそういう訳でもありません。例えばアカウントベースの場合、Replay Attackという攻撃に対する耐性が低いと考えられています。Replay Attack自体の話からはじめないといけないので詳しくは省略しますが、これは、ビットコインがトランザクションベースであり、UTXOを消費するたびに新しいUTXOが生成されるので、アドレス内の残高の内訳(=UTXO)を区別するのが容易ということに主に起因しています(例えば、ビットコインがETCのようにフォークしたとき、同じアドレス内のオリジナルビットコインとフォークビットコインを一度分離すれば、その後は同じアドレス内に移動させてもUTXOが異なる場合、そもそもReplayできません。)一方で、イーサリアムのようなアカウントベースでは、基本的に残高ベースで管理されているので、その残高がどのトランザクションからきたものかということは気にされず、同じアドレスに二つ以上のフォークしたブロックチェーンのコイン残高がある場合、見分けるのが非常に難しくなり、簡単にReplayできてしまいます。
イーサリアムにもトランザクションにnonce(=ワンタイム識別子)をつけることで簡単に二重支払いができない仕組みがあり完全に無防備というわけではありませんでしたが、実際にイーサリアムクラシックが生まれた際にはReplay Attackが広く発生してしまいました。この対策には、UTXOよりもアカウントベースのほうが複雑な仕組みを要します。
スケーラビリティが優れている
理論的には通信速度・帯域的な意味でUTXOベースのほうがアカウントベースのほうが優れているとされています。これは、同じアドレスからの送金を考えた際に、同じ金額であっても複数のUTXOを別々に並行処理できるためです。アカウントベースの場合は、逐次的に一個一個処理するしかありません。しかし、現実的には入力部分のUTXOが複数になるとサイズも増加し手数料が増え、また、実際に都合よく複数のUTXOを使えるような場面が多いわけではなく、UTXOをウォレット内に無駄に増やそうとすると前述のように複雑になってしまう問題もあるので、現実的なメリットはほとんどないと考えられます。
HDD容量的な意味で優れているとされるのがアカウントベースのほうです。単純に全アドレスよりも全UTXOの数のほうが多いので、UTXOのデータをすべて保存するよりもアカウントの残高を直接記録・保存するだけのほうがサイズが小さくなるイメージは分かると思います。実際にビットコインのスケーラビリティ問題の一つとして、UTXO全体のサイズ増加も大きな問題として挙げられています。
とはいえ、アカウントベースはスケーラビリティの点から見て優れていると断言できるほど単純ではありません。単なるウォレットならまだしも、ノードやネットワーク全体を考えた時、実際問題、残高情報だけを記録しているだけでは二重支払いや前述のReplay Attackを防ぐのは難しく、取引データに関連する情報も保存・一部参照しなければならないため、むしろUTXOだけで良いのに残高情報など余計なデータを管理している分UTXOベースのほうが優れているとも考えられます。
まとめ
結論的にはどちらのシステムも一長一短があり、どちらが良いとは一概に言えないものです。
普通のユーザーはUTXOなんて知る必要はありませんが、知っていればビットコインの取引手数料決定の仕組みなどについてちょっと理解がしやすくなるかもしれません。