blockchain / unused-My-Wallet

Legacy Blockchain Web Wallet - current version is at https://github.com/blockchain/My-Wallet-V3-Frontend
206 stars 127 forks source link

Unspent api call returns wrong tx_hash #74

Closed pelle closed 9 years ago

pelle commented 10 years ago

Here is an example:

curl https://blockchain.info/unspent?active=1EURH7eJgZmBH571vVhjTXBkgLTjGVEu5M
{

    "unspent_outputs":[

        {
            "tx_hash":"97417017ecc003e268b8664717d2e43fbb6d3e2a8c93ff1be4970882b9e6474e",
            "tx_index":104079689,
            "tx_output_n": 1,
            "script":"76a91493c921dcc6cd496268a80622423035d57896ff5888ac",
            "value": 365309,
            "value_hex": "0592fd",
            "confirmations":12273
        },

        {
            "tx_hash":"a5218dd9d355111f5de899ea599dddde4374ce020efd31c876e25bc7c64624b1",
            "tx_index":108630824,
            "tx_output_n": 0,
            "script":"76a91493c921dcc6cd496268a80622423035d57896ff5888ac",
            "value": 100000,
            "value_hex": "0186a0",
            "confirmations":7133
        }

    ]

Calling the same url but with html shows the correct hashes:

https://blockchain.info/unspent?active=1EURH7eJgZmBH571vVhjTXBkgLTjGVEu5M&format=html

unspent outputs 1eurh7ejgzmbh571vvhjtxbkgltjgveu5m

FreeTrade commented 10 years ago

Yes - more on this - brainwallet seems to rely on having the incorrect value here to send transactions - but what is the tx_hash value being used? It is not being found as any transaction - https://blockchain.info/tx/97417017ecc003e268b8664717d2e43fbb6d3e2a8c93ff1be4970882b9e6474e

FreeTrade commented 10 years ago

Okay - looks like it is just the order of the bytes being reversed - so instead of

97417017ecc003e268b8664717d2e43fbb6d3e2a8c93ff1be4970882b9e6474e

we get

4e47e6b9820897e41bff938c2a3e6dbb3fe4d2174766b868e203c0ec17704197

pelle commented 10 years ago

LOL that explains it. Good piece of pattern matching that you noticed that @FreeTrade.

dylanparker commented 10 years ago

Pelle, what is your plan to code against this? Wait for a fix? Assume the bytes are swapped and un-swap any returned tx_hash in the unspent_outputs call?

sagivo commented 10 years ago

i don't understand.. how do i get the tx number from tx_hash?

KMHouk commented 10 years ago

You have to decode the hex and reverse the Bytes in order to get the transaction ID that is displayed on the html pages. The format that is displayed in JSON is true to the network, while our html pages present it in a nicer way.

sagivo commented 10 years ago

@KMHouk can you give me an example how to do it?

KMHouk commented 10 years ago

Sure, taking these as an example: https://blockchain.info/unspent?active=15MeziT7z21y4L7PPk2wDYvLR2exa5QnDL&format=html https://blockchain.info/unspent?active=15MeziT7z21y4L7PPk2wDYvLR2exa5QnDL&format=json

So on the json one, take 2b1b20cf4547fd0124a689f186ad0da154c7c887c316a5c9bd98a18d3c4e13f2, put it into a hex decoder (like this site): http://paulschou.com/tools/xlate/ -- It will spit this out in the BINARY section: 00101011 00011011 00100000 11001111 01000101 01000111 11111101 00000001 00100100 10100110 10001001 11110001 10000110 10101101 00001101 10100001 01010100 11000111 11001000 10000111 11000011 00010110 10100101 11001001 10111101 10011000 10100001 10001101 00111100 01001110 00010011 11110010

So then reverse that: 11110010 00010011 01001110 00111100 10001101 10100001 10011000 10111101 11001001 10100101 00010110 11000011 10000111 11001000 11000111 01010100 10100001 00001101 10101101 10000110 11110001 10001001 10100110 00100100 00000001 11111101 01000111 01000101 11001111 00100000 00011011 00101011

Decode it and you get the hex value that looks like what is found on the network (the html version): f2 13 4e 3c 8d a1 98 bd c9 a5 16 c3 87 c8 c7 54 a1 0d ad 86 f1 89 a6 24 01 fd 47 45 cf 20 1b 2b

intelliot commented 9 years ago

What's a library or function that someone can use to reverse the byte order programmatically?

intelliot commented 9 years ago

Finally figured it out --

If using node.js, do:

npm install cryptojs

Then in your code:

var Crypto = require("cryptojs").Crypto
var hash = Crypto.util.bytesToHex(Crypto.util.hexToBytes(tx_hash_in_reverse_byte_order).reverse());
ghost commented 9 years ago

Python reversal:

import binascii
reversed_hash = binascii.hexlify(binascii.unhexlify(hash)[::-1])