协议演进 / BIP/比特币改进提案 / BIP-70

BIP-70 支付协议

定义商户与顾客之间的支付协议:商户发出经 X.509 证书签名的 PaymentRequest 给出收款输出与金额,顾客回送 Payment,商户以 PaymentACK 确认收到。本 BIP 目前处于已部署状态。

一、档案卡

档案卡
编号BIP-70
标题Payment Protocol
作者Gavin Andresen <[email protected]>, Mike Hearn <[email protected]>
指定日期2013-07-29
层级Applications(应用)
类型Specification(规范类)
状态Deployed(已部署)
阅读版https://bips.dev/70
官方原文https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki

二、放在哪一族

BIP-70 是支付协议族的主文档,另有两份配套件与它同日指定:

BIP-71:为这三种协议消息定义 MIME 媒体类型,规定消息经 HTTP 或邮件传递时如何标注封装

BIP-72:给 BIP-21 的 bitcoin: URI 增加 r 参数,让用户点一个链接就能启动本协议

三份合起来是一条完整的商户收款链路:链接负责把顾客带进来(72),MIME 类型负责消息在网线上的身份(71),消息本身的含义与流程由本篇定义(70)。

三、它要解决什么

原文先描摹了当时最简的比特币支付流程:顾客把商品放进购物车、决定用比特币付款;商户生成一个唯一收款地址并与订单关联;顾客从网页上复制地址粘进钱包,或点击 bitcoin: 链接让钱包带金额打开;顾客授权付款并经 P2P 网络广播;商户服务器侦测到付款、等足确认数后视为完成。

BIP-70 要在这个流程上扩展五项能力:

四、规则本身

协议消息用 Google 的 Protocol Buffers 编码,用 X.509 证书认证,经 http / https 传输。原文说明,将来可以有别的 BIP 把它扩展到其他编码、PKI 体系或传输协议。

整场会话只有三条消息:商户发 PaymentRequest,顾客回 Payment,商户回 PaymentACK。

4.1 PaymentRequest:商户开的“账单”

具体内容放在 PaymentDetails 里,外面再套一层 PaymentRequest 装商户身份与签名。PaymentDetails 的主要字段:

外层 PaymentRequest 则含版本号、pki_type(实现须支持 none、x509+sha256、x509+sha1)、pki_data(X.509 时为证书链)、序列化后的 PaymentDetails,以及对整条消息所作的数字签名。

钱包收到 PaymentRequest 后必须依次:按 PKI 验证商户身份与签名(pki_type 非 none 时);确认本机时间未过 expires,过期必须拒绝;向顾客展示商户身份(例如第一张 X.509 证书的 Common Name)并请其确认是否付款。大于 50,000 字节的 PaymentRequest 应被钱包拒绝,以防拒绝服务攻击。

4.2 Payment:顾客的回执与付款

顾客授权付款后,客户端构造并签名一笔或多笔付清 outputs 的交易,再次确认未过期,随后把交易广播到比特币 P2P 网络;若指定了 payment_url,再向该地址 POST 一条 Payment 消息,其中含:

发 Payment 消息时须按 BIP-71 设置 Content-Type: application/bitcoin-payment 与 Accept: application/bitcoin-paymentack。payment_url 必须能防中间人篡改 refund_to(用 HTTP 时须有 TLS 保护)。商户服务器收到 Payment 后,须判定交易是否满足付款条件,当且仅当满足时才把交易广播到 P2P 网络;大于 50,000 字节的 Payment 应被服务器拒绝。若同一请求收到多条相同 Payment,服务器必须逐条确认——顾客端可能因传输失败而重发,确认不能丢。

4.3 PaymentACK:商户的确认

PaymentACK 是流程的最后一条消息,由商户服务器发给钱包,内容是触发它的 Payment 消息的副本,外加一条 memo,向顾客展示交易状态(原文示例:“Payment of 1 BTC for eleven tribbles accepted for processing.”)。大于 60,000 字节的 PaymentACK 应被钱包拒绝;上限比另两条消息大,是因为它内嵌了一整条 Payment。

4.4 证书与扩展

默认 PKI 是 X.509(与认证网站服务器同一套体系)。签名证书必须排在证书链第一位,其后依次为给前一张签名背书的证书,直到(但不含)受信任根;接收方须按 RFC 5280 验证整条链,任一验证失败即拒绝请求。根证书可取自操作系统;没有操作系统的设备推荐用 Mozilla 根证书库。

扩展机制靠 Protocol Buffers 本身:新增可选字段会被旧实现忽略(但会保留并转发);新字段不改变 PaymentDetails 仍为版本 1 的事实。若将来需要“只有新实现能接受”的请求,则定义版本 2 的新 PaymentDetails,旧实现收到时应提示用户升级。需要扩展消息的实现须使用 1000 起始的字段编号,并更新扩展页面以免冲突。

五、谁必须动

普通持币人(顾客):变化在体验层:付款前看到的是经证书认证的商户名而非裸地址;付款后能即时收到商户确认;退款地址由钱包自动提供,无需事后联系商户。

钱包开发者:需实现三条消息的收发:验证证书链与签名、核对过期时间、按 outputs 构造交易、POST Payment 并处理 PaymentACK;同时执行各消息的大小上限。

商户与支付服务器:需生成签名的 PaymentRequest、维护 payment_url、校验回送的 Payment 并广播合格交易、逐条回 PaymentACK。支持多语言的商户应按语言生成对应的 PaymentRequest 与 PaymentACK。

全节点与矿工、共识层:完全不必动。链上最终落地的仍是普通比特币交易,本协议只规范商户与钱包在链下如何商量这笔交易。

六、现在算不算数,以及一个常见误读

状态为 Deployed(已部署)。它是商户收款体验的一层链下协议:认证、账单、回执都在链下完成,结算仍靠链上交易本身。读它要分清两层——协议规定的是消息与流程,不改变任何一笔链上交易的有效性判定。

常见误读:

“用了 BIP-70,收款地址就变成商户域名了,链上记的是域名。”

不对。域名只是经证书认证后展示给顾客看的身份;真正决定钱付到哪里的,仍是 PaymentDetails 里逐条列出的 outputs——金额(聪)与收款脚本。链上交易与此前一样,只认脚本与签名,不认域名。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。