@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); }
protected TransactionSummary transform( Transaction tx, int time, int height, int blockChainHeight) { long value = 0; Address destAddress = null; for (TransactionOutput output : tx.outputs) { if (isMine(output.script)) { value += output.value; } else { destAddress = output.script.getAddress(_network); } } if (tx.isCoinbase()) { // For coinbase transactions there is nothing to subtract } else { for (TransactionInput input : tx.inputs) { // find parent output TransactionOutputEx funding = _backing.getParentTransactionOutput(input.outPoint); if (funding == null) { _logger.logError("Unable to find parent output for: " + input.outPoint); continue; } if (isMine(funding)) { value -= funding.value; } } } int confirmations; if (height == -1) { confirmations = 0; } else { confirmations = Math.max(0, blockChainHeight - height + 1); } // only track a destinationAddress if it is an outgoing transaction (i.e. send money to someone) // to prevent the user that he tries to return money to an address he got bitcoin from. if (value >= 0) { destAddress = null; } boolean isQueuedOutgoing = _backing.isOutgoingTransaction(tx.getHash()); return new TransactionSummary( tx.getHash(), value, time, height, confirmations, isQueuedOutgoing, com.google.common.base.Optional.fromNullable(destAddress)); }