11

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!!

2
  • 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 Feb 21, 2016 at 14:07

2 Answers 2

4

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));
3
  • 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
1
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.