javascript使用比特币类库bitcoinj指南

栏目: JavaScript · 发布时间: 5年前

内容简介:Java8附带了一个名为Nashorn的Javascript引擎,其性能接近V8(它不是那么好,但足够好)。使用此引擎很容易使用Java代码,并且可以从命令行或使用交互式解释器运行Javascript程序。还有一些项目提供了与node.js兼容的API,但本教程不会探讨这些API。要开始使用,请获取JDK的第8版,并确保你可以运行现在让我们看一下源代码树中示例中的

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的开发。

汇智网原创翻译,转载请标明出处。这里是 原文


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员成长的烦恼

程序员成长的烦恼

吴亮、周金桥、李春雷、周礼 / 华中科技大学出版社 / 2011-4 / 28.00元

还在犹豫该不该转行学编程?还在编程的道路上摸爬滚打?在追寻梦想的道路上你并不孤单,《程序员成长的烦恼》中的四位“草根”程序员也曾有过类似的困惑。看看油田焊接技术员出身的周金桥是如何成功转行当上程序员的,做过钳工、当过外贸跟单员的李春雷是如何自学编程的,打小在486计算机上学习编程的吴亮是如何一路坚持下来的,工作中屡屡受挫、频繁跳槽的周礼是如何找到出路的。 《程序员成长的烦恼》记录了他们一步一......一起来看看 《程序员成长的烦恼》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具