协议演进 / BIP/比特币改进提案 / BIP-321
BIP-321
更新 bitcoin: URI 方案:用统一的链接描述链上地址与闪电发票、静默支付等多种支付指令,让点击链接或扫码即可发起付款。本 BIP 目前处于已完成状态。
一、档案卡
| 编号 | BIP-321 |
|---|---|
| 标题 | URI Scheme |
| 作者 | Matt Corallo <[email protected]> |
| 指定日期 | 2024-11-15 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Complete(已完成) |
| 取代文档 | Replaces: BIP-21 |
| 阅读版 | https://bips.dev/321 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0321.mediawiki |
二、放在哪一族
支付链接与发票族。这一族的源头是 BIP-20 与 BIP-21 定义的 bitcoin: URI 方案:把收款地址、金额等信息编码成一条链接或一个二维码,用户点击或扫码即可付款。BIP-321 是 BIP-21 的修改版与指定接替者,档案上以 Replaces 标记取代 BIP-21。
同一族中还有几份近亲:
BIP-72:支付协议的 bitcoin: URI 扩展
BIP-351:Private Payments;其地址经本 BIP 的 pay 参数承载
BIP-352:Silent Payments(静默支付);其地址经本 BIP 的 sp 参数承载
理解 BIP-321 的关键,是看清它如何把“一条 URI 只能装一个链上地址”的老格式,升级为“一条 URI 可以同时装多种支付指令、付款方自选其一”的统一发票格式。
三、它要解决什么
3.1 让付款像点链接一样简单
原文动机的第一句就是 URI 方案的总目的:让用户只需点击网页上的链接或扫描二维码,就能轻松完成付款。bitcoin: URI 是操作系统、浏览器与钱包之间传递“付款指令”的通用语言。
3.2 老格式装不下现代支付方式
BIP-21 写于只有链上地址的年代。如今收款方常常同时希望提供闪电发票、静默支付地址等多种收款方式,新地址类型也不断出现。若每种方式都另造一套链接格式,钱包与商户系统就要反复适配;若把新地址硬塞进 URI 的地址位置,老钱包又会无法识别。
BIP-321 的修法是结构性的:地址部分保留给经典链上地址,新的支付指令一律放进查询参数。这样旧付款方至少还能走链上回退路径,新付款方则能挑更现代的方式。
3.3 付款发起方需要拿到付款凭证
原文还新增了一个老格式没有的环节:发起付款的应用(如在手机上唤起钱包的另一个应用)可能需要知道付款已完成的结果。链上付款尚可自行监控区块链,但闪电等支付没有全局账本可查。为此本 BIP 定义了可选的付款证明(Proof of Payment)回传机制。
四、规则本身
4.1 通用格式与处理纪律
Bitcoin URI 遵循 RFC 3986 的通用 URI 格式:路径部分是比特币地址,查询部分提供附加支付选项;查询元素中超出有效范围的字符须先按 UTF-8 编码,再逐字节做百分号编码。
两条处理纪律原文置于规范之首:
- 比特币客户端不得在未取得用户授权的情况下按 URI 行事;原则上应要求用户逐笔手动批准付款,仅在某些情形下可以让用户预先做自动决定。
- 图形界面的比特币客户端默认应把自己注册为 “bitcoin:” URI 方案的处理程序(若已有处理程序则可提示用户是否更改)。
形式文法(ABNF)要点:方案名 “bitcoin:” 大小写不敏感,查询参数的键同样大小写不敏感(原文指出,用全大写 URI 的二维码已是常见做法,把握这一点才兼容);参数值与地址字段是否大小写敏感取决于其内容。同一键可出现多次的情形有明确区分:代表支付指令的参数可以重复,label、message、pop 不得重复,其他未知参数则必须允许重复。
4.2 地址部分放什么
URI 的 bitcoinaddress 主体必须是 base58 的 P2SH 或 P2PKH 地址、bech32 的 SegWit v0 地址、bech32m 的 SegWit 地址,或者干脆为空。原文强调:未来的地址格式应当改放查询参数作为可选支付指令,以保证升级周期的向后兼容;地址部分也可以留空——前提是查询参数中至少提供了一条支付指令,适合不想提供标准链上回退的收款方。
4.3 查询参数
通用键(适用于任何 URI):
- label:收款方标签(如收款人名称);
- message:向用户描述这笔交易的消息;
- pop:付款证明回传地址,见 4.5 节。
支付指令键(原文列出的现行定义):
- lightning:闪电网络 BOLT 11 发票;
- lno:闪电网络 BOLT 12 offer;
- pay:BIP-351 Private Payment 地址;
- sp:BIP-352 Silent Payment(静默支付)地址。
原文还给了一条命名约定:使用 bech32 或 bech32m 编码的新支付指令,应复用其地址格式的人类可读前缀(HRP)作为参数键。测试网的 SegWit 地址因此要放进 tb 参数而不是 bc 参数:一串 URI 可同时携带多个 bc 参数,分别给出不同 SegWit 版本的地址。
金额参数 amount 必须以十进制 BTC 表示:不得有逗号,小数点用 “.” 分隔。例如 amount=50.00 与 amount=50 都表示 50 BTC,而 amount=50,000.00 是无效的。
4.4 必填参数与前向兼容
带 req- 前缀的查询参数被视为必填:客户端若不理解某个 req- 参数,必须把整条 URI 视为无效;不带前缀的未知参数则可以安全忽略。原文举例:带 req-somethingyoudontunderstand 的 URI 对老客户端是无效的,而同样的未知键不带前缀时 URI 仍有效。地址类型今后一律经查询参数添加,老付款方只需支持经典指令,就能付给提供更现代格式的新收款方。
4.5 付款证明(pop)
URI 可带 pop(或 req-pop)参数,其值是一个经百分号编码的 URI 前缀。付款完成后,支持回传的钱包解码该前缀,拼上实际所用的支付指令键名、一个 “=” 与付款信息,再用系统默认处理程序打开拼成的 URI,把结果交回发起付款的应用。链上付款的付款信息是已广播交易的完整十六进制(含见证数据);经 lightning 参数完成的 BOLT 11 付款,付款信息是支付原像的十六进制编码;其他支付方式各自定义格式。
安全约束有三条:
- 钱包打开回传 URI 前,必须校验其方案不是 http、https、file、javascript、mailto 等会在浏览器中打开的方案——原文的理由部分说清了用意:回传只能切换到本机另一个应用,不得把付款人的 IP 等信息泄露给收款方;
- 若钱包不会打开该 pop 方案(不支持该支付方式的回传,或方案本就不应打开),而参数是以 req-pop 形式给出的,钱包不得发起付款;
- 反之普通的 pop 遇到不该打开的方案(如 https)时,钱包照常付款、只是不与该地址发生任何交互。
4.6 设计理由与兼容性说明
原文专门申明“支付标识符,而非个人标识符”:链上地址的最佳实践是每笔交易使用唯一地址,因此含链上地址的 URI 必须被当作一次性付款指令,而不是个人信息的交换;只有由可复用、且不复用地址的指令(如 BOLT 12 offer、静默支付)构成的 URI,才可以按钱包意愿复用。
与 BIP-21 相比,本 BIP 的变化包括:把承载支付指令的标准查询参数写成规范、查询参数改为大小写不敏感、允许 bech32/bech32m 地址进入地址字段、允许地址字段为空。原文指出:bech32/bech32m 地址用法与 lightning 参数在 2024 年的数年前已成常见做法;任何既有 BIP-21 实现原则上自动符合本 BIP,唯一可能的例外是查询参数大小写不敏感这一点。参考实现指向 rust-bitcoin 的 bitcoin-payment-instructions 库。
五、谁必须动
普通持币人:付款体验不变——点链接或扫码、在钱包里核对金额与收款方、批准。需要知道的是:一条链接现在可能同时给出链上与闪电等多种收款方式,由钱包代为选择;批准前核对的习惯不变。
钱包开发者:这是主要的行动方。要按新文法解析 URI(包括大小写不敏感、重复键规则与 req- 语义),支持查询参数中的多种支付指令与空地址 URI,未经用户授权不得自动付款;实现 pop 的,还须落实方案白名单式的安全校验与 req-pop 的拒绝付款规则。
商户与收款方:生成 URI 时应把链上地址只当一次性指令使用;想同时提供闪电、静默支付等方式时,按参数键规范拼装,并可借助 pop 让发起付款的应用拿到完成凭证。
全节点与矿工:无需改动。URI 是应用层约定,不进入共识与网络协议。
共识层:本 BIP 不修改共识规则。
六、现在算不算数,以及一个常见误读
状态为 Complete(已完成),且档案上正式取代 BIP-21。它的“完成”指规范文本已经完备、可供实现;在应用层标准里,实际效力取决于钱包与商户系统的采用程度——原文亦承认,其中若干做法(bech32 地址入 URI、lightning 参数)在成文之前已是通行实践,本 BIP 做的是把实践固定为标准,并为今后的支付指令留好扩展位。
常见误读:
“BIP-321 是一套全新的付款链接格式,老二维码全要作废。”
不对。原文明确:既有 BIP-21 实现原则上自动符合本 BIP,新格式是老格式的超集——经典地址链接照常可用,新增的只是查询参数里的现代支付指令与付款证明回传。作废之说与原文的向后兼容结论正相反。
七、延伸
- 阅读版:https://bips.dev/321
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0321.mediawiki
- 相关:BIP-21 URI Scheme(被本 BIP 取代)、BIP-352 Silent Payments、BIP-351 Private Payments
- 仓库总目录:https://github.com/bitcoin/bips
