Title: Hashing coinbase transaction to get txid Post by: arch_stanton on September 21, 2017, 07:57:40 AM I'm not able to get a txid from coinbase transactions, by hashing. I can get it from any other transaction by doing the double hash. Here's what I'm trying:
Code: import hashlib Output when using a normal transaction: Code: ** Output when using a coinbase transaction: Code: ** I haven't been able to find any documentation about this. Does anybody know why this is? Title: Re: Hashing coinbase transaction to get txid Post by: DannyHamilton on September 21, 2017, 07:51:46 PM You appear to have a bad copy of the raw transaction.
When I look at the raw transaction for txid in the blockchain (coinbase transaction for block height 486,273, block hash 00000000000000000083cbfd33b63c2ac10e703266c5749bf3ce2fbff88f5791), I get the following: Code: 01000000 01000000 00000000 00000000 When I calculate hashlib.sha256(hashlib.sha256(data).digest()).digest() on that data, I get the correct result. You seem to be working with the following: Code: 01000000 00010100 00000000 00000000 Notice the extra "0120" at the end followed by an extra 36 bytes of "00"? Also notice that you have an extra byte of "00" between the 4-byte version (the 01000000) at the beginning, and the "01" representing the number of inputs? Then notice that you have an extra "01" byte immediately following the in-counter? These extra bytes are resulting in an invalid hash calculation. Title: Re: Hashing coinbase transaction to get txid Post by: arch_stanton on September 22, 2017, 05:15:47 AM Thanks. That's really strange. I'm getting the raw transaction from https://blockchain.info/tx/d0783f480343fb37b009b5e3db90ccad85e2c8314639de98b3bb66c396dd7915?format=hex , I haven't tried getting the data from my node, since I'm currently running tests in regtest mode. By the way, I'm having this problem in regtest aswell. I'll look more into this when I get home from work.
Title: Re: Hashing coinbase transaction to get txid Post by: DannyHamilton on September 22, 2017, 03:06:43 PM - snip - I'm getting the raw transaction from https://blockchain.info/... - snip - Blockchain.info has a reputation for having issues. I wouldn't recommend ever using them as a source for anything significant. Title: Re: Hashing coinbase transaction to get txid Post by: arch_stanton on September 22, 2017, 04:47:53 PM My node is a couple of days of synching behind, so I can't get the transaction from it yet. But I tried getting the raw transaction from electrum wallet and chainquery.com, and they all have the long tail starting with 12... Where did you get your raw transaction?
Title: Re: Hashing coinbase transaction to get txid Post by: DannyHamilton on September 22, 2017, 04:54:43 PM I tried getting the raw transaction from electrum wallet . . . and they all have the long tail starting with 12 That's surprising. Might want to report that. Sounds like an Electrum bug, and they are usually pretty good about fixing their bugs. Where did you get your raw transaction? https://blockexplorer.com/api/rawtx/d0783f480343fb37b009b5e3db90ccad85e2c8314639de98b3bb66c396dd7915 Title: Re: Hashing coinbase transaction to get txid Post by: achow101 on September 22, 2017, 04:56:19 PM You seem to be working with the following: Code: 01000000 00010100 00000000 00000000 Notice the extra "0120" at the end followed by an extra 36 bytes of "00"? Also notice that you have an extra byte of "00" between the 4-byte version (the 01000000) at the beginning, and the "01" representing the number of inputs? Then notice that you have an extra "01" byte immediately following the in-counter? These extra bytes are resulting in an invalid hash calculation. But I tried getting the raw transaction from electrum wallet and chainquery.com, and they all have the long tail starting with 12... They seem to be giving you the transaction in the extended serialiation format (witness serialization when there are witnesses). Edit: That was wrong, explained in a post below. Title: Re: Hashing coinbase transaction to get txid Post by: DannyHamilton on September 22, 2017, 05:03:55 PM They seem to be giving you the transaction in the extended serialiation format (witness serialization when there are witnesses). This is actually incorrect and in violation of the segwit specification which states that the witness serialization for a non-witness transaction (as the coinbase transaction is) is the legacy non-extended (no witnesses) serialization format. Achow101, thanks for explaining what's happening there. I've been too busy, and haven't has a chance to learn and understand the SegWit changes yet. It's clear that I'm going to need to start absorbing some of that material or my knowledge will become stale and useless around here. Title: Re: Hashing coinbase transaction to get txid Post by: arch_stanton on September 22, 2017, 05:43:54 PM Ok, great. But my regtest setup (version 14.1) gives me a similar raw coinbase transaction:
Code: 020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff050282060101ffffffff020e642500000000002321031a70a95a57f63b7d63e46803d385fd483b77f7a71a7a753ffcf7aafb67ec3edcac0000000000000000266a24aa21a9edad9d9c439414e2d257fda34cdc00667c0ecd7d78256721a4178046b49ee7382f0120000000000000000000000000000000000000000000000000000000000000000000000000 Title: Re: Hashing coinbase transaction to get txid Post by: link2yasar on September 22, 2017, 06:25:01 PM My node is a couple of days of synching behind, so I can't get the transaction from it yet. But I tried getting the raw transaction from electrum wallet and chainquery.com, and they all have the long tail starting with 12... Where did you get your raw transaction? Thank you very much, I am python developer and I will take a look into it. Thanks Title: Re: Hashing coinbase transaction to get txid Post by: achow101 on September 22, 2017, 07:05:49 PM Ok, great. But my regtest setup (version 14.1) gives me a similar raw coinbase transaction: Hmm. That's interesting. I can reproduce that. I will investigate and see what's up with that.Code: 020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff050282060101ffffffff020e642500000000002321031a70a95a57f63b7d63e46803d385fd483b77f7a71a7a753ffcf7aafb67ec3edcac0000000000000000266a24aa21a9edad9d9c439414e2d257fda34cdc00667c0ecd7d78256721a4178046b49ee7382f0120000000000000000000000000000000000000000000000000000000000000000000000000 Regardless, the txid is calculated from the non-witness serialization of a transaction, so you should strip out the witness parts of this and hash the remaining. That will get you the txid. Ok, so apparently that is actually expected behavior. From BIP 141: Quote and the coinbase's input's witness must consist of a single 32-byte array for the witness reserved value. This is done to allow for future extensibility.Title: Re: Hashing coinbase transaction to get txid Post by: DannyHamilton on September 22, 2017, 07:20:24 PM - snip - the txid is calculated from the non-witness serialization of a transaction, so you should strip out the witness parts of this and hash the remaining. That will get you the txid. - snip - This is the key information to take away from this thread. Achow101 correct me if I'm mistaken, but I believe that is true regardless of whether it is a legacy transaction or a SegWit transaction. This thread has taught me how to identify a SegWit transaction and how to identify the witness portion of the SegWit transaction. But regarding the topic of the thread (calculating the txid), the key is to remove the witness information before hashing. Title: Re: Hashing coinbase transaction to get txid Post by: arch_stanton on September 23, 2017, 06:25:16 AM Ok, this is great info. But why is the segwit data only attached to coinbase transactions? Of the the random picks of transactions I've checked, this is true.
Edit: Sorry, read the above post again and got it this time. Thanks for your answers. |