Java8附帶了一個名為Nashorn的Javascript引擎,其性能接近V8(它不是那麼好,但足夠好)。使用此引擎很容易使用Java代碼,并且可以從指令行或使用互動式解釋器運作Javascript程式。還有一些項目提供了與node.js相容的API,但本教程不會探讨這些API。
要開始使用,請擷取JDK的第8版,并確定你可以運作
jjs
工具。接下來,從Maven Central下載下傳打包好的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的開發。
彙智網原創翻譯,轉載請标明出處。這裡是原文