3

I'm trying to determine the source address of transactions for automated refunding, but I'm seeing unexpected output from Bitcoin-QT

The transaction in question on blockexplorer: 8bc80f72d9cc6fecda77138e7364f95b48d652db404889deafd48158dc46387e

And below is the result of bitcoind gettransaction for the same txid. Shouldn't I see the same thing? Or is there some issue with inter-wallet sending?

{
"amount" : 0.00000000,
"fee" : -0.00010000,
"confirmations" : 1,
"blockhash" : "0000000000941dab82b8f78596f93832104288c85e7951b5f505b8c1c30dd4ba",
"blockindex" : 1,
"blocktime" : 1377648593,
"txid" : "8bc80f72d9cc6fecda77138e7364f95b48d652db404889deafd48158dc46387e",
"time" : 1377648549,
"timereceived" : 1377648549,
"details" : [
    {
        "account" : "",
        "address" : "n1SrgGXRGjK2gKcvSDRVUDPA1aVKBaG6PQ",
        "category" : "send",
        "amount" : -0.10000000,
        "fee" : -0.00010000
    },
    {
        "account" : "",
        "address" : "mtjmGtkZet4Y7rzQrC8cweuJMYGZFpPw4d",
        "category" : "send",
        "amount" : -0.10000000,
        "fee" : -0.00010000
    },
    {
        "account" : "",
        "address" : "n4N4hQZK1sgHv8z3ikHsuN98vGNhshQZSo",
        "category" : "send",
        "amount" : -0.10000000,
        "fee" : -0.00010000
    },
    {
        "account" : "",
        "address" : "mvw4DVoSL7APFGdHb2RGYebzBKDBankTAM",
        "category" : "send",
        "amount" : -0.99950000,
        "fee" : -0.00010000
    },
    {
        "account" : "account1",
        "address" : "n1SrgGXRGjK2gKcvSDRVUDPA1aVKBaG6PQ",
        "category" : "receive",
        "amount" : 0.10000000
    },
    {
        "account" : "account2",
        "address" : "mtjmGtkZet4Y7rzQrC8cweuJMYGZFpPw4d",
        "category" : "receive",
        "amount" : 0.10000000
    },
    {
        "account" : "account3",
        "address" : "n4N4hQZK1sgHv8z3ikHsuN98vGNhshQZSo",
        "category" : "receive",
        "amount" : 0.10000000
    },
    {
        "account" : "account4",
        "address" : "mvw4DVoSL7APFGdHb2RGYebzBKDBankTAM",
        "category" : "receive",
        "amount" : 0.99950000
    }
]
}

Edit: And here is the result of combining getrawtransaction and decoderawtransaction:

{
"txid" : "8bc80f72d9cc6fecda77138e7364f95b48d652db404889deafd48158dc46387e",
"version" : 1,
"locktime" : 0,
"vin" : [
    {
        "txid" : "f96590f6db1e8748f349e93ae5e1e335c57d55df9a26a70f99e7c06b32538f16",
        "vout" : 0,
        "scriptSig" : {
            "asm" : "304502201d7a5a31936d9a4a0ff17f357dda13e87d7459a7663d127da783865858b552c5022100bac9edf373d42c578c92231cc096a620baa174d7bf141c519047b3ca5dc3577101 03f5fd9f5ad8f4a5ac11c9c8e6f6b094129dbc3d8a9f753dc8d415c5c42a5cccfa",
            "hex" : "48304502201d7a5a31936d9a4a0ff17f357dda13e87d7459a7663d127da783865858b552c5022100bac9edf373d42c578c92231cc096a620baa174d7bf141c519047b3ca5dc35771012103f5fd9f5ad8f4a5ac11c9c8e6f6b094129dbc3d8a9f753dc8d415c5c42a5cccfa"
        },
        "sequence" : 4294967295
    }
],
"vout" : [
    {
        "value" : 0.10000000,
        "n" : 0,
        "scriptPubKey" : {
            "asm" : "OP_DUP OP_HASH160 da9c29ba563c33688e8e1d85b84a634a271b5282 OP_EQUALVERIFY OP_CHECKSIG",
            "hex" : "76a914da9c29ba563c33688e8e1d85b84a634a271b528288ac",
            "reqSigs" : 1,
            "type" : "pubkeyhash",
            "addresses" : [
                "n1SrgGXRGjK2gKcvSDRVUDPA1aVKBaG6PQ"
            ]
        }
    },
    {
        "value" : 0.10000000,
        "n" : 1,
        "scriptPubKey" : {
            "asm" : "OP_DUP OP_HASH160 9105d7f92fd467f0035cd4b5b58bea1167647618 OP_EQUALVERIFY OP_CHECKSIG",
            "hex" : "76a9149105d7f92fd467f0035cd4b5b58bea116764761888ac",
            "reqSigs" : 1,
            "type" : "pubkeyhash",
            "addresses" : [
                "mtjmGtkZet4Y7rzQrC8cweuJMYGZFpPw4d"
            ]
        }
    },
    {
        "value" : 0.10000000,
        "n" : 2,
        "scriptPubKey" : {
            "asm" : "OP_DUP OP_HASH160 fa9c7e784bfae5e3d330cba28b73c804da71f213 OP_EQUALVERIFY OP_CHECKSIG",
            "hex" : "76a914fa9c7e784bfae5e3d330cba28b73c804da71f21388ac",
            "reqSigs" : 1,
            "type" : "pubkeyhash",
            "addresses" : [
                "n4N4hQZK1sgHv8z3ikHsuN98vGNhshQZSo"
            ]
        }
    },
    {
        "value" : 0.99950000,
        "n" : 3,
        "scriptPubKey" : {
            "asm" : "OP_DUP OP_HASH160 a918d01415a09ee82034f1dce3217741dcdf5849 OP_EQUALVERIFY OP_CHECKSIG",
            "hex" : "76a914a918d01415a09ee82034f1dce3217741dcdf584988ac",
            "reqSigs" : 1,
            "type" : "pubkeyhash",
            "addresses" : [
                "mvw4DVoSL7APFGdHb2RGYebzBKDBankTAM"
            ]
        }
    }
]
}

Here's a reference stating the only way is to identify the output index of the previous transaction: https://bitcoin.stackexchange.com/a/12472/3413

If this is accurate, then to determine the "refund" address of a particular transaction, you would have to run the following pseudocode?:

txhex = getrawtransaction(targettxhash)
txjson = decoderawtransaction(txhex)
foreach txinput in txjson.vin:
  txhexprev = getrawtransaction(txinput.txid)
  txjsonprev = decoderawtransaction(txhexprev)
  foreach txprevoutput in txjsonprev.vout:
    txrefundarray[] += {'address':txprevoutput.scriptPubKey.addresses[0], 'amount':txprevout.value} // 0th address only doesn't support multi-sig
1

3 Answers 3

2

Bitcoin transactions do not have a 'from' address, and certainly no guaranteed way of determining a refund address. Transactions consume and produce coins, and while it is in theory possible to use the addresses the input coins were previously sent to, this is no information you should rely on (nor is it guaranteed to be available, though some sites use this technique).

For received transactions, the reference client lists the address by which you've received coins - not the sender. The best advice for determining a refund address, is for asking it from the customer.

In case you need something more automatic, there is a payment protocol being developed that works on top of Bitcoin, and allows negotiating transactions between sender and receiver before broadcasting them on the network. It includes a feature to automatically send a refund address with each transaction.

11
  • 1
    You asked for a way to determine the source address of a transaction, to do refunds. Bitcoin, at the protocol level, has neither source addresses or a reliable way to determine refund addresses. Until the payment protocol is commonly available, the only way to do that is by asking a customer. Yes, transactions have inputs, and the outputs consumed by them may have been assigned to identifiable addresses, and this can be determined as you state. It's not an answer to your question though. Sep 2, 2013 at 9:27
  • 1
    Ok, then the only correct answer is "it does not exist". Refund addresses do not exist currently, and using the prevout addresses for this needs assumptions about the receiver's software, hurts the scalability of the ecosystem and its privacy as a whole. There is no answer to your question. I know many sites don't follow this, but they are hurting the ability of the ecosystem to outgrow some assumptions that may generally hold today. Sep 11, 2013 at 5:11
  • 1
    It is being worked on, and it's called the payment protocol which will be present in the 0.9 release. The point is that it doesn't belong in the P2P protocol, but in a layer on top, which allows transactions to be negotiated between sender and receiver before being broadcasted on the network. The blockchain is a expensive global thing to maintain, and functions only marginally as a communication protocol. There is no reason for putting data that is private information between sender and receiver into it. Sep 12, 2013 at 1:19
  • 1
    @user3338098 Ignoring that being terrible practice for privacy, it doesn't even always work. For example, in a CoinJoin transaction, some of the inputs will come from one sender, and some will come from another. You can of course have an understanding with a sender that a refund can be made, but in general you should not assume that a receiver will accept a transaction as a payment without being given an address to send it to explicitly. Mar 18, 2019 at 22:21
  • 1
    @user3338098 Even if you assume that, how will you deal with the case where multiple owners jointly construct a single transaction (where different input may be associated with different users)? This is very much an encouraged practice. Mar 22, 2019 at 23:13
1

Someone has written a python snippet that attempts to determine the "input addresses" of a particular transaction using the outputs of the previous transaction as a workable, but not 100% unreliable solution. This accomplished what I need.

0

You should be seeing the same thing, but it looks like your results from bitcoind don't tell the full story. Everything in the details section is an output of the transaction. (Notice how each item with a category of "send" has a corresponding "receive" item with the same amount negated -- duplicates!) This doesn't actually tell you anything about the inputs. This could be a bug in bitcoind, but more likely there's another way, perhaps an extra command line parameter that will expose the inputs to the transaction as well.

1
  • 1
    getrawtransaction will show you the blockchain transaction, rather than the effect on your wallet (it does require the txindex=1 setting, though). That still won't give you a refund address, though (see my answer). Aug 28, 2013 at 1:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.