3
Originally posted to StackOverflow but with no response. Thought I might have better luck here.
I've successfully created a Bitcoin transaction in C# according to the protocol specifications. Here's the transaction in binary:
010000000162EF5D87E91090453009860C6F135EA2A490133B2633F8F7BA014889F5FF7E4A000000008A4730440220497E2D3F9BBBC0C122D839968FF880514440CED08A71D28E614FF4C871964024022049687008E4AF72682992325F17E95DA382D63E3FB14605A81B4498DFF9210E310141040BCF1BECF4EF6A5C24FD790CA86E8DCDFA3538CB97E99C254F84D209CFE47BFC6BF3B11ACA05DB7C7638301711070F176E848B650A406EB7AFC30AA9EA242489FFFFFFFF02404B4C00000000001976A9140A24F0387F05A6EECD1F8B327BB442EAB767CBC888ACCA165E00000000001976A914F8FB3B4E5D75652795DD13B209E0BE7BBD66B5D488AC00000000
I know the transaction is solid because the BTCs were transmitted properly. Furthermore, pasting my transaction above into this validator indicates the correct values.
What's stumping me is how the official transaction ID is generated. Everything on the Bitcoin and StackOverflow StackExchange sites indicate that it's generated by hashing the transaction bytes twice. I tried to do so as follows:
const String txHex="010000000162EF5D87E91090453009860C6F135EA2A490133B2633F8F7BA014889F5FF7E4A000000008A4730440220497E2D3F9BBBC0C122D839968FF880514440CED08A71D28E614FF4C871964024022049687008E4AF72682992325F17E95DA382D63E3FB14605A81B4498DFF9210E310141040BCF1BECF4EF6A5C24FD790CA86E8DCDFA3538CB97E99C254F84D209CFE47BFC6BF3B11ACA05DB7C7638301711070F176E848B650A406EB7AFC30AA9EA242489FFFFFFFF02404B4C00000000001976A9140A24F0387F05A6EECD1F8B327BB442EAB767CBC888ACCA165E00000000001976A914F8FB3B4E5D75652795DD13B209E0BE7BBD66B5D488AC00000000";
SHA256Managed sha256Hasher=new SHA256Managed();
Func<byte[],byte[]> doubleHash=(bytes)=>{
return sha256Hasher.ComputeHash((sha256Hasher.ComputeHash(bytes)));
};
String txidHex=Utils.ToHex(doubleHash(Utils.FromHex(txHex)));
Utils.ToHex() and Utils.FromHex() are helper functions copied from StackOverflow which convert between byte[] and a hex string.
The code above yields a txidHex value of 27E6C3EF18D14FB49CBAC182BBDB47FC9D6F79DA65C101873207B60A957852A7 but searching BlockExplorer.com for that particular txid yields no results.
I mentioned earlier that my transaction did execute properly. It turns out that it did so using a txid of 11172aed3a61fe64ae82cb02e886757d352a4452f956a0703d0809880538ba58. If you paste that txid into BlockExplorer you'll see my transaction.
Which leads me to my question: Given a valid transaction byte stream (byte[]), how does one correctly compute a transaction ID?
Thanks.
Thanks, man.. This bitcoin protocol is some fascinating stuff! I'm going to dig into the info you've provided. – Festus Martingale – 2015-09-03T14:51:20.487
1It's just weird mostly, the endianness of elements in transactions flips for no discernible reason. There's no standard for it in Bitcoin whatsoever. Just be aware that hashes for blocks and transactions are internally little endian but are displayed big endian to users. – Anonymous – 2015-09-03T17:13:52.633
Wow, ok, I think I get it now. Everything you stated makes sense but it leads me to a different question: Why is the transaction that was finalized in the block chain slightly different from what I submitted in my original question? The inputs/outputs are all correct. Everything looks good. Yet the transaction bytes are slightly different. – Festus Martingale – 2015-09-03T20:11:42.820
1B/c your Tx has a different signature
48304502205abb829faec8571a6469d40edbceb7938dbb5eeb0efa5b6b284d9730eb8e90a7022100c0aec347ffa72ed22057a821b0219e114a3d2686eb67904403529eac4e2c7c260141040bcf1becf4ef6a5c24fd790ca86e8dcdfa3538cb97e99c254f84d209cfe47bfc6bf3b11aca05db7c7638301711070f176e848b650a406eb7afc30aa9ea242489Vs4730440220497e2d3f9bbbc0c122d839968ff880514440ced08a71d28e614ff4c871964024022049687008e4af72682992325f17e95da382d63e3fb14605a81b4498dff9210e310141040bcf1becf4ef6a5c24fd790ca86e8dcdfa3538cb97e99c254f84d209cfe47bfc6bf3b11aca05db7c7638301711070f176e848b650a406eb7afc30aa9ea242489– Wizard Of Ozzie – 2015-09-04T10:52:17.300