zoukankan      html  css  js  c++  java
  • 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:
    " + 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:
    " + 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的编程模式以及其事件响应机制做了初步介绍.

  • 相关阅读:
    Python基础系列----语法、数据类型、变量、编码
    Python基础系列----环境的搭建及简单输入、输出
    Python 从基础------进阶------算法 系列
    Python数据库访问公共组件及模拟Http请求
    急!急!急!请问win32api参数乱码如何解决!
    打印之Lodop
    Elasticsearch 6.7.2 源码编译
    ElasticSearch源码之——Gateway
    ElasticSearch源码之——Netty在Elasticsearch中的应用
    从BIO到Netty
  • 原文地址:https://www.cnblogs.com/huyouhengbc/p/5898623.html
Copyright © 2011-2022 走看看