見出し画像

Blockchain データ分析(2):分析用データの加工

前回の記事「Blockchain データ分析(1):分析用データの入手」で AWS Public Blockchain Data から、ビットコインのブロックチェーンデータを収集してきました。
ダウンロードしてきたブロックチェーンのデータは、一つのトランザクションの中に、複数の送金元と送金先が混在しています。このため、伝統的な分析を行うためにはアドレス(口座、ウォレット)単位で、送金元と送金先、金額、日付時刻が整理されている形にする必要があります。

今回のタスクでは、ダウンロードしたParquet形式のトランザクション・データ を Pyspark を使って、ハッシュ、日付時刻、アドレス、金額を抽出できるようにしていきます。


前提条件

今回は Jupyter + PySpark で操作を行っていきます。

Parquet ファイルの取り込み

ダウンロードしたトランザクション・データは日別にディレクトリ、ファイルが分かれていますが、spark.read.parquet では一括取り込みが可能です。
今回は data という ディレクトリ配下にデータを置いた前提で読み込みを行っています。
show 関数に `truncate=False` オプションをつけることで、長い値が "41faafa9b8cd12c39…" のように省略されないようにすることができます。

from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()
df = spark.read.parquet("data/*")
df.show(3, truncate=False)

実行結果

実行すると下記の結果が出力されます。出力結果については次の章で解説するので、詳細には踏み込みませんが、outputs / inputs フィールドには、処理が面倒そうな値が入っています。

+----------------------------------------------------------------+-------+----+----------------------------------------------------------------+------------+-----+------------+---------+-----------+------------+-----------+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+---+------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
|hash                                                            |version|size|block_hash                                                      |block_number|index|virtual_size|lock_time|input_count|output_count|is_coinbase|output_value      |outputs                                                                                                                                                                                                                                                                                                                                                                                                            |block_timestamp    |fee|input_value       |inputs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |date      |
+----------------------------------------------------------------+-------+----+----------------------------------------------------------------+------------+-----+------------+---------+-----------+------------+-----------+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+---+------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+
|1d05f6d48a114d037bd3568cf1f021e3edb537c7d6c1305c344e95107a29eeb5|1      |405 |0000000000030c522a40397eaf099b1572d7368a31d0891f71c7222d7980dfa8|101998      |1    |405         |0        |2          |1           |false      |10.0              |[{1PB6WhHnnKyHfzRiBCGK78HvHnn1xaxf4E, 0, 1, OP_DUP OP_HASH160 f33b872ccdbd57a77eb76c2eb5e78e10c6567817 OP_EQUALVERIFY OP_CHECKSIG, 76a914f33b872ccdbd57a77eb76c2eb5e78e10c656781788ac, pubkeyhash, 10.0}]                                                                                                                                                                                                          |2011-01-11 05:37:04|0.0|10.0              |[{13qeBf7v1iemCdjNM2NapxuFmu7tjN15Mw, 0, 1, 3046022100c20e2f4ad2b5fc687f9913f401a582a7be3ac785bd9842774600588bcd18d335022100ce5d94f9c766535178e95775f12a23b8a0584d46d79a9d2835ba79cf95782141[ALL] 040f5d227f1f562848370bcbb6d6c7bda322eadc3c0cca58a5dd4509da43296d4561b4241a09a543014c697d2437456cfa26b79e6cd264c2b042fe5b407404e437, 493046022100c20e2f4ad2b5fc687f9913f401a582a7be3ac785bd9842774600588bcd18d335022100ce5d94f9c766535178e95775f12a23b8a0584d46d79a9d2835ba79cf957821410141040f5d227f1f562848370bcbb6d6c7bda322eadc3c0cca58a5dd4509da43296d4561b4241a09a543014c697d2437456cfa26b79e6cd264c2b042fe5b407404e437, 4294967295, 0, ac158c6305b976a0f3880d5289c8cbb7d3f62caa71c681ef50c57de0b1af3a32, pubkeyhash, 5.0}, {16XoHfq8o8fLgbBxMLM52cvdzBzwXhV26N, 1, 1, 3045022010515380d750c0e0f4ff7ee4397b54a02ed3c9b817c62b0094b3d7e4302364c60221009f96ab3f10e8103dd68286a973e13df6b7a53131d87b2037634fd90b88935de6[ALL] 040590f8803f13c6d09e00e7deba838193c78d9f908a5b16a5105e3525b559b5f7bc8b69a245d30c8eb73d2631cef4f991cc5893ec3aa64a7202bff042afd208c5, 483045022010515380d750c0e0f4ff7ee4397b54a02ed3c9b817c62b0094b3d7e4302364c60221009f96ab3f10e8103dd68286a973e13df6b7a53131d87b2037634fd90b88935de60141040590f8803f13c6d09e00e7deba838193c78d9f908a5b16a5105e3525b559b5f7bc8b69a245d30c8eb73d2631cef4f991cc5893ec3aa64a7202bff042afd208c5, 4294967295, 0, cbc4ff59801d36eb00d5b2ea95675b4503b05e7b4ef2d58a5a65f7d07e8c2d6b, pubkeyhash, 5.0}]|2011-01-10|
|d82444ae6f94cf0e22d4abf303aba06fe6642f5a9dbc2bdd81c5209141cc3479|1      |224 |000000000001d8738fa5a5a27a6fd915e425e6f53d615d40cf8a07bebfc395f7|101861      |4    |224         |0        |1          |1           |false      |0.02              |[{1GgyKFf8TeMArUP9zMtF1CKSQEzarrbZyS, 0, 1, OP_DUP OP_HASH160 ac191e504459aed73644bdb928747b64e9467483 OP_EQUALVERIFY OP_CHECKSIG, 76a914ac191e504459aed73644bdb928747b64e946748388ac, pubkeyhash, 0.02}]                                                                                                                                                                                                          |2011-01-10 09:24:47|0.0|0.02              |[{1DMmUJ9RCVTwVr4RqrFsm2hGwAQVB3E6Wr, 0, 1, 3045022037b40a3eccce1a5957e529eef531a4b7d226313906b33e9eeaa93fef3a100e44022100fc502c0154f08185fff0f318468d2aa9a63705a6e9825d35084f86ca8a9408e6[ALL] 04cd8456c272cc7166fe488e7577e0cfff590026cb764277214443eb1b43a67b5a804da18d24f75e7883174a531ea770f03f71d0af9a9cf0c246d108b91ef1b4c9, 483045022037b40a3eccce1a5957e529eef531a4b7d226313906b33e9eeaa93fef3a100e44022100fc502c0154f08185fff0f318468d2aa9a63705a6e9825d35084f86ca8a9408e6014104cd8456c272cc7166fe488e7577e0cfff590026cb764277214443eb1b43a67b5a804da18d24f75e7883174a531ea770f03f71d0af9a9cf0c246d108b91ef1b4c9, 4294967295, 1, 75fa403d904b1dbac7a8f02c00b4dc4ac335090fbff0eac593865196f059f3de, pubkeyhash, 0.02}]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |2011-01-10|
|19fbe1e4e05986663d1ab1cd7fe80b9ceeb023e1775f9b6222c1799c36e03aba|1      |257 |00000000000241691c6bf08a138c3ce6e2bd648b1b26d2f9236e71172a797243|101988      |6    |257         |0        |1          |2           |false      |45.059999999999995|[{16u5Tq1A5sQhGF3C1M9aMQvjXb25NyTsrZ, 0, 1, OP_DUP OP_HASH160 40b1fbec7c319fe74e6783d8275a4ce085d35e93 OP_EQUALVERIFY OP_CHECKSIG, 76a91440b1fbec7c319fe74e6783d8275a4ce085d35e9388ac, pubkeyhash, 1.08}, {19T3NfHbrQM4eMUWUrfYA21ncjq8apMeT9, 1, 1, OP_DUP OP_HASH160 5cadcd72cfb1358909358faa507d6e144042d253 OP_EQUALVERIFY OP_CHECKSIG, 76a9145cadcd72cfb1358909358faa507d6e144042d25388ac, pubkeyhash, 43.98}]|2011-01-11 04:10:00|0.0|45.059999999999995|[{1KvjyDH9ekeWtwAhSwHvfUmsQcZ6KHksS7, 0, 1, 304402202699e8454ee80df01f24cd393f9a0e71b5dec4c6bed206719427ff4bf8f8747202200da287455a2c1f0bf402fcb96a4201d8611093218c85f20950020ff409b00675[ALL] 04d97bc1bea1b7b396584ce44aaa95d346f02c1bb0d8855818d7a3a2de2bac784eafd9c1f0a6c6554ae17cb2ea710e1824fe99153cd1f2e837debd8aea9300b03c, 47304402202699e8454ee80df01f24cd393f9a0e71b5dec4c6bed206719427ff4bf8f8747202200da287455a2c1f0bf402fcb96a4201d8611093218c85f20950020ff409b00675014104d97bc1bea1b7b396584ce44aaa95d346f02c1bb0d8855818d7a3a2de2bac784eafd9c1f0a6c6554ae17cb2ea710e1824fe99153cd1f2e837debd8aea9300b03c, 4294967295, 0, 4d06adb3f51d60a1cd6bd7bee9556e8f6563d017ea37e970781eccc839ff10c2, pubkeyhash, 45.06}]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |2011-01-10|
+----------------------------------------------------------------+-------+----+----------------------------------------------------------------+------------+-----+------------+---------+-----------+------------+-----------+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+---+------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+

Parquet ファイルの内容確認

読み込んだファイルのフィールドを確認していきます。データセットのフィールドに関する説明は、Github 上にも説明があるのですが、Purquet では、フィールドをネストさせることが可能であり、複雑な構成となっているため、`printSchema()` 関数を使って実ファイルのメタ情報から確認してみました。

df.select("hash", "block_timestamp", "date", "inputs", "outputs").printSchema()

実行結果

ビットコインのトランザクションは、二次元のテーブルではなく、inputs/outputs テーブルは配列+表という複雑な構造になっていることがわかります。

root
 |-- hash: string (nullable = true)
 |-- block_timestamp: timestamp (nullable = true)
 |-- date: string (nullable = true)
 |-- inputs: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- address: string (nullable = true)
 |    |    |-- index: long (nullable = true)
 |    |    |-- required_signatures: long (nullable = true)
 |    |    |-- script_asm: string (nullable = true)
 |    |    |-- script_hex: string (nullable = true)
 |    |    |-- sequence: long (nullable = true)
 |    |    |-- spent_output_index: long (nullable = true)
 |    |    |-- spent_transaction_hash: string (nullable = true)
 |    |    |-- txinwitness: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)
 |    |    |-- type: string (nullable = true)
 |    |    |-- value: double (nullable = true)
 |-- outputs: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- address: string (nullable = true)
 |    |    |-- index: long (nullable = true)
 |    |    |-- required_signatures: long (nullable = true)
 |    |    |-- script_asm: string (nullable = true)
 |    |    |-- script_hex: string (nullable = true)
 |    |    |-- type: string (nullable = true)
 |    |    |-- value: double (nullable = true)

注意事項

2011年2月より前のトランザクションのフィールドには、`Inputs` のフィールドが含まれていないものが多く、現在のトランザクションと異なっているため、データ処理をする際は、カラム追加をする等の措置が必要です。

送金元/送金先アドレスと金額の抽出

ブロックチェーンのデータは、取引を記録した台帳形式のデータであり、口座(ウォレット、アドレス)や口座の関係性を分析するためのフォーマットになっていません。このため、トランザクションからアドレスと金額、送金元/先情報を抽出して、リスト化します。

Cursor にサンプル・データを引き渡して、データ整形用コードの作成を行います。Ctrl + L でチャット・ウィンドウを開いて下記の指示を出します。

+----------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|hash                                                            |outputs                                                                                                                                                                                                                                                                                                                                                                                                            |inputs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+----------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|1d05f6d48a114d037bd3568cf1f021e3edb537c7d6c1305c344e95107a29eeb5|[{1PB6WhHnnKyHfzRiBCGK78HvHnn1xaxf4E, 0, 1, OP_DUP OP_HASH160 f33b872ccdbd57a77eb76c2eb5e78e10c6567817 OP_EQUALVERIFY OP_CHECKSIG, 76a914f33b872ccdbd57a77eb76c2eb5e78e10c656781788ac, pubkeyhash, 10.0}]                                                                                                                                                                                                          |[{13qeBf7v1iemCdjNM2NapxuFmu7tjN15Mw, 0, 1, 3046022100c20e2f4ad2b5fc687f9913f401a582a7be3ac785bd9842774600588bcd18d335022100ce5d94f9c766535178e95775f12a23b8a0584d46d79a9d2835ba79cf95782141[ALL] 040f5d227f1f562848370bcbb6d6c7bda322eadc3c0cca58a5dd4509da43296d4561b4241a09a543014c697d2437456cfa26b79e6cd264c2b042fe5b407404e437, 493046022100c20e2f4ad2b5fc687f9913f401a582a7be3ac785bd9842774600588bcd18d335022100ce5d94f9c766535178e95775f12a23b8a0584d46d79a9d2835ba79cf957821410141040f5d227f1f562848370bcbb6d6c7bda322eadc3c0cca58a5dd4509da43296d4561b4241a09a543014c697d2437456cfa26b79e6cd264c2b042fe5b407404e437, 4294967295, 0, ac158c6305b976a0f3880d5289c8cbb7d3f62caa71c681ef50c57de0b1af3a32, pubkeyhash, 5.0}, {16XoHfq8o8fLgbBxMLM52cvdzBzwXhV26N, 1, 1, 3045022010515380d750c0e0f4ff7ee4397b54a02ed3c9b817c62b0094b3d7e4302364c60221009f96ab3f10e8103dd68286a973e13df6b7a53131d87b2037634fd90b88935de6[ALL] 040590f8803f13c6d09e00e7deba838193c78d9f908a5b16a5105e3525b559b5f7bc8b69a245d30c8eb73d2631cef4f991cc5893ec3aa64a7202bff042afd208c5, 483045022010515380d750c0e0f4ff7ee4397b54a02ed3c9b817c62b0094b3d7e4302364c60221009f96ab3f10e8103dd68286a973e13df6b7a53131d87b2037634fd90b88935de60141040590f8803f13c6d09e00e7deba838193c78d9f908a5b16a5105e3525b559b5f7bc8b69a245d30c8eb73d2631cef4f991cc5893ec3aa64a7202bff042afd208c5, 4294967295, 0, cbc4ff59801d36eb00d5b2ea95675b4503b05e7b4ef2d58a5a65f7d07e8c2d6b, pubkeyhash, 5.0}]|
|d82444ae6f94cf0e22d4abf303aba06fe6642f5a9dbc2bdd81c5209141cc3479|[{1GgyKFf8TeMArUP9zMtF1CKSQEzarrbZyS, 0, 1, OP_DUP OP_HASH160 ac191e504459aed73644bdb928747b64e9467483 OP_EQUALVERIFY OP_CHECKSIG, 76a914ac191e504459aed73644bdb928747b64e946748388ac, pubkeyhash, 0.02}]                                                                                                                                                                                                          |[{1DMmUJ9RCVTwVr4RqrFsm2hGwAQVB3E6Wr, 0, 1, 3045022037b40a3eccce1a5957e529eef531a4b7d226313906b33e9eeaa93fef3a100e44022100fc502c0154f08185fff0f318468d2aa9a63705a6e9825d35084f86ca8a9408e6[ALL] 04cd8456c272cc7166fe488e7577e0cfff590026cb764277214443eb1b43a67b5a804da18d24f75e7883174a531ea770f03f71d0af9a9cf0c246d108b91ef1b4c9, 483045022037b40a3eccce1a5957e529eef531a4b7d226313906b33e9eeaa93fef3a100e44022100fc502c0154f08185fff0f318468d2aa9a63705a6e9825d35084f86ca8a9408e6014104cd8456c272cc7166fe488e7577e0cfff590026cb764277214443eb1b43a67b5a804da18d24f75e7883174a531ea770f03f71d0af9a9cf0c246d108b91ef1b4c9, 4294967295, 1, 75fa403d904b1dbac7a8f02c00b4dc4ac335090fbff0eac593865196f059f3de, pubkeyhash, 0.02}]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|19fbe1e4e05986663d1ab1cd7fe80b9ceeb023e1775f9b6222c1799c36e03aba|[{16u5Tq1A5sQhGF3C1M9aMQvjXb25NyTsrZ, 0, 1, OP_DUP OP_HASH160 40b1fbec7c319fe74e6783d8275a4ce085d35e93 OP_EQUALVERIFY OP_CHECKSIG, 76a91440b1fbec7c319fe74e6783d8275a4ce085d35e9388ac, pubkeyhash, 1.08}, {19T3NfHbrQM4eMUWUrfYA21ncjq8apMeT9, 1, 1, OP_DUP OP_HASH160 5cadcd72cfb1358909358faa507d6e144042d253 OP_EQUALVERIFY OP_CHECKSIG, 76a9145cadcd72cfb1358909358faa507d6e144042d25388ac, pubkeyhash, 43.98}]|[{1KvjyDH9ekeWtwAhSwHvfUmsQcZ6KHksS7, 0, 1, 304402202699e8454ee80df01f24cd393f9a0e71b5dec4c6bed206719427ff4bf8f8747202200da287455a2c1f0bf402fcb96a4201d8611093218c85f20950020ff409b00675[ALL] 04d97bc1bea1b7b396584ce44aaa95d346f02c1bb0d8855818d7a3a2de2bac784eafd9c1f0a6c6554ae17cb2ea710e1824fe99153cd1f2e837debd8aea9300b03c, 47304402202699e8454ee80df01f24cd393f9a0e71b5dec4c6bed206719427ff4bf8f8747202200da287455a2c1f0bf402fcb96a4201d8611093218c85f20950020ff409b00675014104d97bc1bea1b7b396584ce44aaa95d346f02c1bb0d8855818d7a3a2de2bac784eafd9c1f0a6c6554ae17cb2ea710e1824fe99153cd1f2e837debd8aea9300b03c, 4294967295, 0, 4d06adb3f51d60a1cd6bd7bee9556e8f6563d017ea37e970781eccc839ff10c2, pubkeyhash, 45.06}]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+----------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
==
このデータから、output と input のアドレスと金額を抽出して縦持ちデータを作成してください。

すると下記のコードが生成されます。追加で処理を追記しつつ、2-3回デバッグをするだけで下記のコードが書けました。

from pyspark.sql.functions import explode, col, format_number, lit

# Extract sender addresses from inputs
inputs_df = df.select(
    col("hash"),
    col("block_timestamp"),
    explode("inputs").alias("input")
).select(
    col("hash"),
    col("block_timestamp"),
    col("input.address").alias("address"),
    col("input.value").alias("amount"),
).withColumn("direction", lit("input"))

# Extract recipient addresses and amounts from outputs
outputs_df = df.select(
    col("hash"),
    col("block_timestamp"),
    explode("outputs").alias("output")
).select(
    col("hash"),
    col("block_timestamp"),
    col("output.address").alias("address"),
    col("output.value").alias("amount")
).withColumn("direction", lit("output"))

# Combine inputs_df and outputs_df
tx_df = inputs_df.union(outputs_df)
# Select necessary columns
tx_df = tx_df.select("hash", "block_timestamp", "direction", "address", "amount")
# Order by hash and position
tx_df = tx_df.orderBy("hash", "direction")
# Format the amount
tx_df = tx_df.withColumn("amount", format_number("amount", 8))

# Display the result
l = ["4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d", "e9cb6b508ccb4ed1302b4ede21caeb6a7ceeda7f399d5e920160a462155af430", "ca9388fb4b6d2f92c95f1713b99b9f250d6f5635843a2fce9b2417924b2e0297"]
tx_df.filter(col("hash").isin(l)).show(truncate=False)

実行結果

上記コードを実行した結果、下記の結果が得られました。

+----------------------------------------------------------------+-------------------+---------+----------------------------------+-----------+
|hash                                                            |block_timestamp    |direction|address                           |amount     |
+----------------------------------------------------------------+-------------------+---------+----------------------------------+-----------+
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|input    |17TLtRVBZKtWzErFwisMjwnW1RtFUx5Wou|0.01637169 |
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|input    |1GdsUE2KuVXVuKPXwGYVYX2cwuX1cyvTkj|0.04005355 |
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|input    |184Gxrr6pm7ScU2pSB8hibGwW2GttBpY3m|0.49950000 |
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|input    |1HVe3xJ9iG8fjqd5RcNA2aJsiGoskApUth|3.30000000 |
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|input    |1CkywZp8fpH4XWjpxwZYQ1SJA8oojPFfQd|6.00000000 |
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|input    |1MZUCUEoe6q1USdipbPWmAyH6Cn4e57LdM|1.15524789 |
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|output   |1MWjnvLVmRyjaDvJAWtR9NVGggPTM6kKEV|0.01017313 |
|4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d|2011-10-02 02:18:55|output   |1DLbJZqbkwVCjJRhjuBsx8vsCT2HMFVpmY|11.00000000|
|ca9388fb4b6d2f92c95f1713b99b9f250d6f5635843a2fce9b2417924b2e0297|2011-10-01 11:48:49|input    |17dFre6FVXScvsmhrXjJpF72zcpTrXKSG8|0.11868665 |
|ca9388fb4b6d2f92c95f1713b99b9f250d6f5635843a2fce9b2417924b2e0297|2011-10-01 11:48:49|output   |1Q2Kr4Lb1hcUnPUSPJSdEbsMEPTfXHfhqv|0.10868665 |
|ca9388fb4b6d2f92c95f1713b99b9f250d6f5635843a2fce9b2417924b2e0297|2011-10-01 11:48:49|output   |1KsWuvrXe7fhuey4rABbWeob6C1tYDKTmC|0.01000000 |
|e9cb6b508ccb4ed1302b4ede21caeb6a7ceeda7f399d5e920160a462155af430|2011-10-01 09:04:01|input    |1Q8VXmgNL5BiaYS8n9e1iw3t6XXFEeR7MP|50.00000000|
|e9cb6b508ccb4ed1302b4ede21caeb6a7ceeda7f399d5e920160a462155af430|2011-10-01 09:04:01|output   |1NitJP8qHfJJQnXqDx5zDjuKTW647f69xM|50.00000000|
+----------------------------------------------------------------+-------------------+---------+----------------------------------+-----------+

サンプリングした結果の確認

実行結果に表示されている3つのトランザクションを Blockchain.com の Explorer で確認してみました。それぞれのトランザクションにおいて、正しく抽出できていることが確認できています。

取引1

6つのウォレットから、2つのウォレットにお金が流れていることが確認できます。

4dd37c9aa2d9c3faeedd1548c6b3edc75749a60e863cb8a14d8f561f1274b65d

取引2

1つのウォレットから、2つのウォレットにお金が流れていることが確認できます。

ca9388fb4b6d2f92c95f1713b99b9f250d6f5635843a2fce9b2417924b2e0297

取引3

最後のケースはシンプルで、1つのウォレットから、別の1つのウォレットにお金が流れていることが確認できます。

e9cb6b508ccb4ed1302b4ede21caeb6a7ceeda7f399d5e920160a462155af430

最後に

今回の処理で、ビットコインのブロックチェーンに関するパース方法が確立できました。
今回はトランザクション量が少ない2011年10月1日の一日分のデータを使って、Jupyter 上で処理フローを構築しましたが、月間データや年間データを処理する際にはバッチ処理が必要となります。

このため、将来の処理に備えて Python スクリプトも作成しました。
python-training/hello-pyspark at main · new-village/python-training (github.com)

この記事が気に入ったらサポートをしてみませんか?