简介

比特币(BitCoin)是一种基于区块链(BlockChain)技术的数字化货币. 本文介绍了使用基于Java语言的BitCoinJ API实现一个简单的收取和支付比特币的示例程序.

开发环境

本示例使用BitCoinJ(https://bitcoinj.github.io/) API, 目前的发布版本是0.14.3, 其JAR包可以从官网下载, 也可以通过如下的Maven定义在项目POM中引用.

<dependencies>
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>
<version>0.14.3</version>
<scope>compile</scope>
</dependency>
</dependencies>

收取比特币

收取比特币的示例代码如下

public class BitCoinHelloWorld implements WalletCoinsReceivedEventListener {

    public static void main(String[] args) {
BitCoinHelloWorld demo = new BitCoinHelloWorld(); demo.run();
} public void run() {
try {
init(); System.out.println("Waiting for coins..."); while (true) {
Thread.sleep(20);
}
} catch (BlockStoreException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void init() throws BlockStoreException {
NetworkParameters params = TestNet3Params.get(); ECKey key = new ECKey();
System.out.println("We created a new key:\n" + key); Address addressFromKey = key.toAddress(params);
System.out.println("Public Address generated: " + addressFromKey); System.out.println("Private key is: " + key.getPrivateKeyEncoded(params).toString()); Wallet wallet = new Wallet(params);
wallet.importKey(key); File blockFile = new File("/tmp/bitcoin-blocks");
SPVBlockStore blockStore = new SPVBlockStore(params, blockFile); BlockChain blockChain = new BlockChain(params, wallet, blockStore);
PeerGroup peerGroup = new PeerGroup(params, blockChain);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));
peerGroup.addWallet(wallet); System.out.println("Start peer group");
peerGroup.start(); System.out.println("Downloading block chain");
peerGroup.downloadBlockChain();
System.out.println("Block chain downloaded"); wallet.addCoinsReceivedEventListener(this);
} @Override
public void onCoinsReceived(final Wallet wallet, final Transaction transaction, Coin prevBalance, Coin newBalance) {
final Coin value = transaction.getValueSentToMe(wallet); System.out.println("Received tx for " + value.toFriendlyString() + ": " + transaction); System.out.println("Previous balance is " + prevBalance.toFriendlyString()); System.out.println("New estimated balance is " + newBalance.toFriendlyString()); System.out.println("Coin received, wallet balance is :" + wallet.getBalance()); Futures.addCallback(transaction.getConfidence().getDepthFuture(1), new FutureCallback<TransactionConfidence>() {
public void onSuccess(TransactionConfidence result) {
System.out.println("Transaction confirmed, wallet balance is :" + wallet.getBalance());
} public void onFailure(Throwable t) {
t.printStackTrace();
}
});
}
}

该示例程序首先调用init方法进行初始化, 然后进入一个等待循环, 当有比特币到来时, onCoinsReceived方法就被触发.

各个步骤的具体分析如下

选择运行环境

比特币应用可以在三种不同的环境中运行: 正式流通网络, 测试流通网络以及本地开发环境. 初始化的第一步是通过设置一个NetworkParameters变量来选择运行环境, 以下代码使用测试流通网络

NetworkParameters params  = TestNet3Params.get();

获取地址和设置钱包对象

以下代码首先创建一个可用于接受比特币的地址, 并将其导入相应的钱包对象中.

ECKey key = new ECKey();
System.out.println("We created a new key:\n" + key); Address addressFromKey = key.toAddress(params);
System.out.println("Public Address generated: " + addressFromKey); System.out.println("Private key is: " + key.getPrivateKeyEncoded(params).toString()); Wallet wallet = new Wallet(params);
wallet.importKey(key);

接入流通网络并下载比特币区块

以下代码接入流通网络并下载比特币区块

File blockFile = new File("/tmp/bitcoin-blocks");
SPVBlockStore blockStore = new SPVBlockStore(params, blockFile); BlockChain blockChain = new BlockChain(params, wallet, blockStore);
PeerGroup peerGroup = new PeerGroup(params, blockChain);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));
peerGroup.addWallet(wallet); System.out.println("Start peer group");
peerGroup.start(); System.out.println("Downloading block chain");
peerGroup.downloadBlockChain();
System.out.println("Block chain downloaded");

需要注意的是peerGroup.downloadBlockChain();这一步可能会运行很长时间.

设置事件响应

以下代码设置当比特币到来时的事件响应

wallet.addCoinsReceivedEventListener(this);

比特币到来事件响应

当比特币到来时onCoinsReceived方法就会触发, 注意该方法的newBalance参数提供的是钱包中金额的估计值,其实际金额要等到交易被网络确认后才会提现在wallet.getBalance()的返回值中, 如以下代码所示

Futures.addCallback(transaction.getConfidence().getDepthFuture(1), new FutureCallback<TransactionConfidence>() {
public void onSuccess(TransactionConfidence result) {
System.out.println("Transaction confirmed, wallet balance is :" + wallet.getBalance());
} public void onFailure(Throwable t) {
t.printStackTrace();
}
});

支付比特币

支付比特币的过程相对简单, 首选设置要支付的金额.

final Coin amountToSend = Coin.valueOf(10, 0);

其次设置接收方的地址

Address toAddress = Address.fromBase58(params, "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi");

然后发送该支付交易

final Wallet.SendResult sendResult = wallet.sendCoins(peerGroup, toAddress, amountToSend);

并设置交易完成后的事件响应

sendResult.broadcastComplete.addListener(new Runnable() {
@Override
public void run() {
System.out.println("Coins Sent! Transaction hash is " + sendResult.tx.getHashAsString());
}
}, MoreExecutors.sameThreadExecutor());

总结

本文给出了一个基于BitCoinJ的比特币收发示例程序, 并对BitCoinJ的编程模式以及其事件响应机制做了初步介绍.

BitCoinJ之Hello World示例程序的更多相关文章

  1. 通过Jexus 部署 dotnetcore版本MusicStore 示例程序

    ASPNET Music Store application 是一个展示最新的.NET 平台(包括.NET Core/Mono等)上使用MVC 和Entity Framework的示例程序,本文将展示 ...

  2. .NET跨平台:在Ubuntu上用自己编译的dnx运行ASP.NET 5示例程序

    在 Linux Ubuntu 上成功编译 dnx 之后,会在 artifacts/build/ 文件夹中生成 dnx-coreclr-linux-x64/ 与 dnx-mono/ 这2个文件夹,前者是 ...

  3. .NET跨平台:在CentOS上编译dnx并运行ASP.NET 5示例程序

    在之前的博文中我们在 Ubuntu 上成功编译出了 dnx ,并且用它成功运行了 ASP.NET 5 示例程序.在这篇博文中我们将 Ubuntu 换成 CentOS. 目前 dnx 的编译需要用到 m ...

  4. Salesforce Apex 使用JSON数据的示例程序

    本文介绍了一个在Salesforce Apex中使用JSON数据的示例程序, 该示例程序由以下几部分组成: 1) Album.cls, 定了了封装相关字段的数据Model类 2) RestClient ...

  5. osg 示例程序解析之osgdelaunay

    osg 示例程序解析之osgdelaunay 转自:http://lzchenheng.blog.163.com/blog/static/838335362010821103038928/ 本示例程序 ...

  6. DotNetBar for Windows Forms 12.7.0.10_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.7.0.10_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版------------- ...

  7. DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  8. DotNetBar for Windows Forms 12.2.0.7_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.2.0.7_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  9. ACEXML解析XML文件——简单示例程序

    掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...

随机推荐

  1. mono for android学习过程系列教程(7)

    首先说个抱歉,这段时候由于个人原因未及时更新博客.故此今天先给大家来个小料. 以后会及时更新我自己的学习过程. 不多说,终于私人生活安定下来了,可以安心学习.直接进入主体: 今天咱们摒弃所有的前面的知 ...

  2. Ubuntu下安装 jdk6

    Ubuntu下安装 jdk6 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公用协议   1,下载最新的 jdk6 版本,目前最 ...

  3. 【转载】关于sql server 代理(已禁用代理xp)

    原文地址:http://blog.sina.com.cn/s/blog_493cafbb0100qy91.html 症状: SQL SERVER2005里面,启动SQL代理服务,启动正常,但是在sql ...

  4. 测试博文中添加可执行JS代码

    昨天申请开通了博客园的JS权限,今天来看看效果. 测试执行JS 测试执行JS // 运行

  5. 【译】用jQuery 处理XML-- DOM(文本对象模型)简介

    用jQuery 处理XML--写在前面的话 用jQuery 处理XML-- DOM(文本对象模型)简介 用jQuery 处理XML--浏览器中的XML与JavaScript 用jQuery 处理XML ...

  6. C/C++中动态链接库的创建和调用

    DLL 有助于共享数据和资源.多个应用程序可同时访问内存中单个DLL 副本的内容.DLL 是一个包含可由多个程序同时使用的代码和数据的库.下面为你介绍C/C++中动态链接库的创建和调用. 动态连接库的 ...

  7. iOS xcode6 设置多语言

    1,首先新建一个文件,选中ios模块下Rescource的Strings File 类型.eg:文件 2,选中该文件,右边栏选该文件属性,选中Localizable模块,选中localiz,这时会弹出 ...

  8. Bootstrap~日期控制

    回到目录 一个成熟的框架,日期控制是少不了的,在网上也有很多日期控制可以选择,而主框架用了bootstrap,日期控制也当前要用它自己的, 控件地址:http://www.bootcss.com/p/ ...

  9. 大叔最新课程~EF核心技术剖析

    EF核心技术剖析介绍 数据上下文(共享对象与实例对象的选择) 自动初始化(Initializer初始化的几种方式) 数据迁移(Migrations如何使用及其重要作用) 实体关系映射(一对一,一对多, ...

  10. WPF入门教程系列十二——依赖属性(二)

    二. 依赖属性的优先级 由于WPF 允许我们可以在多个地方设置依赖属性的值,所以我们就必须要用一个标准来保证值的优先级别.比如下面的例子中,我们在三个地方设置了按钮的背景颜色,那么哪一个设置才会是最终 ...