The official indexer for the Bitcoin Stamps meta-protocol: immutable digital assets stored directly in Bitcoin's UTXO set
SRC-20 / SRC-721 / OLGA / SRC-721r / SRC-101
btc_stamps is the official indexer for Bitcoin Stamps, a meta-protocol built on Bitcoin
and dedicated to immutability and permanent data storage on the Bitcoin blockchain.
This protocol is experimental and provided without warranty (see LICENSE).
The project evolved from a meta-protocol design created by Mikeinspace (Bitcoin Stamps Github) in February 2023 (initial commit). Reinamora137 developed this implementation, which has since become the foundation for the entire Bitcoin Stamps ecosystem.
Core principle: Unlike Ordinals, Bitcoin Stamps operate directly on the UTXO set to ensure true immutability. This fundamental design choice makes it impossible to accidentally spend or "inscribe" a Stamp.
The Bitcoin Stamps meta-protocol offers a suite of sub-protocols built on Bitcoin, all designed with immutability at their core:
| Protocol | Purpose | Activation |
|---|---|---|
| ποΈ Classic Stamps | Immutable digital collectibles via Counterparty standards | Block 779,652 |
| π° SRC-20 | Fair-launch fungible tokens, standard BTC miner fees only | Block 788,041 |
| πΌοΈ SRC-721 | Layered NFTs composed from multiple Stamps via JSON manifests | Block 792,370 |
| β‘ OLGA | P2WSH encoding: smaller transactions, 60-70% lower costs | Blocks 833,000 (Classic Stamps) / 865,000 (direct Bitcoin) |
| π SRC-721r | Recursive Stamps with JavaScript, virtually unlimited file sizes | Active |
| π SRC-101 | Bitcoin-native domain name system | Block 870,652 |
Immutable digital collectibles with built-in token functionality via Counterparty standards. While originally intended for 1:1 editions, creators can issue up to 4,294,967,295 editions per Stamp. Initially implemented using OP_MULTISIG transactions with Base64 encoded images, Classic Stamps now also support the OLGA P2WSH transaction format for up to 65kb per transaction. This design directly addresses the accidental spending vulnerability and prunability issues found in Ordinals.
History: The first Official Bitcoin Stamp (Stamp 0) was created by Mikeinspace in Block 779,652.
A fair, accessible fungible token protocol where users only pay standard BTC miner fees. Inspired by BRC-20 but enhanced with the immutability guarantees of Stamps.
History: The first SRC-20 Token, "KEVIN," was deployed by Reinamora in Block 788,041 (on Counterparty). SRC-20 moved to direct Bitcoin transactions at Block 793,068 and adopted the OLGA / P2WSH encoding at Block 865,000.
An advanced NFT format that uses JSON manifests to construct complex, layered images from data distributed across multiple Stamps. This approach enables high-resolution artworks while maintaining compatibility with Counterparty's token layer.
History: First implemented in Block 792,370.
A technical breakthrough that eliminates Base64 encoding overhead, reducing transaction size by 50% and lowering costs by 60-70% compared to the original OP_MULTISIG format. OLGA maintains full functionality while being significantly more efficient.
History: OLGA activated in two steps. Classic Stamps gained P2WSH at Block 833,000
(CP_P2WSH_FEAT_BLOCK_START). P2WSH data collection for direct Bitcoin transactions activated
at Block 865,000 (BTC_SRC20_OLGA_BLOCK) and covers SRC-20 and SRC-101 alike. It is now the
standard for new Classic Stamps. See docs/CONSENSUS.md for the
byte-level format.
The next evolution of SRC-721, enabling complex recursive images created using JavaScript and other libraries stored directly on Stamps. By recursively combining multiple Stamps, creators can build experiences with virtually unlimited file sizes.
A domain name system native to Bitcoin Stamps, developed by bitname.pro.
- π Local full BTC Node or an account with Quicknode.com (free tier is sufficient)
- ποΈ MySQL Database or default MySQL installation from the provided Docker setup
- π Python 3.10-3.12 (3.12 recommended). Do not use Python 3.13: it diverges from consensus (tracked in #871)
- π‘ RECOMMENDED: Local Counterparty Node (optional but recommended for production)
For a simple Docker-based installation of the Bitcoin Node and Counterparty stack, see: Setting up a Counterparty Node
The default configuration uses the public Counterparty.io API and Stampchain.io Counterparty APIs for XCP asset data. For production use, we strongly recommend running a local Counterparty node to reduce dependency on public resources.
If you don't have Docker installed, follow the official guide: Install Docker Engine.
main is the trunk and default branch, so a fresh clone already checks it out:
git clone https://github.com/stampchain-io/btc_stamps.git
cd btc_stampsFor a verified, reproducible deployment, check out a signed release tag (e.g.
git switch --detach 1.9.1) and verify its Docker image per
Signed Releases.
The docker stack reads a single env file (.env.local by default). Create it
from the template and fill in your Bitcoin node + database details:
cp .env.example .env.local
# edit .env.local: set RDS_USER / RDS_PASSWORD / RDS_DATABASE and node RPC credsThe compose setup uses one canonical base (docker-compose.yml) plus overrides:
- Development (default):
docker-compose.override.ymlis applied automatically and brings up the indexer (on host networking) + a local MySQL with persistentdb_data. - Production:
docker-compose.prod.ymlis selected explicitly and targets a managed MySQL (RDS/Aurora) with no local database. (Production currently runs natively via systemd; the docker-prod path is not yet deployed.)
# Development: indexer + local MySQL
docker compose up -d
# View indexer logs
docker compose logs -f indexer
# Stop the stack
docker compose down
# Production overlay (managed RDS/Aurora; not yet deployed)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dThe same flows are available via make (make dev, make logs,
make down, make prod); run make help for the full list.
The indexer includes a flexible container management system for development and testing:
cd indexer
# Run local development build (outputs to log files)
./run-container.sh --build
# Run a specific registry version with local MySQL
./run-container.sh --image 1.9.1 # or --image edge (latest main build)
# Run with logs to stdout (ideal for testing)
./run-container.sh --image edge --prod
# Run detached in background
./run-container.sh --image edge --detach
# Show all options
./run-container.sh --helpEnvironment modes:
--dev(default): Saves logs to local files, ideal for long-running development--prod: Directs logs to stdout/stderr, better for testing and debugging
Database connection:
All modes use the MySQL connection details from your .env.local file, so you can test any
registry version against your local database.
For backward compatibility, the legacy
local-dev.shscript is still available and delegates to the new unified runner.
For rapid testing without building locally:
- Set up environment file:
cd indexer
cp .env.sample .env.local
# Edit .env.local with your MySQL and BTC node details- Run the latest pre-release (edge) build:
./run-container.sh --image edge --prodThis will:
- Pull the latest edge image from GitHub Container Registry (newest main build)
- Connect to your local MySQL database (specified in .env.local)
- Output logs to stdout for easy debugging
- Use your local Bitcoin node configuration
Before deploying or committing changes to Docker configuration, validate your builds:
# Run a quick build test without starting services
cd indexer
./run-container.sh --testThis will build a test image, verify it can run properly, clean up after testing, and exit
with status code 0 on success or 1 on failure. The --test option is ideal for CI pipelines
and pre-commit validation.
If you encounter problems with container execution:
-
Verify database connection: The container connects to the MySQL server based on your .env.local file. Make sure your database is accessible at the address specified by
RDS_HOSTNAME. -
Test with production mode:
./run-container.sh --image edge --prod
This outputs logs directly to the console, making it easier to identify errors.
-
Clean up Docker resources:
./run-container.sh --cleanup
This removes all containers, volumes, and images related to the project.
-
Check container logs:
docker logs indexer-local-indexer-1
-
Verify network mode: If using host mode (default), ensure your local services are available on localhost. If your services are on different hosts, try bridge mode:
./run-container.sh --image edge --bridge
Configure environment variables for MySQL, Bitcoin Node, and Counterparty in the .env file.
Before installing Python dependencies, install system requirements:
sudo apt-get update
sudo apt-get install libgmp-devInstall Poetry:
curl -sSL https://install.python-poetry.org | python3 - --version 2.1.1Install dependencies and build the Rust parser:
cd indexer
poetry install --only main
# Build the high-performance Rust parser
poetry run task buildRun the indexer:
poetry run indexer- Install Development Dependencies:
poetry install # Installs all dependencies including dev tools- Run Code Quality Checks:
# Run all checks (code quality, Rust parser, integration tests)
poetry run run_checks
# Or run specific checks:
poetry run check-code # Run only code quality checks
poetry run check-rust # Run only Rust checks
poetry run check-integration # Run only integration tests
poetry run task bandit # Run security checks with bandit- Build Rust Parser During Development:
# Using taskipy
poetry run task build-dev # Development build with debug symbols
# Or directly
cd src/rust_parser
./build.sh # Builds and verifies the Rust parserThe indexer features a high-performance Rust-based transaction parser that dramatically improves processing speed:
- π 20-50x faster transaction parsing than pure Python implementation
- π§ Efficient memory management
- π Thread-safe operation with built-in caching
- βοΈ Parallel batch processing capabilities
The Rust parser is automatically built during installation. To rebuild:
cd indexer
poetry run task buildFor development builds with debug symbols:
cd indexer/src/rust_parser
cargo buildThe indexer can use ZeroMQ (ZMQ) notifications from Bitcoin Core to receive immediate notification of new blocks. This is more efficient than polling for new blocks.
When a new block is received via ZMQ, the indexer delays processing it to allow Counterparty
to catch up. Configure the delay with the ZMQ_NOTIFICATION_DELAY environment variable
(default: 5 seconds):
# Example: Set ZMQ notification delay to 10 seconds
export ZMQ_NOTIFICATION_DELAY=10.0This delay helps prevent 404 errors when fetching new blocks from the Counterparty API, as it gives Counterparty time to process the new block before the indexer tries to fetch it.
Protocol evolution is governed through community-driven SIPs. See SIP-0000 for the full process.
| SIP | Title | Status |
|---|---|---|
| 0001 | SRC-20 Conditional Transfers (Hashlock/Timelock) | Draft |
| 0002 | SRC-20 UTXO Binding & Transfer Format v2.0 | Superseded (by 0001) |
| 0003 | SRC-20 Cross-Chain Bridge Specification | Draft |
| 0004 | Shielded SRC-20 (Privacy Extension, Phased) | Draft |
| 0005 | Binary Transfer Format for SRC-20 | Draft |
| 0006 | Native SRC-20 AMM (Automated Market Maker) | Draft |
| 0007 | Probabilistic Atomic Swaps for SRC-20 | Draft |
| 0008 | Dual Transaction Parsing | Draft |
| 0009 | On-Demand SRC-20 SVG Generation | Draft |
| 0010 | Decentralised Stamp Relay Network | Draft |
| 0011 | Batch Operations & State Channels for SRC-20 | Draft |
| 0110 | Ordinals Provenance Preservation ("Stamp an Inscription") | Draft |
SIP-0110 (PRESERVE) lets Ordinals holders preserve their content on the UTXO set. The reserved number leaves 0012-0109 available for sequential assignment.
Full roadmap and gating criteria: bitcoinstamps.xyz/en/protocols/sips | Whitepaper details: docs/whitepaper/improvement-proposals.md
Start at docs/README.md, the documentation map for this repository.
The four documents most people need:
| Document | Answers |
|---|---|
docs/CONSENSUS.md |
What exactly makes a transaction a stamp: activation heights, carrier encoding byte by byte, carrier precedence, SRC-20 and SRC-101 validation, the block hash model, reorg and rollback. Read this before writing a second implementation. |
docs/ARCHITECTURE.md |
Components, data flow, and where each responsibility lives. |
docs/PROTOCOLS.md |
Message shapes and worked examples per protocol. |
docs/DATABASE.md |
The schema the indexer writes into. |
External links:
- π Full protocol documentation at bitcoinstamps.xyz, the core Bitcoin Stamps protocol site
- π Explore stamps, tokens, and transactions at stampchain.io
- π Developer API docs at stampchain.io/docs
- π Technical Whitepaper for protocol architecture and specifications
- πΊοΈ SIP Roadmap & Registry for protocol improvement proposals
- π¬ Join the community in the Bitcoin Stamps Telegram chat
The Bitcoin Stamps protocol is open source and community-driven. If you have ideas, improvements, or bug fixes, please submit a pull request or open an issue.
This repository follows a trunk model: branch off main and open PRs against main
(the single primary branch). Every PR is reviewed by two code owners. Releases are cut by
maintainers via the automated Cut Release workflow. See
CONTRIBUTING.md for the full workflow and
docs/dev/versioning.md for versioning and the release process.
Release images published to GitHub Container Registry (ghcr.io/bitcoinuniverseio/btc-stamps-indexer) are signed keyless with
Sigstore/cosign (GitHub Actions OIDC, no private keys) and
carry an SPDX SBOM attestation. Each
GitHub Release records the exact
ghcr.io/bitcoinuniverseio/btc-stamps-indexer@sha256:β¦ digest and the cosign verify command. To verify provenance
before running an image (substitute the release version and digest):
cosign verify \
--certificate-identity-regexp '^https://github.com/stampchain-io/btc_stamps/.github/workflows/docker-auto-publish.yml@refs/tags/X.Y.Z$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/bitcoinuniverseio/btc-stamps-indexer@sha256:<digest>Bitcoin Stamps is community-funded and currently maintained by Reinamora137. Donations directly support maintenance, development, and hosting costs for the stampchain.io infrastructure.
Bitcoin Stamps Dev Fund: bc1qe5sz3mt4a3e57n8e39pprval4qe0xdrkzew203
SRC-20 (KEVIN) tokens or BTC donations are greatly appreciated and serve as the primary funding source for this experimental project.
This project is experimental and provided without warranty. See LICENSE for full details.