BitCoinJ之Hello World示例程序
简介
比特币(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示例程序的更多相关文章
- 通过Jexus 部署 dotnetcore版本MusicStore 示例程序
ASPNET Music Store application 是一个展示最新的.NET 平台(包括.NET Core/Mono等)上使用MVC 和Entity Framework的示例程序,本文将展示 ...
- .NET跨平台:在Ubuntu上用自己编译的dnx运行ASP.NET 5示例程序
在 Linux Ubuntu 上成功编译 dnx 之后,会在 artifacts/build/ 文件夹中生成 dnx-coreclr-linux-x64/ 与 dnx-mono/ 这2个文件夹,前者是 ...
- .NET跨平台:在CentOS上编译dnx并运行ASP.NET 5示例程序
在之前的博文中我们在 Ubuntu 上成功编译出了 dnx ,并且用它成功运行了 ASP.NET 5 示例程序.在这篇博文中我们将 Ubuntu 换成 CentOS. 目前 dnx 的编译需要用到 m ...
- Salesforce Apex 使用JSON数据的示例程序
本文介绍了一个在Salesforce Apex中使用JSON数据的示例程序, 该示例程序由以下几部分组成: 1) Album.cls, 定了了封装相关字段的数据Model类 2) RestClient ...
- osg 示例程序解析之osgdelaunay
osg 示例程序解析之osgdelaunay 转自:http://lzchenheng.blog.163.com/blog/static/838335362010821103038928/ 本示例程序 ...
- DotNetBar for Windows Forms 12.7.0.10_冰河之刃重打包版原创发布-带官方示例程序版
关于 DotNetBar for Windows Forms 12.7.0.10_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版------------- ...
- DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版原创发布-带官方示例程序版
关于 DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...
- DotNetBar for Windows Forms 12.2.0.7_冰河之刃重打包版原创发布-带官方示例程序版
关于 DotNetBar for Windows Forms 12.2.0.7_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...
- ACEXML解析XML文件——简单示例程序
掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...
随机推荐
- CSS3之绽放的花朵(网页效果--每日一更)
今天,带来的是纯CSS3打造的效果--绽放的花朵. 先来看效果吧:亲,请点击这里 这是纯CSS3样式打造的效果,关键是采用了animation属性和transform属性.详细请看下面代码. HTML ...
- EntityFunctions.AsNonUnicode
http://blog.csdn.net/zzx3q/article/details/7863797 使用工具VS2010 凡是调用FindAll的地方,如果传入参数是String类型的变量(数字类型 ...
- openwrt-智能路由器hack技术(1)---"DNS劫持"
openwrt-智能路由器hack技术(1)---"DNS劫持" 1 导读 PS:之前写的一个文章,现在发现结构内容排版不是太好,导致阅读体验太差,影响传播和SEO,所以现在整 ...
- 每周一书-2016年8月15日到21日(bootstrap基础教程)获奖读者公布
本次赠书 由微信昵称为“………….”的网友以10个赞获得. 请这位网友,订阅号回复你的联系方式,明天给你邮递这本书.谢谢!同时感谢<把时间当朋友>的获奖者“永梅”为<bootsrap ...
- java提高篇(三十)-----Iterator
迭代对于我们搞Java的来说绝对不陌生.我们常常使用JDK提供的迭代接口进行Java集合的迭代. Iterator iterator = list.iterator(); while(iterator ...
- Unity3D热更新全书-PageZero
由于深刻的认识到自己是个思维跳跃的人,深入浅出是个我还要努力很久的目标,为了让大家不至于在我乱七八糟的文字中迷失,特整理目录一份 无分类 <Unity3D热更新全书-何谓热更新,为何热更新,如何 ...
- Android多线程分析之四:MessageQueue的实现
Android多线程分析之四:MessageQueue的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前面两篇文章<Androi ...
- [ZigBee] 3、ZigBee基础实验——GPIO输出控制实验-控制Led亮灭
1.CC2530的IO口概述 CC2530芯片有21 个数字输入/输出引脚,可以配置为通用数字I/O 或外设I/O 信号,配置为连接到ADC.定时器或USART外设.这些I/O 口的用途可以通过一系列 ...
- [nRF51822] 6、基于nRF51822平台的flash读写研究
前言 本文重点介绍flash的数据存取特性.flash的内存划分.一个简单的存取图片的内存管理方式,以及对flash写前删的时间.删后读的时间.写后读的时间进行测量的一个小实验.目的在于更全面了解fl ...
- CSS控制样式的三种方式优先级对比验证
入职已经一个月了,自此后,就好久没有写过博客了,在此先跟关注我的博友们说声抱歉.今天,在公司的一个培训作业的驱动以及伟哥那句“再不写博客就开除你”的监督下,我终于重拾旧爱,再次登录博客园,继续与大家分 ...