支付协议是用于指代BIP70,71,72和73中指定的协议的术语。支付协议旨在经过用可编码更复杂参数的小文件替换广泛存在的比特币地址来为比特币添加附加功能。它指定了直接在资金发送方和接收方之间流动的支付请求,付款和支付方式的格式。php
支付协议对于比特币的各类重要功能的开发相当重要,所以,了解它如何使用比特币很是重要。本文介绍了基本功能,并显示了将其集成到钱包应用程序中的一些示例代码。java
具体而言,该协议的第1版提供:node
支付请求自己能够进行数字签名这一事实能够实现一些很是重要和有用的功能。中间的一我的不能重写输出来劫持付款。这对于像Trezor这样的硬件钱包来讲尤为重要,由于Trezor会假设主机受到损害,不然用户没法知道他们受权的付款与商家要求的付款相同。python
此外,数字签名的付款请求和在区块链上知足它的交易一块儿建立很是相似收据的付款证实。收据对于争议调解和证实购买是有用的,而商家没必要保留他们曾经拥有的每一个客户的详尽数据库——即便商家删除了有关你的数据,只需出示收据就足以证实你已进行购买。android
协议缓冲区是一种能够轻松扩展的二进制数据序列化格式。所以,咱们能够很容易地想象未来可能添加的许多其余功能。程序员
你能够阅读付款协议的常见问题解答,详细说明其设计背后的基本原理。web
在正常的比特币支付中,该过程从用户点击比特币URI或复制并将文本地址粘贴到他们的钱包应用程序并手动指定金额开始。mongodb
在付款协议处理的付款中,该过程以两种方式之一启动:数据库
而后,用户的钱包解析做为协议缓冲区的支付请求数据,并开始正常请求确认的过程。单击比特币URI时,将忽略URI其他部分中的指令(它们仅用于向后兼容),而且在给定URL处找到的数据优先。编程
支付请求由外部“skin”消息组成,该消息包含(可选的)签名和证书数据,以及包含所请求支付的详细信息的内部“core”消息的嵌入式序列化。外部PaymentRequest
消息与所使用的数字签名基础结构的类型无关,但目前仅定义了X.509绑定。这与SSL中使用的系统相同。内部PaymentDetails
消息以二进制形式存储,而不像普通的protobuf消息那样被嵌入,以确保签名字节始终匹配。
一旦钱包建立了使人满意的比特币交易集,就会格式化付款消息并将其上传到PaymentDetails
指定的目标URL,一旦满意地接受付款,钱包就会收到PaymentACK
消息。
签名付款请求的目的是在用户钱包应用中替换此类消息:
Pay 10mBTC to 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?
与这样的一个:
......固然,第一种形式是最无用的,由于在这种状况下,身份只是一个没有意义或稳定性的随机数。这致使了其余示例中的字符串来自何处的问题。
答案是它们包含在X.509数字证书中,该证书自己由证书颁发机构签名。尽管有这个名字,但CA只是签署证书的任何实体,惟一赋予它们权力的是人们对软件的信任。ID验证和证书颁发具备竞争市场,这意味着你能够免费得到很是容易验证的身份证书(如电子邮件地址或域名)的证书。更复杂的身份,例如人或公司的合法名称,须要更多的努力来验证,所以必须付费。
从技术上讲,证书只是关于公钥的声明,所以要求你必须首先生成私钥,而后是证书签名请求(CSR),而后选择CA并上传CSR,以及你想要的身份和任何验证所需的信息。而后,CA会发回一个签名证书,该证书能够嵌入到付款请求中,同时还能够嵌入到达到一组根证书所需的任何中间证书。而后使用私钥对PaymentDetails
消息进行签名,如今其余用户软件能够验证全部这些并在用户界面中显示通过验证的ID。它还充当你在指定时间实际发出给定付款请求的加密证实。
实际上,上述手动建立密钥,建立CSR,上传密码等过程一般会自动取消最终用户电子邮件地址证书:相反,任何支持HTML5的现代Web浏览器均可以用来自动完成整个过程。在访问发布Comodo等免费证书的CA后,用户输入所请求的电子邮件地址并单击按钮。而后他们的浏览器生成一个新的私钥并记录下来。当用户单击传递到其电子邮件地址的验证连接时,签名过程完成,证书将安装在本地密钥存储中,能够在其中使用或导出到其余设备。整个过程与注册网站没有太大区别。
在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”,所以建立此类文件是有效的。为了简单的用户体验,咱们建议:
Gavin在这里运行一个简单的付款请求生成器应用:
https://bitcoincore.org/~gavin/createpaymentrequest.php
你可使用它来测试你的钱包实现。
建议你浏览咱们汇智网的各类编程语言的区块链教程和区块链技术博客,深刻了解区块链,比特币,加密货币,以太坊,和智能合约。
- 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
- 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
- java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
- python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
- php以太坊,主要是介绍使用php进行智能合约开发交互,进行帐号建立、交易、转帐、代币开发以及过滤器和交易等内容。
- C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括帐户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
- php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如建立地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
- java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如建立地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
- EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、帐户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
汇智网原创翻译,转载请标明出处。这里是原文