4

I am trying to use Bitcoinj for my app. I am using regtest mode. I have a balance of 42 BTC on my account:

bitcoin-cli -regtest getbalance mirko3
-> 42.00000000

My code follows:

public class ProvaBitcoinj {
    public static void main(String ... args) throws Exception {
        final DumpedPrivateKey dumpedPrivateKey = new DumpedPrivateKey(RegTestParams.get(), "cNDSqymhJbqmRJRpx3QPM8KBZuca2WePFkzj2uezp5TZhqHX4q4d");
        final ECKey key = dumpedPrivateKey.getKey();
        System.out.println("BTC address that will be added: " + key.toAddress(RegTestParams.get()));
        System.out.println("Private key that will be added: " + key.getPrivateKeyEncoded(RegTestParams.get()));

        final WalletAppKit kit = new WalletAppKit(RegTestParams.get(), new File("/tmp/bitcoinj"), "test_btc") {
            protected void onSetupCompleted() {
                System.out.println("Key chain size: " + wallet().getKeychainSize());
                for (ECKey k : wallet().getKeys()) {
                    wallet().removeKey(k);
                }

                wallet().addKey(key);
            }
        };
        kit.setAutoSave(true);
        kit.connectToLocalHost();
        System.out.println("Started!: " + kit.startAndWait());


        System.out.println("Keys: " + kit.wallet().getKeychainSize());
        System.out.println("BTC Address: " + kit.wallet().getKeys().get(0).toAddress(RegTestParams.get()));
        System.out.println("Private key: " + kit.wallet().getKeys().get(0).getPrivateKeyEncoded(RegTestParams.get()));

        System.out.println("Balance " + kit.wallet().getBalance());

//      kit.wallet().addEventListener(new AbstractWalletEventListener() {
//          @Override
//          public void onCoinsReceived(Wallet wallet, Transaction tx,
//                  BigInteger prevBalance, BigInteger newBalance) {
//              System.out.println("TX!!!!!!!!!!!!!");
//              System.out.println(tx.getValueSentToMe(wallet));
//              System.out.println(wallet.getBalance());
//          }
//      });
//      
//      Thread.sleep(Long.MAX_VALUE);
        for (Transaction tx : kit.wallet().getTransactions(true)) {
            System.out.println(tx.getValueSentFromMe(kit.wallet()));
        }
        System.out.println("Stopping");
        System.out.println("Stopped!: " + kit.stopAndWait());
    }
}

This programs dumps the following output:

BTC address that will be added: mnJRedAFBzRScnnKp5eS5CgR165uGi75tm
Private key that will be added: cSY1oeXfTADVXg2WnMzR2uMqQWqXNNia424SF2mHRPr54Ruj9Fzs
Key chain size: 1
Started!: RUNNING
Keys: 1
BTC Address: mnJRedAFBzRScnnKp5eS5CgR165uGi75tm
Private key: cSY1oeXfTADVXg2WnMzR2uMqQWqXNNia424SF2mHRPr54Ruj9Fzs
Balance 0
Stopping
Stopped!: TERMINATED

I have verified that the key pair is correct:

bitcoin-cli -regtest getaccountaddress mirko3
-> mnJRedAFBzRScnnKp5eS5CgR165uGi75tm
bitcoin-cli -regtest dumpprivkey mnJRedAFBzRScnnKp5eS5CgR165uGi75tm
-> cSY1oeXfTADVXg2WnMzR2uMqQWqXNNia424SF2mHRPr54Ruj9Fzs

I have also noticed that if I run the commented out code and send some money using bitcoin-cli, I receive correctly events and the wallet is charged with the amount I have sent. At a certain point, I could see my wallet with 2 BTC, but the other 40 ones were never found and, anyway, after some tests also the 2 BTC have disappeared.

I am totally confused, any help would be greatly appreciated.

Thank you

1 Answer 1

3

Okay, so it's been a while since I've played around with BitcoinJ but the problem might be that you need to rebuild your BlockStore file. A BitcoinJ application is essentially made up of four main objects, a BlockChain object which is responsible for parsing and validating the actual blocks, a BlockStore object which is responsible for saving this data, a PeerGroup object responsible for actually getting this information from the bitcoin network (in the case of your regtest example it simply connects to your localhost bitcoind node), and a Wallet object that actually holds that data about the public/private keys you are interested in.

You are using WalletAppKit which is a boilerplate class BitcoinJ offers to bootstrap all of this for you. It creates a BlockChain object and relates it to an SPVBlockStore object that is related to a PeerGroup object which is itself related to a Wallet object. If you look at your /tmp/bitcoinj location I believe there should be two files, one a wallet file for saving the information about your addresses and the other a spv file that has a bunch of information saved about the blockchain. The SPV method that BitcoinJ uses doesn't actually download and verify the entire blockchain, it uses a more streamlined system (which you can read about here: https://en.bitcoin.it/wiki/Thin_Client_Security#Simplified_Payment_Verification_.28SPV.29). The SPV file doesn't hold any information about transactions, and if you want to get any information about an address from a previous point in time you have to rebuild this file and effectively force BitcoinJ to reparse the blockchain.

You should try deleting this /tmp/bitcoinj.spv file (I believe that the naming convention of BitcoinJ for WalletAppKit is two files with the path you specified with different file extensions but you might need to verify) and allow it to be rebuilt knowing that it should look for all activity on those watched addresses. Then you'll want to save that wallet to disk so that you don't need to reconstruct the SPV file again.

1
  • Thank you very much for your help. You have provided a greatly extended answer. I was pretty sure that I had tried with that solution as well. I will double check. Thank you.
    – fcracker79
    Oct 12, 2014 at 6:46

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.