Run a Blockbook indexer + explorer¶
Blockbook is the indexer + REST API backend used by Trezor's block explorers and the Bitcoin Gold (BTG) community explorer at explorer.bitcoingold.services. It maintains a RocksDB-backed address index on top of a bgoldd full node, then exposes a JSON-over-HTTP API that any front-end (Trezor's open-source blockbook-frontend, or your own) can render.
This course covers standing up Blockbook with the BTCGPU-specific configuration used in production.
Who this is for¶
You want to expose a public block explorer for Bitcoin Gold (BTG), or you need address-level index data for a wallet service. Blockbook consumes ZMQ events from a bgoldd instance, so you need a synced full node with zmqpubhashblock enabled.
What you'll build¶
- A compiled Blockbook binary at
/opt/coins/blockbook/bgold/bin/blockbook. - A dedicated
blockbook-bgoldsystem user. - A
blockchaincfg.jsonthat tells Blockbook about Bitcoin Gold (BTG)'s address formats, coin type, and ZMQ endpoint. - A
systemdunit withPrivateTmp,ProtectSystem=full,NoNewPrivileges,MemoryDenyWriteExecute. - A reverse-proxied
nginxvhost on 443 → 127.0.0.1:9135. - A public REST API you can hit from any web client.
Requirements¶
| Resource | Minimum | Recommended (public explorer) |
|---|---|---|
| OS | Ubuntu 22.04 LTS | Ubuntu 22.04 / 24.04 LTS |
| CPU | 4 cores | 8+ cores |
| RAM | 8 GB | 16 GB |
| Disk | 200 GB SSD (RocksDB) | 500 GB NVMe (initial sync + growth) |
| Backend | bgoldd v0.17.3 with zmqpubhashblock=tcp://127.0.0.1:38335 |
Same host or LAN |
| Ports | 9135 (internal), 9035 (internal) | 443 (public, via nginx) |
1. Get the BTCGPU Blockbook fork¶
The upstream Trezor Blockbook doesn't know about Bitcoin Gold (BTG) address formats, xpub magic, or the Bitcoin Gold (BTG) genesis hash. The community fork lives in the BTCGPU organization.
sudo mkdir -p /opt/coins/blockbook
cd /opt/coins/blockbook
git clone https://github.com/BTCGPU/blockbook.git bgold
cd bgold
git log --oneline -1
2. Build¶
Blockbook is a Go project. Build with Go 1.18+.
A static, ~30 MB binary. Test:
3. Create the system user¶
sudo useradd --system --home /opt/coins/blockbook/bgold --shell /usr/sbin/nologin blockbook-bgold
sudo chown -R blockbook-bgold:blockbook-bgold /opt/coins/blockbook/bgold
4. Configure Blockbook¶
The blockchaincfg.json is the single most important file. This is what runs in production at bitcoingold.services:
sudo tee /opt/coins/blockbook/bgold/config/blockchaincfg.json > /dev/null <<'EOF'
{
"fiat_rates": "",
"fiat_rates_params": "",
"fiat_rates_vs_currencies": "",
"coin_name": "Bgold",
"coin_shortcut": "Bitcoin Gold (BTG)",
"coin_label": "Bitcoin Gold",
"rpc_url": "http://127.0.0.1:8332",
"rpc_user": "explorer",
"rpc_pass": "SWbeR6SkQ4cP3BVPNetr",
"rpc_timeout": 25,
"parse": true,
"message_queue_binding": "tcp://127.0.0.1:38335",
"subversion": "/Bitcoin Gold:0.17.3/",
"address_format": "",
"xpub_magic": 76067358,
"xpub_magic_segwit_p2sh": 77429938,
"xpub_magic_segwit_native": 78792518,
"slip44": 156,
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 300
}
EOF
# Replace rpc_user / rpc_pass with your real bgoldd credentials.
# Replace "SWbeR6SkQ4cP3BVPNetr" with the actual rpcpassword.
sudo chown blockbook-bgold:blockbook-bgold /opt/coins/blockbook/bgold/config/blockchaincfg.json
sudo chmod 600 /opt/coins/blockbook/bgold/config/blockchaincfg.json
The xpub_magic values are the BIP32 extended-public-key version bytes for Bitcoin Gold (BTG). The slip44 is Bitcoin Gold (BTG)'s coin type, 156.
What's the difference between mempool_workers and mempool_sub_workers?
mempool_workers is the number of goroutines that pull tx details from the daemon. mempool_sub_workers is how many parallel RPC calls each one can make. With 8 cores, 8 / 2 is a reasonable starting point.
5. Data directory¶
sudo mkdir -p /opt/coins/data/bgold/blockbook/db
sudo chown -R blockbook-bgold:blockbook-bgold /opt/coins/data/bgold/blockbook
Size the disk generously
Blockbook's RocksDB index is currently ~140 GB and grows by ~5 GB/month. Plan for at least 500 GB of free space on whatever volume holds /opt/coins/data/bgold/blockbook/db.
6. systemd unit¶
sudo tee /etc/systemd/system/blockbook-bitcoingold.service > /dev/null <<'EOF'
[Unit]
Description=Blockbook daemon (Bgold)
After=network.target
Wants=btgd.service
[Service]
ExecStart=/opt/coins/blockbook/bgold/bin/blockbook \
-blockchaincfg=/opt/coins/blockbook/bgold/config/blockchaincfg.json \
-datadir=/opt/coins/data/bgold/blockbook/db \
-sync \
-internal=127.0.0.1:9035 \
-public=127.0.0.1:9135 \
-log_dir=/opt/coins/blockbook/bgold/logs
User=blockbook-bgold
Type=simple
Restart=on-failure
TimeoutStopSec=300
WorkingDirectory=/opt/coins/blockbook/bgold
# Resource limits
LimitNOFILE=500000
# Hardening measures
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
MemoryDenyWriteExecute=true
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now blockbook-bitcoingold.service
sudo journalctl -u blockbook-bitcoingold.service -f
The two ports are:
-internal=127.0.0.1:9035— used by the front-end (or your own reverse proxy).-public=127.0.0.1:9135— public REST API. Do not expose 9035 to the internet.
7. Reverse proxy with nginx (TLS)¶
sudo tee /etc/nginx/sites-available/explorer.conf > /dev/null <<'EOF'
server {
listen 80;
server_name explorer.bitcoingold.services;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name explorer.bitcoingold.services;
ssl_certificate /etc/letsencrypt/live/bitcoingold.services/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bitcoingold.services/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
add_header X-Robots-Tag "all" always;
location / {
proxy_pass http://127.0.0.1:9035;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/explorer.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo nginx -s reload
8. Verification¶
Local¶
# Is it up?
systemctl status blockbook-bitcoingold.service
# Sync progress (block height Blockbook has indexed)
curl -s http://127.0.0.1:9135/api/v2/btg/info | jq '.data | {blocks, bestblockhash, version}'
Public¶
# Public REST API
curl -s https://explorer.bitcoingold.services/api/v2/btg/info | jq
# Address details
curl -s https://explorer.bitcoingold.services/api/v2/btg/address/GYf8nyo1c8oWsHzbvL1fD3Ckgg68UzBi5J | jq
# Block by height
curl -s https://explorer.bitcoingold.services/api/v2/btg/block/800000 | jq
WebSocket (real-time)¶
wscat -c wss://explorer.bitcoingold.services/api/v2/btg/ws
> {"id":1,"method":"subscribeAddresses","params":["GYf8nyo1c8oWsHzbvL1fD3Ckgg68UzBi5J"]}
< {"id":1,"data":{"address":"GYf8nyo1c8oWsHzbvL1fD3Ckgg68UzBi5J","status":"ok"}}
9. Operating¶
Initial sync¶
The RocksDB index is built from scratch on first run. Expect 1–3 days for a 165 GB chain. Watch the logs:
Look for lines like synced 800000/949737 (block index progress).
Disk monitoring¶
Add a daily alert when the data dir exceeds 80 % of its volume:
Restart behaviour¶
Restart=on-failure + Type=simple. The -sync flag means Blockbook reindexes from the last persisted RocksDB checkpoint on restart, which is fast (minutes) once the initial sync is done.
Updating¶
cd /opt/coins/blockbook/bgold
sudo -u blockbook-bgold git pull
go build -o bin/blockbook
sudo systemctl restart blockbook-bitcoingold.service
Troubleshooting¶
"Cannot connect to RPC" at startup¶
Test the same URL from the command line:
curl -u explorer:SWbeR6SkQ4cP3BVPNetr http://127.0.0.1:8332 \
-H 'Content-Type: application/json' \
-d '{"id":1,"method":"getblockchaininfo","params":[]}' | jq
If this works, the issue is in the JSON (typo, bad password escape). If it doesn't, fix bgoldd first.
"ZMQ: no block events in 10 minutes"¶
bgoldd is not emitting. Confirm zmqpubhashblock=tcp://127.0.0.1:38335 is in bitcoingold.conf and the daemon was reloaded after the change.
API returns 504 for normal queries¶
Increase nginx's proxy_read_timeout. Blockbook queries that touch many addresses can take >60 s during initial sync.
Address validation rejects G... P2PKH addresses¶
The xpub_magic in blockchaincfg.json is wrong. For Bitcoin Gold (BTG) it should be 76067358 (hex 0x0488B21E corresponds to xpub segwit-native in BTC — verify against src/chainparams.cpp in BTCGPU source).
What to do next¶
- Run the Trezor blockbook-frontend on top of the JSON API: https://github.com/trezor/blockbook-frontend.
- Add an ElectrumX layer alongside Blockbook — see Electrum server.
- Expose a public address-tagging service for exchanges / custodians.
- Harden the host following Hardening.
- Add monitoring with Prometheus + Grafana: Blockbook exposes
/metricson the internal port.
Source / further reading¶
- Trezor Blockbook docs
- BTCGPU/blockbook fork
- Bitcoin Gold (BTG) technical spec — for the address format constants