A minimal, cyberpunk Bitcoin block explorer written in Go. Served directly from a Bitcoin Core full node over JSON-RPC. No database, no indexer, no JavaScript framework — just your node and a single static binary.
- Zero external dependencies beyond Bitcoin Core — no Electrum, no database
- Server-side rendered with
html/template; no JavaScript - Single binary — templates and CSS are embedded at compile time
- Per-network UI accent — mainnet green, testnet3 cyan, testnet4 amber, regtest purple
- LRU cache for immutable blocks and confirmed transactions
- Address scans with CSS-only progress bar and
<meta>auto-refresh (no polling JS) - Supports mainnet, testnet3, testnet4, regtest
| Route | Description |
|---|---|
GET / |
Overview — latest N blocks + chain summary |
GET /block/:id |
Block detail by hash or height |
GET /tx/:txid |
Transaction — confirmed or mempool, inputs/outputs, raw JSON |
GET /address/:addr |
Address validation + links to scans |
GET /address/:addr/utxos |
UTXO set scan with live progress bar |
GET /address/:addr/history |
Block filter tx history (requires blockfilterindex) |
GET /node |
Node info — version, connections, chain |
GET /search |
Routes height / hash / txid / address to the right view |
- Go 1.22+
- Bitcoin Core v25+ (v28+ for testnet4)
blockfilterindex=1inbitcoin.conffor address history scanstxindex=1optional — not required (verbosity-3getrawtransactionprovides prevouts)
git clone https://github.com/alex27riva/mempunk
cd mempunk
make buildThe version is read automatically from the current git tag (git describe --tags --always). Tag a release before building:
git tag v1.0.0
make build # embeds "v1.0.0" in the binaryWithout make, or on systems without make installed:
go build -ldflags "-X github.com/alex27riva/mempunk/internal/version.Version=$(git describe --tags --always)" -o mempunk ./cmd/mempunkThe binary embeds all templates and the stylesheet; no extra files needed at runtime.
cp config.example.yaml config.yaml
$EDITOR config.yamlMinimal config:
network: mainnet
rpc:
host: "127.0.0.1"
user: "bitcoin"
password: "your-rpc-password"
# or cookie auth:
# cookie_file: "/home/bitcoin/.bitcoin/.cookie"
server:
listen: "0.0.0.0:2100"Every field can be overridden with a MEMPUNK_* environment variable:
MEMPUNK_RPC_PASSWORD=secret MEMPUNK_LOG_LEVEL=debug ./mempunk| Key | Default | Description |
|---|---|---|
network |
mainnet |
mainnet | testnet3 | testnet4 | regtest |
rpc.host |
127.0.0.1 |
Bitcoin Core RPC host |
rpc.port |
network default | 8332 / 18332 / 48332 / 18443 |
rpc.user / rpc.password |
— | RPC auth (mutually exclusive with cookie) |
rpc.cookie_file |
— | Path to .cookie file |
server.listen |
0.0.0.0:2100 |
HTTP listen address |
log.level |
info |
debug | info | warn | error |
log.format |
text |
text | json |
explorer.latest_blocks |
12 |
Blocks shown on the overview page |
explorer.block_tx_details |
true |
Load full tx list on block pages |
explorer.block_tx_page_size |
200 |
Initial tx count per block page; "load more" doubles it |
explorer.shorten_hashes |
true |
Show hashes as 00000000…392e92b5 in list views |
explorer.cache_size |
1000 |
LRU cache entries (0 = disabled) |
./mempunk
# or during development:
go run ./cmd/mempunkmempunk verifies connectivity and chain on startup (getblockchaininfo + getnetworkinfo) and exits fast on misconfiguration.
By default it listens on 0.0.0.0:2100. To expose it publicly, put it behind a reverse proxy:
location / {
proxy_pass http://127.0.0.1:2100;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}Create /etc/systemd/system/mempunk.service:
[Unit]
Description=mempunk Bitcoin block explorer
After=network.target bitcoind.service
Wants=bitcoind.service
[Service]
Type=simple
User=mempunk
WorkingDirectory=/home/mempunk
ExecStart=/home/mempunk/mempunk
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetInstall and start:
# create dedicated user with home directory (matches RaspiBlitz conventions)
sudo useradd -m -s /usr/sbin/nologin mempunk
# install binary and config
sudo cp mempunk /home/mempunk/
sudo cp config.yaml /home/mempunk/
sudo chown -R mempunk:mempunk /home/mempunk
# enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now mempunk
# check logs
sudo journalctl -u mempunk -fOpen the firewall port:
sudo ufw allow 2100 comment "mempunk HTTP"If using cookie auth (recommended on RaspiBlitz), grant read access to .cookie and set the path in config.yaml:
sudo usermod -aG bitcoin mempunkrpc:
cookie_file: "/home/bitcoin/.bitcoin/.cookie"Recommended settings for full mempunk functionality:
server=1
rpcuser=bitcoin
rpcpassword=your-password
# required for address history scans
blockfilterindex=1
# optional — mempunk works without it
# txindex=1cmd/mempunk/ # entrypoint
internal/
config/ # YAML config, env overrides, network params
rpc/ # JSON-RPC client (read-only, 30s / 5min timeouts)
cache/ # generic LRU cache
version/ # build metadata (Version/GitCommit/BuildDate), set via ldflags
explorer/ # RPC orchestration, view models, address scans
handlers/ # thin Echo HTTP handlers
render/ # Echo renderer backed by embedded templates
web/
templates/ # html/template files (embedded)
static/style.css # cyberpunk stylesheet (embedded)
config.example.yaml
- Go — standard library + minimal deps
- Echo v4 — HTTP framework
html/template— server-side renderinglog/slog— structured loggingembed— single binary, no external assets
MIT