BRC-20 token development (Bitcoin Ordinals)

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
BRC-20 token development (Bitcoin Ordinals)
Medium
~3-5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1215
  • 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
    1043
  • 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

BRC-20 Token Development (Bitcoin Ordinals)

BRC-20—experimental token standard on Bitcoin built atop Ordinals protocol. No smart contract, no virtual machine—just JSON data in witness part of Bitcoin transactions and off-chain indexers tracking all balances.

First thing to understand: BRC-20 is not ERC-20 on Bitcoin. Fundamentally different system, no on-chain logic execution. "Contract" of BRC-20 token—JSON object inscribed in satoshi via Ordinals inscription.

How Ordinals Works

Satoshi Nakamoto gave each satoshi unique ordinal number (ordinal number) according to mining order. Ordinals protocol (Casey Rodarmor, 2023) uses these numbers to attach arbitrary data to specific satoshis via inscriptions—data recorded in witness field of SegWit transaction.

Inscription size not strictly limited, but Bitcoin nodes accept witness data up to 4MB (block limit in SegWit). Inscription cost depends on fee rate (sat/vbyte) and data size. Average cost at normal network load: $5–50 per inscription.

JSON Format for BRC-20

BRC-20 uses three operation types, each—separate Ordinals inscription:

Deploy—create token:

{
  "p": "brc-20",
  "op": "deploy",
  "tick": "MYtk",
  "max": "21000000",
  "lim": "1000",
  "dec": "18"
}

tick—4-character ticker (case-insensitive, stored as-is). max—maximum supply. lim—max per single mint transaction. dec—decimals (optional, default 18).

Mint—mint tokens (anyone can execute until max filled):

{
  "p": "brc-20",
  "op": "mint",
  "tick": "MYKT",
  "amt": "1000"
}

Transfer—transfer tokens (two-step process):

{
  "p": "brc-20",
  "op": "transfer",
  "tick": "MYKT",
  "amt": "500"
}

BRC-20 transfer—not one step. First create transfer inscription on sender address. Then this inscription transferred to recipient via standard Bitcoin transaction. Indexer records both steps and counts transfer only when exact UTXO containing transfer inscription is sent.

Working with Ordinals API and Indexers

For creating inscriptions—ord library (official client) or third-party APIs:

import axios from 'axios';

// Using Ordinalsbot API to create inscription
async function deployBRC20Token(config: {
    tick: string;
    max: string;
    lim: string;
    receiverAddress: string;
}) {
    const inscriptionData = JSON.stringify({
        p: "brc-20",
        op: "deploy",
        tick: config.tick,
        max: config.max,
        lim: config.lim,
    });

    const response = await axios.post('https://api.ordinalsbot.com/inscribe', {
        files: [{
            name: "deploy.json",
            size: Buffer.byteLength(inscriptionData),
            type: "text/plain;charset=utf-8",
            dataURL: `data:text/plain;charset=utf-8,${inscriptionData}`,
        }],
        receiveAddress: config.receiverAddress,
        fee: 15,  // sat/vbyte — check current fee
        lowPostage: false,
    });

    return response.data;  // contains payment address to send BTC to
}

Check balance via indexers. No official indexers—BRC-20 completely depends on third-party services:

// Hiro API — one of most reliable indexers
async function getBRC20Balance(address: string, ticker: string): Promise<string> {
    const response = await axios.get(
        `https://api.hiro.so/ordinals/v1/brc-20/balances/${address}`,
        {
            params: { ticker: ticker.toUpperCase() },
            headers: { 'x-api-key': process.env.HIRO_API_KEY },
        }
    );
    const token = response.data.results.find(
        (t: any) => t.ticker.toLowerCase() === ticker.toLowerCase()
    );
    return token?.overall_balance ?? "0";
}

// Check transferable (ready to transfer) balance
async function getTransferableBalance(address: string, ticker: string): Promise<string> {
    const response = await axios.get(
        `https://api.hiro.so/ordinals/v1/brc-20/balances/${address}`,
        { params: { ticker, balance_type: "transferable" } }
    );
    return response.data.results[0]?.transferable_balance ?? "0";
}

Quirks That Often Break Integrations

Two-step transfer. Developers used to ERC-20 expect transfer—one transaction. No. If UTXO with transfer inscription spent not to recipient but arbitrary address—indexer counts this "burn". Irreversible.

UTXO dependency. BRC-20 balance tied to Bitcoin UTXO containing inscriptions. If wallet not "aware" of inscriptions and accidentally spends UTXO with inscription as regular bitcoin (e.g., fee bumping)—tokens lost.

Different indexers—different results. Early BRC-20 different indexers interpreted edge cases differently. Situation stabilized now, but when developing verify results across multiple indexers (Hiro, UniSat, OKX Ordinals).

Ticker capture. First deploy with ticker "MYKT" becomes canonical. Second deploy with same ticker valid technically, but indexers ignore it—first gets priority. Before deploy always check ticker not taken.

async function isTickerAvailable(ticker: string): Promise<boolean> {
    const response = await axios.get(
        `https://api.hiro.so/ordinals/v1/brc-20/tokens/${ticker.toLowerCase()}`
    );
    return response.status === 404;  // 404 = ticker free
}

Mint Mechanics and Fair Launch

Standard BRC-20 presumes open mint: anyone can mint up to lim per transaction while max not reached. This fair launch—first miners get tokens for gas cost.

Projects wanting controlled distribution—BRC-20 doesn't fit natively. Options:

  • Set lim = max, then one address mints entire supply
  • Use ORC-20 or other experimental extensions with richer logic
  • Apply external whitelist and sell mint rights to addresses

Infrastructure for BRC-20 Project

Beyond token deployment itself, real project needs:

Indexer node. For reliable service—own or trusted provider. Running full Bitcoin node + ord daemon: requires 600+ GB SSD, sync 3–7 days.

Inscription service. Service creating mint/transfer inscriptions on behalf of users (if part of your UX). UTXO management, fee estimation, retry on failed transactions.

Explorer. Most BRC-20 projects build own explorer—standard Bitcoin explorers don't show BRC-20.

BRC-20 Limitations

BRC-20 has no:

  • Programmable logic (no smart contracts)
  • Atomic swaps between other BRC-20 tokens (DEX on BRC-20—complex off-chain construct)
  • Instant confirmation (Bitcoin blocks ~10 minutes)
  • Cheap transactions at load (at BRC-20 activity peaks fee reached $30–100 per transfer)

For projects needing programmability—Stacks (Clarity smart contracts with Bitcoin finality) or Bitcoin L2 (Merlin, BEVM).

Timeline: BRC-20 deploy itself—few hours. Full infrastructure (indexer, mint service, explorer, wallet)—4–8 weeks.