3 ms·
Both of these exchanges apparently implemented the Bitcoin protocol incorrectly. Their code that verifies a transaction has completed is incorrect, so they can
by dangrossman 13y ago
Both of these exchanges apparently implemented the Bitcoin protocol incorrectly. Their code that verifies a transaction has completed is incorrect, so they can be tricked into thinking a withdrawal did not happen when it actually did (or that a lesser amount was withdrawn). They need to fix their code, as there is a proper way to verify a transaction occurred or not.
Some reading:
http://qz.com/175565/why-nobody-can-withdraw-bitcoins-from-one-of-the-currencys-largest-exchanges/ http://qz.com/175565/why-nobody-can-withdraw-bitcoins-from-o...
- mason55 13y agoFWIW it's an error in the BTC reference implementation so it's an easy error to make
- TwoBit 13y agoIs that true? If so then significant blame goes to that in addition to the exchanges.
- Dosenpfand 13y agoPlease stop spreading FUD. >In the meantime, users of the reference implementation do not need to be concerned. Transactions are always tracked properly by the Bitcoin-Qt/bitcoind software. https://bitcoinfoundation.org/blog/?p=418 https://bitcoinfoundation.org/blog/?p=418
- mason55 13y agoInteresting. This thread on reddit states that it IS an issue in the reference implementation and includes a patch http://www.reddit.com/r/Bitcoin/comments/1xm49o/due_to_active_malleable_transaction_relayers_it/ http://www.reddit.com/r/Bitcoin/comments/1xm49o/due_to_activ... Edit: The concern with the Bitstamp appears to be confusion due to transaction malleability and NOT actual double spend or cancellation issues. However the BTC reference client is not perfect at handling malleability and only gets it right eventually.
- makomk 13y agoWhile it's not an issue if you're using the GUI, the official client makes it hard for API consumers to track what's going on. As far as they're concerned, the transaction they requested never succeeds and a new one with a completely different ID that they never sent appears. It's entirely up to API consumers to reliably match the new, different transaction up with what they originally requested - and the API doesn't actually expose the information they need to do this cleanly.
- hmsimha 13y agoThis is what you're referring to, right? https://en.bitcoin.it/wiki/Original_Bitcoin_client https://en.bitcoin.it/wiki/Original_Bitcoin_client I imagine that the more recent versions of the satoshi client don't have this bug, it may have a few years ago when bitstamp and mtgox may have been looking to draw inspiration from it.
- mason55 13y agoI was referring to this thread: http://www.reddit.com/r/Bitcoin/comments/1xm49o/due_to_active_malleable_transaction_relayers_it/ http://www.reddit.com/r/Bitcoin/comments/1xm49o/due_to_activ...
- Judson 13y agoThis is NOT the case. To quote gmaxwell on the bitcoin-development mailing list: "Not that Bitcoin-QT handles Malleability fantastically— but because it tracks inputs it will still detect the mutant transactions." http://sourceforge.net/mailarchive/message.php?msg_id=31956576 http://sourceforge.net/mailarchive/message.php?msg_id=319565...
- mason55 13y agoRight... so I believe what's happening is that the client handles them correctly.... eventually. But from what people are saying it's causing confusion in the accounting with the effected exchanges, not necessarily cancellation or double spend issues.
- Judson 13y agoI'll explain it to the best of my understanding, at least in a narrow scope. A user on an exchange requests to withdraw btc. MtGox creates a transaction with a tx hash of abc1234cdf... and sends it to the blockchain, polling for the status of tx hash "abc1234cdf...". Due to tx malleability, the tx hash can change by changing some of the tx data (in insignificant ways), which doesn't invalidate the tx signatures. A malicious user could wait for MtGox to create a tx, flip a bit and resubmit the tx and try to get it confirmed under a different hash, invalidating Gox's tx as a double spend. Which leaves Gox polling for the status of tx hash "abc1234cdf...", which will never confirm. A user then submits a support request and says their tx is "Stuck". MtGox then creates a new tx, Which doesn't respend the same coins, and thus, the user is paid 2x.
- yetfeo 13y agoThis is not true. It does not handle malleability in one case. See http://www.reddit.com/r/Bitcoin/comments/1xm49o/due_to_active_malleable_transaction_relayers_it/ http://www.reddit.com/r/Bitcoin/comments/1xm49o/due_to_activ... This is why many sites are having issues. It is in fact a problem with the reference client.
- waterlesscloud 13y agoI wouldn't call it an error, exactly. But it is a design flaw that other implementations are expected to work around.
- wcummings 13y ago>(or that a lesser amount was withdrawn) As I understand it, this is not correct, the new tx must be functionally identical to the old one (same inputs and outputs), just with a different txid. Someone correct me if I'm wrong
- patio11 13y agoThe Bitcoin protocol is the Satoshi client; the Satoshi client is the Bitcoin protocol. No Bitcoin protocol exists outside of the single source of truth, which is "how does the Satoshi client actually operate?" Both exchanges use the JSON/RPC interface to the Satoshi bitcoin client. That is the One True Way to use Bitcoin to develop Bitcoin-consuming applications. To do otherwise is madness. (I've seen explanations that Mt. Gox was using a custom client, but I believe they mean "Mt. Gox was using a custom system which took care of bookkeeping for itself, because the Satoshi client cannot operate thousand of wallets in any sane fashion, but used the Satoshi client for interacting with the Bitcoin network.") The Bitcoin RPC interface exposes many methods. I don't have intimate knowledge of which one these exchanges were using, but since they all have similar issues, let's assume they used sendtoaddress. The message signature of sendtoaddress is (pseudo-code): #returns transaction_id sendtoaddress(from_account, to_bitcoin_address, amount, optional_message) The mistake which both exchanges made is they assumed transaction_id is the same transaction_id used for gettransaction(transaction_id). It is. If you send a transaction, wait an hour, and then get it by ID, that will work. But it isn't. Transaction ID means absolutely nothing. It can be changed by any party, worldwide, for up to one hour after the invocation of sendtoaddress. If you use gettransaction(transaction_id) and it returns nil, that does not prove that the transaction you previously created did not succeed correctly. You should not attempt to retry the transaction until first verifying that you have all the coins you started with and that the recipient does not have some of your coins. You can conveniently do this with an O(n) scan over all Bitcoin transactions ever. (Someone pointed out to me on twitter that it isn't O(n) if you have your database indices set properly. Well, yeah, true.) You'll need to know what addresses you actually sent from, which is obscured by the sentoaddress API described above, for that scan to succeed, so essentially you're going to reimpliment much of the Satoshi Bitcoin client, particularly around the area of wallet management. Don't reimpliment everything, though -- down that path lies madness. Also, try not to make any bugs anywhere, particularly not the kind which only show up when someone tries to steal from you. Good luck!