支付协议被视为已弃用,将在更高版本的比特币核心中删除。该协议在一些钱包中存在多个安全设计缺陷和实现缺陷。当使用BIP70 URI时,用户将开始在比特币核心版本0.18中接收弃用警告。商家应该从BIP70过渡到更安全的选项,如BIP21。商家不应该要求BIP70付款,并且应该提供BIP21后备。
比特币核心0.9支持新的支付协议。付款协议为付款请求添加了许多重要功能:
- 支持X.509证书和SSL加密,以验证接收者的身份并帮助防止中间人攻击。
- 提供有关所需支付给消费者的更多详细信息。
- 允许消费者直接向接收者提交交易而无需通过对等网络。这可以加快支付处理速度并使用计划的功能,例如child-pays-for-parent交易费和离线NFC或基于蓝牙的支付。
不再被要求支付给无意义的地址,例如mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
,而是要求消费者从接收者的X.509证书中支付公共名称(CN)描述,例如www.bitcoin.org
。
要使用支付协议请求付款,你使用扩展(但向后兼容)bitcoin:
URI。例如:
bitcoin:mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
?amount=0.10
&label=Example Merchant
&message=Order of flowers & chocolates
&r=https://example.com/pay/mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
除了r
之外,上面提供的任何参数都不是支付协议所必需的,但是你的应用程序可能包含它们以便与尚未处理支付协议的钱包程序向后兼容。
r
参数告知支持协议的钱包程序忽略其他参数并从提供的URL中获取PaymentRequest。浏览器,QR代码阅读器或处理URI的其他程序在URI上打开消费者的比特币钱包程序。
支付协议在BIP70,BIP71和BIP72中有详细描述。可以在支付协议中使用的所有参数的示例CGI程序和描述在开发者示例支付协议子部分中提供。在本小节中,我们将简要介绍故事格式如何使用付款协议。
客户Charlie在商人Bob经营的网站上购物。Charlie在他的购物车中添加了一些商品,点击Checkout With Bitcoin
按钮。
Bob的服务器自动将以下信息添加到其采购数据库:
- Charlie订单的详细信息,包括订购的物品和送货地址。
- satoshis中的订单总数,通过将法定价格转换为satoshis中的价格并被创建。
- 该总数不再被接受的到期时间。
- Charlie应该向其发送付款的pubkey脚本。通常,这将是一个P2PKH或P2SH pubkey脚本,其中包含一个唯一的(从未使用过的)secp256k1公钥。
将所有信息添加到数据库后,Bob的服务器显示查询点击付费的bitcoin:
URI。
Charlie点击了他的浏览器中的bitcoin:
URI。他的浏览器的URI处理程序将URI发送到他的钱包程序。钱包知道支付协议,因此它解析r
参数并向该URL发送HTTP GET以查找PaymentRequest消息。
返回的PaymentRequest消息可能包括私人信息,例如Charlie的邮件地址,但钱包必须能够访问它而不使用先前的身份验证,例如HTTP cookie,因此通常使用具有猜测部分的可公开访问的HTTPS URL。为支付请求创建的唯一公钥可用于创建唯一标识符。这就是为什么在上面的示例URI中,PaymentRequest URL包含P2PKH地址:https://example.com/pay/mjSk1Ny9spzU2fouzYgLqGUD8U41iR35QN
收到HTTP GET到上面的URL后,Bob的网络服务器上的PaymentRequest生成CGI程序从URL中获取唯一标识符,并在数据库中查找相应的详细信息。然后,它会创建一个PaymentDetails消息,其中包含以下信息:
- satoshis中的订单数量和要支付的pubkey脚本。
- 一份包含订购物品清单的备忘录,因此Charlie知道他要付的是什么。它可能还包括Charlie的邮寄地址,因此他可以仔细检查它。
- PaymentDetails消息的创建时间加上它到期的时间。
- Charlie的钱包应该向其发送完成的交易的URL。
PaymentDetails消息放在PaymentRequest消息中。付款请求允许Bob的服务器使用服务器的X.509 SSL证书对整个请求进行签名。(付款协议的目的是在将来允许其他签名方法。)Bob的服务器在对HTTP GET的回复中向Charlie的钱包发送付款请求。
Charlie的钱包收到PaymentRequest消息,检查其签名,然后将显示PaymentDetails消息中的详细信息给Charlie。Charlie同意付款,因此钱包构建了对Bob提供的服务器提供的pubkey脚本的付款。与传统的比特币支付不同,Charlie的钱包不一定会自动将此付款广播到网络。相反,钱包构造一个Payment消息,并将其作为HTTP POST发送到PaymentDetails消息中提供的URL。除其他外,付款消息包含:
- 签约交易,Charlie付钱给Bob。
- Charlie可以发送给Bob的可选备忘录。(不保证Bob会读它。)
- 退款地址(pubkey脚本)如果Bob需要退回部分或全部Charlie的satoshis,可以支付。
Bob的服务器接收付款消息,验证交易将所请求的金额支付给所提供的地址,然后将该交易广播到网络。它还回复带有PaymentACK消息的HTTP POSTed Payment消息,其中包括来自Bob服务器的可选备忘录,感谢Charlie的赞助并提供有关订单的其他信息,例如预期到达日期。
Charlie的钱包看到了PaymentACK,并告诉Charlie付款已经发送。PaymentACK并不意味着Bob已经验证了Charlie的付款,请参阅下面的验证付款小节,但这确实意味着Charlie可以在交易得到确认时再做其他事情。Bob的服务器从区块链验证Charlie的交易已得到适当确认后,它授权运送Charlie的订单。
如果发生争议,Charlie可以从各种签名或其他证明的信息中生成经过加密验证的收据。
- 由Bob的网络服务器签名的PaymentDetails消息证明Charlie收到一张发票,用于为备忘录字段中指定的货物支付指定数量的satoshis的指定pubkey脚本。
- 比特币区块链可以证明Bob指定的pubkey脚本支付了指定数量的satoshis。