UXTOってなんぞ?

経緯

モナコインの取引トランザクションを取得する方法を調べたとき、コメントでらいうさんに教えていただきました。

vinとvoutの関係はUTXO構造によるものですね(ブロックチェーン系のTXは基本全てこの作りのはず。)記事の中の例を見てみると、まず僕のTXのvinのtxidを見てみるとhttps://blockbook.electrum-mona.org/tx/e1e94be2b6f541e6639d9bd1cce79ac9a668dd25b0c3bd5f48c411ade94f8003 最終的に2.16261631 MONAが僕のアドレスに入ってきたことがわかります。このTXを入力にして1.14114MONAを送ると2.16261631 - 1.14114 = 1.02147631がお釣りとなって僕に帰ってきます。しかし実際にお釣りで帰ってきたのは1.02124906で0.00022725の差があることがわかります。この差がTX手数料としてマイナーに支払われています。この辺はちょっと複雑なのですがmastering bitcoinの日本語訳pdfが公開されていたのでそちらを見るといいかもしれません

手数料を算出する方法を教えていただきました。どうやら手数料を算出するにはvinにある最終額が必要とのことです。それを取得するAPIリクエストの方法はまた別途調べるとして、今はまずUTXO構造なるものについて調べます。噂のPDFとやらを探してみることにしました。

Mastering Bitcoin 日本語訳 PDF

ググると以下URLを発見。たぶんこれでしょう。

オリジナルは英語かな。上のほうをダウンロードします。

UTXO

ダウンロードしたPDFから「UTXO」で文字列検索してみます。

Bitcoinトランザクションの基本的な構成要素は、 未使用トランザクションアウトプット またはUTXO(unspent transaction output)です。

はあ。

UTXOは、特定の所有者にロックされた分割不可能なbitcoinの固まりです。これはブロックチェーンに記録されており、Bitcoinネットワーク全体によって通貨の単位として捉えられているものです。

取引データであるトランザクションの正体は、それ自体がコインだったらしい。

ああ、なるほど。だからvintxidで指しているトランザクションが、送金するときの入力になるのか。それ自体がコインだから。

これを前提にらいうさんのコメントをもう一度みてみると理解できます。「まず僕のTXのvinのtxidを見てみると」のくだりで、なぜ取引するのに別の取引データがインプットになるのかわからなかったのですが、その理由は、その取引データ自体がコインだから、なのでしょう。

なら、送金するときは、きっと次のようになるのかな。

  1. これまでの取引データのうち、今回送金する金額+手数料以上の残高が残っている取引データを選ぶ
  2. 1をインプットにして、新しい送金トランザクションを作る

Bitcoinネットワークは全ての利用可能(未使用)なUTXOを追跡しており、現在数百万に達するほどの量があります。ユーザがbitcoinを受け取るときはいつでも、UTXOとしてブロックチェーンに記録されます。このため、ユーザのbitcoinは数百個のトランザクションまたは数百個のブロックの中にUTXOとして散り散りな状態になってしまっているかもしれません。

空いているデータを適当に探して割り当てるということかな。物理的な連続性と日時の連続には関連がないという意味だろう。たぶん。

プログラミングでいうとメモリ割当するとき、連続した位置でなく離れた位置にあるメモリを取得するようなイメージかな?

実際には、Bitcoinアドレスまたは口座の残高として記録されている訳ではないのです。あるのはただ散り散りになり特定の所有者に利用が制限されたUTXOだけです。ユーザのbitcoin残高という概念は、ウォレットによって作り上げられたものにすぎません。ウォレットはブロックチェーンをスキャンしてユーザに属している全てのUTXOを掻き集め残高を計算しているのです。

mpurseやmonaPartyでは残高を一発で取得できるAPIがある。それはブロックチェーン内に点在する自分のアドレスにまつわるトランザクション情報をかき集めて集計した結果、算出された値ということか。

それについてはモナコイン取引集計+取引ユーザ相関図ページを作った 追記で実際にプログラミングしたのでわかる。APIを使って指定したアドレスの全トランザクションを取得し、自力で集計した。やはり私の認識で間違いなかったのだろう。

さらに詳しく読む。

vout, vin

UTXOは satoshi を単位とした任意の値を持つことができます。ドルがセントというさらに下の2桁の十進数を持つように、bitcoinはsatoshiという8桁の十進数を持ちます。

サトシ。ポケモンマスター? そっちでなく、サトシ・ナカモト氏のことでしょう。

UTXOは任意の値ですが、一度作られるとコインのように2つに切ることができません。 別の言い方をすると、もし20bitcoinのUTXOを持っていて1bitcoinだけ使いたいとすると、トランザクションは20bitcoinのUTXOを消費しなければならないため2つのアウトプットを作らなければいけません。1つは支払った1bitcoin、もう1つはあなたのウォレットに戻ってくるおつりの19bitcoinです。結果として、ほとんどのBitcoinトランザクションはおつりを生成します。

なぜvoutの要素が2つあるのか。それは支払った金額と、おつりを算出した金額の2つが必要だから。そういうことなのね。

おつりが必要なのは、ぴったりの金額をインプットにできないから。その理由は、以前のトランザクションを入力にしているから。それがたまたま偶然、次の支払い額とぴったり一致することはごく稀だから、ほぼいつもおつりが出る。

$1.50の飲み物を買う人を想像してみましょう。彼女の財布から$1.50になるコインと紙幣の組み合わせを探しだします。もし財布にあるならおつりのいらないちょうどの金額(1ドル札と2つの25セントコイン、または6つの25セントコイン)、無理であれば5ドル札のような大きな単位の紙幣を選びます。もし多くのお金を持っているとすると、$5をショップオーナーに支払い$3.50のおつりが帰ってくると考えるでしょう。彼女はこの$3.50を財布に戻し、将来の買い物のときに使うことができます。

私たちが紙幣や硬貨を使って取引するときも、大抵ぴったりになるとは限りません。私はそうなるように支払いますけどね。小銭を使ってピッタリ支払い額と一致したら気持ちいいし、小銭が財布からなくなれば軽くなりますし。

でも暗号通貨はそんなチマチマした作業なんてやらない。前回残った金額をまるごとポンと出す。「宵越しのカネは持たねぇぜ! てやんでぇべらぼうめ!」という江戸っ子気質なのでしょう。でも実際、おつりは欲しいので、そのためのデータを作る必要があると。

ところで、取引データから支払額を差っ引くことを繰り返していたら、いずれすべてのトランザクション残高が支払い額に満たなくなる日が来るのでは? そうなったらどうするのでしょうか。少額のトランザクションを寄せ集めて合併し、新しいトランザクション情報とするのかな?

同様に、Bitcoinトランザクションはユーザが使用可能なUTXOから作られます。ユーザはUTXOを半分に割ることはできません。ウォレットは通常ユーザの利用可能なUTXOを選び、トランザクションに必要な金額以上になるように組み合わせます。

ああ、そうか。トランザクションをわざわざ合併するんじゃなくて、複数使うのか。だからvinは配列だったんだな。少額のトランザクションでもたくさんかき集めれて支払い額を満たせればいいと。それをvinの配列要素にぶちこむのね。なるほど理解した。

そして取引が成立したら、そのトランザクションの所有者を変更する。おつりの分だけは新たなトランザクションとして支払い者である自分のものとすることで返してもらう。そういうことか。

実用上は、Bitcoinアプリケーションは購入額を満たすためにいくつかのやり方を使うことができます。いくつかのより小さい単位の額を組み合わせる、おつりがないようなきっちりした金額を選ぶ、またはトランザクションに必要な金額より大きい額を使っておつりを作るなどです。このやり方はウォレットのほうで自動的に実行され、ユーザには見えないようになっています。関係してくるとしたら、生トランザクションをUTXOからプログラムを通して手で構成する場合だけです。

たぶん新しいトランザクションを作る回数が、できるだけ少くなる方法にしているのだろう。ディスクにそれを書き込むコストが高いとか、なんかそんな理由で。

でもその戦略をそれぞれのウォレットアプリに丸投げしちゃうのか。ちょっと不安。もし自分でウォレットを作るなら、どういうアルゴリズムで作ればいいのか。最適解はあるのか。効率がよいのはどれか。

トランザクションによって消費されたUTXOはトランザクションインプットと呼ばれ、トランザクションによって作られたUTXOをトランザクションアウトプットと呼びます。

vin,voutのことかな。なぜvなのかわからないけど。

UTXOを消費し作成するトランザクション連鎖の中で、bitcoinの固まりはある所有者からある所有者に移っていきます。トランザクションは現在の所有者の署名を使って解錠されることでUTXOを消費します。

取引アドレスの秘密鍵をもっていることが確認できたら、UTXOデータ領域を使って取引データを作成する。という意味だろう。

インプットとアウトプットのチェーンの例外は、 coinbaseトランザクションと呼ばれる特殊なトランザクションです。これは、それぞれのブロックの一番最初のトランザクションです。このトランザクションはマイニングに"勝った"マイナーによってブロックの一番最初に置かれ、マイニングに対する報酬としてマイナーにbitcoinが支払われるトランザクションとなります。このようにしてマイニングプロセスを通してBitcoinのお金が供給されていきます。

最初のトランザクションデータはマイニングにより作成されるらしい。

まとめ

  • UXTOはトランザクションデータであり、その構造であり、その保存領域であり、ブロックチェーンに保存されている
  • UXTOはコインの実体である
  • UXTOには所有者がいる
  • 自分のアドレスが所有している全UXTOの金額を合計すると残高になる
  • 支払うときは支払額以上のUXTOを探し、それを入力とする
  • 入力から支払額を差し引いた額を、おつりとして出力にする

基本的なトランザクションの枠組みが見えてみた。続きは「トランザクション手数料」について。これも気になるので読みたい。