btc: bitcoind だけで知らないアドレスの残高を得たい
2025/03/26
はじめに
これまで私は Bitcoin などのウォレットのAPIがある環境で作業していた。
bitcoind でもウォレット有りにして getbalance
すれば残高は取得できる。
しかし、ウォレットが無い環境だとどうやったらよいのだろう?
Electrum Server API
Electrum Server API では blockchain.scripthash.get_balance という API があった。 scriptPubKey を SHA256 してエンディアンを逆転した値を引数に与えると、confirmed と unconfirmed の残高を返してくれる。
お手軽だ。 非常にお手軽である。
bitcoind にはそういうのがない
bitcoin-cli help
で使用できるコマンド一覧が出力されるが、v28.1 にはそういうコマンドはない。
ウォレットがあれば getbalance
できるが、これはあくまで bitcoind が管理しているウォレットについてだけだ。
ではどうする?
たぶんだが、Electrum Server を起動するときに bitcoind からブロックを取得し、 トランザクションを抜き出し、 OUTPUT から SHA256(scriptPubKey) をキーにして value などを DB に保存しているのだと思う。
いや、それだけだとその OUTPUT が UTXO かどうかわからないな。
トランザクションを単体で見たとき、その OUTPUT が UTXO かどうかを見分けることはできない。
ブロックに組み込まれるときには UTXO だし、ブロックに組み込まれた後に書き換えることはないからだ。
結局のところ、違うトランザクションの INPUT が指す OUTPUT を spent にするしかないか。
DB としては、TXID をキーにするのと、SHA256(scriptPubKey) をキーにするのとがあり、
- ブロックからトランザクション群を取得
- OUTPUT の scriptPubKey を SHA256 して検索し、なければ新規、あれば更新で value を残高に加算
- coinbaseトランザクションは INPUT がないのでそのまま DBに保存
- それ以外は INPUT の TXID をキーにして検索し、該当する outpoint と INPUT の TXID を紐付ける(spent扱い)
- scriptPubKey を取得して SHA256 して検索し、合計残高から value を減算
他にもあるだろうが残高に関してはこんな感じか。
confirmed と unconfirmed を区別しているからそういう分類もいるか。
大変だなあ。
おわりに
本当は electrs のコードを見ながら推測したかったのだけど、わからんかった。
たぶんこのあたりなのだろうけど、
これは API の入口で値を取得して返すだけだ。
DB の更新は定期的に行わないと unconfirmed の情報は取ってくることができない。
こういうのを自分で作るのは大変なので、フルノードを自分で立てたとしても Electrum Server も一緒に立てた方がアプリ作成は楽になるな。
せっかく立てるなら公開した方がシステムのためには良いのだろうけど、DB がけっこうなサイズを使いそうだしクラウドには立てたくない。
一般に公開しないとしても、自分で作ったモバイルアプリだけは自宅の Electrum Server につなぎたいだろう。
その辺もいずれ調べたいところだ。