1. 程式人生 > >比特幣使用BIP70支付協議API

比特幣使用BIP70支付協議API

支付協議是用於指代BIP70,71,72和73中指定的協議的術語。支付協議旨在通過用可編碼更復雜引數的小檔案替換普遍存在的比特幣地址來為比特幣新增附加功能。它指定了直接在資金髮送方和接收方之間流動的支付請求,付款和支付方式的格式。

支付協議對於比特幣的各種重要功能的開發至關重要,因此,瞭解它如何使用比特幣非常重要。本文介紹了基本功能,並顯示了將其整合到錢包應用程式中的一些示例程式碼。

具體而言,該協議的第1版提供:

  • 1.接收器/商家使用任意指令碼請求多個輸出的方式,而不僅僅是單個付費金鑰雜湊型別的輸出。多個獨立交易可以滿足付款,允許將來實施基於規避合併的隱私技術。
  • 2.自由文字備忘錄欄位,因此商家可以填寫由錢包儲存的購買細節,及使用者在付款時附加訊息。
  • 3.到期時間,過期的付款請求可能會被視為無效。這允許接收器在伺服器端繫結其資源使用並放棄從未付費的請求。
  • 4.發行時間,付款請求知道何時發出——有利於記錄儲存。
  • 5.二進位制cookie-esque欄位,在提交支付交易時將簡單地回顯給伺服器,允許商家實現無狀態後端。
  • 6.使用者指定的退款地址。
  • 7.使用X.509數字證書對上述所有內容進行簽名的可選功能,從而將付款請求繫結到某種經過驗證的身份。

支付請求本身可以進行數字簽名這一事實可以實現一些非常重要和有用的功能。中間的一個人不能重寫輸出來劫持付款。這對於像Trezor這樣的硬體錢包來說尤其重要,因為Trezor會假設主機受到損害,否則使用者無法知道他們授權的付款與商家要求的付款相同。

此外,數字簽名的付款請求和在區塊鏈上滿足它的交易一起建立非常類似收據的付款證明。收據對於爭議調解和證明購買是有用的,而商家不必保留他們曾經擁有的每個客戶的詳盡資料庫——即使商家刪除了有關你的資料,只需出示收據就足以證明你已進行購買。

協議緩衝區是一種可以輕鬆擴充套件的二進位制資料序列化格式。因此,我們可以很容易地想象將來可能新增的許多其他功能

協議概述

在正常的比特幣支付中,該過程從使用者點選比特幣URI或複製並將文字地址貼上到他們的錢包應用程式並手動指定金額開始。

在付款協議處理的付款中,該過程以兩種方式之一啟動:

  • 使用者單擊具有新“r”引數的比特幣URI,該引數包含解析為付款請求檔案的(http)URL。
  • 使用者直接開啟付款請求檔案。

然後,使用者的錢包解析作為協議緩衝區的支付請求資料,並開始正常請求確認的過程。單擊比特幣URI時,將忽略URI其餘部分中的指令(它們僅用於向後相容),並且在給定URL處找到的資料優先。

支付請求由外部“skin”訊息組成,該訊息包含(可選的)簽名和證書資料,以及包含所請求支付的詳細資訊的內部“core”訊息的嵌入式序列化。外部PaymentRequest訊息與所使用的數字簽名基礎結構的型別無關,但目前僅定義了X.509繫結。這與SSL中使用的系統相同。內部PaymentDetails訊息以二進位制形式儲存,而不像普通的protobuf訊息那樣被嵌入,以確保簽名位元組始終匹配。

一旦錢包建立了令人滿意的比特幣交易集,就會格式化付款訊息並將其上傳到PaymentDetails指定的目標URL,一旦滿意地接受付款,錢包就會收到PaymentACK訊息。

簽名和證書

簽名付款請求的目的是在使用者錢包應用中替換此類訊息:

Pay 10mBTC to 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa?

與這樣的一個:

  • 支付10mBTC到[email protected]
  • 向邁克爾赫恩支付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在這裡執行一個簡單的付款請求生成器應用:

你可以使用它來測試你的錢包實現。

建議你瀏覽我們匯智網的各種程式語言的區塊鏈教程和區塊鏈技術部落格,深入瞭解區塊鏈,比特幣,加密貨幣,以太坊,和智慧合約。

  • 以太坊入門教程,主要介紹智慧合約與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的開發。

匯智網原創翻譯,轉載請標明出處。這裡是原文