Разработка инфраструктуры для Bitcoin Ordinals
Клиент хотел запустить маркетплейс для Ordinals на Bitcoin mainnet, но столкнулся с проблемой: полная синхронизация Bitcoin Core занимала две недели, а ord индексер падал с ошибкой OOM при обработке блока 750 000. Выяснилось, что стандартная конфигурация не учитывала особенности witness данных — потребовалась оптимизация памяти и использование ZMQ для real-time обновлений. Мы переписали часть индексера на Rust, что сократило время синхронизации до 8 часов.
Этот кейс — типичный пример того, почему инфраструктура для Ordinals требует иного подхода, чем привычная EVM-разработка. В этой статье я разберу ключевые архитектурные решения и поделюсь реальными конфигами.
Как устроены Ordinals и Inscriptions технически
Ordinal theory (Wikipedia) присваивает каждому satoshi порядковый номер на основе порядка майнинга. Номер сатоши детерминирован — он вычисляется из номера блока и позиции в coinbase транзакции. Передача ordinals — это передача конкретного сатоши в транзакции с правильным порядком inputs/outputs.
Inscriptions — произвольные данные, записанные в witness поле транзакции через envelope паттерн:
OP_FALSE OP_IF OP_PUSH "ord" // маркер OP_PUSH 1 // tag: content-type OP_PUSH "image/png" // MIME тип OP_PUSH 0 // tag: content OP_PUSH <data_chunk1> // данные (до 520 байт на чанк) OP_PUSH <data_chunk2> // продолжение ... OP_ENDIF OP_FALSE OP_IF создаёт ветку, которая никогда не выполняется, но данные записываются в witness. После Taproot (BIP 341) witness данные дешевле обычных данных транзакции в ~4x. Именно это сделало Ordinals экономически целесообразными.
Commit-reveal схема: Inscription создаётся в две транзакции. Commit tx содержит P2TR output с commitment к скрипту с inscription. Reveal tx тратит этот output, раскрывая скрипт с данными. Это защищает от front-running.
Почему для Ordinals нужна иная инфраструктура, чем для EVM?
В EVM смарт-контракты имеют состояние, события и ABI. В Bitcoin ничего этого нет. Вся логика строится вокруг UTXO и witness данных. Индексеры должны самостоятельно интерпретировать содержимое witness, а не полагаться на стандартные RPC-методы. Для production требуется кастомная обработка edge-кейсов, таких как double-spend попытки в BRC-20. Мы обеспечиваем надёжную валидацию и синхронизацию данных через собственные индексеры.
Как поддержать high-load при росте коллекции?
Для маркетплейса с тысячами транзакций в день необходима производительная архитектура. Мы используем шардирование PostgreSQL по satoshi range, кеширование через Redis и асинхронную обработку через очередь RabbitMQ. Это позволяет обрабатывать до 1000 запросов в секунду без деградации.
Настройка node инфраструктуры
Bitcoin Core + ord индексер
Минимальный production стек: Bitcoin Core (полная нода, pruned не подходит) → ord индексер → PostgreSQL/RocksDB → API
Bitcoin Core требует архивный режим (unpruned) — Ordinals нужен доступ к witness данным всех исторических транзакций. Размер на момент написания: ~700GB и растёт. SSD обязателен.
# bitcoin.conf txindex=1 server=1 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 — референсная реализация индексера от Casey Rodarmor. Первичная синхронизация занимает 12–48 часов. В production сервер запускается за nginx с кешированием.
Серверные требования
| Компонент | CPU | RAM | Disk |
|---|---|---|---|
| Bitcoin Core (mainnet) | 4+ cores | 8GB | 700GB+ NVMe SSD |
| ord индексер | 8+ cores | 16GB | 100GB+ NVMe SSD |
| Итого | 12 cores | 24GB | 800GB+ |
Разработка кастомных индексеров
ord сервер покрывает базовые запросы, но для сложных продуктов (маркетплейс, аналитика коллекций, parent-child inscriptions) нужен кастомный индексер.
from bitcoinrpc.authproxy import AuthServiceProxy import json rpc = AuthServiceProxy("http://rpc:[email protected]:8332") def parse_inscription_from_tx(txid: str) -> dict | None: """Извлекает inscription из reveal транзакции""" 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: """Парсит ord envelope из witness script""" try: idx = script.index(b"\x00\x63") except ValueError: return None # Дальнейший парсинг ~100 строк pass Parent-child Inscriptions
С версии ord 0.6+ поддерживаются parent inscriptions — NFT коллекции с провенансом. Для их индексации мы используем связь через внешний ключ.
CREATE TABLE inscriptions ( id TEXT PRIMARY KEY, sat BIGINT NOT NULL, content_type TEXT, content_length INTEGER, block_height INTEGER NOT NULL, parent_id TEXT REFERENCES inscriptions(id), created_at TIMESTAMP NOT NULL ); BRC-20 и Runes
BRC-20
BRC-20 использует JSON-контент в inscriptions как операции. Балансы полностью определяются индексером. Для production необходима строгая следование спецификации l1brc20 indexer.
Runes
Runes — стандарт от автора Ordinals (апрель). Состояние хранится в UTXO, что снижает нагрузку на индексер. ord поддерживает Runes нативно с версии 0.17.
Кастодиальные операции через PSBT
Для маркетплейса требуется PSBT (Partially Signed Bitcoin Transactions). Продавец подписывает inscription UTXO, покупатель добавляет свои inputs. Мы реализуем полную цепочку листинга и обмена без централизованного хранения средств.
Пошаговый процесс настройки инфраструктуры
- Развёртывание Bitcoin Core в архивном режиме с включённым txindex и ZMQ.
- Установка ord индексера и первичная синхронизация (12–48 часов).
- Настройка PostgreSQL или RocksDB для хранения данных inscriptions.
- Разработка кастомного индексера для BRC-20/Runes (если требуется).
- Сборка API-слоя с кешированием и авторизацией.
- Интеграция PSBT-механизма для маркетплейса.
- Тестирование на testnet и нагрузочное тестирование.
- Мониторинг через ZMQ и алерты.
Мониторинг и алерты
ZMQ от Bitcoin Core обеспечивает real-time получение новых блоков. Это быстрее поллинга RPC. Мы автоматизируем алерты на аномалии в транзакциях.
Сроки и что входит
| Фаза | Содержание | Срок |
|---|---|---|
| Инфраструктура | Настройка Bitcoin Core + ord, server, мониторинг | 3–5 дней |
| Кастомный индексер | Парсинг inscriptions, BRC-20/Runes, PostgreSQL схема | 1–2 нед |
| API слой | REST API для фронтенда, кеширование | 1 нед |
| Маркетплейс механика | PSBT листинг/покупка, кастодиальные операции | 2–3 нед |
| Тестирование | Testnet (signet), edge cases, нагрузочное тестирование | 1 нед |
Полная инфраструктура для маркетплейса Ordinals: 5–8 недель. Просто индексер + API: 2–3 недели.
Стоимость таких проектов рассчитывается индивидуально, но typically экономия на транзакциях за счёт оптимизации witness данных может достигать 30%. Клиенты, внедрившие нашу архитектуру, сокращают расходы на инфраструктуру в среднем на 20–40% по сравнению с типовыми решениями.
Если вы планируете запуск маркетплейса Ordinals или интеграцию BRC-20/Runes, свяжитесь с нами — мы поможем спроектировать и развернуть production-ready инфраструктуру. Получите консультацию по вашему проекту — мы оценим архитектуру и подберём оптимальное решение.







