@Override public TransactionDetails getTransactionDetails(Sha256Hash txid) { // Note that this method is not synchronized, and we might fetch the transaction history while // synchronizing // accounts. That should be ok as we write to the DB in a sane order. TransactionEx tex = _backing.getTransaction(txid); Transaction tx = TransactionEx.toTransaction(tex); if (tx == null) { throw new RuntimeException(); } List<TransactionDetails.Item> inputs = new ArrayList<TransactionDetails.Item>(tx.inputs.length); if (tx.isCoinbase()) { // We have a coinbase transaction. Create one input with the sum of the outputs as its value, // and make the address the null address long value = 0; for (TransactionOutput out : tx.outputs) { value += out.value; } inputs.add(new TransactionDetails.Item(Address.getNullAddress(_network), value, true)); } else { // Populate the inputs for (TransactionInput input : tx.inputs) { Sha256Hash parentHash = input.outPoint.hash; // Get the parent transaction TransactionOutputEx parentOutput = _backing.getParentTransactionOutput(input.outPoint); if (parentOutput == null) { // We never heard about the parent, skip continue; } // Determine the parent address Address parentAddress; ScriptOutput parentScript = ScriptOutput.fromScriptBytes(parentOutput.script); if (parentScript == null) { // Null address means we couldn't figure out the address, strange script parentAddress = Address.getNullAddress(_network); } else { parentAddress = parentScript.getAddress(_network); } inputs.add(new TransactionDetails.Item(parentAddress, parentOutput.value, false)); } } // Populate the outputs TransactionDetails.Item[] outputs = new TransactionDetails.Item[tx.outputs.length]; for (int i = 0; i < tx.outputs.length; i++) { Address address = tx.outputs[i].script.getAddress(_network); outputs[i] = new TransactionDetails.Item(address, tx.outputs[i].value, false); } return new TransactionDetails( txid, tex.height, tex.time, inputs.toArray(new TransactionDetails.Item[] {}), outputs); }