Bitcoin-платежи: кошельки библиотеки и читателя
В первом уроке отделили regtest от других окружений. Теперь подготовим две роли: библиотека принимает оплату, читатель её отправляет. Для них нужны разные учебные кошельки. Если пользоваться одним, полученный перевод легко спутать со сдачей или собственным перемещением средств, а демонстрация перестаёт объяснять реальную границу продавца и покупателя.
Команды ниже являются исходным материалом для будущего самостоятельного запуска. Bitcoin Core и кошельки сейчас не создаются. У нас нет действительных адресов, баланса или хешей блоков; вместо выдуманного вывода будем разбирать, какие свойства результата потребуется установить.
Создаём две независимые роли
Возьмём имена library и reader. Это фиксированные служебные имена внутри отдельного каталога лаборатории. Они не приходят из параметра HTTP-запроса и не совпадают с именами личных кошельков. В профиле Bitcoin Core 31.0 используем descriptor-кошельки. Будущая подготовка выглядит следующим образом:
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" -named createwallet wallet_name=library descriptors=true
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" -named createwallet wallet_name=reader descriptors=true
Ссылка на createwallet позволяет отдельно сверить параметры закреплённой версии. Ответ должен сообщить созданное имя и возможные предупреждения. Повторное выполнение не является способом «обнулить» существующий кошелёк. Если имя уже занято, сначала нужно разобраться с состоянием лаборатории, а не удалять неизвестные файлы.
Для упражнения обоим кошелькам нужны собственные ключи. Watch-only вариант полезен для наблюдения продавцом, но не позволит читателю подписывать перевод без внешнего подписанта. Здесь не подключаем аппаратное устройство и не экспортируем приватные ключи: эти задачи изменили бы границы урока.
Всегда выбираем конкретный кошелёк
Когда загружены два кошелька, команда уровня кошелька должна указывать свою роль. В консоли для этого используется -rpcwallet. На сервере соответствующая операция обращается к endpoint /wallet/library/ или /wallet/reader/, как описано в интерфейсе JSON-RPC.
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" -rpcwallet=reader getnewaddress "reader-mining" "bech32"
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" -rpcwallet=library getnewaddress "library-receive" "bech32"
Первый адрес предназначен для учебного получения средств читателем. Второй покажет, что библиотека тоже умеет выделять адреса получения. Этот второй адрес пока не является счётом курса: мы ещё не записали серверное назначение и срок оплаты. Подпись в кошельке помогает человеку, но не заменяет таблицу заказов.
Возвращённые строки следует сохранить вместе с названием сети и ролью. Их нельзя подставлять в mainnet-кошелёк или объявлять действительными адресами до собственного запуска. Для дальнейшего примера обозначим первый фактически полученный адрес переменной READER_MINING_ADDRESS. Её значение читатель заполнит своим результатом, а не строкой из статьи.
Получаем учебные средства
Regtest позволяет самостоятельно создать блоки. В будущей лаборатории можно направить награду на адрес читателя:
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" generatetoaddress 101 "$READER_MINING_ADDRESS"
bitcoin-cli -regtest -datadir="$PAYMENT_LAB" -rpcwallet=reader getbalances
Метод generatetoaddress присутствует в исходнике Core 31.0. В публичном оглавлении RPC он может не находиться среди обычных методов майнинга; это не повод заменить его случайной устаревшей командой. Параметры задают число блоков и получателя, а ответ содержит хеши созданных блоков.
Количество 101 выбрано из-за созревания coinbase. Только что созданная награда не сразу доступна для траты. Дополнительные блоки дают ранним выходам необходимую зрелость, однако последние награды всё ещё останутся незрелыми. Поэтому ожидаем наличие разных категорий баланса, а не обещаем, что весь объём наград стал свободным.
Не будем выводить фиктивную сумму или хеши. После будущего исполнения читатель должен установить, что сеть осталась regtest, ранние награды стали доступны, а свежие ещё относятся к незрелым. Эта проверка состояния описана для самостоятельной работы и сейчас не выполняется.
Что записываем в паспорт ролей
Сохраним имена кошельков, назначение адресов и выбранную сеть вместе с исходными командами. Эта небольшая запись позволит после перезапуска понять, какое действие относится к покупателю, а какое — к продавцу.
Что означает баланс в нашем примере
Баланс — агрегат кошелька, а перевод расходует конкретные выходы транзакций. Кошелёк может выбрать несколько UTXO, добавить сдачу и комиссию. Поэтому нельзя взять общий баланс и считать, что именно его целиком пересылают библиотеке. Следующий урок будет хранить денежные значения в целых сатоши, независимо от представления RPC в BTC.
Для объяснения арифметики во всей серии используем отдельный условный выход 80 000 сатоши. Из него мысленно выделяем 30 000 библиотеке, 49 300 сдачи читателю и 700 комиссии. Это учебное равенство, а не утверждение о размере coinbase или фактическом выборе Core. Создание 101 блока не означает, что кошелёк автоматически получил такой маленький выход.
Различие полезно и при чтении интерфейса. Сдача принадлежит читателю, комиссия оплачивает включение транзакции, а стоимость курса определяется продавцом. Все три суммы имеют разное назначение, хотя входят в одну арифметику расходования входа.
Меняем условие: загружен только продавец
Предположим, после перезапуска загрузился только library. Получение адреса продавца продолжает работать, но отправка от читателя должна быть недоступна до загрузки reader. Нельзя автоматически переключить отправителя на «любой доступный» кошелёк: так приложение начнёт тратить средства другой роли.
В паспорте лаборатории фиксируем отдельное ожидание для каждой роли: библиотека наблюдает поступления, читатель формирует оплату. Не переносим команды отправки в общий веб-адаптер. Позже сервис наблюдения вообще получит только ограниченный набор методов, достаточный для просмотра своего кошелька и цепочки.
Разбор результата
После будущей подготовки у нас будут два названных кошелька и источник учебных средств у читателя. Библиотека ещё ничего не продала, заказ не создан, доступ к материалу не выдан. Это правильное промежуточное состояние: инфраструктура существует отдельно от делового решения «оплачено».
Ошибка на этом этапе обычно проявляется как отсутствие явной роли, использование адреса другой сети или смешивание незрелой награды с доступным UTXO. Исправлять её нужно по паспорту окружения и документированным полям кошелька, а не добавлением случайных повторов команды.
В следующем уроке зададим точное представление сатоши на сервере и в браузере. Полный маршрут находится в оглавлении курса.