The 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):
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.
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):
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!