mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-03-09 05:14:46 +01:00
Adding more examples.
This adds example usages of: * using the WalletAppKit * restoring a wallet from a seed * sending coins * implementing a WalletEventListener
This commit is contained in:
parent
a8e227ae1b
commit
cfd795ccbd
4 changed files with 289 additions and 0 deletions
|
@ -0,0 +1,30 @@
|
|||
package com.google.bitcoin.examples;
|
||||
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.params.TestNet3Params;
|
||||
import com.google.bitcoin.wallet.DeterministicSeed;
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
/**
|
||||
* The following example shows you how to create a deterministic seed from a hierarchical deterministic wallet represented as a mnemonic code.
|
||||
* This seed can be used to fully restore your wallet. The RestoreFromSeed.java example shows how to load the wallet from this seed.
|
||||
*
|
||||
* In Bitcoin Improvement Proposal (BIP) 39 and BIP 32 describe the details about hierarchical deterministic wallets and mnemonic sentences
|
||||
* https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
||||
* https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||
*/
|
||||
public class BackupToMnemonicSeed {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
NetworkParameters params = TestNet3Params.get();
|
||||
Wallet wallet = new Wallet(params);
|
||||
|
||||
DeterministicSeed seed = wallet.getKeyChainSeed();
|
||||
System.out.println("seed: " + seed.toString());
|
||||
|
||||
System.out.println("creation time: " + seed.getCreationTimeSeconds());
|
||||
System.out.println("mnemonicCode: " + Joiner.on(" ").join(seed.getMnemonicCode()));
|
||||
}
|
||||
}
|
105
examples/src/main/java/com/google/bitcoin/examples/Kit.java
Normal file
105
examples/src/main/java/com/google/bitcoin/examples/Kit.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
package com.google.bitcoin.examples;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.bitcoin.core.AbstractWalletEventListener;
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.kits.WalletAppKit;
|
||||
import com.google.bitcoin.params.TestNet3Params;
|
||||
import com.google.bitcoin.script.Script;
|
||||
|
||||
/**
|
||||
* The following example shows how to use the by bitcoinj provided WalletAppKit.
|
||||
* The WalletAppKit class wraps the boilerplate (Peers, BlockChain, BlockStorage, Wallet) needed to set up a new SPV bitcoinj app.
|
||||
*
|
||||
* In this example we also define a WalletEventListener class with implementors that are called when the wallet changes (for example sending/receiving money)
|
||||
*/
|
||||
public class Kit {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// First we configure the network we want to use.
|
||||
// The available options are:
|
||||
// - MainNetParams
|
||||
// - TestNet3Params
|
||||
// - RegTestParams
|
||||
// While developing your application you probably want to use the Regtest mode and run your local bitcoin network. Run bitcoind with the -regtest flag
|
||||
// To test you app with a real network you can use the testnet. The testnet is an alternative bitcoin network that follows the same rules as main network. Coins are worth nothing and you can get coins for example from http://faucet.xeno-genesis.com/
|
||||
//
|
||||
// For more information have a look at: https://bitcoinj.github.io/testing and https://bitcoin.org/en/developer-examples#testing-applications
|
||||
NetworkParameters params = TestNet3Params.get();
|
||||
|
||||
// Now we initialize a new WalletAppKit. The kit handles all the boilerplate for us and is the easiest way to get everything up and running.
|
||||
// Have a look at the WalletAppKit documentation and its source to understand what's happening behind the scenes: https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/com/google/bitcoin/kits/WalletAppKit.java
|
||||
WalletAppKit kit = new WalletAppKit(params, new File("."), "walletappkit-example");
|
||||
|
||||
// In case you want to connect with your local bitcoind tell the kit to connect to localhost.
|
||||
// You must do that in reg test mode.
|
||||
//kit.connectToLocalHost();
|
||||
|
||||
// Now we start the kit and sync the blockchain.
|
||||
// bitcoinj is working a lot with the Google Guava libraries. The WalletAppKit extends the AbstractIdleService. Have a look at the introduction to Guava services: https://code.google.com/p/guava-libraries/wiki/ServiceExplained
|
||||
kit.startAsync();
|
||||
kit.awaitRunning();
|
||||
|
||||
// To observe wallet events (like coins received) we implement a EventListener class that extends the AbstractWalletEventListener bitcoinj then calls the different functions from the EventListener class
|
||||
WalletListener wListener = new WalletListener();
|
||||
kit.wallet().addEventListener(wListener);
|
||||
|
||||
// Ready to run. The kit syncs the blockchain and our wallet event listener gets notified when something happens.
|
||||
// To test everything we create and print a fresh receiving address. Send some coins to that address and see if everything works.
|
||||
System.out.println("send money to: " + kit.wallet().freshReceiveAddress().toString());
|
||||
|
||||
// Make sure to properly shut down all the running services when you manually want to stop the kit. The WalletAppKit registers a runtime ShutdownHook so we actually do not need to worry about that when our application is stopping.
|
||||
//System.out.println("shutting down again");
|
||||
//kit.stopAsync();
|
||||
//kit.awaitTerminated();
|
||||
}
|
||||
|
||||
// The Wallet event listener its implementations get called on wallet changes.
|
||||
static class WalletListener extends AbstractWalletEventListener {
|
||||
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
System.out.println("-----> coins resceived: " + tx.getHashAsString());
|
||||
System.out.println("received: " + tx.getValue(wallet));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
|
||||
System.out.println("-----> confidence changed: " + tx.getHashAsString());
|
||||
TransactionConfidence confidence = tx.getConfidence();
|
||||
System.out.println("new block depth: " + confidence.getDepthInBlocks());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
System.out.println("coins sent");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReorganize(Wallet wallet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWalletChanged(Wallet wallet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeysAdded(List<ECKey> keys) {
|
||||
System.out.println("new key added");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptsAdded(Wallet wallet, List<Script> scripts) {
|
||||
System.out.println("new script added");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.google.bitcoin.examples;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.google.bitcoin.core.BlockChain;
|
||||
import com.google.bitcoin.core.DownloadListener;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.PeerGroup;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.net.discovery.DnsDiscovery;
|
||||
import com.google.bitcoin.params.TestNet3Params;
|
||||
import com.google.bitcoin.store.SPVBlockStore;
|
||||
import com.google.bitcoin.wallet.DeterministicSeed;
|
||||
|
||||
/**
|
||||
* The following example shows you how to restore a HD wallet from a previously generated deterministic seed.
|
||||
* In this example we manually setup the blockchain, peer group, etc. You can also use the WalletAppKit which provides a restoreWalletFromSeed function to load a wallet from a deterministic seed.
|
||||
*/
|
||||
public class RestoreFromSeed {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
NetworkParameters params = TestNet3Params.get();
|
||||
|
||||
// Bitcoinj supports hierarchical deterministic wallets (or "HD Wallets"): https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||
// HD wallets allow you to restore your wallet simply from a root seed. This seed can be represented using a short mnemonic sentence as described in BIP 39: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
||||
|
||||
// Here we restore our wallet from a seed with no passphrase. Also have a look at the BackupToMnemonicSeed.java example that shows how to backup a wallet by creating a mnemonic sentence.
|
||||
String seedCode = "yard impulse luxury drive today throw farm pepper survey wreck glass federal";
|
||||
String passphrase = "";
|
||||
Long creationtime = new Long(1409478661);
|
||||
|
||||
DeterministicSeed seed = new DeterministicSeed(seedCode, passphrase, creationtime);
|
||||
|
||||
// The wallet class provides a easy fromSeed() function that loads a new wallet from a given seed.
|
||||
Wallet wallet = Wallet.fromSeed(params, seed);
|
||||
|
||||
// Because we are importing an existing wallet which might already have transactions we must re-download the blockchain to make the wallet picks up these transactions
|
||||
// You can find some information about this in the guides: https://bitcoinj.github.io/working-with-the-wallet#setup
|
||||
// To do this we clear the transactions of the wallet and delete a possible existing blockchain file before we download the blockchain again further down.
|
||||
System.out.println(wallet.toString());
|
||||
wallet.clearTransactions(0);
|
||||
File chainFile = new File("restore-from-seed.spvchain");
|
||||
if (chainFile.exists()) {
|
||||
chainFile.delete();
|
||||
}
|
||||
|
||||
// Setting up the BlochChain, the BlocksStore and connecting to the network.
|
||||
SPVBlockStore chainStore = new SPVBlockStore(params, chainFile);
|
||||
BlockChain chain = new BlockChain(params, chainStore);
|
||||
PeerGroup peers = new PeerGroup(params, chain);
|
||||
peers.addPeerDiscovery(new DnsDiscovery(params));
|
||||
|
||||
// Now we need to hook the wallet up to the blockchain and the peers. This registers event listeners that notify our wallet about new transactions.
|
||||
chain.addWallet(wallet);
|
||||
peers.addWallet(wallet);
|
||||
|
||||
DownloadListener bListener = new DownloadListener() {
|
||||
@Override
|
||||
public void doneDownload() {
|
||||
System.out.println("blockchain downloaded");
|
||||
}
|
||||
};
|
||||
|
||||
// Now we re-download the blockchain. This replays the chain into the wallet. Once this is completed our wallet should know of all its transactions and print the correct balance.
|
||||
peers.startAsync();
|
||||
peers.awaitRunning();
|
||||
peers.startBlockChainDownload(bListener);
|
||||
|
||||
bListener.await();
|
||||
|
||||
// Print a debug message with the details about the wallet. The correct balance should now be displayed.
|
||||
System.out.println(wallet.toString());
|
||||
|
||||
// shutting down again
|
||||
peers.stopAsync();
|
||||
peers.awaitTerminated();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.google.bitcoin.examples;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.google.bitcoin.core.Address;
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.core.Wallet.BalanceType;
|
||||
import com.google.bitcoin.kits.WalletAppKit;
|
||||
import com.google.bitcoin.params.TestNet3Params;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* The following example shows you how to create a SendRequest to send coins from a wallet to a given address.
|
||||
*/
|
||||
public class SendRequest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// We use the WalletAppKit that handles all the boilerplate for us. Have a look at the Kit.java example for more details.
|
||||
NetworkParameters params = TestNet3Params.get();
|
||||
WalletAppKit kit = new WalletAppKit(params, new File("."), "sendrequest-example");
|
||||
kit.startAsync();
|
||||
kit.awaitRunning();
|
||||
|
||||
System.out.println("Send money to: " + kit.wallet().currentReceiveAddress().toString());
|
||||
|
||||
// How much coins do we want to send?
|
||||
// The Coin class represents a monetary Bitcoin value.
|
||||
// We use the parseCoin function to simply get a Coin instance from a simple String.
|
||||
Coin value = Coin.parseCoin("0.09");
|
||||
|
||||
// To which address you want to send the coins?
|
||||
// The Address class represents a Bitcoin address.
|
||||
Address to = new Address(params, "mupBAFeT63hXfeeT4rnAUcpKHDkz1n4fdw");
|
||||
|
||||
// There are different ways to create and publish a SendRequest. This is probably the easiest one.
|
||||
// Have a look at the code of the SendRequest class to see what's happening and what other options you have: https://bitcoinj.github.io/javadoc/0.11/com/google/bitcoin/core/Wallet.SendRequest.html
|
||||
//
|
||||
// Please note that this might raise a InsufficientMoneyException if your wallet has not enough coins to spend.
|
||||
// When using the testnet you can use a faucet (like the http://faucet.xeno-genesis.com/) to get testnet coins.
|
||||
// In this example we catch the InsufficientMoneyException and register a BalanceFuture callback that runs once the wallet has enough balance.
|
||||
try {
|
||||
Wallet.SendResult result = kit.wallet().sendCoins(kit.peerGroup(), to, value);
|
||||
System.out.println("coins sent. transaction hash: " + result.tx.getHashAsString());
|
||||
// you can use a block explorer like https://www.biteasy.com/ to inspect the transaction with the printed transaction hash.
|
||||
} catch (InsufficientMoneyException e) {
|
||||
System.out.println("Not enough coins in your wallet. Missing " + e.missing.getValue() + " satoshis are missing (including fees)");
|
||||
System.out.println("Send money to: " + kit.wallet().currentReceiveAddress().toString());
|
||||
|
||||
// Bitcoinj allows you to define a BalanceFuture to execute a callback once your wallet has a certain balance.
|
||||
// Here we wait until the we have enough balance and display a notice.
|
||||
// Bitcoinj is using the ListenableFutures of the Guava library. Have a look here for more information: https://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained
|
||||
ListenableFuture<Coin> balanceFuture = kit.wallet().getBalanceFuture(value, BalanceType.AVAILABLE);
|
||||
FutureCallback<Coin> callback = new FutureCallback<Coin>() {
|
||||
public void onSuccess(Coin balance) {
|
||||
System.out.println("coins arrived and the wallet now has enough balance");
|
||||
}
|
||||
|
||||
public void onFailure(Throwable t) {
|
||||
System.out.println("something went wrong");
|
||||
}
|
||||
};
|
||||
Futures.addCallback(balanceFuture, callback);
|
||||
}
|
||||
|
||||
// shutting down
|
||||
//kit.stopAsync();
|
||||
//kit.awaitTerminated();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue