概述
Bitcoin 公链可以理解为是一个公共的数据库,里面存储的是Bitcoin发布至今的所有转账记录,并且任何人只要接入到其网络中都可以获取,并不需要任何交易、挖矿、持币等相关操作。
本文主要主题的是将原始的Bitcoin公链数据进行清洗规整,写入到阿里云SLS,然后做一些有趣的数据处理,比如实现简洁的区块链浏览器、数据分析、交易链路追踪等。整个框架如下图:
阿里云 SLS 的使用教程参考官方文档,这里假设已经拥有阿里云账号并开通SLS,创建了测试project和logstore。关于 Bitcoin 的技术细节这里不会做深入讨论,不过如果要完全理解Bitcoin公链数据的ETL过程,也需要对Bitcoin的原理(比如UTXO机制)有基础了解。
Bitcoin 公链数据
Bitcoin公链数据接收需要运行一个接收端,具体的操作步骤可移步互联网搜索,这里补充一个细节,在运行bitcoind的时候需要指定 -txindex 参数,为交易数据维护索引提供ETL来使用,运行命令参考
./bitcoind \
-rpcuser=username \
-rpcpassword=password \
-daemon \
-txindex
Bitcoin公链数据结构其实就是一个单链表,连续的区块(block)之间通过hash指针连接,而区块则是多笔交易(transaction)的集合,每一个交易则包含了一组输入(input,关联的是某次交易的输出)和一组输出(output,关联一个目标)。数据结构细节参考 Bitcoin Wiki。
ETL 过程
Bitcoin公链数据 Python ETL代码已经放到 Github ,其使用了开源项目 Bitcoin ETL做数据解析。
假如我们需要将本机运行的bitcoin接收端的数据从0至10000区块解析后写入SLS的 project my-blockchain-data
中的logstore bitcoin
。使用样例如下:
python bitcoin-etl.py \
--ak-id=LTA******* \
--ak-secret=******** \
--endpoint=cn-shanghai.log.aliyuncs.com \
--project=my-blockchain-data \
--logstore=bitcoin \
--btc-provider="http://username:password@localhost:8332" \
--start-block=0 \
--end-block=10000 \
--workers=5
解析后的数据包含4个类别的数据内容:block、transaction、input、output,通过SLS内知字段 __topic__
来做区分。在解析后的数据中添加了3个元字段:_bk_
表示区块高度、 _ts_
表示出块时间, _tx_
表示交易在区块中的序号。
以下是解析后的数据样例。
- block
__topic__: block
_bk_: 100000
_ts_: 1293623863
bits: 1b04864c
coinbase_param: 044c86041b020602
hash: 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506
merkle_root: f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766
nonce: 10572b0f
size: 957
stripped_size: 957
transaction_count: 4
version: 1
weight: 3828
- transaction
__topic__: transaction
_bk_: 100000
_ts_: 1293623863
_tx_: 3
fee: 0
hash: e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d
input_count: 1
input_value: 1000000
is_coinbase: n
lock_time: 0
output_count: 1
output_value: 1000000
size: 225
version: 1
virtual_size: 225
- input
__topic__: input
_bk_: 100000
_ts_: 1293623863
_tx_: 3
addresses: 1JxDJCyWNakZ5kECKdCU9Zka6mh34mZ7B2
index: 0
required_signatures:
script_asm: 3046022100bb1ad26df930a51cce110cf44f7a48c3c561fd977500b1ae5d6b6fd13d0b3f4a022100c5b42951acedff14abba2736fd574bdb465f3e6f8da12e2c5303954aca7f78f3[ALL] 04a7135bfe824c97ecc01ec7d7e336185c81e2aa2c41ab175407c09484ce9694b44953fcb751206564a9c24dd094d42fdbfdd5aad3e063ce6af4cfaaea4ea14fbb
script_hex: 493046022100bb1ad26df930a51cce110cf44f7a48c3c561fd977500b1ae5d6b6fd13d0b3f4a022100c5b42951acedff14abba2736fd574bdb465f3e6f8da12e2c5303954aca7f78f3014104a7135bfe824c97ecc01ec7d7e336185c81e2aa2c41ab175407c09484ce9694b44953fcb751206564a9c24dd094d42fdbfdd5aad3e063ce6af4cfaaea4ea14fbb
sequence: 4294967295
spent_output_index: 0
spent_transaction_hash: f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b
type: pubkeyhash
value: 1000000
- output
__topic__: output
_bk_: 100000
_ts_: 1293623863
_tx_: 3
addresses: 16FuTPaeRSPVxxCnwQmdyx2PQWxX6HWzhQ
index: 0
required_signatures:
script_asm: OP_DUP OP_HASH160 39aa3d569e06a1d7926dc4be1193c99bf2eb9ee0 OP_EQUALVERIFY OP_CHECKSIG
script_hex: 76a91439aa3d569e06a1d7926dc4be1193c99bf2eb9ee088ac
type: pubkeyhash
value: 1000000
区块链浏览器
这里基于SLS的查询、分析以及数据展示能力,我们将写入到 SLS 的Bitcoin公链数据快速实现Bitcoin的区块链浏览器。
- 最新的10个区块信息
SQL 语句:
(__topic__: block)| select
_bk_ as "区块高度",
_ts_ as "出块时间",
transaction_count as "交易笔数",
size as "区块大小",
nonce as "出块 Nonce"
order by
_bk_ desc
limit
10
结果展示:
- 最新的10000个交易信息
SQL 语句:
(__topic__: transaction) |
select
hash as "交易Hash",
_ts_ as "出块时间",
if(is_coinbase = 'y', '是', '否') as "是否为Coinbase",
input_value as "交易量(sat)",
fee as "交易费用(sat)",
size as "交易大小",
round(fee / size, 2) as "交易费率(sat/byte)"
limit
10000
结果展示:
- 区块 727,932 的所有参与交易的地址
SQL 语句:
(*
and _bk_: 727932
and (
__topic__: input
or __topic__: output
) not _tx_ :0)| select
_bk_ as "区块高度",
arbitrary(_ts_) as "出块时间",
_tx_ as "交易编号",
arbitrary(inputs) as "源",
arbitrary(outputs) as "目标",
arbitrary(value) as "量(sat)"
from(
select
*,
if(__topic__ = 'input', addresses, NULL) as inputs,
if(__topic__ = 'output', addresses, NULL) as outputs
FROM (
select
arbitrary(_ts_) as _ts_,
_bk_,
_tx_,
__topic__,
array_join(max(addresses, 1000), ', ') as addresses,
sum(value) as value
FROM log
group by
_bk_,
_tx_,
__topic__
order by
_tx_,
__topic__
)
)
group by
_bk_,
_tx_
order by
_bk_,
_tx_
limit
10000
结果展示:
总结
本文讨论了如何将原始的Bitcoin公链数据进行清洗规整,写入到阿里云SLS,然后实现简洁的区块链浏览器。后续还将分享如何通过Bitcoin公链数据追踪转账链路,敬请关注。
下图是 SLS 团队的技术博客,我们会不定期推出技术文章分享和产品更新介绍,欢迎大家订阅,有任何问题也欢迎与我们反馈。