here is a patch-like mod of the code of TxToJSON in rpcrawtransaction.cpp which is used to output a verbosed version of getrawtransaction or decoderawtransaction:
(added code has + in front)
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
{
entry.push_back(Pair("txid", tx.GetHash().GetHex()));
entry.push_back(Pair("version", tx.nVersion));
entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime));
Array vin;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
Object in;
if (tx.IsCoinBase())
in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
else
{
in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n));
+ CTransaction txPrev;
+ uint256 hashBlock;
+ GetTransaction(txin.prevout.hash, txPrev, hashBlock); // get the vin's previous transaction
+ CTxDestination source;
+ if (ExtractDestination(txPrev.vout[txin.prevout.n].scriptPubKey, source)) // extract the destination of the previous transaction's vout[n]
+ {
+ CBitcoinAddress addressSource(source); // convert this to an address
+ in.push_back(Pair("address",addressSource.ToString())); // add the address to the returned object
+ }
Object o;
o.push_back(Pair("asm", txin.scriptSig.ToString()));
o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
in.push_back(Pair("scriptSig", o));
}
in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence));
vin.push_back(in);
}
entry.push_back(Pair("vin", vin));
Array vout;
for (unsigned int i = 0; i < tx.vout.size(); i++)
{
const CTxOut& txout = tx.vout[i];
Object out;
out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
out.push_back(Pair("n", (boost::int64_t)i));
Object o;
ScriptPubKeyToJSON(txout.scriptPubKey, o);
out.push_back(Pair("scriptPubKey", o));
vout.push_back(out);
}
entry.push_back(Pair("vout", vout));
if (hashBlock != 0)
{
entry.push_back(Pair("blockhash", hashBlock.GetHex()));
map::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
{
CBlockIndex* pindex = (*mi).second;
if (pindex->IsInMainChain())
{
entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight));
entry.push_back(Pair("time", (boost::int64_t)pindex->nTime));
entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime));
}
else
entry.push_back(Pair("confirmations", 0));
}
}
}