アーパボー(ARPABLE)
アープらしいエンジニア、それを称賛する言葉・・・アーパボー(商標登録6601061)
ブロックチェーン

実際のトランザクションデータを見てみよう

実際のトランザクションデータを見てみよう

それではここでプログラムから実際のブロックチェーンのトランザクションデータを見てみましょう。

前にもお話しましたが、ビットコイン等の一つの仮想通貨の取引履歴情報は原則として世の中にただ一つしかありませんので、どの取引所を経由したとしてもブロックチェーンのトランザクションデータとして全く同じ情報を取得することができます。

公開APIを利用しよう

プログラムからそれを取得するには何か難しいことをやる必要があるのではないだろうかと思うかもしれませんが、実はいくつかのサイトでAPIが公開されているのでそれを利用すれば、簡単にブロックチェーン情報を取得することができます。

今回利用するAPIはblockchain.infoというWebサービスです。
プログラムから簡単に利用できるAPIによりブロックチェーンの全てのデータにアクセスすることが可能となります。

PythonからAPIを利用する場合、サードパーティー製のライブラリであるrequestsを使用します。
このライブラリは、APIが提供されているURLと取得したいパラメータを指定することにより、HTTP経由で簡単にデータを取得することができます。

今回は、ブロックチェーンエクスプローラの稿の中でChainFlyerを利用してたまたま取得したトランザクションと同じデータをプログラム経由で取得してみましょう。

ブロック番号(ブロック高)702683の2番目のトランザクションでIDは以下の通りでしたね。

73185a1d2b8d953668670ee1e2f467ed21ddae629decdeb8084f9dff4ac810a3

フクロウ君
フクロウ君
ちなみにこのトランザクションを選んだのはたまたまで特に他意はありません。

ChainFlyerから取得したトランザクションの内容を確認しておきましょう。

 

プログラムから取得したトランザクションデータ

以下にプログラムと結果を示します。
結果はレイアウトをJSON形式に変換した上で、説明しやすいように赤字で”・・①”のように通し番号を追記してます。

プログラム

# Let’s try to get raw transaction data using API of “blockchain.info” 
import requests
import json

API_BlockchainInfo = “https://blockchain.info/rawtx/”

# set transaction ID from “ChainFlyer”
ChainFlyer_TXID = “73185a1d2b8d953668670ee1e2f467ed21ddae629decdeb8084f9dff4ac810a3”

# get raw transaction by “request” package ( library )
raw_Transaction = requests.get( API_BlockchainInfo + ChainFlyer_TXID )
print( raw_Transaction.text )

結果

{
“hash”:”73185a1d2b8d953668670ee1e2f467ed21ddae629decdeb8084f9dff4ac810a3“, ・・①

“ver”:2,
“vin_sz”:1,
“vout_sz”:1,
size”:195,  ・・②
“weight”:450, ・・③
fee”:55341, ・④
“relayed_by”:”0.0.0.0″,
“lock_time”:0,
“tx_index”:5737359205200809,
“double_spend”:false,
“time”:1643334946,
block_index”:720683,  ・・⑤
block_height”:720683, ・・⑤
“inputs”:[ ・・⑥
  {“sequence”:4294967295, ・・⑦ 
  ”witness“:” ・・⑧
      0248

        3045022100db5bed1f45eedb77b312b4941e13f9ce8d73c04f4ea
        3462139ddf7407cec25ab02201752f7f610a7679e4bebd5916380
        d94888cdcd80d7521cd334495c2c2133c50e01・・⑨

      21
        0267a8b8d70e870b311c884dbb28022138e9167b65b6c1dc0e8b
        52c28207363a31“,・・➉

  ”script”:””,
  “index”:0,・・⑦ 
  ”prev_out”:
  {“spent”:true,
  ”script”:”0014122c564ac64c8bd42168f99d06f4bb10a71ca8df”,
  ”spending_outpoints”:
  [{“tx_index”:5737359205200809,”n”:0}],
  ”tx_index”:6734731876875308,
  ”value”:333341, ・・⑪
  ”addr”:”bc1qzgk9vjkxfj9aggtglxwsda9mzzn3e2xlzd6ptl“, ・・⑫
  ”n”:159,
  ”type”:0}}],
“out”:[ ・・⑬
  {“type”:0,
  ”spent”:true,
  ”value”:278000, ・・⑭
  ”spending_outpoints”:[{“tx_index”:6269777910971162,”n”:6}],
  ”n”:0,
  ”tx_index”:5737359205200809,
  ”script“: ・・⑮
  ”76a914
   ed36812833696d04651087af4812cb4f511df9db ・・⑯
  88ac“,
  ”addr”:”1NdGSWFDmD3Gm1dUJdB4AuFnQLbTvqr4ED”} ・・⑰

  ]
}

(リスト1)プログラムで取得したトランザクションのRawデータ

取得したトランザクションを確認してみよう

それではプログラムによる出力データとChainFlayer(以下CF)の値が一致している事を
確認していきましょう。

ChainFlayerで取得した画面に対して、(リスト1)プログラムで取得したトランザクションのRawデータに追記した通し番号と同じ情報に対して同じ通し番号を追記しました。

(註)ここでRawデータとはプログラムから直接ブロックチェーンのバイナリデータを取得していることから生データという意味で使用してます。


(図1)ChainFlyerで表示したトランザクションデータ

この図を使って(リスト1)の「プログラムで取得したトランザクションのRawデータ」を追記した番号順に説明していきましょう。
(※1)上記ChainFlyerの画面に追記した番号は(図1)の番号と対応してます。
(※2)以下の説明ではChainFlyerの画面を単に「CF」と略してます。

トランザクションデータの解説

先頭に”hash”とあるのでトランザクションハッシュ値、すなわちこれがトラン
ザクションIDとなります(CFの先頭にある数値)

はトランザクションサイズ
はトランザクションウェイト
共にCFの画面中央左側の「480確認」の下)

トランザクションウェイトは、Segwitと共に導入された指標で、トランザクションデータのWitness(=ScriptSig:電子署名+公開鍵))に対してそれ以外のデータが大き程、値が大きく(重く)なります。

Greg WalkerさんのブログサイトによるとWeightは以下のような計算式になるようです。
weight = (Txsize – Witness size)*4+Witness size

feeはマイナーさんに支払う手数料(中央右側の送信額の下)
プログラムで出力したRawデータでは”55341″で、CFでは0.00055341となってます。
これはRawデータの
単位が”satoshi”、すなわち1億分の1ビットコインだからです。
つまり、0.00055341*100,000,000=55341となりますね。

block_heightは通常「ブロック高」と呼びますが、ブロックの通し番号なので、ここでは「ブロック番号」と読んでます。
(CFでは送信額の下にある「ブロックの高さ」に相当します)

トランザクションは基本的にINPUTとOUTPUTから構成されますが、ここからがINPUTの領域が始まります。

シーケンス番号
Rawデータでは”sequence”:4294967295で、CFの画面では左側の最終行にシーケンス番号と記載されてます。
これはUTX
Oを特定するために必要なブロックチェーン内の場所を示すシーケンス番号です。

そこから10行下にindex”:0とありますが、これはUTXO内の何番目のOUTPUTを使うかを表してます。
この値が0なので、先頭のOUTPUTを使用するという意味ですね。

witnessの情報が記載されてます。
CFの画面左下の”Input Scripts”の領域にwitnessが記載されてます。
ここにはScriptSig(アンロッキングスクリプト)の情報である電子署名と公開鍵がセットされてます。
Rawデータでは電子署名にを公開鍵をとしており、これがCFのWitnessに記載されているデータペアと一致することが確認できます。

公開鍵の値は以下のように02から始まりますので、以下のことが分かりますね。

  1. 圧縮型の公開鍵フォーマットである
  2. Y座標は正の値である

0267a8b8d70e870b311c884dbb28022138e9167b65b6c1dc0e8b52c28207363a31

INPUTにセットされたUTXOの額
Rawデータにはvalue”:333341とあり単位はsatoshiです。
またC
Fの画面では中央左のInput(1)のアドレスの右に0.00333341とあり、単位はビットコインです。

UTXOのアドレス
Rawデータでは”addr”:”bc1qzgk9vjkxfj9aggtglxwsda9mzzn3e2xlzd6ptl”とあり、CFの画面では中央左のInput(1)に記載されてます。

INPUTの領域が終わり、ここからOUTPUTが続きます。

まずは送金額が記載されてますね。
Rawデータでは”value”:278000(satoshi) ,CFの画面では0.00278ビットコインと表記さてます。

OUTPUTのスクリプト
Rawデータでは”script”:から始まる数字列でロッキングスクリプトと呼ばれてます。
このスクリプトの中には、この送金額をもらう人の公開鍵ハッシュ(≒アドレス)が含まれている為、ScriptPubKeyと呼ばれることもあります。

公開鍵ハッシュがどこに記載されているかというと、
Rawデータではにある以下のデータです。

“ed36812833696d04651087af4812cb4f511df9db”

CFの画面では、画面右下の”Output Script”にロッキングスクリプト( ScriptPubKey )がオペコード形式で記載されているのが分かりますね。
この3行目の”OP_PUSHDATA:”に続く数字列が上記のデータと一致していることが確認できます。

ロッキングスクリプトは、後にこのOUTPUT(金額は0.00278ビットコインでしたね)がUTXOとして送金の原資に使われるときの使用許諾条件(解除条件)をスクリプト言語で記載されてます。

具体的には、このスクリプトの中の公開鍵ハッシュと、これをUTXOとして送金の原資にする時のINPUTの領域に記載されている公開鍵をハッシュ化して比較して検証することになります。

といわれてもちょっと分かりにくいと思いますので、トランザクションスクリプトに関しては別稿で詳しく説明する予定ですが、

送金先アドレス
Rawデータでは”addr”:”1NdGSWFDmD3Gm1dUJdB4AuFnQLbTvqr4ED”とあり、CFの画面では中央左のOutput(1)の下に同じ数字が記載されてますね。

まとめ

この稿ではまず公開されたAPIを使用してトランザクションデータを取得しました。
利用したAPIはBlockchain.Infoが提供しているWebサービスです。

これを利用すると簡単にトランザクションデータを取得することが確認できましたが、Rawデータを読み解くのはそれなりの知識が必要となりますす。。

一方ブロックチェーンエクスプローラー、今回のようにChainFlyerを利用するとトランザクションの主なデータが分かりやすく成形されて表示できるということも確認できました。

従って単にトランザクションデータを参照するだけなら、プログラムで簡単に取得できるにしても、ChainFlyer等のブロックチェーンエクスプローラーを利用した方が良いでしょう。

例えば、リアルタイムで特定のアドレスが使われるのをチェックしたい等のニーズにはプログラムは適していますね。

今後はブロクチェーンデータを利用する際には、以下の2つの方法を用途に応じて選択していきましょう。

  1. ブロックチェーン用に公開されたAPIをプログラムから利用する
  2. ブロクチェーンエクスプローラーを利用する

(アーパボー)