165 / 736BOLT12

BOLT 12

Один QR, новый счёт для каждого платежа

Зачем продавцу создавать ещё один Lightning-счёт для следующего клиента? BOLT 12 добавляет многоразовое предложение: по одному опубликованному коду каждый запрашивает свой счёт. Но более удобное начало ещё не означает оплату.

BOLT 12 — протокол согласования платежа в Lightning Network. Он различает предложение offer, запрос invoice_request и итоговый счёт invoice. Предложение может оставаться опубликованным для многих платежей, а каждый счёт задаёт условия конкретной оплаты.

Представьте кафе, которое хочет оставить на стойке один код для добровольных взносов. Многократная оплата одного обычного счёта BOLT 11 создавала бы проблемы. Вместо него BOLT 12 публикует offer. Кошелёк клиента отправляет invoice_request, запрашивая собственный счёт, а получатель отвечает новой invoice. Только затем её можно оплатить. Один напечатанный QR служит разным людям без использования общего счёта. Получить счёт, например через fetchinvoice, ещё не значит отправить деньги. Предложение также не даёт кафе права списывать последующие платежи из чужого кошелька. [1] [3] [4]

Предложение может указывать цену в биткоине или другой валюте. Поле offer_currency использует коды ISO 4217; например, сумма в USD выражена в центах. При выставлении счёта могут учитываться количество товаров и пересчёт валюты. Итоговая биткоиновая invoice_amount, однако, указана в millisatoshi, то есть тысячных долях satoshi: 1000 msat = 1 sat. До оплаты плательщик должен знать эту сумму и комиссию, а не только исходный ценник. Если запрос задаёт точную invreq_amount, счёт обязан совпадать с ней. Иначе кошелёк проверяет разрешённый диапазон и должен запросить новое согласие за его пределами. Пересчёт не должен становиться невидимым согласием на любую цену. [1] [3]

Напечатанный код может остаться на стойке, но само предложение может истечь в offer_absolute_expiry. У каждого счёта дополнительно есть время создания invoice_created_at и срок invoice_relative_expiry. Без указанного срока действует стандартное значение 7200 секунд, то есть два часа. Старый счёт поэтому не равен постоянно действующему контакту. Кошельки также должны понимать обязательные возможности в сообщениях. Неизвестный чётный бит означает необходимую функцию и ведёт к отказу; неизвестный нечётный необязателен и может игнорироваться. Это безопасная совместимость, а не помеха, которую пользователю следует обходить ручным переписыванием кода. [1]

После оплаты сохраните счёт и результат из кошелька. К доказательствам расчёта относится preimage — секретное значение, полученное при завершении платежа. Кошелёк вычисляет из него хеш, то есть контрольное значение, и сравнивает с платёжным хешем в счёте. Вместе со счётом это позволяет подтвердить оплату, но само по себе не определяет, какой человек платил. Если приложение отключилось или потеряло ответ, сначала проверьте состояние прежнего платежа: новый счёт может привести к ещё одной оплате. Так же внимательно относитесь к обещаниям регулярных платежей. Поддержка BOLT 12 не означает всех расширений или согласия на автоматические списания. Отдельно проверяйте приём платежей через предложения, оплату чужих предложений и права подключённого приложения. [1] [3]

Запрос счёта и перевод используют сеть для разных задач. offer_paths направляет сообщение с запросом, а invoice_paths задаёт маршруты платежа. BOLT 12 использует blinded paths — пути, скрывающие часть данных о соединении с получателем. Меньшее раскрытие структуры сети помогает приватности, но не обещает полной анонимности. Скрытый путь также не гарантирует доступного получателя или ликвидности, то есть достаточных средств на нужных сторонах каналов. Технически нынешняя invoice должна содержать эти пути и соответствующие параметры invoice_blindedpay, даже для прямого пути к получателю. Запрос счёта не требует обычного платёжного сервера HTTPS. [1] [2]

Когда продавец хочет вернуть клиенту деньги, направление согласования меняется. Будущий плательщик может опубликовать invoice_request без предшествующей offer. Клиент как получатель отвечает собственной invoice, которую продавец оплачивает. Это не стирает и не отзывает исходный платёж, а создаёт новый в обратную сторону. Продавец должен проверить, что счёт принадлежит нужному получателю, иногда договорившись вне протокола. Сканирование запроса само по себе не доказывает право на возврат и не одобряет перевод. Техническая процедура облегчает общение, но не решает, кому причитаются деньги. [1]

BOLT 12 хранит данные как TLV: каждое поле указывает тип, длину и значение. Текстовое предложение начинается с lno, запрос — с lnr. Набор символов похож на Bech32, но не содержит его завершающей контрольной суммы. Само по себе это не говорит, кому следует платить. Offer не подписана. Цифровые подписи BIP340 Schnorr удостоверяют счёт и обычный запрос в ответ на предложение. Самостоятельный запрос, опубликованный без предложения, например для возврата денег, не содержит подписи. Подпись связана с корнем структуры Merkle — общим контрольным значением, вычисленным из соответствующих полей. Так можно доказывать отдельные поля, не раскрывая каждый раз все подробности. Это не позволяет менять подписанные условия и не подтверждает личность продавца по документам. [1]

Кошелёк должен установить, что получил ответ на свой запрос, а не просто правильно подписанный чужой счёт. Он сравнивает перенесённые поля invoice_request с invoice, а также сеть, сумму и подпись. Публичный ключ invoice_node_id должен соответствовать offer_issuer_id; если предложение вместо него использует нужный скрытый путь без этого идентификатора, проверяется его конечный blinded_node_id. Это похоже на проверку, что счёт относится к вашему столику, а не только что печать настоящая. Структура Merkle позволяет выборочные доказательства, но не освобождает кошелёк от проверки всех необходимых условий. Чужой действительный счёт не становится правильным лишь потому, что подпись прошла проверку. [1]

Для полной картины прочитайте эту статью вместе с BOLT 11, Lightning Network, Lightning Routing, Приватность в Bitcoin, Satoshi, LNURL. На эту статью также ссылаются BOLT 11, LNURL, Just-in-Time Channels.

DOC · 001BOLT 12 — Negotiation protocolСпецификация DOC · 002BOLT 4 — Route blindingСпецификация DOC · 003Core Lightning — Fetching an invoiceДокументация DOC · 004BOLT 12 — Project overviewПервичный источник
Обновлено: Сначала источники · Не является инвестиционной рекомендацией