public class Wallet extends Object implements Serializable, BlockChainListener, PeerFilterProvider
A Wallet stores keys and a record of transactions that send and receive value from those keys. Using these, it is able to create new transactions that spend the recorded transactions, and this is the fundamental operation of the Bitcoin protocol.
To learn more about this class, read working with the wallet.
To fill up a Wallet with transactions, you need to use it in combination with a BlockChain
and various
other objects, see the Getting started tutorial
on the website to learn more about how to set everything up.
Wallets can be serialized using either Java serialization - this is not compatible across versions of bitcoinj,
or protocol buffer serialization. You need to save the wallet whenever it changes, there is an auto-save feature
that simplifies this for you although you're still responsible for manually triggering a save when your app is about
to quit because the auto-save feature waits a moment before actually committing to disk to avoid IO thrashing when
the wallet is changing very fast (eg due to a block chain sync). See
autosaveToFile(java.io.File, long, java.util.concurrent.TimeUnit, com.google.bitcoin.wallet.WalletFiles.Listener)
for more information about this.
Modifier and Type | Class and Description |
---|---|
static class |
Wallet.BalanceType
It's possible to calculate a wallets balance from multiple points of view.
|
static class |
Wallet.SendRequest
A SendRequest gives the wallet information about precisely how to send money to a recipient or set of recipients.
|
static class |
Wallet.SendResult
A SendResult is returned to you as part of sending coins to a recipient.
|
Modifier and Type | Field and Description |
---|---|
protected ReentrantLock |
lock |
Constructor and Description |
---|
Wallet(NetworkParameters params)
Creates a new, empty wallet with no keys and no transactions.
|
Wallet(NetworkParameters params,
KeyCrypter keyCrypter)
Create a wallet with a keyCrypter to use in encrypting and decrypting keys.
|
Modifier and Type | Method and Description |
---|---|
void |
addEventListener(WalletEventListener listener)
Adds an event listener object.
|
void |
addEventListener(WalletEventListener listener,
Executor executor)
Adds an event listener object.
|
void |
addExtension(WalletExtension extension)
By providing an object implementing the
WalletExtension interface, you can save and load arbitrary
additional data that will be stored with the wallet. |
boolean |
addKey(ECKey key)
Adds the given ECKey to the wallet.
|
int |
addKeys(List<ECKey> keys)
Adds the given keys to the wallet.
|
ECKey |
addNewEncryptedKey(CharSequence password)
Convenience wrapper around
addNewEncryptedKey(com.google.bitcoin.crypto.KeyCrypter,
org.spongycastle.crypto.params.KeyParameter) which just derives the key afresh and uses the pre-set
keycrypter. |
ECKey |
addNewEncryptedKey(KeyCrypter keyCrypter,
org.spongycastle.crypto.params.KeyParameter aesKey)
Create a new, random encrypted ECKey and add it to the wallet.
|
WalletExtension |
addOrGetExistingExtension(WalletExtension extension)
Atomically adds extension or returns an existing extension if there is one with the same id alreadypresent.
|
void |
addOrUpdateExtension(WalletExtension extension)
Either adds extension as a new extension or replaces the existing extension if one already exists with the same
id.
|
void |
addWalletTransaction(WalletTransaction wtx)
Adds a transaction that has been associated with a particular wallet pool.
|
boolean |
addWatchedAddress(Address address)
Same as
addWatchedAddress(Address, long) with the current time as the creation time. |
boolean |
addWatchedAddress(Address address,
long creationTime)
Adds the given address to the wallet to be watched.
|
int |
addWatchedAddresses(List<Address> addresses,
long creationTime)
Adds the given address to the wallet to be watched.
|
int |
addWatchedScripts(List<Script> scripts)
Adds the given output scripts to the wallet to be watched.
|
void |
allowSpendingUnconfirmedTransactions()
Convenience wrapper for setCoinSelector(Wallet.AllowUnconfirmedCoinSelector.get()).
|
WalletFiles |
autosaveToFile(File f,
long delayTime,
TimeUnit timeUnit,
WalletFiles.Listener eventListener)
Sets up the wallet to auto-save itself to the given file, using temp files with atomic renames to ensure
consistency.
|
LinkedList<TransactionOutput> |
calculateAllSpendCandidates(boolean excludeImmatureCoinbases)
Returns a list of all possible outputs we could possibly spend, potentially even including immature coinbases
(which the protocol may forbid us from spending).
|
boolean |
checkAESKey(org.spongycastle.crypto.params.KeyParameter aesKey)
Check whether the AES key can decrypt the first encrypted key in the wallet.
|
boolean |
checkPassword(CharSequence password)
Check whether the password can decrypt the first key in the wallet.
|
void |
cleanup()
Clean up the wallet.
|
void |
clearTransactions(int fromHeight)
Deletes transactions which appeared above the given block height from the wallet, but does not touch the keys.
|
void |
commitTx(Transaction tx)
Updates the wallet with the given transaction: puts it into the pending pool, sets the spent flags and runs
the onCoinsSent/onCoinsReceived event listener.
|
void |
completeTx(Wallet.SendRequest req)
Given a spend request containing an incomplete transaction, makes it valid by adding outputs and signed inputs
according to the instructions in the request.
|
Transaction |
createSend(Address address,
BigInteger nanocoins)
Statelessly creates a transaction that sends the given value to address.
|
void |
decrypt(org.spongycastle.crypto.params.KeyParameter aesKey)
Decrypt the wallet with the wallets keyCrypter and AES key.
|
boolean |
doesAcceptRiskyTransactions()
See
setAcceptRiskyTransactions(boolean) for an explanation of this property. |
org.spongycastle.crypto.params.KeyParameter |
encrypt(CharSequence password)
Convenience wrapper around
encrypt(com.google.bitcoin.crypto.KeyCrypter,
org.spongycastle.crypto.params.KeyParameter) which uses the default Scrypt key derivation algorithm and
parameters, derives a key from the given password and returns the created key. |
void |
encrypt(KeyCrypter keyCrypter,
org.spongycastle.crypto.params.KeyParameter aesKey)
Encrypt the wallet using the KeyCrypter and the AES key.
|
ECKey |
findKeyFromPubHash(byte[] pubkeyHash)
Locates a keypair from the keychain given the hash of the public key.
|
ECKey |
findKeyFromPubKey(byte[] pubkey)
Locates a keypair from the keychain given the raw public key bytes.
|
BigInteger |
getBalance()
Returns the AVAILABLE balance of this wallet.
|
BigInteger |
getBalance(CoinSelector selector)
Returns the balance that would be considered spendable by the given coin selector.
|
BigInteger |
getBalance(Wallet.BalanceType balanceType)
Returns the balance of this wallet as calculated by the provided balanceType.
|
com.google.common.util.concurrent.ListenableFuture<BigInteger> |
getBalanceFuture(BigInteger value,
Wallet.BalanceType type)
Returns a future that will complete when the balance of the given type has becom equal or larger to the given
value.
|
BloomFilter |
getBloomFilter(double falsePositiveRate)
Gets a bloom filter that contains all of the public keys from this wallet, and which will provide the given
false-positive rate.
|
BloomFilter |
getBloomFilter(int size,
double falsePositiveRate,
long nTweak)
Gets a bloom filter that contains all of the public keys from this wallet,
and which will provide the given false-positive rate if it has size elements.
|
int |
getBloomFilterElementCount()
Gets the number of elements that will be added to a bloom filter returned by
PeerFilterProvider.getBloomFilter(int, double, long) |
Address |
getChangeAddress()
Returns the address used for change outputs.
|
CoinSelector |
getCoinSelector()
Returns the
CoinSelector object which controls which outputs can be spent by this wallet. |
String |
getDescription()
Get the description of the wallet.
|
long |
getEarliestKeyCreationTime()
Returns the earliest creation time of keys or watched scripts in this wallet, in seconds since the epoch, ie the min
of
ECKey.getCreationTimeSeconds() . |
Protos.Wallet.EncryptionType |
getEncryptionType()
Get the type of encryption used for this wallet.
|
Map<String,WalletExtension> |
getExtensions()
Returns a snapshot of all registered extension objects.
|
int |
getKeychainSize()
Returns the number of keys in the keychain.
|
KeyCrypter |
getKeyCrypter()
Get the wallet's KeyCrypter.
|
Date |
getKeyRotationTime()
Returns a UNIX time since the epoch in seconds, or zero if unconfigured.
|
List<ECKey> |
getKeys()
Returns a snapshot of the keychain.
|
Sha256Hash |
getLastBlockSeenHash()
Returns the hash of the last seen best-chain block, or null if the wallet is too old to store this data.
|
int |
getLastBlockSeenHeight()
Returns the height of the last seen best-chain block.
|
Date |
getLastBlockSeenTime()
Returns a
Date representing the time extracted from the last best seen block header. |
long |
getLastBlockSeenTimeSecs()
Returns the UNIX time in seconds since the epoch extracted from the last best seen block header.
|
NetworkParameters |
getNetworkParameters() |
NetworkParameters |
getParams()
Returns the parameters this wallet was created with.
|
Collection<Transaction> |
getPendingTransactions()
Returns an immutable view of the transactions currently waiting for network confirmations.
|
List<Transaction> |
getRecentTransactions(int numTransactions,
boolean includeDead)
Returns an list of N transactions, ordered by increasing age.
|
RiskAnalysis.Analyzer |
getRiskAnalyzer()
Gets the current
RiskAnalysis implementation. |
Transaction |
getTransaction(Sha256Hash hash)
Returns a transaction object given its hash, if it exists in this wallet, or null otherwise.
|
Set<Transaction> |
getTransactions(boolean includeDead)
Returns a set of all transactions in the wallet.
|
List<Transaction> |
getTransactionsByTime()
Returns all non-dead, active transactions ordered by recency.
|
int |
getVersion()
Get the version of the Wallet.
|
Iterable<WalletTransaction> |
getWalletTransactions()
Returns a set of all WalletTransactions in the wallet.
|
BigInteger |
getWatchedBalance()
Returns the available balance, including any unspent balance at watched addresses
|
BigInteger |
getWatchedBalance(CoinSelector selector)
Returns the balance that would be considered spendable by the given coin selector, including
any unspent balance at watched addresses.
|
LinkedList<TransactionOutput> |
getWatchedOutputs(boolean excludeImmatureCoinbases)
Returns all the outputs that match addresses or scripts added via
addWatchedAddress(Address) or
addWatchedScripts(java.util.List) . |
List<Script> |
getWatchedScripts()
Returns a snapshot of the watched scripts.
|
boolean |
hasKey(ECKey key)
Returns true if the given key is in the wallet, false otherwise.
|
boolean |
isAddressWatched(Address address)
Return true if we are watching this address.
|
boolean |
isConsistent() |
boolean |
isEncrypted()
Returns true if the wallet is encrypted using any scheme, false if not.
|
boolean |
isKeyRotating(ECKey key)
Returns whether the keys creation time is before the key rotation time, if one was set.
|
boolean |
isPendingTransactionRelevant(Transaction tx)
This method is used by a
Peer to find out if a transaction that has been announced is interesting,
that is, whether we should bother downloading its dependencies and exploring the transaction to decide how
risky it is. |
boolean |
isPubKeyHashMine(byte[] pubkeyHash)
Returns true if this wallet contains a public key which hashes to the given hash.
|
boolean |
isPubKeyMine(byte[] pubkey)
Returns true if this wallet contains a keypair with the given public key.
|
boolean |
isRequiringUpdateAllBloomFilter()
If we are watching any scripts, the bloom filter must update on peers whenever an output is
identified.
|
boolean |
isTransactionRelevant(Transaction tx)
Returns true if the given transaction sends coins to any of our keys, or has inputs spending any of our outputs,
and if includeDoubleSpending is true, also returns true if tx has inputs that are spending outputs which are
not ours but which are spent by pending transactions.
|
boolean |
isTransactionRisky(Transaction tx,
List<Transaction> dependencies)
Given a transaction and an optional list of dependencies (recursive/flattened), returns true if the given
transaction would be rejected by the analyzer, or false otherwise.
|
boolean |
isWatchedScript(Script script)
Returns true if this wallet is watching transactions for outputs with the script.
|
static Wallet |
loadFromFile(File f)
Returns a wallet deserialized from the given file.
|
static Wallet |
loadFromFileStream(InputStream stream)
Returns a wallet deserialized from the given input stream.
|
boolean |
maybeCommitTx(Transaction tx)
Calls
commitTx(com.google.bitcoin.core.Transaction) if tx is not already in the pending pool |
void |
notifyNewBestBlock(StoredBlock block)
Called by the
BlockChain when a new block on the best chain is seen, AFTER relevant wallet
transactions are extracted and sent to us UNLESS the new block caused a re-org, in which case this will
not be called (the reorganize(StoredBlock, java.util.List, java.util.List) method will
call this one in that case). |
void |
notifyTransactionIsInBlock(Sha256Hash txHash,
StoredBlock block,
AbstractBlockChain.NewBlockType blockType,
int relativityOffset)
Called by the
BlockChain when we receive a new filtered block that contains a transactions previously
received by a call to @{link receivePending}. |
void |
receiveFromBlock(Transaction tx,
StoredBlock block,
AbstractBlockChain.NewBlockType blockType,
int relativityOffset)
Called by the
BlockChain when we receive a new block that sends coins to one of our addresses or
spends coins from one of our addresses (note that a single transaction can do both). |
void |
receivePending(Transaction tx,
List<Transaction> dependencies)
Called when we have found a transaction (via network broadcast or otherwise) that is relevant to this wallet
and want to record it.
|
void |
receivePending(Transaction tx,
List<Transaction> dependencies,
boolean overrideIsRelevant)
Called when we have found a transaction (via network broadcast or otherwise) that is relevant to this wallet
and want to record it.
|
boolean |
removeEventListener(WalletEventListener listener)
Removes the given event listener object.
|
boolean |
removeKey(ECKey key)
Removes the given key from the keychain.
|
void |
reorganize(StoredBlock splitPoint,
List<StoredBlock> oldBlocks,
List<StoredBlock> newBlocks)
Don't call this directly.
|
void |
saveToFile(File f)
Uses protobuf serialization to save the wallet to the given file.
|
void |
saveToFile(File temp,
File destFile)
Saves the wallet first to the given temp file, then renames to the dest file.
|
void |
saveToFileStream(OutputStream f)
Uses protobuf serialization to save the wallet to the given file stream.
|
Transaction |
sendCoins(Peer peer,
Wallet.SendRequest request)
Sends coins to the given address, via the given
Peer . |
Wallet.SendResult |
sendCoins(TransactionBroadcaster broadcaster,
Address to,
BigInteger value)
Sends coins to the given address, via the given
PeerGroup . |
Wallet.SendResult |
sendCoins(TransactionBroadcaster broadcaster,
Wallet.SendRequest request)
Sends coins according to the given request, via the given
TransactionBroadcaster . |
Wallet.SendResult |
sendCoins(Wallet.SendRequest request)
Satisfies the given
Wallet.SendRequest using the default transaction broadcaster configured either via
PeerGroup.addWallet(Wallet) or directly with setTransactionBroadcaster(TransactionBroadcaster) . |
Transaction |
sendCoinsOffline(Wallet.SendRequest request)
Sends coins to the given address but does not broadcast the resulting pending transaction.
|
void |
setAcceptRiskyTransactions(boolean acceptRiskyTransactions)
Whether or not the wallet will ignore received pending transactions that fail the selected
RiskAnalysis . |
void |
setCoinSelector(CoinSelector coinSelector)
A coin selector is responsible for choosing which outputs to spend when creating transactions.
|
void |
setDescription(String description)
Set the description of the wallet.
|
void |
setKeyCrypter(KeyCrypter keyCrypter)
Sets the wallet's KeyCrypter.
|
void |
setKeyRotationEnabled(boolean enabled)
Toggles key rotation on and off.
|
void |
setKeyRotationTime(Date time)
When a key rotation time is set, and money controlled by keys created before the given timestamp T will be
automatically respent to any key that was created after T.
|
void |
setKeyRotationTime(long unixTimeSeconds)
When a key rotation time is set, and money controlled by keys created before the given timestamp T will be
automatically respent to any key that was created after T.
|
void |
setLastBlockSeenHash(Sha256Hash lastBlockSeenHash) |
void |
setLastBlockSeenHeight(int lastBlockSeenHeight) |
void |
setLastBlockSeenTimeSecs(long timeSecs) |
void |
setRiskAnalyzer(RiskAnalysis.Analyzer analyzer)
Sets the
RiskAnalysis implementation to use for deciding whether received pending transactions are risky
or not. |
void |
setTransactionBroadcaster(TransactionBroadcaster broadcaster)
Specifies that the given
TransactionBroadcaster , typically a PeerGroup , should be used for
sending transactions to the Bitcoin network by default. |
void |
setVersion(int version)
Set the version number of the wallet.
|
void |
shutdownAutosaveAndWait()
Disables auto-saving, after it had been enabled with
autosaveToFile(java.io.File, long, java.util.concurrent.TimeUnit, com.google.bitcoin.wallet.WalletFiles.Listener)
before. |
String |
toString() |
String |
toString(boolean includePrivateKeys,
boolean includeTransactions,
boolean includeExtensions,
AbstractBlockChain chain)
Formats the wallet as a human readable piece of text.
|
protected final ReentrantLock lock
public Wallet(NetworkParameters params)
public Wallet(NetworkParameters params, KeyCrypter keyCrypter)
public NetworkParameters getNetworkParameters()
public List<Script> getWatchedScripts()
public boolean removeKey(ECKey key)
public int getKeychainSize()
public void saveToFile(File temp, File destFile) throws IOException
IOException
public void saveToFile(File f) throws IOException
WalletProtobufSerializer
. Writes out first to a temporary file in the same directory and then renames
once written.IOException
public void setAcceptRiskyTransactions(boolean acceptRiskyTransactions)
Whether or not the wallet will ignore received pending transactions that fail the selected
RiskAnalysis
. By default, if a transaction is considered risky then it won't enter the wallet
and won't trigger any event listeners. If you set this property to true, then all transactions will
be allowed in regardless of risk. Currently, the DefaultRiskAnalysis
checks for non-finality of
transactions. You should not encounter these outside of special protocols.
Note that this property is not serialized. You have to set it each time a Wallet object is constructed, even if it's loaded from a protocol buffer.
public boolean doesAcceptRiskyTransactions()
setAcceptRiskyTransactions(boolean)
for an explanation of this property.public void setRiskAnalyzer(RiskAnalysis.Analyzer analyzer)
RiskAnalysis
implementation to use for deciding whether received pending transactions are risky
or not. If the analyzer says a transaction is risky, by default it will be dropped. You can customize this
behaviour with setAcceptRiskyTransactions(boolean)
.public RiskAnalysis.Analyzer getRiskAnalyzer()
RiskAnalysis
implementation. The default is DefaultRiskAnalysis
.public WalletFiles autosaveToFile(File f, long delayTime, TimeUnit timeUnit, @Nullable WalletFiles.Listener eventListener)
Sets up the wallet to auto-save itself to the given file, using temp files with atomic renames to ensure consistency. After connecting to a file, you no longer need to save the wallet manually, it will do it whenever necessary. Protocol buffer serialization will be used.
If delayTime is set, a background thread will be created and the wallet will only be saved to disk every so many time units. If no changes have occurred for the given time period, nothing will be written. In this way disk IO can be rate limited. It's a good idea to set this as otherwise the wallet can change very frequently, eg if there are a lot of transactions in it or during block sync, and there will be a lot of redundant writes. Note that when a new key is added, that always results in an immediate save regardless of delayTime. You should still save the wallet manually when your program is about to shut down as the JVM will not wait for the background thread.
An event listener can be provided. If a delay >0 was specified, it will be called on a background thread with the wallet locked when an auto-save occurs. If delay is zero or you do something that always triggers an immediate save, like adding a key, the event listener will be invoked on the calling threads.
f
- The destination file to save to.delayTime
- How many time units to wait until saving the wallet on a background thread.timeUnit
- the unit of measurement for delayTime.eventListener
- callback to be informed when the auto-save thread does things, or nullpublic void shutdownAutosaveAndWait()
Disables auto-saving, after it had been enabled with
autosaveToFile(java.io.File, long, java.util.concurrent.TimeUnit, com.google.bitcoin.wallet.WalletFiles.Listener)
before. This method blocks until finished.
public void saveToFileStream(OutputStream f) throws IOException
WalletProtobufSerializer
.IOException
public NetworkParameters getParams()
public static Wallet loadFromFile(File f) throws UnreadableWalletException
UnreadableWalletException
public boolean isConsistent()
public static Wallet loadFromFileStream(InputStream stream) throws UnreadableWalletException
UnreadableWalletException
public void notifyTransactionIsInBlock(Sha256Hash txHash, StoredBlock block, AbstractBlockChain.NewBlockType blockType, int relativityOffset) throws VerificationException
BlockChain
when we receive a new filtered block that contains a transactions previously
received by a call to @{link receivePending}.This is necessary for the internal book-keeping Wallet does. When a transaction is received that sends us coins it is added to a pool so we can use it later to create spends. When a transaction is received that consumes outputs they are marked as spent so they won't be used in future.
A transaction that spends our own coins can be received either because a spend we created was accepted by the network and thus made it into a block, or because our keys are being shared between multiple instances and some other node spent the coins instead. We still have to know about that to avoid accidentally trying to double spend.
A transaction may be received multiple times if is included into blocks in parallel chains. The blockType parameter describes whether the containing block is on the main/best chain or whether it's on a presently inactive side chain. We must still record these transactions and the blocks they appear in because a future block might change which chain is best causing a reorganize. A re-org can totally change our balance!
notifyTransactionIsInBlock
in interface BlockChainListener
VerificationException
public void receivePending(Transaction tx, @Nullable List<Transaction> dependencies, boolean overrideIsRelevant) throws VerificationException
Called when we have found a transaction (via network broadcast or otherwise) that is relevant to this wallet and want to record it. Note that we cannot verify these transactions at all, they may spend fictional coins or be otherwise invalid. They are useful to inform the user about coins they can expect to receive soon, and if you trust the sender of the transaction you can choose to assume they are in fact valid and will not be double spent as an optimization.
This is the same as receivePending(Transaction, java.util.List)
but allows you to override the
isPendingTransactionRelevant(Transaction)
sanity-check to keep track of transactions that are not
spendable or spend our coins. This can be useful when you want to keep track of transaction confidence on
arbitrary transactions. Note that transactions added in this way will still be relayed to peers and appear in
transaction lists like any other pending transaction (even when not relevant).
VerificationException
public boolean isTransactionRisky(Transaction tx, @Nullable List<Transaction> dependencies)
doesAcceptRiskyTransactions()
. Risky transactions yield a logged warning. If you
want to know the reason why a transaction is risky, create an instance of the RiskAnalysis
yourself
using the factory returned by getRiskAnalyzer()
and use it directly.public void receivePending(Transaction tx, @Nullable List<Transaction> dependencies) throws VerificationException
Called when we have found a transaction (via network broadcast or otherwise) that is relevant to this wallet and want to record it. Note that we cannot verify these transactions at all, they may spend fictional coins or be otherwise invalid. They are useful to inform the user about coins they can expect to receive soon, and if you trust the sender of the transaction you can choose to assume they are in fact valid and will not be double spent as an optimization.
Before this method is called, isPendingTransactionRelevant(Transaction)
should have been
called to decide whether the wallet cares about the transaction - if it does, then this method expects the
transaction and any dependencies it has which are still in the memory pool.
VerificationException
public boolean isPendingTransactionRelevant(Transaction tx) throws ScriptException
Peer
to find out if a transaction that has been announced is interesting,
that is, whether we should bother downloading its dependencies and exploring the transaction to decide how
risky it is. If this method returns true then receivePending(Transaction, java.util.List)
will soon be called with the transactions dependencies as well.ScriptException
public boolean isTransactionRelevant(Transaction tx) throws ScriptException
Returns true if the given transaction sends coins to any of our keys, or has inputs spending any of our outputs, and if includeDoubleSpending is true, also returns true if tx has inputs that are spending outputs which are not ours but which are spent by pending transactions.
Note that if the tx has inputs containing one of our keys, but the connected transaction is not in the wallet, it will not be considered relevant.
isTransactionRelevant
in interface BlockChainListener
ScriptException
public void receiveFromBlock(Transaction tx, StoredBlock block, AbstractBlockChain.NewBlockType blockType, int relativityOffset) throws VerificationException
BlockChain
when we receive a new block that sends coins to one of our addresses or
spends coins from one of our addresses (note that a single transaction can do both).This is necessary for the internal book-keeping Wallet does. When a transaction is received that sends us coins it is added to a pool so we can use it later to create spends. When a transaction is received that consumes outputs they are marked as spent so they won't be used in future.
A transaction that spends our own coins can be received either because a spend we created was accepted by the network and thus made it into a block, or because our keys are being shared between multiple instances and some other node spent the coins instead. We still have to know about that to avoid accidentally trying to double spend.
A transaction may be received multiple times if is included into blocks in parallel chains. The blockType parameter describes whether the containing block is on the main/best chain or whether it's on a presently inactive side chain. We must still record these transactions and the blocks they appear in because a future block might change which chain is best causing a reorganize. A re-org can totally change our balance!
receiveFromBlock
in interface BlockChainListener
VerificationException
public void notifyNewBestBlock(StoredBlock block) throws VerificationException
Called by the BlockChain
when a new block on the best chain is seen, AFTER relevant wallet
transactions are extracted and sent to us UNLESS the new block caused a re-org, in which case this will
not be called (the reorganize(StoredBlock, java.util.List, java.util.List)
method will
call this one in that case).
Used to update confidence data in each transaction and last seen block hash. Triggers auto saving. Invokes the onWalletChanged event listener if there were any affected transactions.
notifyNewBestBlock
in interface BlockChainListener
VerificationException
public void addEventListener(WalletEventListener listener)
public void addEventListener(WalletEventListener listener, Executor executor)
public boolean removeEventListener(WalletEventListener listener)
public boolean maybeCommitTx(Transaction tx) throws VerificationException
commitTx(com.google.bitcoin.core.Transaction)
if tx is not already in the pending poolVerificationException
public void commitTx(Transaction tx) throws VerificationException
Updates the wallet with the given transaction: puts it into the pending pool, sets the spent flags and runs the onCoinsSent/onCoinsReceived event listener. Used in two situations:
Triggers an auto save.
VerificationException
public Set<Transaction> getTransactions(boolean includeDead)
includeDead
- If true, transactions that were overridden by a double spend are included.public Iterable<WalletTransaction> getWalletTransactions()
public void addWalletTransaction(WalletTransaction wtx)
WalletProtobufSerializer
class. It isn't normally useful for
applications. It does not trigger auto saving.public List<Transaction> getTransactionsByTime()
public List<Transaction> getRecentTransactions(int numTransactions, boolean includeDead)
Note: the current implementation is O(num transactions in wallet). Regardless of how many transactions are requested, the cost is always the same. In future, requesting smaller numbers of transactions may be faster depending on how the wallet is implemented (eg if backed by a database).
@Nullable public Transaction getTransaction(Sha256Hash hash)
public void clearTransactions(int fromHeight)
public void cleanup()
public Transaction createSend(Address address, BigInteger nanocoins) throws InsufficientMoneyException
Statelessly creates a transaction that sends the given value to address. The change is sent to
getChangeAddress()
, so you must have added at least one key.
If you just want to send money quickly, you probably want
sendCoins(TransactionBroadcaster, Address, java.math.BigInteger)
instead. That will create the sending
transaction, commit to the wallet and broadcast it to the network all in one go. This method is lower level
and lets you see the proposed transaction before anything is done with it.
This is a helper method that is equivalent to using Wallet.SendRequest.to(Address, java.math.BigInteger)
followed by completeTx(Wallet.SendRequest)
and returning the requests transaction object.
Note that this means a fee may be automatically added if required, if you want more control over the process,
just do those two steps yourself.
IMPORTANT: This method does NOT update the wallet. If you call createSend again you may get two transactions
that spend the same coins. You have to call commitTx(Transaction)
on the created transaction to
prevent this, but that should only occur once the transaction has been accepted by the network. This implies
you cannot have more than one outstanding sending tx at once.
You MUST ensure that nanocoins is larger than Transaction.MIN_NONDUST_OUTPUT
or the transaction will
almost certainly be rejected by the network as dust.
address
- The Bitcoin address to send the money to.nanocoins
- How much currency to send, in nanocoins.InsufficientMoneyException
- if the request could not be completed due to not enough balance.public Transaction sendCoinsOffline(Wallet.SendRequest request) throws InsufficientMoneyException
PeerGroup
or Peer
the transaction will be
announced to the network. The given Wallet.SendRequest
is completed first using
completeTx(Wallet.SendRequest)
to make it valid.InsufficientMoneyException
- if the request could not be completed due to not enough balance.public Wallet.SendResult sendCoins(TransactionBroadcaster broadcaster, Address to, BigInteger value) throws InsufficientMoneyException
Sends coins to the given address, via the given PeerGroup
. Change is returned to
getChangeAddress()
. Note that a fee may be automatically added if one may be required for the
transaction to be confirmed.
The returned object provides both the transaction, and a future that can be used to learn when the broadcast is complete. Complete means, if the PeerGroup is limited to only one connection, when it was written out to the socket. Otherwise when the transaction is written out and we heard it back from a different peer.
Note that the sending transaction is committed to the wallet immediately, not when the transaction is successfully broadcast. This means that even if the network hasn't heard about your transaction you won't be able to spend those same coins again.
You MUST ensure that value is smaller than Transaction.MIN_NONDUST_OUTPUT
or the transaction will
almost certainly be rejected by the network as dust.
broadcaster
- a TransactionBroadcaster
to use to send the transactions out.to
- Which address to send coins to.value
- How much value to send. You can use Utils.toNanoCoins() to calculate this.InsufficientMoneyException
- if the request could not be completed due to not enough balance.public Wallet.SendResult sendCoins(TransactionBroadcaster broadcaster, Wallet.SendRequest request) throws InsufficientMoneyException
Sends coins according to the given request, via the given TransactionBroadcaster
.
The returned object provides both the transaction, and a future that can be used to learn when the broadcast is complete. Complete means, if the PeerGroup is limited to only one connection, when it was written out to the socket. Otherwise when the transaction is written out and we heard it back from a different peer.
Note that the sending transaction is committed to the wallet immediately, not when the transaction is successfully broadcast. This means that even if the network hasn't heard about your transaction you won't be able to spend those same coins again.
broadcaster
- the target to use for broadcast.request
- the SendRequest that describes what to do, get one using static methods on SendRequest itself.InsufficientMoneyException
- if the request could not be completed due to not enough balance.public Wallet.SendResult sendCoins(Wallet.SendRequest request) throws InsufficientMoneyException
Wallet.SendRequest
using the default transaction broadcaster configured either via
PeerGroup.addWallet(Wallet)
or directly with setTransactionBroadcaster(TransactionBroadcaster)
.request
- the SendRequest that describes what to do, get one using static methods on SendRequest itself.IllegalStateException
- if no transaction broadcaster has been configured.InsufficientMoneyException
- if the request could not be completed due to not enough balance.public Transaction sendCoins(Peer peer, Wallet.SendRequest request) throws InsufficientMoneyException
Peer
. Change is returned to getChangeAddress()
.
If an exception is thrown by PeerSocketHandler.sendMessage(Message)
the transaction is still committed, so the
pending transaction must be broadcast by you at some other time. Note that a fee may be automatically added
if one may be required for the transaction to be confirmed.Transaction
that was created or null if there was insufficient balance to send the coins.InsufficientMoneyException
- if the request could not be completed due to not enough balance.public void completeTx(Wallet.SendRequest req) throws InsufficientMoneyException
req
- a SendRequest that contains the incomplete transaction and details for how to make it valid.InsufficientMoneyException
- if the request could not be completed due to not enough balance.IllegalArgumentException
- if you try and complete the same SendRequest twice, or if the given send request
cannot be completed without violating the protocol rules.public LinkedList<TransactionOutput> calculateAllSpendCandidates(boolean excludeImmatureCoinbases)
public LinkedList<TransactionOutput> getWatchedOutputs(boolean excludeImmatureCoinbases)
addWatchedAddress(Address)
or
addWatchedScripts(java.util.List)
.excludeImmatureCoinbases
- Whether to ignore outputs that are unspendable due to being immature.public Address getChangeAddress()
public boolean addKey(ECKey key)
autosaveToFile(java.io.File, long, java.util.concurrent.TimeUnit, com.google.bitcoin.wallet.WalletFiles.Listener)
has been called, triggers an auto save bypassing the normal coalescing delay and event handlers.
If the key already exists in the wallet, does nothing and returns false.public int addKeys(List<ECKey> keys)
autosaveToFile(java.io.File, long, java.util.concurrent.TimeUnit, com.google.bitcoin.wallet.WalletFiles.Listener)
has been called, triggers an auto save bypassing the normal coalescing delay and event handlers.
Returns the number of keys added, after duplicates are ignored. The onKeyAdded event will be called for each key
in the list that was not already present.public boolean isAddressWatched(Address address)
public boolean addWatchedAddress(Address address)
addWatchedAddress(Address, long)
with the current time as the creation time.public boolean addWatchedAddress(Address address, long creationTime)
getWatchedOutputs(boolean)
.creationTime
- creation time in seconds since the epoch, for scanning the blockchainpublic int addWatchedAddresses(List<Address> addresses, long creationTime)
getWatchedOutputs(boolean)
.public int addWatchedScripts(List<Script> scripts)
getWatchedOutputs(boolean)
.@Nullable public ECKey findKeyFromPubHash(byte[] pubkeyHash)
public boolean hasKey(ECKey key)
public boolean isPubKeyHashMine(byte[] pubkeyHash)
public boolean isWatchedScript(Script script)
@Nullable public ECKey findKeyFromPubKey(byte[] pubkey)
public boolean isPubKeyMine(byte[] pubkey)
public BigInteger getBalance()
Wallet.BalanceType.AVAILABLE
for details on what this
means.public BigInteger getBalance(Wallet.BalanceType balanceType)
public BigInteger getBalance(CoinSelector selector)
public BigInteger getWatchedBalance()
public BigInteger getWatchedBalance(CoinSelector selector)
public String toString(boolean includePrivateKeys, boolean includeTransactions, boolean includeExtensions, @Nullable AbstractBlockChain chain)
includePrivateKeys
- Whether raw private key data should be included.includeTransactions
- Whether to print transaction data.includeExtensions
- Whether to print extension data.chain
- If set, will be used to estimate lock times for block timelocked transactions.public void reorganize(StoredBlock splitPoint, List<StoredBlock> oldBlocks, List<StoredBlock> newBlocks) throws VerificationException
Don't call this directly. It's not intended for API users.
Called by the BlockChain
when the best chain (representing total work done) has changed. This can
cause the number of confirmations of a transaction to go higher, lower, drop to zero and can even result in
a transaction going dead (will never confirm) due to a double spend.
The oldBlocks/newBlocks lists are ordered height-wise from top first to bottom last.
reorganize
in interface BlockChainListener
VerificationException
public Collection<Transaction> getPendingTransactions()
public long getEarliestKeyCreationTime()
ECKey.getCreationTimeSeconds()
. This can return zero if at least one key does
not have that data (was created before key timestamping was implemented).
This method is most often used in conjunction with PeerGroup.setFastCatchupTimeSecs(long)
in order to
optimize chain download for new users of wallet apps. Backwards compatibility notice: if you get zero from this
method, you can instead use the time of the first release of your software, as it's guaranteed no users will
have wallets pre-dating this time.
If there are no keys in the wallet, the current time is returned.
getEarliestKeyCreationTime
in interface PeerFilterProvider
@Nullable public Sha256Hash getLastBlockSeenHash()
public void setLastBlockSeenHash(@Nullable Sha256Hash lastBlockSeenHash)
public void setLastBlockSeenHeight(int lastBlockSeenHeight)
public void setLastBlockSeenTimeSecs(long timeSecs)
public long getLastBlockSeenTimeSecs()
@Nullable public Date getLastBlockSeenTime()
Date
representing the time extracted from the last best seen block header. This timestamp
is not the local time at which the block was first observed by this application but rather what the block
(i.e. miner) self declares. It is allowed to have some significant drift from the real time at which the block
was found, although most miners do use accurate times. If this wallet is old and does not have a recorded
time then this method returns null.public int getLastBlockSeenHeight()
public org.spongycastle.crypto.params.KeyParameter encrypt(CharSequence password)
encrypt(com.google.bitcoin.crypto.KeyCrypter,
org.spongycastle.crypto.params.KeyParameter)
which uses the default Scrypt key derivation algorithm and
parameters, derives a key from the given password and returns the created key.public void encrypt(KeyCrypter keyCrypter, org.spongycastle.crypto.params.KeyParameter aesKey)
KeyCrypterScrypt
.keyCrypter
- The KeyCrypter that specifies how to encrypt/ decrypt a keyaesKey
- AES key to use (normally created using KeyCrypter#deriveKey and cached as it is time consuming to create from a password)KeyCrypterException
- Thrown if the wallet encryption fails. If so, the wallet state is unchanged.public void decrypt(org.spongycastle.crypto.params.KeyParameter aesKey)
aesKey
- AES key to use (normally created using KeyCrypter#deriveKey and cached as it is time consuming to create from a password)KeyCrypterException
- Thrown if the wallet decryption fails. If so, the wallet state is unchanged.public ECKey addNewEncryptedKey(KeyCrypter keyCrypter, org.spongycastle.crypto.params.KeyParameter aesKey)
keyCrypter
- The keyCrypter to use in encrypting the new keyaesKey
- The AES key to use to encrypt the new keypublic ECKey addNewEncryptedKey(CharSequence password)
Convenience wrapper around addNewEncryptedKey(com.google.bitcoin.crypto.KeyCrypter,
org.spongycastle.crypto.params.KeyParameter)
which just derives the key afresh and uses the pre-set
keycrypter. The wallet must have been encrypted using one of the encrypt methods previously.
Note that key derivation is deliberately very slow! So if you plan to add multiple keys, it can be
faster to use the other method instead and re-use the KeyParameter
object instead.
public boolean checkPassword(CharSequence password)
public boolean checkAESKey(org.spongycastle.crypto.params.KeyParameter aesKey)
public KeyCrypter getKeyCrypter()
public void setKeyCrypter(KeyCrypter keyCrypter)
getEncryptionType()
and
isEncrypted()
will not return the correct results.public Protos.Wallet.EncryptionType getEncryptionType()
public boolean isEncrypted()
public int getVersion()
public void setVersion(int version)
getVersion()
.public void setDescription(String description)
public String getDescription()
Wallet#setDescription(String))
public int getBloomFilterElementCount()
PeerFilterProvider
PeerFilterProvider.getBloomFilter(int, double, long)
getBloomFilterElementCount
in interface PeerFilterProvider
public boolean isRequiringUpdateAllBloomFilter()
isRequiringUpdateAllBloomFilter
in interface PeerFilterProvider
public BloomFilter getBloomFilter(double falsePositiveRate)
BloomFilter
for a brief explanation of anonymity when using filters.public BloomFilter getBloomFilter(int size, double falsePositiveRate, long nTweak)
BloomFilter(int, double)
for a brief explanation of anonymity when using bloom filters.getBloomFilter
in interface PeerFilterProvider
public CoinSelector getCoinSelector()
CoinSelector
object which controls which outputs can be spent by this wallet.public void setCoinSelector(@Nonnull CoinSelector coinSelector)
Wallet.SendRequest.coinSelector
.public void allowSpendingUnconfirmedTransactions()
public com.google.common.util.concurrent.ListenableFuture<BigInteger> getBalanceFuture(BigInteger value, Wallet.BalanceType type)
Returns a future that will complete when the balance of the given type has becom equal or larger to the given value. If the wallet already has a large enough balance the future is returned in a pre-completed state. Note that this method is not blocking, if you want to actually wait immediately, you have to call .get() on the result.
Also note that by the time the future completes, the wallet may have changed yet again if something else
is going on in parallel, so you should treat the returned balance as advisory and be prepared for sending
money to fail! Finally please be aware that any listeners on the future will run either on the calling thread
if it completes immediately, or eventually on a background thread if the balance is not yet at the right
level. If you do something that means you know the balance should be sufficient to trigger the future,
you can use Threading.waitForUserCode()
to block until the future had a
chance to be updated.
public void addExtension(WalletExtension extension)
WalletExtension
interface, you can save and load arbitrary
additional data that will be stored with the wallet. Each extension is identified by an ID, so attempting to
add the same extension twice (or two different objects that use the same ID) will throw an IllegalStateException.public WalletExtension addOrGetExistingExtension(WalletExtension extension)
public void addOrUpdateExtension(WalletExtension extension)
public Map<String,WalletExtension> getExtensions()
public void setTransactionBroadcaster(@Nullable TransactionBroadcaster broadcaster)
Specifies that the given TransactionBroadcaster
, typically a PeerGroup
, should be used for
sending transactions to the Bitcoin network by default. Some sendCoins methods let you specify a broadcaster
explicitly, in that case, they don't use this broadcaster. If null is specified then the wallet won't attempt
to broadcast transactions itself.
You don't normally need to call this. A PeerGroup
will automatically set itself as the wallets
broadcaster when you use PeerGroup.addWallet(Wallet)
. A wallet can use the broadcaster when you ask
it to send money, but in future also at other times to implement various features that may require asynchronous
re-organisation of the wallet contents on the block chain. For instance, in future the wallet may choose to
optimise itself to reduce fees or improve privacy.
public void setKeyRotationTime(Date time)
public Date getKeyRotationTime()
public void setKeyRotationTime(long unixTimeSeconds)
When a key rotation time is set, and money controlled by keys created before the given timestamp T will be
automatically respent to any key that was created after T. This can be used to recover from a situation where
a set of keys is believed to be compromised. Once the time is set transactions will be created and broadcast
immediately. New coins that come in after calling this method will be automatically respent immediately. The
rotation time is persisted to the wallet. You can stop key rotation by calling this method again with zero
as the argument, or by using setKeyRotationEnabled(boolean)
.
Note that this method won't do anything unless you call setKeyRotationEnabled(boolean)
first.
public void setKeyRotationEnabled(boolean enabled)
public boolean isKeyRotating(ECKey key)
Copyright © 2014. All rights reserved.