5

Both on "send" and "receive" transactions, the command gettransaction gives me the account name, and the receiving address, ignoring the send address. Why should I care about receiving address in a "receive" transaction? I want to know the send address, of course...

  • "receive" --> send address, receive account
  • "send" --> send account, receive address

Why doesn't it work this way, what am I missing, and how can I get the send address in a receive transaction?

edit: I'd like to stress out the question about why it behaves this way? as in this comment "I don't get it: if I enter the txid into blockchain.info it tells me the sender address, since it obviously is present in the blockchain... so it's just a choice of bitcoind not to tell me?"

edit: sending back anything to the from address is totally out of the scope of the question, so it is irrelevant if they might not wish receiving anything there.

11

I was intending to answer another question, which was closed as a duplicate in the meantime, but I will use the case that was described there as an example to answer this question.

Assuming the transaction is in fact a standard transaction, the script does in fact reveal the sender of the transaction. According to the standard transaction description in the protocol specification the transaction has to first prove ownership of an output in order to claim it and spend it in the new transaction. The transaction that gave the sender the funds specifies the hash of a public key to which to send the funds. In this case it's the output script 1 of transaction f8c71a9f7...:

OP_DUP OP_HASH160 496650cdb4b6275ca4478c0ce98cb6f7224bb1e7 OP_EQUALVERIFY OP_CHECKSIG

Notice the 496650cdb4b6275ca4478c0ce98cb6f7224bb1e7 in there. That is the hash of the public key. To claim this output, and then send it to you, the sender has to provide both the public key and a valid signature. So let's take a look at the script that claimed this output:

304402205e81e8ed0b1f7cf6d1d415961859d3b95f5e5c353af303b6cef1e3efa6c3349702202fa9fdd6914abd0e9606c78899e7f3010cafdad211645cf459ae18b3b827b2c101 0365e0beb9a0c1497f3667067aeb8f3ea9dc4c9d5696cee7f19eae49f9457a5cfb

This being a standard transaction it will conform to the format <sig> <pubKey>, so the public key is 0365e0beb9a0c1497f3667067aeb8f3ea9dc4c9d5696cee7f19eae49f9457a5cfb. To verify this we check an see if the hashes match (python code ahead):

script = "304402205e81e8ed0b1f7cf6d1d415961859d3b95f5e5c353af303b6cef1e3efa6c3349702202fa9fdd6914abd0e9606c78899e7f3010cafdad211645cf459ae18b3b827b2c101 0365e0beb9a0c1497f3667067aeb8f3ea9dc4c9d5696cee7f19eae49f9457a5cfb".split()
h = hashlib.sha256(script[1].decode("hex")).digest()
ripe160 =  hashlib.new('ripemd160')
ripe160.update(h)
d = ripe160.digest()
print d.encode("hex")

This should result in 496650cdb4b6275ca4478c0ce98cb6f7224bb1e7, which is the hash we have seen in the output script of the claimed out that was finally sent to you. Notice that to calculate this we did not have to fetch the transaction f8c71a9f7... but merely relied on information you could get from the transaction that you received. Now since an address is not much more than the hash of a public key we can simply build an address from the information we have gathered so far (having the hash already we start from step 4 in the address construction):

#Prepend the Mainnet prefix
address = ('\x00' + d)
#Calculate checksum
checksum = hashlib.sha256(hashlib.sha256(address).digest()).digest()[:4]
# Build the raw address
address += checksum
# Encode the address in base58
encoded_address = b58encode(address)
print encoded_address

The encoding can be done with any base58 encoder, I used this. This should print out the address 17h6u26N2TVmoPRcvxwUdfAUjDzBJX513V which is the address that sent the bitcoins in the transaction that we were looking at all the time. So you see, the information you were looking for was in the transaction all along, but quite hidden. So given an incoming transaction (or an outgoing as a matter of fact) you can reconstruct who the sender (or receiver) was. Notice that this allows you to reconstruct the sender of each individual input, which might be multiple addresses. Simply assuming that any of the addresses signing the inputs is the sender of the transaction may or may not lead to the desired semantic result.

1

I think it's because of the intended security model - you generate an address for a customer, who sends bitcoins to it.

Allowing people to figure out the sending address might cause people to create one bitcoin address, then ask customers to enter their sending address.

As for how...

I found these three threads:

  • 1
    I don't get it: if I enter the txid into blockchain.info it tells me the sender address, since it obviously is present in the blockchain... so it's just a choice of bitcoind not to tell me? – o0'. Feb 21 '13 at 19:03
  • 1
    It is not a choice: Bitcoin transactions do not have a "from" address. What they do have is inputs, and each input refers to an output of a previous transaction. Each of these previous outputs may or may not have an identifiable address it sent things to. It would be both inefficient to look it up, and incorrect to rely on it. It gives you an address owned by someone who previously controlled those outputs (which may be different from the sender, e.g. for e-wallets), and who may not intend to receive anything there. – Pieter Wuille Mar 30 '13 at 0:45
  • @PieterWuille I don't follow: how does blockchain.info tells me the input address, how much is that precise? (sending back anything there is out of the scope of the question) – o0'. Mar 30 '13 at 0:54
  • 2
    They give you the address (if any) the consumed previous outputs belonged to. This is not part of the transaction itself, and finding out requires looking up all previous transactions whose outputs were spent by this one. It's certainly doable, but it's inefficient, it's not part of the transaction you're looking up (which is what getrawtransaction fetches), and it reinforces the incorrect notion of that Bitcoin transactions have a from address. – Pieter Wuille Mar 30 '13 at 0:59

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.