Never Too Late

いつだってゼロからやり直そう

ビットコイントランザクションのインプットを見てみる

(2017年10月6日にQiitaにて執筆した記事をこちらに転載しています。)

前回やったこと

前回の記事ではあるひとつのビットコイントランザクション(誰かが堀江貴文さんにビットコインを送ったときのもの)に着目し、内容を詳しく見ていきました。

今回はその続きで、前回触れなかったトランザクションのインプットについてもう少し見ていきたいと思います。

インプットを表示してみる

百聞は一見に如かずということで、まずは前回と同じトランザクションのインプットの情報を出力してみましょう。

using NBitcoin;
using QBitNinja.Client;
using QBitNinja.Client.Models;
using System;

namespace NBitcoinTest1
{
    class Program
    {
        static void Main(string[] args)
        {
            QBitNinjaClient client = new QBitNinjaClient(Network.Main);
            var transactionId = uint256.Parse("7008807adb713205d01d378f3d25f1bc5e06bda7d30b526c2b9d2c018cfa08b4");
            GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result;

            var tx = transactionResponse.Transaction;
            tx.Inputs.ForEach((txIn) =>
            {
                var outPoint = txIn.PrevOut;
                Console.WriteLine("Transaction hash ->" + outPoint.Hash);
                Console.WriteLine("The index of the transaction's outputs ->" + outPoint.N);
                Console.WriteLine();
            });
        }
    }
}

出力は以下のようになります。

Transaction hash ->f59a92861aee231edcfee65834b6acf48ba6f4ee624e572f9fba6a7f720499ca
The index of the transaction's outputs ->0

Transaction hash ->7507e1301b3db2e9c62e4c3f9bbfc2c2b829e01fdaf3c95651a31caf811855c0
The index of the transaction's outputs ->0

Transaction hash ->1151d6903411836c11117bfcff3e5a3a076ae2c22f88d8b5673f7123a30cd507
The index of the transaction's outputs ->0

Transaction hash ->86b8472a86dc9e0836a55171417f8b6056754de46162d635c1e70adfd452a39b
The index of the transaction's outputs ->0

Transaction hash ->35b1aaf2e486f8366440484e040fb8ee196cb2684e77e3c5bfa237f9cf9e0d2d
The index of the transaction's outputs ->0

Transaction hash ->9b8b3f718cb6b247c5855574bd1f4719eee49e99aa4016a29135b2ad1871191b
The index of the transaction's outputs ->0

Transaction hash ->ab5940ca9246aa02596058a0dc512973a5abb3575e4b3a4a57c45eda8b525861
The index of the transaction's outputs ->0

Transaction hash ->2598d0e4a9a6eb393726fc84f549186cbd08934464836b28210e9319816d50f7
The index of the transaction's outputs ->0

Transaction hash ->3924ba8a21fc1c704f0c8cce6e9ad4dd1ab6a1efa6d178c57172f429b02b039a
The index of the transaction's outputs ->0

Transaction hash ->482b50307a941d853dcf88e044ece23b29e054dd4f90312533404d02e56d4353
The index of the transaction's outputs ->0

前回も書いたとおりこのトランザクションには10個ものインプットが結び付けられています。そしてそのインプットはそれぞれ別のトランザクションを指すハッシュの値と、それからインデックス番号を持っています。

未使用トランザクションアウトプット(UTXO)とは何か

ビットコインのブロックチェーンとはお金の移動を記した台帳です。そしてあなたが(正確に言うとあなたのウォレットが)ビットコインを所有しているとして、その所有とはすなわちあなたが受取人になっているトランザクションアウトプットの中で、まだあなたが誰にも渡していないものということです。

このようなまだ未使用なトランザクションアウトプットのことをUTXO(Unused Transaction Output)と呼びます。あなたの所有しているビットコインの総量とは、即ちあなたが受取人になっているUTXOの合計量です

上記の10個のインプットは、このトランザクションでビットコインを堀江さんに送った方の(その時点での)UTXOだったということになります。その方の使用したウォレットが、送信するビットコイン量に足るようにブロックチェーンから集めてきたUTXOです。

前回述べた通りひとつのトランザクションに複数のトランザクションアウトプットがある場合があるので、上記のインプットの情報にはインデックスも付いています。ちなみにこのトランザクションハッシュとアウトプットインデックスの組み合わせをアウトポイントと呼ぶようです。

10個のトランザクションアウトプットの受取人を見てみる

確認の為に、上記10個のトランザクションアウトプットの受取人が誰だったのかをブロックチェーンに問い合わせてみましょう。すべてのトランザクションアウトプットは、堀江さんにビットコインを送ったアドレスを受取人としているはずです。

using NBitcoin;
using QBitNinja.Client;
using QBitNinja.Client.Models;
using System;
using System.Collections.Generic;

namespace NBitcoinTest1
{
    class Program
    {
        static void Main(string[] args)
        {
            var outPoints = new List<Tuple<string, int>>()
            {
                new Tuple<string, int>("f59a92861aee231edcfee65834b6acf48ba6f4ee624e572f9fba6a7f720499ca", 0),
                new Tuple<string, int>("7507e1301b3db2e9c62e4c3f9bbfc2c2b829e01fdaf3c95651a31caf811855c0", 0),
                new Tuple<string, int>("1151d6903411836c11117bfcff3e5a3a076ae2c22f88d8b5673f7123a30cd507", 0),
                new Tuple<string, int>("86b8472a86dc9e0836a55171417f8b6056754de46162d635c1e70adfd452a39b", 0),
                new Tuple<string, int>("35b1aaf2e486f8366440484e040fb8ee196cb2684e77e3c5bfa237f9cf9e0d2d", 0),
                new Tuple<string, int>("9b8b3f718cb6b247c5855574bd1f4719eee49e99aa4016a29135b2ad1871191b", 0),
                new Tuple<string, int>("ab5940ca9246aa02596058a0dc512973a5abb3575e4b3a4a57c45eda8b525861", 0),
                new Tuple<string, int>("2598d0e4a9a6eb393726fc84f549186cbd08934464836b28210e9319816d50f7", 0),
                new Tuple<string, int>("3924ba8a21fc1c704f0c8cce6e9ad4dd1ab6a1efa6d178c57172f429b02b039a", 0),
                new Tuple<string, int>("482b50307a941d853dcf88e044ece23b29e054dd4f90312533404d02e56d4353", 0)
            };

            outPoints.ForEach((outPoint) =>
            {
                QBitNinjaClient client = new QBitNinjaClient(Network.Main);
                var txHash = outPoint.Item1;
                var outIndex = outPoint.Item2;
                var transactionId = uint256.Parse(txHash);
                GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result;

                var transaction = transactionResponse.Transaction;
                var addr = transaction.Outputs[outIndex].ScriptPubKey.GetDestinationAddress(Network.Main);

                Console.WriteLine(addr);
            }
            );
        }
    }
}

出力は以下のようになります。

1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu
1BdzVJ5EEWZz8zHx31F8M4c7uD5ziLVmCu

すべて同じビットコインアドレスに対して送られているトランザクションアウトプットであることが分かると思います。これは確かに前回の記事で確認したこのトランザクションに送信者のところで見られたビットコインアドレスです。

まとめ

ブロックチェーンとはビットコインがあるビットコインアドレスから別のビットコインアドレスに移ったという情報がひたすら書かれている台帳です。よってあなたの所有するビットコインの実体とは、ブロックチェーンに記載されたトランザクションアウトプットの中であなたが受取人に指定されていてかつあなたが使用していないものです。未使用のトランザクションアウトプットのことをUTXOと呼びます。

次回やること

トランザクションのインプットをどんどんどんどん遡ってみましょう。

参照