术语表 /闪电网络与 Layer 2
BOLT12 offer
又称 offer。
- BOLT12 offer 是什么?
- BOLT12 offer 是一种以 lno1 开头、可重复使用的闪电网络支付码,任意数量的付款方都可以通过闪电网络本身向发行方请求,将其转换为各自全新的发票。
offer 是一种可以在付款后继续有效的收款请求,因此一个打印出来的二维码即可服务所有客户。offer 不含签名,也不含校验和,其字段占用 TLV 类型2至22,长度有意控制得足够短,以便低端手机的摄像头也能扫描。如果您是收款方,这就是只需打印一次的二维码与由其生成的发票之间的区别,后者会在7200秒后过期。
运作方式
BOLT12 offer 是一串类型-长度-值记录,以人类可读前缀 lno、分隔符1,再加上按顺序承载这些记录的 bech32 风格字符写成。
末尾没有六个字符的校验和。规范取消了它,理由是二维码自带校验和,而且损坏的 offer 只会得到一个无法解析的字符串,而不是一笔丢失的付款。较长的 offer 可以用加号断开,加号后可以跟空白字符,这样粘贴到有字符数限制的文本框时仍能保持完整,读取方在解码前必须去掉加号和空白字符。写入方必须全部使用小写或全部使用大写,用于二维码时应选择大写。
这些字段本身是有编号的。offer_chains 为2,offer_metadata 为4,offer_currency 为6,offer_amount 为8,offer_description 为10,offer_features 为12,offer_absolute_expiry 为14,offer_paths 为16,offer_issuer 为18,offer_quantity_max 为20,offer_issuer_id 为22。写入方必须保持在类型1至79之内,另有1000000000至1999999999的第二个范围留作实验之用。该列表中没有任何一项是签名,这是有意为之:签名会增加字符串长度而没有任何好处,因为每个非签名字段都会被复制到随后的请求中,所以被篡改的 offer 不会产生任何发票。
付款还需要再发送两条消息。您的钱包通过洋葱消息发送前缀为 lnr 的 invoice_request,复制 offer 的所有字段(包括它不理解的字段),并用对 Merkle 根的 BIP340 签名对结果签名。发行方回复一张已签名的发票。Merkle 结构将每个字段的叶子与一个 nonce 叶子配对,这使付款方日后可以只披露有争议发票中的某一个字段,而不暴露相邻字段,这是对整个字符串的 BOLT11 签名做不到的。
这三条消息中有两条在退款和取款机场景中方向相反。商户发布一个 invoice_request,注明它想发送的金额,您回复一张发票,商户在付款前确认 invoice_node_id。
购买比特币时为何重要
offer 改变的是您发布收款方式的方法,对收款成本没有任何改变。
以本站的 Phoenix 评测为例。ACINQ 公布了一份手续费表,而不是让您自己去发现:通过闪电网络发送的费用为0.4%加4聪,在已有入站流动性时接收免费,在钱包必须上链以腾出空间时接收的费用为1%加链上交易手续费,新建通道的费用为1,000聪。提供 offer 而不是发票,并不影响上述任何数字。它省去的是为每位付款方生成新二维码的步骤,而不是有人为流动性付费的步骤。
隐私方面的好处是真实的,但范围有限。闪电地址会把每次发票请求经由某个域名下的网络服务器转发,该运营方能看到金额和时间。offer 则以洋葱消息的形式经闪电网络转发请求,offer_paths 让通道全部为私有的节点无需公布节点 ID 也能保持可达。但这并不能让您对自己的服务商保密:本站的 Phoenix 评测引用了 ACINQ 的常见问题,其中明确说明它知道付款的最终目的地和金额。
实际使用中的提醒与粘贴有关。交易所的提币框要求填写闪电发票,而 lno1 字符串不是发票。Strike 是此处63家交易所记录之一,原生支持闪电网络,在超过100个国家的转账不收取自身的手续费,正是这类流程容易让人混淆两种格式。本站的41款钱包评测和63家交易所记录目前都没有把对 offer 的支持记录为一项功能,因此请在您自己钱包的发行说明中确认,不要想当然。
帽子摊的 offer 及其变成的发票
一个以25美元一顶出售帽子的摊位,写了一个 offer,offer_currency 设为 USD,offer_amount 设为2500。
这是规范对比特币以外的货币所定的规则:使用三个字母的 ISO 4217代码,金额以按 ISO 4217指数调整后的货币单位表示,对美元而言就是美分。只要设置了 offer_amount,offer_description 就是必填项,因为被收取具体费用的付款方必须知道这笔费用是什么。如果还剩三顶帽子,offer_quantity_max 为3,如果摊位没有固定上限,则为0。明确允许值为1,尽管看起来有些别扭,这样库存系统就不需要为最后一件商品设置特殊情况。offer_issuer 可以写成 hats@example.com Hat Stall,因为规范要求先写域名,空格之后可以是任何便于识别的文字。
您的钱包读取后,向您报价25美元,并发送 invoice_request,其中 invreq_quantity 为2(两顶帽子)、一个 invreq_payer_id,另可选择附带 invreq_payer_note。返回的是一张发票,包含支付哈希、创建时间戳、至少一条盲化路径,以及每条路径的费用报价,涵盖基础手续费、比例手续费、CLTV delta 以及其可承载的最小和最大 HTLC。这里有两条规则保护您。如果0至159范围内的任何字段与您所发送的不一致,您的钱包必须拒绝该发票;如果毫聪金额与 offer 给出的美元估值相差较大,钱包必须向您发出警告。除非发行方设置了 invoice_relative_expiry,否则发票必须在创建后7200秒被拒绝。
BOLT12 offer vs BOLT11 发票
BOLT12 offer 是对收款请求的请求;BOLT11 发票才是收款请求本身。
BOLT12 的文本开头列出了对其前身的八项不满,付款方能感受到的是以下几项。BOLT11 发票作为一个整体签名,因此要证明其中一个字段就必须披露全部字段。规范认为其人类可读的金额问题多多:p 乘数经常被误处理,而以皮比特币计数比以聪计数更困难。它的 payment_secret 只有在发票仅在付款方和收款方之间保持私密时才能阻止探测,而公开发布的发票并非如此。而且,用规范自己的话说,发票必须按用户分别提供,如果为同一用户发起两次付款尝试则有实际危险。offer 通过根本不是发票,解决了这四个问题。
BOLT12 offer vs 闪电地址
BOLT12 offer 是一个自包含的字符串;闪电地址是一个由他人的服务器为您解析的名称。
两者都可重复使用,因此容易混淆。闪电地址依赖域名、证书和一个让服务持续运行的运营方,三者中任何一个失效,它就失效。offer 只依赖双方节点支持洋葱消息,别无其他,故障面更小,不过您需要确认自己的钱包支持,而不是想当然。闪电地址的优势在于可以口头说出。很长的 lno1 字符串是二维码,而不是可以对着麦克风念出来的东西。