比特币如何使用BIP70支付协议API

支付协议是用于指代BIP70,71,72和73中指定的协议的术语。支付协议旨在经过用可编码更复杂参数的小文件替换广泛存在的比特币地址来为比特币添加附加功能。它指定了直接在资金发送方和接收方之间流动的支付请求,付款和支付方式的格式。php

支付协议对于比特币的各类重要功能的开发相当重要,所以,了解它如何使用比特币很是重要。本文介绍了基本功能,并显示了将其集成到钱包应用程序中的一些示例代码。java

具体而言,该协议的第1版提供:数据库

  • 1.接收器/商家使用任意脚本请求多个输出的方式,而不只仅是单个付费密钥哈希类型的输出。多个独立交易能够知足付款,容许未来实施基于规避合并的隐私技术。
  • 2.自由文本备忘录字段,所以商家能够填写由钱包存储的购买细节,及用户在付款时附加消息。
  • 3.到期时间,过时的付款请求可能会被视为无效。这容许接收器在服务器端绑定其资源使用并放弃从未付费的请求。
  • 4.发行时间,付款请求知道什么时候发出——有利于记录保存。
  • 5.二进制cookie-esque字段,在提交支付交易时将简单地回显给服务器,容许商家实现无状态后端。
  • 6.用户指定的退款地址。
  • 7.使用X.509数字证书对上述全部内容进行签名的可选功能,从而将付款请求绑定到某种通过验证的身份。

支付请求自己能够进行数字签名这一事实能够实现一些很是重要和有用的功能。中间的一我的不能重写输出来劫持付款。这对于像Trezor这样的硬件钱包来讲尤为重要,由于Trezor会假设主机受到损害,不然用户没法知道他们受权的付款与商家要求的付款相同。后端

此外,数字签名的付款请求和在区块链上知足它的交易一块儿建立很是相似收据的付款证实。收据对于争议调解和证实购买是有用的,而商家没必要保留他们曾经拥有的每一个客户的详尽数据库——即便商家删除了有关你的数据,只需出示收据就足以证实你已进行购买。浏览器

协议缓冲区是一种能够轻松扩展的二进制数据序列化格式。所以,咱们能够很容易地想象未来可能添加的许多其余功能服务器

你能够阅读付款协议的常见问题解答,详细说明其设计背后的基本原理cookie

协议概述

在正常的比特币支付中,该过程从用户点击比特币URI或复制并将文本地址粘贴到他们的钱包应用程序并手动指定金额开始。session

在付款协议处理的付款中,该过程以两种方式之一启动:app

  • 用户单击具备新“r”参数的比特币URI,该参数包含解析为付款请求文件的(http)URL。
  • 用户直接打开付款请求文件。

而后,用户的钱包解析做为协议缓冲区的支付请求数据,并开始正常请求确认的过程。单击比特币URI时,将忽略URI其他部分中的指令(它们仅用于向后兼容),而且在给定URL处找到的数据优先。dom

支付请求由外部“skin”消息组成,该消息包含(可选的)签名和证书数据,以及包含所请求支付的详细信息的内部“core”消息的嵌入式序列化。外部PaymentRequest消息与所使用的数字签名基础结构的类型无关,但目前仅定义了X.509绑定。这与SSL中使用的系统相同。内部PaymentDetails消息以二进制形式存储,而不像普通的protobuf消息那样被嵌入,以确保签名字节始终匹配。

一旦钱包建立了使人满意的比特币交易集,就会格式化付款消息并将其上传到PaymentDetails指定的目标URL,一旦满意地接受付款,钱包就会收到PaymentACK消息。

签名和证书

签名付款请求的目的是在用户钱包应用中替换此类消息:

Pay 10mBTC to 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?

与这样的一个:

  • 支付10mBTC到satoshin@gmx.com?
  • 支付20mBTC到overstock.com?
  • 向迈克尔赫恩支付30亿比特币?
  • 向加利福尼亚州旧金山的Genius Widgets公司支付100 BTC

......固然,第一种形式是最无用的,由于在这种状况下,身份只是一个没有意义或稳定性的随机数。这致使了其余示例中的字符串来自何处的问题。

答案是它们包含在X.509数字证书中,该证书自己由证书颁发机构签名。尽管有这个名字,但CA只是签署证书的任何实体,惟一赋予它们权力的是人们对软件的信任。ID验证和证书颁发具备竞争市场,这意味着你能够免费得到很是容易验证的身份证书(如电子邮件地址或域名)的证书。更复杂的身份,例如人或公司的合法名称,须要更多的努力来验证,所以必须付费。

从技术上讲,证书只是关于公钥的声明,所以要求你必须首先生成私钥,而后是证书签名请求(CSR),而后选择CA并上传CSR,以及你想要的身份和任何验证所需的信息。而后,CA会发回一个签名证书,该证书能够嵌入到付款请求中,同时还能够嵌入到达到一组根证书所需的任何中间证书。而后使用私钥对PaymentDetails消息进行签名,如今其余用户软件能够验证全部这些并在用户界面中显示通过验证的ID。它还充当你在指定时间实际发出给定付款请求的加密证实。

实际上,上述手动建立密钥,建立CSR,上传密码等过程一般会自动取消最终用户电子邮件地址证书:相反,任何支持HTML5的现代Web浏览器均可以用来自动完成整个过程。在访问发布Comodo等免费证书的CA后,用户输入所请求的电子邮件地址并单击按钮。而后他们的浏览器生成一个新的私钥并记录下来。当用户单击传递到其电子邮件地址的验证连接时,签名过程完成,证书将安装在本地密钥存储中,能够在其中使用或导出到其余设备。整个过程与注册网站没有太大区别。

bitcoinj中的支付协议API

在0.12中,bitcoinj中的支付协议支持是有限的。它支持钱包应用程序中基本支持所需的一切,用于签名和使用付款请求。可是,它不支持将它们存储在钱包中以供未来参考。bitcoinj也没有利用这个机会向收件人提交多个独立交易以规避合并。

尽管如此,这里仍是咱们如何使用新功能的演示。

String url = QRCodeScanner.scanFromCamera(.....);
ListenableFuture<PaymentSession> future;
if (url.startsWith("http")) {
    // URL may serve either HTML or a payment request depending on how it's fetched. 
    // Try here to get a payment request.
    future = PaymentSession.createFromUrl(url);
} else if (url.startsWith("bitcoin:")) {
    future = PaymentSession.createFromBitcoinUri(new BitcoinURI(url));
}

PaymentSession session = future.get();    // may throw PaymentRequestException.

String memo = session.getMemo();
Coin amountWanted = session.getValue();

if (session.isExpired()) {
    showUserErrorMessage();
}

PaymentSession.PkiVerificationData identity = null;
try {
    identity = session.verifyPki();
} catch (Exception e) {
    log.error(e);
    // Don't show errors that occur during PKI verification to the user!
    // Just treat such payment requests as if they were unsigned. This way
    // new features and PKI roots can be introduced in future without
    // being disruptive.
}

if (identity != null) {
    showUserConfirmation(identity.domainName, identity.orgName);
} else { 
    showUserConfirmation();
}

// a bit later when the user has confirmed the payment

SendRequest req = session.getSendRequest();
wallet.completeTx(req);  // may throw InsufficientMoneyException
// No refund address specified, no user specified memo field.
ListenableFuture<PaymentSession.Ack> ack = session.sendPayment(ImmutableList.of(req.tx), null, null);
Futures.addCallback(ack, new FutureCallback() {
    @Override public onSuccess(PaymentSession.Ack ack) {
        wallet.commitTx(req.tx);
        displayMessage(ack.getMemo());
    }
});

用户界面注意事项

以特定方式提交付款协议确认很是重要。

首先,若是签名的PKI数据可用,你应该以一些具备视觉意义的方式向用户代表,所以他们知道所呈现的字符串是由第三方验证的ID。第三方(即CA)的名称也应该是可见的,尽管默认状况下将其隐藏在切换/滑块后面是能够接受的。

其次,若是提供了签名的PKI数据但未能验证,则应以与彻底丢失签名数据彻底相同的方式呈现付款。打开错误签名的请求的经验永远不会比打开一个彻底没有签名的请求更糟糕。这使咱们能够灵活地引入新的证书颁发机构或签署系统。

二维码

若是你的应用程序集成了扫描QR码的支持,你应该注意BIP 73.它说若是钱包应用程序扫描QR码并找到HTTP URL而不是比特币URI,它应该执行HTTP [S] GET到具备特殊HTTP标头的URL,该标头要求服务器提供付款请求。

这种机制的目的是让商家和支付处理商能够提供能够在任何类型的QR扫描仪上工做的QR码,若是用户没有带有集成扫描仪的钱包,那么带有说明的一个漂亮的HTML发票页面和能够显示可点击的比特币连接。

操做系统集成

若是要编写钱包应用程序,你应该注册处理比特币URI,你还应注册处理类型为application/bitcoin-paymentrequest的文件,扩展名为.bitcoinpaymentrequest。

经过这样作,你能够确保你的应用能够处理附加到电子邮件的付款请求,经过IM应用程序发送等等。

理想状况下,你还能够容许用户建立付款请求。PaymentRequest消息的pki_type能够为“none”,所以建立此类文件是有效的。为了简单的用户体验,咱们建议:

  • 在桌面上,容许用户拖放支付请求文件(将其表示为图标)。例如,用户能够将其拖动到电子邮件撰写窗口以将付款请求附加到电子邮件与手动复制/粘贴地址和金额。 Gmail支持将文件拖放到编辑器上,其余HTML5应用也能够接受拖放数据。
  • 在移动设备上,容许用户“共享”支付请求文件,这将容许用户经过聊天应用程序发送,附加到电子邮件,经过DropBox/Google Drive等共享。

测试

Gavin在这里运行一个简单的付款请求生成器应用:

https://bitcoincore.org/~gavi...

你可使用它来测试你的钱包实现。

分享一个java比特币开发教程,面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如建立地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。

汇智网(专业区块链教程网站)原创翻译,转载请标明出处。这里是原文

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息