javascript使用比特幣類庫bitcoinj指南
Java8附帶了一個名為Nashorn的Javascript引擎,其效能接近V8(它不是那麼好,但足夠好)。使用此引擎很容易使用Java程式碼,並且可以從命令列或使用互動式直譯器執行Javascript程式。還有一些專案提供了與node.js相容的API,但本教程不會探討這些API。
要開始使用,請獲取JDK的第8版,並確保你可以執行jjs
工具。接下來,從Maven Central下載打包好的ofollow,noindex">bitcoinj JAR檔案
並將其放入你的工作目錄。這樣我們就可以通過Javascript開始使用bitcoinj。
現在讓我們看一下原始碼樹中示例中的demo.js檔案 。演示程式執行一些基本操作,例如建立金鑰並列印其地址,然後開啟網路並列印有關其連線的節點的一些資訊。
執行demo
要執行在Javascript中使用bitcoinj的demo程式,可以簡單地執行:
jjs -cp bitcoinj-0.14.7-bundled.jar demo.js
這在Nashorn執行程式。請注意,Nashorn支援Web風格的Javascript中並沒有的一些額外內容,例如從Java庫匯入程式碼的功能。cp
命令列引數可設定類路徑:它是JAR列表(java庫)。在這種情況下,我們只要告訴它載入捆綁的bitcoinj版本,就可以包括庫及其所有依賴項。
你從SLF4J
收不到任何有關日誌記錄的後端警告。沒關係,我們稍後可以看看如何設定日誌記錄。現在讓我們先來看看程式碼。
demo.js
// Import some stuff. var bcj = org.bitcoinj; var ECKey = bcj.core.ECKey; // We'll use the testnet for now. var params = bcj.params.TestNet3Params.get(); // Most basic operation: make a key and print its address form to the screen. var key = new ECKey(); print(key.toAddress(params)); // Keys record their creation time. Java getFoo()/setFoo() style methods can be treated as js properties: print(key.creationTimeSeconds); key.creationTimeSeconds = 0;
該檔案的第一部分非常簡單。Nashorn自動將Java庫對映到Javascript名稱空間中,但我們將org.bitcoinj定義為bcj,以使程式碼更簡潔。我們也可以定義單獨的類等。然後我們獲取“網路引數”,它控制我們是使用主比特幣網路還是測試網路(或本地節點上的regtest模式)。引數物件傳遞給bitcoinj中的許多API。
接下來,我們建立一個金鑰,並顯示如何列印其地址。
要了解可用的API,可以瀏覽線上javadoc。顯然,這些是供Java開發人員使用的。但是,將API轉換為Javascript很容易。最後,我們看到了Nashorn提供的便利:Java要求你呼叫getFoo()
或setFoo(“foo”)
方法,在Javascript中我們可以將它們視為物件的常規屬性。這樣會好很多。
// Let's connect to the network. This won't download the block chain. var PeerGroup = bcj.core.PeerGroup; var pg = new PeerGroup(params) pg.addPeerDiscovery(new bcj.net.discovery.DnsDiscovery(params)); pg.startAsync(); pg.awaitRunning(); // Wait until we have at least three peers. print("Waiting for some peers") pg.waitForPeers(3).get() print("Connected to: " + pg.connectedPeers);
這段程式碼顯示瞭如何連線到P2P網路。PeerGroup
管理多個對等連線。我們必須使用DNS發現例項對其進行配置,然後啟動它。它將在後臺查詢並設定連線。最後一行等待它找到至少三個連線的對等體,然後打印出它們的IP地址和埠。connectedPeers
屬性提供Peer
物件列表。
標記非同步
Javascript是為Web瀏覽器開發的,它是單執行緒環境,因此Javascript無法建立執行緒,V8(最流行的JS執行時)執行緒也不安全。相反,大多數JS環境只為你提供一種可以追溯到Visual Basic時代的執行緒樣式——你可以執行並行javascript引擎,這些引擎只能通過訊息傳遞進行通訊。這反過來意味著你不能阻塞它而被迫大量形成回撥導向的程式設計風格。
相比之下,Nashorn將Javascript編譯為在JVM上執行的位元組碼。因此,它是完全執行緒安全的。雖然如果你願意,你當然也可以實現帶有大量回調的純訊息傳遞,但你並沒有被迫並且可以以多正規化的方式進行併發程式設計。
在這裡,我們採用簡單的路徑:當我們需要等待某些事情發生時,我們只是阻塞主執行緒。下面,我們將看到如何非同步執行操作。waitForPeers(3)
方法返回一個future
,一旦我們至少有三個peers
,它將完成。futures有時被稱為Javascript世界中的promises。呼叫get
方法塊直到future
的結果準備就緒。
集合和陣列的迭代
pg.connectedPeers
屬性是Java集合。這被Nashorn視為Javascript陣列。但是因為Javascript歷史上沒有一種方便的方法來迭代集合,所以Nashorn使用類似Java的foreach語句擴充套件了該語言。我們可以在這裡使用它:
var connectedPeers = pg.connectedPeers; for each (var peer in connectedPeers) print(peer.peerVersionMessage.subVer); // which for me outputs this: // /Satoshi:0.9.99/ // /Satoshi:0.9.2/ // /Satoshi:0.9.1/ // Of course we can do it the old JS way too: for (var i = 0; i < connectedPeers.length; i++) { print("Chain height for " + connectedPeers[i] + " is " + connectedPeers[i].bestHeight) }
Peer的subVer
欄位是HTTP使用者代理字串的比特幣等價物。bestHeight
欄位是對等方聲稱自己報告的(未經身份驗證的)鏈高度。
當然,你也可以使用更現代的JS風格的foreach,它使用一個閉包,這自然效率低下:
// or slightly more modern js: connectedPeers.forEach(function(peer) { peer.ping().get(); print("Ping time for " + peer + " is " + peer.lastPingTime); // The get() call above forced the program to wait for the ping. Peers are pinged in the background and the ping // times averaged, but if we didn't wait here we might not get a realistic ping time back because the program only // just started up. });
在這裡,我們可以看到我們再次阻塞並測量到遠端對等體的ping時間。請注意,這不是ICMP(網際網路級別)的ping,而是比特幣協議特定的ping訊息。
讓我們再次這樣做,但這次是以非同步的方式:
var futures = []; connectedPeers.forEach(function(peer) { var future = peer.ping(); futures.push(future); future.addListener(function() { var pingTime = future.get(); print("Async callback ping time for " + peer + " is " + pingTime); }, bcj.utils.Threading.USER_THREAD); }); // Just wait for all the pings here by calling get again ... futures.forEach(function(f) { f.get() }); print("Done!");
在這裡,我們為每個對等體啟動ping,並將返回的future新增到陣列中。然後我們新增一個將在未來完成時執行的閉包。注意最後的(必需的)引數:它說明了執行閉包的執行緒。這裡我們指定user thread
使用者執行緒,這是一個由bitcoinj建立的專用執行緒,它等待執行事件處理程式。通過在使用者執行緒中執行內容,你可以確定自己的事件處理程式不會最終彼此並行執行(儘管它們仍然可以與主執行緒並行執行!)。一旦future的偵聽器執行,我們可以將結果視為正常安全,因為它不會阻塞它。
最後一個forEach迴圈只是讓程式保持執行,直到所有ping都有響應。
總結
bitcoinj還有許多其他功能,本教程不涉及這些功能。你可以閱讀其他文章以瞭解有關完整驗證,錢包加密等的更多資訊,當然JavaDocs還詳細介紹了完整的API。
還有另一個Javascript示例實現了與Java教程forwarding.js 相同的轉發程式。你可以閱讀該程式以瞭解如何使用錢包以及如何接收和匯款。
我建議你瀏覽我們的區塊鏈教程和區塊鏈技術部落格,深入瞭解區塊鏈,比特幣,加密貨幣,以太坊,和智慧合約。
- 以太坊入門教程,主要介紹智慧合約與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的開發。
匯智網原創翻譯,轉載請標明出處。這裡是原文