btc: scantxoutset
2025/04/18
Bitcoin Core の JSON-RPC はいろいろあるが、 基本的にはブロックとかトランザクションについての機能で アドレス関係については自分のウォレットだけしかない、と思っていた。
今日なんとなく RPC コマンドを眺めていると scantxoutset
というコマンドを見つけた。
そんなのあったっけ?
scantxoutset
これを書いている時点でこのページには EXPERIMENTAL と書いてあるが Bitcoin Core v29.0 の help では出てこなかった。
v22.0 で外れたようだ。
単に私がこのコマンドを知らなかっただけか。
Descriptors の形式で与えると UTXO を探してくれるようだ。
試しに、coinbase トランザクションの送金先を調べてみよう。
どこでもよいのだけど、あんまり個人のアドレスだったりすると嫌な感じがするので気を遣ったのだ。
$ time bitcoin-cli scantxoutset start '["addr(3G7jcEELKh38L6kaSV8K35pTqsh5bgZW2D)"]'
{
"success": true,
"txouts": 173857921,
"height": 892934,
"bestblock": "00000000000000000001e4474608c793d7e3e2fdf667c0ecba0f999d433f774d",
"unspents": [
{
"txid": "b79d0a7444951fc1ed05e5950a599535a489e057630263c7fd75976b9e429a06",
"vout": 1,
"scriptPubKey": "a9149e3e8a50d9acb3ac7649625432e2207c25e0faf887",
"desc": "addr(3G7jcEELKh38L6kaSV8K35pTqsh5bgZW2D)#qd5g5gfy",
"amount": 0.01576048,
......
"blockhash": "0000000000000000000082a78f5b3857825a93252ca8e84e041144750b1a5001",
"confirmations": 106
}
],
"total_amount": 21.39097851
}
real 9m40.333s
user 0m0.005s
sys 0m0.015s
Raspberry Pi4 で HDD にデータをかなり置いているためだとは思うが 10 分もかかってしまった。
同じことを Electrs でやってみる。
こちらは残高しか出てこないので直接の比較はできないが目安にはなろう。
アドレスの 3G7jcEELKh38L6kaSV8K35pTqsh5bgZW2D
の scriptPubKey a9149e3e8a50d9acb3ac7649625432e2207c25e0faf887
を SHA256 して 3f0b309bdd754c467262cc3fd79b2ec5be5a8ea2478cb262cad00f99536cb9e0
。
これをエンディアンを逆に並び替えて e0b96c53990fd0ca62b28c47a28e5abec52e9bd73fcc6272464c75dd9b300b3f
。
$ echo '{"jsonrpc": "2.0", "method": "blockchain.scripthash.get_balance", "params": ["e0b96c53990fd0ca62b28c47a28e5abec52e9bd73fcc6272464c75dd9b300b3f"], "id": 0}' | netcat 192.168.0.30 50001
{"id":0,"jsonrpc":"2.0","result":{"confirmed":2139097851,"unconfirmed":0}}
こちらは目視で時計を見ての計測になったが 2分33秒程度だった。
ちなみにトランザクションの履歴ならば blockchain.scripthash.get_history
メソッドで取得できる。
$ echo '{"jsonrpc": "2.0", "method": "blockchain.scripthash.get_history", "params": ["e0b96c53990fd0ca62b28c47a28e5abec52e9bd73fcc6272464c75dd9b300b3f"], "id": 0}' | netcat 192.168.0.30 50001
出力は長いので省略するが、1つ分はこういうデータになっている。
古い方から出力されていて一番最後が最新だ。
get_balance に続けて実行したせいか 1分半もかからず結果が返ってきた。
{
"height": 846326,
"tx_hash": "c1d734430dd77fff1115f1500ddfc528a13000f7ff2f47597320d426a51cb63d"
},
Electrs のデータベースは RocksDB という LevelDB 系だそうだ。
key-value DB である。
残高は output 関係なので Electrs のスキーマからすると funding というテーブルか。
引数が SHA256(script)
なのも一致する。
該当するブロック高が全部載っていて、それぞれ Bitcoin Core で検索してブロックを取得し、
そのトランザクションの中から該当する output を探し出して value
を合計する、という感じか。
大変そうだが、これ以上細かくするなら Bitcoin Core に txindex=1
を付けて直接トランザクションを引っ張ってくるくらいしか思いつかない。
が、Electrs は txindex=0
で運用できるようになっている。
これは Blockstream版も mempool.space版もそうだ。
にもかかわらず取得は速いので、やっぱりうちが HDD で運用しているのが原因か。