支付協議是用於指代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的開發。
匯智網原創翻譯,轉載請標明出處。這裏是原文