I'm trying to get the balance of a specific address in a wallet by using bitcoinj, but I don't know how. Can someone help me? Thanks in advance!!
-
This has been flagged as "Unclear what you’re asking", can somebody explain why? I don’t know enough about bitcoinj to be certain whether it would be useful to the asker’s issue.– Murch ♦Dec 21, 2015 at 13:48
-
this is very clear and usefull question– Pavel NiedobaFeb 21, 2016 at 14:07
2 Answers
I found the solution for this question. I used this class:
/**
* This class implements a {@link org.bitcoinj.wallet.CoinSelector} which attempts to select all outputs
* from a designated address. Outputs are selected in order of highest priority. Note that this means we may
* end up "spending" more priority than would be required to get the transaction we are creating confirmed.
*/
public class AddressBalance implements CoinSelector {
private Address addressToQuery;
public AddressBalance(Address addressToQuery) {
this.addressToQuery = addressToQuery;
}
@Override
public CoinSelection select(Coin biTarget, List<TransactionOutput> candidates) {
long target = biTarget.longValue();
HashSet<TransactionOutput> selected = new HashSet<TransactionOutput>();
// Sort the inputs by age*value so we get the highest "coindays" spent.
// TODO: Consider changing the wallets internal format to track just outputs and keep them ordered.
ArrayList<TransactionOutput> sortedOutputs = new ArrayList<TransactionOutput>(candidates);
// When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
// them in order to improve performance.
if (!biTarget.equals(NetworkParameters.MAX_MONEY)) {
sortOutputs(sortedOutputs);
}
// Now iterate over the sorted outputs until we have got as close to the target as possible or a little
// bit over (excessive value will be change).
long totalOutputValue = 0;
for (TransactionOutput output : sortedOutputs) {
if (totalOutputValue >= target) break;
// Only pick chain-included transactions, or transactions that are ours and pending.
if (!shouldSelect(output)) continue;
selected.add(output);
totalOutputValue += output.getValue().longValue();
}
// Total may be lower than target here, if the given candidates were insufficient to create to requested
// transaction.
return new CoinSelection(Coin.valueOf(totalOutputValue), selected);
}
static void sortOutputs(ArrayList<TransactionOutput> outputs) {
Collections.sort(outputs, new Comparator<TransactionOutput>() {
public int compare(TransactionOutput a, TransactionOutput b) {
int depth1 = 0;
int depth2 = 0;
TransactionConfidence conf1 = a.getParentTransaction().getConfidence();
TransactionConfidence conf2 = b.getParentTransaction().getConfidence();
if (conf1.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
depth1 = conf1.getDepthInBlocks();
if (conf2.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
depth2 = conf2.getDepthInBlocks();
Coin aValue = a.getValue();
Coin bValue = b.getValue();
BigInteger aCoinDepth = BigInteger.valueOf(aValue.value).multiply(BigInteger.valueOf(depth1));
BigInteger bCoinDepth = BigInteger.valueOf(bValue.value).multiply(BigInteger.valueOf(depth2));
int c1 = bCoinDepth.compareTo(aCoinDepth);
if (c1 != 0) return c1;
// The "coin*days" destroyed are equal, sort by value alone to get the lowest transaction size.
int c2 = bValue.compareTo(aValue);
if (c2 != 0) return c2;
// They are entirely equivalent (possibly pending) so sort by hash to ensure a total ordering.
BigInteger aHash = a.getParentTransaction().getHash().toBigInteger();
BigInteger bHash = b.getParentTransaction().getHash().toBigInteger();
return aHash.compareTo(bHash);
}
});
}
/** Sub-classes can override this to just customize whether transactions are usable, but keep age sorting. */
protected boolean shouldSelect(TransactionOutput output) {
Address outputToAddress = output.getScriptPubKey().getToAddress(addressToQuery.getParameters());
try {
// Check if output address matches addressToQuery and check if it can be spent.
if(outputToAddress.equals(addressToQuery)) {
if(output.isAvailableForSpending()) {
return isSelectable(output.getParentTransaction());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean isSelectable(Transaction tx) {
// Only pick chain-included transactions, or transactions that are ours and pending.
TransactionConfidence confidence = tx.getConfidence();
TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
return type.equals(TransactionConfidence.ConfidenceType.BUILDING) || type.equals(TransactionConfidence.ConfidenceType.PENDING) && confidence.getSource().equals(TransactionConfidence.Source.SELF) && confidence.numBroadcastPeers() > 1;
}
}
EDIT: Use Wallet.getBalance(CoinSelector)
. Example:
Coin addressBalance = wallet.getBalance(new AddressBalance(myBtcAddress));
-
How do you use such code ? Don't see any method Coin getBalance(Address a) Feb 21, 2016 at 14:09
-
@PavelNiedoba use
Wallet.getBalance(CoinSelector)
. Example:Coin addressBalance = wallet.getBalance(new AddressBalance(myBtcAddress));
Feb 22, 2016 at 0:40 -
Seems this is not useful anymore. Always returns 0.0 balance all the time at the year 2021 with the bitcoinj-core 0.15.10 Jul 2, 2021 at 6:12
public static void main(String[] args) {
NetworkParameters params = TestNet3Params.get();
String filePrefix = "peer2-testnet";
WalletAppKit kit = new WalletAppKit(params, new File("."), filePrefix);
// Download the block chain and wait until it's done.
kit.startAsync();
kit.awaitRunning();
String ads = "n1XZMMm3ikh97Mr8JVnnahfugad2DRcVrB";
Address address = new Address(params, ads);
Wallet wallet = new Wallet(params);
wallet.addWatchedAddress(address, 0);
System.out.println("wallet.getWatchedAddresses()"+wallet.getWatchedAddresses());
BlockChain chain;
try {
chain = new BlockChain(params, wallet,
new MemoryBlockStore(params));
PeerGroup peerGroup = new PeerGroup(params, chain);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));
peerGroup.addWallet(wallet);
peerGroup.start();
peerGroup.downloadBlockChain();
Coin balance = wallet.getBalance();
System.out.println("Wallet balance: " + balance);
} catch (BlockStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I tired this one and it worked but each and every time it is taking time to download the blockchian