Hollow.Quincy
Hollow.Quincy

Reputation: 577

bitcoinJ get transaction value

I downloaded a lot of blockchain data using https://bitcoin.org, I took some file and I try to analyse it with bitcoinj library.

I would like to get information from every transaction: -who send bitcoins, -how much, -who receive bitcoins.

I use:

   <dependency>
      <groupId>org.bitcoinj</groupId>
      <artifactId>bitcoinj-core</artifactId>
      <version>0.15.10</version>
    </dependency>

I have a code:

NetworkParameters np = new MainNetParams();
Context.getOrCreate(MainNetParams.get());
BlockFileLoader loader = new BlockFileLoader(np,List.of(new File("test/resources/blk00450.dat")));

for (Block block : loader) {
  for (Transaction tx : block.getTransactions()) { 
    System.out.println("Transaction ID" + tx.getTxId().toString());
    for (TransactionInput ti : tx.getInputs()) {
      // how to get wallet addresses of inputs? 
    }

  
    // this code works for 99% of transactions but for some throws exceptions
    for (TransactionOutput to : tx.getOutputs()) {
      // sometimes this line throws: org.bitcoinj.script.ScriptException: Cannot cast this script to an address
      System.out.println("out address:" + to.getScriptPubKey().getToAddress(np));
      System.out.println("out value:" + to.getValue().toString());
    }
  }
}

Can you share some snippet that will work for all transactions in the blockchain?

Upvotes: -1

Views: 576

Answers (1)

mikemelon
mikemelon

Reputation: 82

There are at least two type of transaction, P2PKH and P2SH. Your code would work well with P2PKH, but wouldn not work with P2SH. You can change the line from:

System.out.println("out address:" + to.getScriptPubKey().getToAddress(np));

to:

System.out.println("out address:" + to.getAddressFromP2PKHScript(np)!=null?to.getAddressFromP2PKHScript(np):to.getAddressFromP2SH(np));

The API of Bitcoin says the methods getAddressFromP2PKHScript() and getAddressFromP2SH() are deprecated, and I have not find suitable method.

However, P2SH means "Pay to Script Hash", which means it could contain two or more public keys to support multi-signature. Moreover, getAddressFromP2SH() returns only one address, perhaps this is the reason why it is deprecated.

I also wrote a convinient method to check the inputs and outputs of a block:

private void printCoinValueInOut(Block block) {
    Coin blockInputSum = Coin.ZERO;
    Coin blockOutputSum = Coin.ZERO;

    System.out.println("--------------------Block["+block.getHashAsString()+"]------"+block.getPrevBlockHash()+"------------------------");
    for(Transaction tx : block.getTransactions()) {
        Coin txInputSum = tx.getOutputSum();
        Coin txOutputSum = tx.getOutputSum();   
        blockInputSum = blockInputSum.add(txInputSum);  
        blockOutputSum = blockOutputSum.add(txOutputSum);
        System.out.println("Tx["+tx.getTxId()+"]:\t" + txInputSum + "(satoshi) IN, " + txOutputSum +  "(satoshi) OUT.");
    }
    System.out.println("Block total:\t" + blockInputSum + "(satoshi) IN, " + blockOutputSum +  "(satoshi) OUT. \n");
}

Upvotes: -1

Related Questions