Разработка Runes-токена (Bitcoin)
До Runes была путаница: BRC-20 работал поверх Ordinals, создавал inscription для каждого transfer, засорял mempool "junk" транзакциями с малополезными данными. Casey Rodarmor, создатель Ordinals, разработал Runes как clean-room решение для fungible токенов на Bitcoin — без лишних данных, с использованием существующих биткоин-примитивов эффективно. Runes запустились в блоке 840,000 (halving 2024).
Как работает протокол Runes
Runes не требует никаких изменений в Bitcoin консенсусе. Протокол живёт в OP_RETURN outputs — данные в них не хранятся в UTXO set, блокчейн не засоряется (в отличие от BRC-20 который хранил состояние в satoshi).
Ключевые концепции:
Runestone — сообщение протокола, закодированное в OP_RETURN output транзакции. Содержит инструкции: etching (создание), mint, transfer, edict (перемещение балансов между outputs).
UTXO как носитель баланса — балансы Runes хранятся не в глобальном маппинге (как ERC-20), а в конкретных UTXO. Если вы держите 1000 RUNE, значит у вас есть UTXO с attached balance 1000 RUNE. Это фундаментальное отличие от EVM токенов.
Rune ID — {block_height}:{tx_index} транзакции etching. Например, первый Rune etchted в блоке 840,000 имеет ID 840000:3.
Spacers — визуальные разделители в имени (точки), UNCOMMON•GOODS — стандартный первый Rune от Casey.
Создание Rune (Etching)
Etching — это транзакция с Runestone в OP_RETURN, объявляющая новый Rune:
Параметры etching:
- divisibility: 0–38 (аналог decimals в ERC-20, но для сатоши-субъединиц)
- symbol: Unicode символ для отображения
- premine: количество токенов для etcher'а сразу
- terms: условия open mint (если разрешён)
- amount: сколько за одну mint транзакцию
- cap: максимальное количество mint'ов
- height: [start_block, end_block] для open mint
- offset: [start_offset, end_offset] относительно etching блока
- turbo: флаг совместимости с будущими версиями протокола
Структура данных Runestone кодируется через varint encoding (LEB128) — компактное представление чисел переменной длины. Каждый тег — пара (tag, value).
Практическая реализация через ord CLI
# Установка ord (официальный клиент)
cargo install ord
# Синхронизация с Bitcoin нодой (или через RPC к внешней)
ord --bitcoin-rpc-url http://user:pass@localhost:8332 index
# Создание wallet
ord wallet create
# Etching нового Rune
ord wallet etch \
--rune "MYTOKEN•NAME" \
--divisibility 8 \
--symbol "M" \
--supply 21000000 \
--premine 21000000 \
--fee-rate 20
# Mint (если включён open mint)
ord wallet mint \
--rune "MYTOKEN•NAME" \
--fee-rate 20
Через библиотеку (JavaScript/TypeScript)
Для интеграции в приложение используется runestone npm пакет или прямая работа с bitcoinjs-lib:
import { Runestone, Etching, Terms, RuneId } from "runestone-lib";
import * as bitcoin from "bitcoinjs-lib";
function buildEtchingTransaction(
utxo: UTXO,
runeName: string,
divisibility: number,
supply: bigint,
feeRate: number
): bitcoin.Transaction {
const runestone = new Runestone({
etching: new Etching({
rune: Rune.fromString(runeName),
divisibility,
symbol: "T",
premine: supply,
turbo: true,
}),
// Edicts определяют распределение premine по outputs
edicts: [{
id: new RuneId(0n, 0n), // 0:0 = самого себя при etching
amount: supply,
output: 1n, // output index для получения premine
}],
});
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.bitcoin });
// Input: funded UTXO для оплаты fee
psbt.addInput({
hash: utxo.txid,
index: utxo.vout,
witnessUtxo: { script: utxo.scriptPubKey, value: utxo.value },
});
// Output 0: OP_RETURN с Runestone
psbt.addOutput({
script: bitcoin.script.compile([
bitcoin.opcodes.OP_RETURN,
Buffer.from("52554e45", "hex"), // RUNE magic bytes
runestone.encipher(),
]),
value: 0,
});
// Output 1: получатель premine (должен быть не dust)
psbt.addOutput({
address: recipientAddress,
value: 546, // dust limit для P2WPKH
});
// Output 2: сдача
psbt.addOutput({ address: changeAddress, value: changeAmount });
return psbt;
}
Transfer логика: edicts
Передача Runes — транзакция с Runestone, содержащим edicts. Каждый edict задаёт: какой Rune, сколько, в какой output.
Важное правило протокола: если Rune balance входного UTXO не полностью покрыт edicts — остаток автоматически идёт в первый non-OP_RETURN output (это называется "pointer"). Нет явного указания = первый output. Это отличие от EVM, где "неуказанные" средства остаются у отправителя.
Пример: у вас UTXO с 1000 RUNE
Транзакция с edict: send 300 RUNE → output 2
Автоматически: 700 RUNE → output 1 (default pointer)
Если output 1 = burn address — вы нечаянно сожгли 700 RUNE.
Это основная причина потери токенов — непонимание pointer логики. При разработке кошелька для Runes нужно явно конфигурировать pointer output на change адрес пользователя.
Индексирование Runes балансов
Runes не имеют стандартного RPC API в Bitcoin Core — нужен отдельный индексер. Варианты:
ord indexer — официальный, написан на Rust. Требует полную Bitcoin ноду + SSD для индекса (~50–100GB). Предоставляет JSON API:
# Запуск с API сервером
ord --bitcoin-rpc-url http://localhost:8332 server --http-port 8080
# Баланс адреса
curl http://localhost:8080/runes/balance/bc1q...
# Информация о Rune
curl http://localhost:8080/rune/MYTOKEN•NAME
Hiro Ordinals API — hosted, платный, без необходимости поднимать собственную ноду. Подходит для MVP.
Unisat API — аналогично, REST API с поддержкой Runes. Rate limited на free tier.
Для production приложения с высокой нагрузкой — собственный ord индексер обязателен. Зависимость от внешнего API создаёт single point of failure.
Типичные кейсы
Governance токен Bitcoin-native приложения — проект хочет держать управляющий токен "native" на Bitcoin без кастодиальных рисков ERC-20 wrapped BTC. Runes подходит если governance механика простая (по сути snapshot voting off-chain, Rune как weight).
In-game currency / reward token — игра с Bitcoin-centric аудиторией хочет награждать пользователей токенами на Bitcoin. Runes с open mint механикой.
Мем-токены — наиболее распространённый use case в 2024 году. Простой etching, открытый mint, листинг на Magic Eden / UniSat.
Ограничения, которые нужно понимать
Runes — не смарт-контракты. Никаких conditional transfers, никакого staking, никаких DEX без отдельного решения. Вся логика, которую вы привыкли делать в Solidity, здесь невозможна on-chain. Возможны только: создание, transfer, burn.
Для DeFi логики поверх Runes нужен либо offchain matching (централизованный orderbook), либо отдельный L2/sidechain с проверкой Runes UTXO через Bitcoin SPV.
Срок разработки: etching и базовый кошелёк — 1–2 недели. Полноценная интеграция с индексером, marketplace функциональностью и custody solution — 6–10 недель.







