5

Suppose I'm making a service like SatoshiDice and when I receive a transaction I want to give some money back. Where can I find the sender address?

If I run this, e.g.:

bitcoin-cli gettransaction 8386a8d2870c0df79f652ef4d981b21649ebf40601948c1c0709de0f02de8c8c

I get:

{
    "amount" : -0.00750000,
    "fee" : -0.00050000,
    "confirmations" : 10130,
    "blockhash" : "00000000000000002b44cdc1b2fe4ec2aa6b31b25ae8eedc8d1ef16799bd3114",
    "blockindex" : 13,
    "blocktime" : 1398584440,
    "txid" : "8386a8d2870c0df79f652ef4d981b21649ebf40601948c1c0709de0f02de8c8c",
    "walletconflicts" : [
    ],
    "time" : 1398584248,
    "timereceived" : 1398584248,
    "details" : [
        {
            "account" : "",
            "address" : "1Gxua3AptLgz1DWbG38dakLP4DVY2Jia4d",
            "category" : "send",
            "amount" : -0.00750000,
            "fee" : -0.00050000
        }
    ],
    "hex" : "01000000013c75459d163a5343725362a5b412dde392784814ec04c4e77df7ee5edbd10352010000006a47304402200ee65c9f757eb6c240efe5a7e4427e04174a32da14b1eef459d36d61d031f6e702202d6b5383f86f155d92a494e80a1242af7e160faf16d597ea457b6e3bf08bb1ca012102be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9ffffffff0250c30000000000001976a9144233e899673c755c11664d43d0a83a56d06ce23188acb0710b00000000001976a914af1ca5c63970b893a4ef79d030b28ca91ccd22ce88ac00000000"
}

I can find the address I am looking for in details -> address. But is this the right place to look? The details array can be empty or have more than one element?

I know there are two similar questions already: How to findout the sender of a transaction and What's the best way for a website to detect payments from green addresses? but the problem is that theses questions don't explain if I can use gettransaction securely to find it.

Following the answer tip, I was able to do this:

bitcoin-cli decoderawtransaction "01000000013c75459d163a5343725362a5b412dde392784814ec04c4e77df7ee5edbd10352010000006a47304402200ee65c9f757eb6c240efe5a7e4427e04174a32da14b1eef459d36d61d031f6e702202d6b5383f86f155d92a494e80a1242af7e160faf16d597ea457b6e3bf08bb1ca012102be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9ffffffff0250c30000000000001976a9144233e899673c755c11664d43d0a83a56d06ce23188acb0710b00000000001976a914af1ca5c63970b893a4ef79d030b28ca91ccd22ce88ac00000000"

which produces:

{
    "txid" : "8386a8d2870c0df79f652ef4d981b21649ebf40601948c1c0709de0f02de8c8c",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "5203d1db5eeef77de7c404ec14487892e3dd12b4a562537243533a169d45753c",
            "vout" : 1,
            "scriptSig" : {
                "asm" : "304402200ee65c9f757eb6c240efe5a7e4427e04174a32da14b1eef459d36d61d031f6e702202d6b5383f86f155d92a494e80a1242af7e160faf16d597ea457b6e3bf08bb1ca01 02be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9",
                "hex" : "47304402200ee65c9f757eb6c240efe5a7e4427e04174a32da14b1eef459d36d61d031f6e702202d6b5383f86f155d92a494e80a1242af7e160faf16d597ea457b6e3bf08bb1ca012102be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9"
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 0.00050000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 4233e899673c755c11664d43d0a83a56d06ce231 OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a9144233e899673c755c11664d43d0a83a56d06ce23188ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "1733nLJx6QrYa7AemEHXgq89G2NaWjPpRW"
                ]
            }
        },
        {
            "value" : 0.00750000,
            "n" : 1,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 af1ca5c63970b893a4ef79d030b28ca91ccd22ce OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a914af1ca5c63970b893a4ef79d030b28ca91ccd22ce88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "1Gxua3AptLgz1DWbG38dakLP4DVY2Jia4d"
                ]
            }
        }
    ]
}

This let's me find the change address.

But can I skip these steps and take it from "details"?

3

Bitcoin may use multiple outputs from different addresses to fund the transaction. It will always be impossible to predict what the user is doing, for example, they could be using CoinJoin and the actual sender could be any of the inputs.

Also remember that services like SatoshiDice causes huge network strain and is preferred to use a deposit address and have the user specify an address to withdraw. It solves both network strain and your issue.

In addition, never assume that a certain output is the change address. The user could be doing anything (like sending the rest to someone else).

EDIT: Downvoting both mine and David Schwartz's answer doesn't help anything. It is just not possible to anticipate every use-case. In the words of the Satoshi client developers; "Sometimes a documentation limit is a feature, not a bug". The important point there is that if you have to ask then maybe giving you the answer will cause more harm than good. The only ways to do this are:

  1. Try to guess the change address. If there are two outputs you could use the one that isn't yours. If the sender has an exact output then you might not even get a second output. If there are >2 outputs you might use the last one but that makes a ton of assumptions and any wallet that even cares about privacy will randomise the outputs.
  2. Try to guess the sending address. If there is one sending address you could use that, in the case of more than one, it's anyone's guess (maybe use the top one?).

Noone can answer the question any more than that. Even my answer is just made up, it is not allocated for using the protocol and is just a guess based on how some wallet software works.

I can't recommend against this enough though. It is extremely dangerous. SatoshiDice is not recommended by anyone who knows anything about how Bitcoin works, it is simply popular because it was one of the first, if not the first Bitcoin betting site.

  • I know that it should be avoided (guess the change address) but I am not asking here best practices, I am asking how to do it. It's a controlled and specific situation, I know the sender won't use a mix service and so on. – Felipe Jul 1 '14 at 0:24
  • I don't think that your question conveyed explicitly your special situation, so I don't think it is fair of you to rebut the answers you got for not catering to your special situation. Especially your question whether "it is the right place to look", easily allows for these answers. You should improve your question to precisely state the underlying conditions of your situation, instead of critizing the answers. – Murch Aug 12 '14 at 9:06
  • Related: bitcoin.stackexchange.com/questions/12111/… – Felipe Dec 2 '14 at 1:24
  • I'm somewhat confused by all this talk about change addresses and so forth. Why does it matter? If the OP is receiving money in the current transaction at address "1733nLJx6QrYa7AemEHXgq89G2NaWjPpRW", then it's clear that the other output is the change output. And since there's only one input in this transaction, its clear that the sole sender is the signer of that input. That is, the sender's pubkey is "02be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9" while the sender's address is "1388D9sHH4HXdGLxkSipxe2noZuekHZmaF". – Ryan Dec 2 '14 at 2:26
4

Each transaction can have multiple inputs and thus can have multiple senders.

Here's how you get the sender(s):

bitcoin-cli getrawtransaction 8386a8d2870c0df79f652ef4d981b21649ebf40601948c1c0709de0f02de8c8c 1

(the 1 flag indicates that you want the raw tx to be decoded)

Note: make sure that you have already indexed the blockchain or else this might not work. To index, restart bitcoind with txindex=1 as a config variable.

From that, you get a fairly big response, which contains the following:

"vin" : [{
    "txid" : "5203d1db5eeef77de7c404ec14487892e3dd12b4a562537243533a169d45753c",
    "vout" : 1,
    "scriptSig" : {
        "asm" : "304402200ee65c9f757eb6c240efe5a7e4427e04174a32da14b1eef459d36d61d031f6e702202d6b5383f86f155d92a494e80a1242af7e160faf16d597ea457b6e3bf08bb1ca01 02be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9",
        "hex" : "47304402200ee65c9f757eb6c240efe5a7e4427e04174a32da14b1eef459d36d61d031f6e702202d6b5383f86f155d92a494e80a1242af7e160faf16d597ea457b6e3bf08bb1ca012102be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9"
    },
    "sequence" : 4294967295
}]

This means there's a single input, so there is in fact one sender.

Now, there are two ways to get the sender.

Method A (should always work but is slower):

  1. grab the txid and the vout
  2. do bitcoin-cli getrawtransaction <txid> 1
  3. find the output of this new tx where the value n is equal to the vout of our original tx
  4. go to the scriptPubKey section and check the hex or addresses field - that's the sender (in hex pubkey script or address form)

We now have:

"scriptPubKey" : {
    "asm" : "OP_DUP OP_HASH160 17492e77be2c666af78993020b90235cd1d3738d OP_EQUALVERIFY OP_CHECKSIG",
    "hex" : "76a91417492e77be2c666af78993020b90235cd1d3738d88ac",
    "reqSigs" : 1,
    "type" : "pubkeyhash",
    "addresses" : [
        "1388D9sHH4HXdGLxkSipxe2noZuekHZmaF"
    ]
}

and the sender is 1388D9sHH4HXdGLxkSipxe2noZuekHZmaF

Method B (faster but only works for certain types of transactions):

  1. check the 'asm' field inside the 'scriptSig' field
  2. if the field has two components separated by a space, and the second component is a valid public key, then we have a standard pay-to-pubkey(-hash) transaction, so convert the pubkey to an address
  3. fallback to method A

We see that there is in fact a valid pubkey in the original tx scriptSig:

02be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9

We use Coinkit to extract the address:

$ sudo pip install coinkit
$ python
>>> from coinkit import BitcoinPublicKey
>>> pub = BitcoinPublicKey('02be7759e73363488269f0257158177f3295af42d1f3a6b2fdf8fb4380b1d16ae9')
>>> pub.address()
'1388D9sHH4HXdGLxkSipxe2noZuekHZmaF'

And we have the same answer!

P.S. you can inspect the Coinkit library I used above on github

  • −1 In your example for method A getrawtransaction 5203d1db5eeef77de7c404ec14487892e3dd12b4a562537243533a169d45753c 1 returns No such mempool transaction. Use -txindex to enable blockchain transaction queries. Use gettransaction for wallet transactions. (code -5) so this don’t works. – user2284570 Apr 22 at 14:29
1

Please just don't do this. If you have an agreement with someone and you want to pay them Bitcoins, just have them tell you what account to pay. Don't try kludges to figure out the correct address to pay because many payments do not contain any account the sender can receive Bitcoins from anywhere in the payment.

Here's what happens when you do this:

Jack uses Foo Online Wallet. He sends some Bitcoins to his deposit address. Foo Online Wallet credits his online wallet account for these Bitcoins. Jeff sends you money using his Foo Online Wallet. Foo uses the coins Jack deposited. So the source address for the transaction is Jack's deposit address. When you make a payment to the source address, you are sending the coins to Jack's deposit address -- giving the Bitcoins to the owner of the deposit coincidentally used by Foo Online Wallet. But you should be making the payment to Jeff's deposit address which you cannot know unless you ask Jeff.

Just Don't Do This

  • tell me why SatoshiDice do this and why is it so successful? It's so easy: you transfer bitcoin to an account and receive or not the change. The point is: I want to do this, what is the better manner to do it? SatoshiDice warns the user like this: "Only use wallets that allow you to receive Bitcoin from the same address you sent from. If you're not sure, test by sending a bet for the minimum amount. If you get nothing back, then your wallet is not compatible. Note that some bets may require one confirmation before the win/loss value is sent back." – Felipe Jul 1 '14 at 0:11
  • @FelipeMicaroniLalli I answered all your questions already in my answer. My second sentence explains how to do this correctly. As for why SatoshiDice is successful -- it's because they were first and they did enough things right to succeed. As I explained in detail, this is one of the things they've done wrong and it's caused a lot of pain. I can't force you to learn from their mistakes, but I can strongly advise you to. – David Schwartz Jul 1 '14 at 2:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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