Адрес Bitcoin и условия расходования средств
Читатель должен получить адрес библиотеки, чтобы оплатить курс 17. Для него это строка и, возможно, QR-код. Для кошелька адрес представляет способ сформировать условие будущего выхода. В уроке отделим адрес от счёта и ключа, а затем определим правила проверки, которые сохраняют назначение платежа.
Начальные понятия — байты, открытый ключ и подпись — уже заданы. Сейчас мы не генерируем настоящие адреса и не отправляем средства. Обозначение LIBRARY_REGTEST_ADDRESS далее является меткой для адреса, полученного вашим локальным кошельком, а не допустимым адресом для перевода.
Из строки в выход
Кошелёк отправителя разбирает адрес и строит соответствующий scriptPubKey. Именно этот скрипт вместе с суммой записывается в выход транзакции. В дальнейшем расходование должно удовлетворить его условиям. Само приложение может хранить исходную строку для интерфейса, но наблюдение платежа должно понимать, какое условие ей соответствует.
В Bitcoin есть несколько семейств адресов. Исторические формы используют Base58Check; формы SegWit — Bech32 или Bech32m в зависимости от версии witness-программы. Версия и содержимое кодируют тип назначения. Из одной лишь длины строки нельзя вывести все правила проверки. Нужен разбор формата, контрольной суммы и сети.
Для библиотеки удобно получать адреса через собственный кошелёк с явно выбранным типом. Например, в закреплённом справочнике Bitcoin Core можно посмотреть описание getnewaddress. Параметр типа адреса позволяет задать ожидаемый формат, а кошелёк сохраняет соответствующие данные наблюдения. Учебный интерфейс не конструирует адрес путём добавления префикса к произвольному хешу.
Сеть имеет значение
Формат помогает заметить часть ошибочных назначений. У SegWit-адресов основной сети привычен префикс bc1, для regtest используется bcrt1; тестовые сети имеют свои соглашения. Однако некоторые сети могут разделять семейство адресного кодирования. Поэтому проверка префикса — полезный фильтр, но не универсальное доказательство выбора правильной цепочки.
Пример договора счёта:
{
"invoiceId": "library-17-001",
"network": "regtest",
"address": "LIBRARY_REGTEST_ADDRESS",
"amountSats": "30000",
"addressType": "bech32"
}
В записи явно указана сеть, а сумма сохранена целым значением в строке. Поле addressType описывает выбранную конфигурацию получения; оно не заменяет декодирование адреса. Для EVM и Bitcoin адреса также нельзя смешивать в одном поле без указания платёжной системы: это разные пространства назначений и разные правила.
Если пользователь показывает адрес основной сети на странице локальной лаборатории, остановим создание платёжной ссылки. Не будем автоматически «исправлять» строку заменой префикса. Контрольная сумма и смысл программы должны быть сформированы согласованно. Надёжный путь — запросить новый адрес у правильного кошелька в правильном окружении.
Адрес не содержит номер заказа
Допустим, два читателя получили один и тот же адрес и оба отправили по 30 000 сатоши. Узел видит два корректных выхода, но не знает, какой из них относится к какому заказу. Если сервер ожидает уникальную связь «адрес — счёт», повторное использование разрушит это предположение.
В нашей модели каждый новый счёт получает отдельный адрес из ветви получения библиотеки. Это не обязательно новый независимый приватный ключ, созданный отдельным случайным экспериментом: дескрипторный кошелёк может выводить последовательность адресов по заданному правилу. Важно, чтобы приложение сохраняло факт выдачи адреса до того, как покажет его читателю.
Адрес может получить перевод после истечения срока счёта. Истечение предложения — прикладное событие, оно не уничтожает сетевое условие и не запрещает отправителю создать выход. Поэтому старую связь нельзя удалять так, будто адрес никогда не существовал. Позднее платёжный курс введёт отдельное состояние поздней оплаты.
Контрольная сумма и человеческая проверка
Адресные контрольные суммы помогают обнаружить ошибки записи. Они не защищают от подмены адреса на другой корректный адрес. Вредоносный скрипт может заменить назначение и сформировать полностью допустимую строку. Такая замена не даст ошибки декодирования.
Для нашей страницы оплаты важны сохранённая серверная запись, защищённый транспорт и понятное отображение назначения. Покажем адрес текстом рядом с QR, чтобы читатель мог сравнить полученные данные. QR-код является способом кодирования строки, а не дополнительным доказательством правильности. Если текст и QR берутся из разных источников, они могут противоречить друг другу.
| Проверка | Какую ошибку обнаруживает |
|---|---|
| Разбор адреса | Неподдерживаемый или повреждённый формат |
| Ожидаемая сеть | Часть ошибок выбора окружения |
| Серверная связь со счётом | Подмену назначения в приложении |
| Сравнение QR и текста | Несогласованные способы отображения |
При проверке внешнего адреса возврата библиотека также не может узнать из строки, принадлежит ли он заявителю. Для этого нужен отдельный процесс подтверждения назначения. Отправлять возврат на первый адрес, обнаруженный во входах оплаты, неправильно: входы могут принадлежать промежуточному сервису или быть совместно сформированы несколькими участниками.
Скрипт как устойчивое назначение
Внутреннее наблюдение удобно связывать с декодированным условием выхода. Разные представления или типы строк требуют осторожности, тогда как scriptPubKey непосредственно сравнивается с выходом. Однако хранение скрипта не отменяет хранение исходного адреса: он нужен для интерфейса, аудита выдачи и объяснения пользователю.
В досье счёта сохраняем сеть, адрес, соответствующий скрипт, идентификатор кошелька и время выдачи. Секреты в эту запись не входят. Для поиска поступлений используем точное условие, для коммерческого решения — связь со счётом, для отображения — безопасно сформированный текст. Такое разделение позволяет позднее заменить формат адресов без изменения смысла заказа.
Изменение формата без изменения счёта
Если библиотека решила получать новые платежи на Taproot-адреса, уже выданные SegWit-счета сохраняют прежние назначения. Пользователь может иметь старую платёжную ссылку, поэтому её нельзя молча направить на другой адрес через изменение глобальной настройки. В записи счёта хранится конкретное назначение, а не выражение «текущий адрес библиотеки». Новый профиль применяется к новым счетам. Это сохраняет объяснимую связь позднего перевода с прежним предложением.
Официальные правила современных адресов приведены в BIP 173 и BIP 350; создание адреса кошельком — в getnewaddress. Полученный учебный результат — проверяемое назначение, которое можно однозначно связать с выходом. Следующим шагом построим журнал таких выходов.