Bitcoin-платежи: изолированная лаборатория regtest
В этом курсе построим учебную модель оплаты материалов библиотеки. Читатель заказывает курс 17 за 30 000 сатоши, приложение наблюдает поступление и выдаёт право доступа по выбранной политике. Затем к той же модели добавим Lightning. Это отдельный учебный проект, а не подключённая оплата действующего ProfessorWeb.
Начнём с границ лаборатории: собственный каталог данных, сеть regtest, локальный RPC и роли приложения. Команды ниже предназначены для будущей самостоятельной подготовки. Мы не запускаем Bitcoin Core, не создаём кошельки и не переводим средства; фактических адресов и результатов сети пока нет.
Почему выбираем regtest
Regtest позволяет создавать отдельную локальную историю Bitcoin и управлять появлением блоков в учебной среде. Её единицы не являются настоящими средствами mainnet. Такая модель удобна для изучения подтверждений, поздних переводов и восстановления наблюдения без зависимости от публичной сети.
При этом regtest не делает программу автоматически изолированной. Неправильный datadir, подключённые узлы или открытый RPC всё ещё могут смешать окружения. Поэтому сеть, каталог, адрес интерфейса и роли задаются явно. Слово «локально» без конкретной конфигурации не является достаточным описанием проекта.
Используем справочник Bitcoin Core 31.0 как закреплённый учебный профиль. Это не утверждение о последней доступной версии и не свидетельство установленного бинарного инструмента. Читатель перед своим запуском должен сверить фактическую версию и особенности собственной операционной системы.
Выделяем каталог данных
Будущий проект имеет отдельную папку payment-lab. Внутри находятся данные узла, исходники серверной модели и паспорт лаборатории. Не направляем учебный узел на каталог существующего личного кошелька: предмет курса должен иметь собственное известное начало.
payment-lab/
bitcoin/
bitcoin.conf
backend/
web/
README.md
В оболочке Linux или macOS можно подготовить путь следующими строками. Переменная относится только к проекту и не подменяет домашний каталог пользователя. Эти строки сейчас не выполняются.
PAYMENT_LAB="$PWD/payment-lab/bitcoin"
mkdir -p "$PAYMENT_LAB"
Путь зависит от текущей рабочей папки. В паспорте сохраняем окончательное расположение, чтобы последующие вызовы bitcoin-cli обращались к тому же узлу. Одинаковое имя папки в другой директории не обозначает ту же историю.
Задаём конфигурацию перед запуском
В будущем файле bitcoin/bitcoin.conf используем следующий профиль. networkactive=0 отключает P2P-активность узла; этот параметр присутствует в официальном исходнике Core 31.0. Он не выключает RPC, который нужен локальному серверному адаптеру.
regtest=1
server=1
networkactive=0
[regtest]
rpcport=18443
RPC по умолчанию предназначен для локального доступа с аутентификацией. Мы не добавляем публичный bind или разрешение всему интернету. Основной механизм локальной аутентификации Core — cookie, создаваемая узлом; её фактическое значение не включается в статьи или браузерный код.
Если порт уже занят другим процессом, читатель должен выбрать и записать другой, согласованно изменив будущий адаптер. Нельзя молча подключаться к первому ответившему сервису и считать его нашей лабораторией. Важна принадлежность endpoint нужному окружению, а не только наличие HTTP-ответа.
Отделяем будущий запуск от проверки паспорта
После сохранения конфигурации возможный запуск на Linux/macOS имеет такую форму. На других платформах способ запуска процесса отличается. Наличие команды в тексте не означает, что соответствующий узел уже работает.
bitcoind -regtest -datadir="$PAYMENT_LAB" -conf="$PAYMENT_LAB/bitcoin.conf" -daemon
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" getblockchaininfo
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" getnetworkinfo
В первом ответе ожидаем поле chain со значением regtest. Во втором проверяем фактическую версию и состояние сетевой активности. Не приводим придуманный полный JSON с высотой, хешем и временем: эти значения появятся только после реального собственного запуска.
Наличие правильного chain ещё не гарантирует правильный кошелёк. Узел может загрузить несколько кошельков, поэтому последующие wallet-методы будут явно выбирать роль. В следующем уроке создадим отдельные library и reader и не будем полагаться на случайный единственный загруженный объект.
Распределяем роли приложения
Узел проверяет историю и предоставляет RPC доверенному клиенту. Сервер библиотеки создаёт счёт, назначает адрес получения и принимает решения о праве доступа. Браузер показывает назначение, сумму и состояние заказа. Он не получает cookie узла и не выбирает произвольный RPC-метод.
| Участник | Ответственность | Чего он не доказывает |
|---|---|---|
| Bitcoin Core | Наблюдаемое состояние своей цепочки | Законность выдачи конкретного курса |
| Сервер библиотеки | Связь заказа и поступлений | Неизменность будущей публичной сети |
| Браузер | Понятная форма оплаты | Факт платежа по нажатию кнопки |
| Читатель | Подготовка своей учебной оплаты | Полномочие изменить цену заказа |
Если пользователь нажал «Я оплатил», сервер получает лишь сообщение о намерении. Поступление должно подтверждаться своим источником наблюдения. Это различие будет сохраняться во всех следующих уроках, включая Lightning-уведомления и повторную обработку.
Меняем окружение и замечаем расхождение
Представим, что один вызов забывает -regtest или использует другой datadir. Он может обратиться к иному окружению либо завершиться ошибкой подключения. Такой результат не следует объяснять дефектом модели счета: сначала сравниваем паспорт узла и параметры клиента.
Другая вариация — включённая P2P-активность при ожидаемой изоляции. Это изменение конфигурации, которое нужно заметить до учебных экспериментов с историей. Наш профиль делает намерение явным, но фактический запуск всё равно требует чтения полученных параметров.
В README пока записываем ожидаемые значения и статус not_run: Core 31.0, regtest, выбранный datadir, RPC 18443, отключённая P2P-активность. После самостоятельного запуска рядом появляются фактические ответы. Такая запись позволит отличить подготовленную модель от подтверждённого окружения.
Что означает недоступность источника
Если будущая команда чтения не ответила, это не свидетельство нулевого баланса или отсутствия кошелька. Сначала устанавливают, какой datadir, сеть и endpoint использованы. Лаборатория не должна переключаться на другой доступный узел автоматически: успешный ответ чужого окружения нарушит исходную границу примера.
В следующем уроке подготовим роли кошельков и учебные средства. Общие границы RPC описаны в официальной документации Core 31.0, параметр сети — в исходнике конфигурации. Оглавление курса.