Bitcoin Forum
May 06, 2024, 02:33:51 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: bitcoind/bitcoin-qt find source address of input  (Read 2271 times)
xblitz (OP)
Newbie
*
Offline Offline

Activity: 32
Merit: 0



View Profile
October 04, 2012, 09:01:56 PM
 #1

Im trying to find the input address of a transaction but i can't seem to find out how..  anyone ?

Code:
CWalletTx wtx;
pwalletMain->GetTransaction(uint256(txid), wtx);
CTxIn vin = wtx.vin[0];
CScript scriptSig = vin.scriptSig;

how can I get the source address of that vin .. I dont seem to understand how I can get the address of the scriptsig ..


1714962831
Hero Member
*
Offline Offline

Posts: 1714962831

View Profile Personal Message (Offline)

Ignore
1714962831
Reply with quote  #2

1714962831
Report to moderator
1714962831
Hero Member
*
Offline Offline

Posts: 1714962831

View Profile Personal Message (Offline)

Ignore
1714962831
Reply with quote  #2

1714962831
Report to moderator
The forum strives to allow free discussion of any ideas. All policies are built around this principle. This doesn't mean you can post garbage, though: posts should actually contain ideas, and these ideas should be argued reasonably.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714962831
Hero Member
*
Offline Offline

Posts: 1714962831

View Profile Personal Message (Offline)

Ignore
1714962831
Reply with quote  #2

1714962831
Report to moderator
1714962831
Hero Member
*
Offline Offline

Posts: 1714962831

View Profile Personal Message (Offline)

Ignore
1714962831
Reply with quote  #2

1714962831
Report to moderator
1714962831
Hero Member
*
Offline Offline

Posts: 1714962831

View Profile Personal Message (Offline)

Ignore
1714962831
Reply with quote  #2

1714962831
Report to moderator
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652
Merit: 2216


Chief Scientist


View Profile WWW
October 04, 2012, 09:48:14 PM
 #2

Im trying to find the input address of a transaction but i can't seem to find out how..  anyone ?

Transactions do not have an input address.

They have one or more inputs, which may or may not correspond to one or more addresses.

If you have a CScript, then you can call:
Code:
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);

What are you trying to do?

How often do you get the chance to work on a potentially world-changing project?
xblitz (OP)
Newbie
*
Offline Offline

Activity: 32
Merit: 0



View Profile
October 04, 2012, 10:12:18 PM
 #3

Im trying to find the input address of a transaction but i can't seem to find out how..  anyone ?

Transactions do not have an input address.

They have one or more inputs, which may or may not correspond to one or more addresses.

If you have a CScript, then you can call:
Code:
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);

What are you trying to do?


Im just trying to output more info on the getrawtransaction rpc command for my personal bitcoins ...

lets say i have this transaction output (testnet):
Code:
{
    "hex" : "0100000001241514a48241f8af8abde6e6e3a657a6ff67beb2febdd5c1f4c62a71a1fb81c3000000008b483045022100a84c1b1a89938c4b16ec7749e9afc16f1a5ec26ddbb16e44739818f4bb85b74c02205d5ce610e0b9d80a373f305dbe67d7347d47470e4b3f6bd98e670ae511d98b920141043ac715efdea8815afc64d7441549e9114ba5d2658f0dcc1a75a8420e8af4791ad8ac46b2eec0463bc54946662e860717d92afe137f0a9fb1b7e1eea812487285ffffffff0200a3e111000000001976a9144988abbeb751dcd6e9f4ec40d50b84c99ed1426d88ac00c2eb0b000000001976a914539862a4bc81786df288265752e12bd7c0c0a6c488ac00000000",
    "txid" : "6aeb3de625830fcc45f675042e1ed98d2c08af72119f81a6e7819d55a6f8ab83",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "c381fba1712ac6f4c1d5bdfeb2be67ffa657a6e3e6e6bd8aaff84182a4141524",
            "vout" : 0,
            "scriptSig" : {
                "asm" : "3045022100a84c1b1a89938c4b16ec7749e9afc16f1a5ec26ddbb16e44739818f4bb85b74c02205d5ce610e0b9d80a373f305dbe67d7347d47470e4b3f6bd98e670ae511d98b9201 043ac715efdea8815afc64d7441549e9114ba5d2658f0dcc1a75a8420e8af4791ad8ac46b2eec0463bc54946662e860717d92afe137f0a9fb1b7e1eea812487285",
                "hex" : "483045022100a84c1b1a89938c4b16ec7749e9afc16f1a5ec26ddbb16e44739818f4bb85b74c02205d5ce610e0b9d80a373f305dbe67d7347d47470e4b3f6bd98e670ae511d98b920141043ac715efdea8815afc64d7441549e9114ba5d2658f0dcc1a75a8420e8af4791ad8ac46b2eec0463bc54946662e860717d92afe137f0a9fb1b7e1eea812487285"
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 3.00000000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 4988abbeb751dcd6e9f4ec40d50b84c99ed1426d OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a9144988abbeb751dcd6e9f4ec40d50b84c99ed1426d88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "mnDmM7j73HEqo746F1cLQZXwTXNPzLxc3W"
                ]
            }
        },
        {
            "value" : 2.00000000,
            "n" : 1,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 539862a4bc81786df288265752e12bd7c0c0a6c4 OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a914539862a4bc81786df288265752e12bd7c0c0a6c488ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "mo8xvtom7uyCwjh3MHzjdc8ZtWqAQp6xW7"
                ]
            }
        }
    ],
    "blockhash" : "00000000235841896dc9856e8a3ef214df8f5e4f2127e534ff18199616f8da00",
    "confirmations" : 103,
    "time" : 1349331390,
    "blocktime" : 1349331390
}

well i would like it to display the vin's address ... a bit like what blockchain.info displays!
xblitz (OP)
Newbie
*
Offline Offline

Activity: 32
Merit: 0



View Profile
October 04, 2012, 11:40:00 PM
 #4

Ok from the help of the people on freenode/bitcoin-dev I was able to resolve the addresses from the inputs of a transaction using the vin.prevout

so just for other people to know...  exmaple to find out the first input's address

Code:
CWalletTx wtx;
pwalletMain->GetTransaction(uint256(txid), wtx);     // get current transaction
CTxIn vin = wtx.vin[0];                                        //get first input
CWalletTx wtxPrev;                                     
pwalletMain->GetTransaction(vin.prevout.hash, wtxPrev);    // get the vin's previous transaction
CTxDestination source;
ExtractDestination(wtxPrev.vout[vin.prevout.n].scriptPubKey, source);  // extract the destination of the previous transaction's vout[n]
CBitcoinAddress addressSource(source);                // convert this to an address

print addressSource.ToString() // might as well print it!

kjj
Legendary
*
Offline Offline

Activity: 1302
Merit: 1024



View Profile
October 05, 2012, 12:28:58 AM
 #5

Just as a reminder, while this like it should work, the concept of a sending address does not exist in bitcoin.  What this is doing is finding the last address to have received these funds.  This is occasionally what you expect, but not always.  If you are thinking that this address is owned or controlled by the person that sent you a transaction, you will be wrong fairly often.

17Np17BSrpnHCZ2pgtiMNnhjnsWJ2TMqq8
I routinely ignore posters with paid advertising in their sigs.  You should too.
xblitz (OP)
Newbie
*
Offline Offline

Activity: 32
Merit: 0



View Profile
October 05, 2012, 12:36:24 AM
 #6

Just as a reminder, while this like it should work, the concept of a sending address does not exist in bitcoin.  What this is doing is finding the last address to have received these funds.  This is occasionally what you expect, but not always.  If you are thinking that this address is owned or controlled by the person that sent you a transaction, you will be wrong fairly often.

I'm only interested in the address.. not the owner.. 
I know this will not always resolve to an address.. but in most case it will.. I will just catch the errors of when it is not the case and handle it gracefully
kjj
Legendary
*
Offline Offline

Activity: 1302
Merit: 1024



View Profile
October 05, 2012, 12:50:19 AM
 #7

I'm only interested in the address.. not the owner.. 
I know this will not always resolve to an address.. but in most case it will.. I will just catch the errors of when it is not the case and handle it gracefully

Good to hear.  Sounded like you were working on a website, but I like to give that reminder in these threads, so that when people go searching and find out how you did it, they also find out that it might not do what they expect.

17Np17BSrpnHCZ2pgtiMNnhjnsWJ2TMqq8
I routinely ignore posters with paid advertising in their sigs.  You should too.
xblitz (OP)
Newbie
*
Offline Offline

Activity: 32
Merit: 0



View Profile
October 05, 2012, 12:56:41 AM
 #8

ok so my previous example was good for wallet transactions..  so instead I made a more "general" implementation for it to be in getrawtransaction of the bitcoin client

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)

Code:
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<uint256, CBlockIndex*>::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));
        }
    }
}
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!