ブロックチェーンの課題と可能性~BBc-1(Beyond Blockchain One)から学ぶブロックチェーン開発

第6回UTXO型のトランザクション

前回に引き続き、BBc-1のトランザクションの構成の仕方について具体例を交えて解説します。今回は、UTXO(Unspent Transaction Output)型について説明します。

UTXOとは

UTXOはビットコインをはじめ、多くのブロックチェーンプラットフォームで採用されています。ネットや書籍など情報源はたくさんありますのでここで詳細は説明しませんが、エッセンスだけ紹介します。

UTXO型のトランザクションには、帳簿(仕訳帳)と同様の考え方で、トークン取引そのものを記録していきます。取引そのものの記録というのは、⁠誰から誰にいくら支払った」という情報です。記録する情報には1つ工夫があり、⁠おつりを自分に返す(支払う⁠⁠」という取引情報を必ず含めるようにします。自分への支払い記録の中で、まだどのトランザクションからも参照されていない、すなわち支払いに利用されていないトークンを「未使用なトランザクション出力」⁠Unspent Transaction Outputをそのまま訳した意味)と見なしています。この工夫により、支払いに必要な額になるようにいくつかのUTXOを見つけて積算すれば、それら取引情報に含まれているトークンを支払いに充てることができます。ちなみに、ここで「出力」とありますが、UTXO型のトランザクションでは、デジタルアセットを出力(output)と入力(input)で表現する考え方があるので覚えておきましょう。トークンの取引では出力が支払いの情報、入力がその原資の情報として表現することがよくあります。⁠Aさんは○○トークン、Bさんは○○トークンを所有」といった、トークンの残高情報は直接的には記録されませんが、すべての自分のUTXOを見つけて合計すれば、その時点での自分のトークン残高を知ることができます。図1で、トークン取引の具体例を示して説明します。

図1 UTXO型トランザクションのトークン取引例
図1 UTXO型トランザクションのトークン取引例

図1は、UTXOを使ったトランザクションの例です。図1の場合は、各transactionには2つのOutputがありますが、上が「誰から誰へ」支払ったトークン、下が「自分へ」返却されるおつりのトークンを表しています。例えばtransaction_3は、BさんからAさんに7トークンを支払うトランザクションです。支払いの原資は、transaction_1でBさんが受け取った10トークンです。transaction_3ではおつりの3トークンが自分に支払われています(B→B: 3の部分⁠⁠。さらにtransaction_4では、BさんからCさんに15トークンを支払うのですが、transaction_2(CさんからBさんへ20トークン支払われた)とtransaction_3に含まれる2つのUTXOを束ねて、合計23トークンをinputとします。したがって、transaction_4には、BさんからCさんへの支払い分15トークンと、Bさん自身に返却されるおつり8トークンの出力が記録されます。ここまでの取引の結果、図1には次の4つのUTXOが残っています。

  • transaction_1: Aが5トークン持っている
  • transaction_3: Aが7トークン持っている
  • transaction_4: Bが8トークン持っている
  • transaction_4: Cが15トークン持っている

UTXOを使うメリットは、残高を管理しなくても支払いができる、各トランザクションに必要な承認(署名)の数がアカウント型よりも少なくて済む、という点です。特に前者の特徴は、パブリック型ブロックチェーンシステムのように、完全な自律分散システムではメリットになります。ただし、トークンのような量を扱うアセットには向いていますが、個別のモノの所有状況などを表したい場合には、アカウント型の方が向いています。また、UTXO型の方は、利用可能なUTXOを過去の取引履歴から積算して把握しなければならないため、トランザクションを検索する手間が多くなるというデメリットもあります。

BBc-1におけるUTXO型トランザクション

前述しましたが、UTXO型のトランザクションには出力と入力という考え方があります。出力とは支払いの情報で、入力とはその原資の情報です。当然出力と入力の合計値は一致しなければなりません。BBc-1もこの形式に準拠しており、出力はevent、入力はreferenceと呼んでいます。具体的には、eventリストは複数のBBcEventオブジェクトを含み、それぞれ「誰から誰への支払い」であるかが記録されます。referenceリストは複数のBBcReferenceオブジェクトを含み、それぞれ過去のトランザクションに含まれるBBcEventへのポインタになっています。

それでは、具体例で見ていきましょう。以下のようなシナリオを考えます。

表1 UTXO型トランザクションの例
構成要素内容
登場人物Aさん(ユーザ⁠⁠、Bさん(ユーザ⁠⁠、Zさん(トークン発行者)
アセット種別トークン
シナリオの流れ

初期状況:Aさん、Bさんともにトークンを持っていない(BBc-1には登録されていない)

  1. Aさんが100トークンをZさんから発行してもらう
  2. Aさんが200トークンをZさんから追加発行してもらう
  3. Aさんが240トークンをBさんに支払う

シナリオ-1 トークン発行のためのトランザクション

図2 Aさんが100トークンをZさんから発行してもらう
図2 Aさんが100トークンをZさんから発行してもらう
図3 シナリオ-1 トランザクションのデータ構造
図3 シナリオ-1 トランザクションのデータ構造

図3に示したようなトランザクションが、TXID1というtransaction_idでBBc-1に登録されることで、シナリオ-1の処理が完了したことになります。なお、今回の説明に直接関係ない部分は省略しています(後述の図5図7も同様です⁠⁠。TXID1、GROUP_TOKEN、userA、userZ、ASSET_1などは実際には32バイトの識別子です。

このトランザクションはアプリケーションとしては特別なトランザクションで、原資なしに支払いが発生しています。これは発行主体であるZさんが生み出したトークンをAさんに発行していることを表します。BBcEventに、Aさんに100トークンが発行されたことが記録されています。mandatory_approversという項目にuserAが設定されています。これは、このUTXOを利用するときに、Aさんの署名が必要であることを指定しています(後述のシナリオ-3の解説に関係してきます⁠⁠。witnessにはuserZを記載し、Zさんによる署名をsignatureリストに格納します。これによって、このトークン発行行為が、確かにZさんの権限で行われたことを表します。ただ、BBcSignatureは単純な構造で、公開鍵本体と署名から構成されます。署名主についての情報(つまりuser_id)はwitnessに書かれているので、ここには含まれません。図3では、⁠userZの」公開鍵、⁠userZの」秘密鍵による署名と記載していますが、これは便宜的にuser_idを記載しているだけなので、注意してください(後述の図5図7も同様です⁠⁠。

シナリオ-2 トークン発行のためのトランザクション

図4 Aさんが200トークンをZさんから追加発行してもらう
図4 Aさんが200トークンをZさんから追加発行してもらう
図5 シナリオ-2 トークン発行のためのトランザクション
図5 シナリオ-2 トークン発行のためのトランザクション

このシナリオ-2はシナリオ-1と同様で、ZさんからAさんに追加で200トークンが発行されたことを表します。図3図5を見比べれば、ほとんど同じであることがわかると思います。なお、最初の100トークンとこの200トークンは、アセットとしては別のもの、すなわちASSET_1とASSET_2であることに注意してください。

シナリオ-3 トークン支払いのためのトランザクション

図6 Aさんが240トークンをBさんに支払う
図6 Aさんが240トークンをBさんに支払う
図7 シナリオ-3 トークン発行のためのトランザクション
図7 シナリオ-3 トークン発行のためのトランザクション

急に複雑になりましたが、この例が一般的な支払いのトランザクションです。このトランザクションがBBc-1に登録されると、この支払処理が完了したことになります。

まずは支払いの原資となるトークンのUTXOをreferenceリストに指定します。240トークン以上のトークンを含むUTXOを見つける必要があります。さきほどまでのシナリオ-1とシナリオ-2で、Aさんは200トークンと100トークンの計300トークンを持っています。これらは、それぞれTXID1の1番目のBBcEvent、TXID2の1番目のBBcEventに記載されていました図3図5参照⁠⁠。BBcReferenceはそれぞれ1つずつBBcEventを指定するので、referenceリストには2つのBBcReferenceが格納されます。event_indicesというのは、transaction_idで指定したトランザクション図7の場合はTXID1、TXID2)にあるeventリスト内の何番目のBBcEventであるかを指定する配列要素番号です。TXID1、TXID2どちらも1番目のBBcEventを指定しているので[0]としています。

次に、図3のTXID1のBBcEventにあるmandatory_approversと、図5のTXID2にあるmandatory_approversにはuserAが指定されていました。これはつまり、このTXID3のトランザクション(Aさん所有の300トークンを支払いに充てる)にはAさんの署名が必要ということになりますので、TXID3のsignatureリストにAさんの署名を格納します。そしてそのAさんの署名がsignatureリストの何番目のBBcSignatureに格納されているかをsig_indexで示しています。今のトランザクション(TXID3)には、1番目のBBcSignatureにAさんの署名が格納されているので、sig_index: 0と指定します。ちなみに、図7ではBBcReference内のsig_indexでAさんの署名を指定しているので、図3図5のトランザクションにはあったwitnessがありません。なお、Aさんの署名が必要な理由は、支払う人がその支払いに合意していることを表すためです。

そして、referenceリストに記載された原資の300トークンを支払いに充てます。支払いの情報はeventリストに書かれており、Bさんへの支払いのBBcEventとAさんへのおつりのBBcEventが含まれます。

まとめ

今回は、UTXO型のトランザクションについて説明しました。

表現形式は異なりますが、合意に関する考え方はアカウント型とまったく同じです。トランザクションに含まれるBBcEventやBBcReferenceを参照して、各自が過去の関連するトランザクションに記載された内容が正しいかどうかをチェックします。UTXO型の場合は、支払う人(つまりBBcReferenceが参照しているBBcEventの持ち主)の署名があれば、取引に合意していると考えます。今回のシナリオでいえば、TXID3のBBcReferenceが参照しているTXID1/ TXID2のBBcEventの持ち主であるAさんの署名です。

次回は、アカウント型とUTXO型のコンビネーションについて説明します。relationリスト、eventリスト、referenceリストが同じトランザクションに格納されるケースです。

おすすめ記事

記事・ニュース一覧