Bitcoin Ordinals infrastructure development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Bitcoin Ordinals infrastructure development
Complex
~1-2 weeks
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1217
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1046
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Development of Bitcoin Ordinals Infrastructure

Ordinals are not smart contracts. When developers come with EVM experience and expect a standard stack (ABI, events, RPC), the first two weeks are spent rethinking the fundamentals. Bitcoin doesn't emit events, it has no state, no address abstraction in the familiar sense. Ordinals work on top of witness data in SegWit transactions — this is fundamentally different infrastructure work.

How Ordinals and Inscriptions work technically

Ordinal theory assigns each satoshi a sequence number based on mining order. The satoshi number is deterministic — it is calculated from the block number and position in the coinbase transaction. Transferring ordinals — transferring a specific satoshi in a transaction with the correct input/output order.

Inscriptions — arbitrary data written to the witness field of a transaction via the envelope pattern:

OP_FALSE
OP_IF
  OP_PUSH "ord"          // marker
  OP_PUSH 1              // tag: content-type
  OP_PUSH "image/png"    // MIME type
  OP_PUSH 0              // tag: content
  OP_PUSH <data_chunk1>  // data (up to 520 bytes per chunk)
  OP_PUSH <data_chunk2>  // continuation
  ...
OP_ENDIF

OP_FALSE OP_IF creates a branch that never executes, but data is written to witness. After Taproot (BIP 341), witness data is ~4x cheaper than regular transaction data (discount factor). This made Ordinals economically viable.

Commit-reveal scheme: Inscription is created in two transactions:

  1. Commit tx — contains P2TR output with commitment to the script with inscription
  2. Reveal tx — spends this output, revealing the script with inscription data

This protects against front-running: before the reveal transaction, inscription content is unknown.

Node infrastructure setup

Bitcoin Core + ord indexer

Minimal production stack:

Bitcoin Core (full node, pruned NOT suitable) → ord indexer → PostgreSQL/RocksDB → API

Bitcoin Core requires archival mode (unpruned) — Ordinals need access to witness data of all historical transactions. Size as of early 2025: ~650GB and growing. SSD is mandatory, HDD is unacceptable for production.

# bitcoin.conf
txindex=1           # index all transactions by hash
server=1            # RPC
rpcuser=rpc
rpcpassword=strong_password
rpcallowip=127.0.0.1
zmqpubrawblock=tcp://127.0.0.1:28332
zmqpubrawtx=tcp://127.0.0.1:28333

ord — reference indexer implementation by Casey Rodarmor:

# Initial synchronization (takes 12-48 hours)
ord --bitcoin-data-dir /data/bitcoin \
    --data-dir /data/ord \
    index update

# Run server
ord --bitcoin-data-dir /data/bitcoin \
    --data-dir /data/ord \
    server --http-port 8080

ord provides REST API: /inscription/{id}, /sat/{sat_number}, /output/{outpoint}. For production — behind nginx with caching.

Server requirements

Component CPU RAM Disk
Bitcoin Core (mainnet) 4+ cores 8GB 700GB+ NVMe SSD
ord indexer 8+ cores 16GB 100GB+ NVMe SSD
Total 12 cores 24GB 800GB+

Initial Bitcoin Core synchronization — 1–3 days. ord index on top — another 12–48 hours. Block updates — real-time (seconds after confirmation).

Custom indexer development

ord server covers basic queries, but for complex products (marketplace, collection analytics, parent-child inscriptions) a custom indexer is needed.

Transaction parsing via Bitcoin RPC

from bitcoinrpc.authproxy import AuthServiceProxy
import json

rpc = AuthServiceProxy("http://rpc:[email protected]:8332")

def parse_inscription_from_tx(txid: str) -> dict | None:
    """Extracts inscription from reveal transaction"""
    raw = rpc.getrawtransaction(txid, True)

    for vin in raw.get("vin", []):
        witness = vin.get("txinwitness", [])
        for item in witness:
            script_bytes = bytes.fromhex(item)
            inscription = try_parse_inscription_script(script_bytes)
            if inscription:
                return inscription
    return None

def try_parse_inscription_script(script: bytes) -> dict | None:
    """Parses ord envelope from witness script"""
    # Look for marker: OP_FALSE(0x00) OP_IF(0x63) ... "ord" ...
    try:
        idx = script.index(b"\x00\x63")  # OP_FALSE OP_IF
    except ValueError:
        return None

    # Parse content-type and content
    # ... (full parser envelope ~100 lines)
    pass

Parent-child Inscriptions (recursive)

From ord 0.6+ parent inscriptions are supported — NFT collections with provenance. Child inscription references parent via pointer in envelope. For collection marketplace need to index these relationships:

CREATE TABLE inscriptions (
    id          TEXT PRIMARY KEY,          -- inscription id (txid + i)
    sat         BIGINT NOT NULL,           -- ordinal number
    content_type TEXT,
    content_length INTEGER,
    block_height INTEGER NOT NULL,
    parent_id   TEXT REFERENCES inscriptions(id),
    created_at  TIMESTAMP NOT NULL
);

CREATE INDEX ON inscriptions(parent_id);   -- for fast collection lookup
CREATE INDEX ON inscriptions(sat);

BRC-20 and Runes: tokens on top of Ordinals

BRC-20

BRC-20 uses JSON content in text/plain inscriptions as operations (deploy, mint, transfer). No smart contract — the indexer must interpret the sequence of operations itself:

// Deploy
{"p":"brc-20","op":"deploy","tick":"ordi","max":"21000000","lim":"1000"}

// Mint
{"p":"brc-20","op":"mint","tick":"ordi","amt":"1000"}

// Transfer (two-step: inscribe transfer → send)
{"p":"brc-20","op":"transfer","tick":"ordi","amt":"500"}

Critical point: balances are completely determined by the indexer. No on-chain state — balance is the result of applying all operations to the initial state. Different indexers can give different results in edge cases (double-spend attempts, invalid sequences). For production — strict adherence to l1brc20 indexer specification.

Runes (Casey Rodarmor, April 2024)

Runes — official token standard from the author of Ordinals. Unlike BRC-20, Runes store state in UTXO: each UTXO carries the balance of a specific Rune. This is closer to Bitcoin UTXO model, less burden on the indexer.

OP_RETURN OP_13 <encoded_runestone>

Runestone — CBOR-like structure in OP_RETURN output. Contains: Etching (deploy), Mint (minting), Edicts (transfers). ord indexer supports Runes natively from version 0.17.

Custodial operations: working with UTXO

For a marketplace or platform that manages user inscriptions, a PSBT (Partially Signed Bitcoin Transactions) scheme is needed:

# PSBT logic for inscription sale
# Buyer and seller sign their parts independently

# Seller signs: input (inscription UTXO) + output (price in BTC)
seller_psbt = create_psbt_seller(
    inscription_outpoint=outpoint,
    price_sats=price_sats,
    seller_payment_address=seller_addr
)

# Buyer adds: input (BTC) + output (inscription to them)
final_psbt = buyer_sign_and_complete(
    seller_psbt,
    buyer_address=buyer_addr,
    funding_utxos=buyer_utxos
)

# Broadcast
rpc.sendrawtransaction(final_psbt.extract_transaction().serialize().hex())

PSBT (BIP 174) — standard for multi-party transactions. For marketplace: seller lists inscription with PSBT-signature for sale, buyer adds their inputs and finalizes.

Sat-control during transfers: need to precisely control which satoshi (and its number) goes to which output. Input and output order determines this. The ord library contains sat-tracking logic, which can be reused.

Monitoring and alerts

ZMQ from Bitcoin Core — the right way to receive real-time notifications of new blocks and transactions:

import zmq, asyncio

async def watch_new_blocks():
    ctx = zmq.asyncio.Context()
    sock = ctx.socket(zmq.SUB)
    sock.connect("tcp://127.0.0.1:28332")
    sock.setsockopt_string(zmq.SUBSCRIBE, "rawblock")

    while True:
        topic, body, seq = await sock.recv_multipart()
        block_hash = body[:32].hex()
        await process_new_block(block_hash)

This is faster than RPC polling and doesn't overload the node with extra requests.

Timelines and scope

Phase Content Duration
Infrastructure Bitcoin Core + ord setup, server, monitoring 3–5 days
Custom indexer Inscription parsing, BRC-20/Runes, PostgreSQL schema 1–2 weeks
API layer REST API for frontend/partners, caching 1 week
Marketplace mechanics PSBT listing/purchase, custodial operations 2–3 weeks
Testing Testnet (signet), edge cases, load testing 1 week

Complete infrastructure for Ordinals marketplace: 5–8 weeks. Just indexer + API for existing product: 2–3 weeks.