12

Please note that this question is NOT a duplicate of other questions regarding .

My question is regarding a following scenario, that could happen on an exchange that uses on-chain wallet management:

  • user deposits funds on address A, belonging to his account on an exchange. Exchange waits n confirmations before it credits user account.
  • user then moves funds from address A to address B, which also belongs to his account on the same exchange. Exchange doesn't wait for any confirmations here, because the it knows it won't double-spend itself. Exchange thus notes the TXID of this transaction for future use.
  • while transaction is unconfirmed, someone exploits transaction malleability issue and pushes its tweaked version, which gets picked up by miners instead.
  • in the mean time, user wants to withdraw funds to address C, which is another exchange or external wallet. Exchange creates this transaction using TXID that it stored earlier. Unfortunately, Blockchain doesn't know this TXID because it was rejected by majority of miners. The exchange though doesn't get immediate feedback about that, because it doesn't know that a tweaked version of that transaction exists (since both are still unconfirmed)
  • in effect, funds are not withdrawn, and exchange operators are left wondering why this happened.

Now the following situation has NOT happened to me (yet), but I'm wondering:

  • is it realistic enough that it could happen, or is there something I missed?
  • how I can guard against this? For me it seems that the best fix for this would be use of the new NTXID instead of TXID in transaction inputs. But that will probably not be possible in near future, because required quite a big change in the protocol.
1
  • For what I understand about the normalized transaction ID (NTXID), you can use it as a "helpdesk identifier" for transactions you created yourself. In your example you should also detect the changed TXID of B, to be able to use its outputs in the C transaction. The answer to how to do that: bitcoin.stackexchange.com/questions/24048/… Commented Apr 23, 2014 at 9:03

2 Answers 2

5

This is the new issue, the one that's causing all the trouble. You basically have two choices:

  1. Don't spend any of your own outputs until you're quite confident they're fully confirmed. For example, you could wait for three confirmations.

  2. Be prepared to deal with this problem by monitoring your outstanding transaction chains and re-issuing any orphaned transactions with new input transaction IDs.

5
  • 1
    Both solutions have their flaws. Number one implies that user will need to wait between taking actions with his wallet, which isn't the end of the world, but far from ideal. Number two is impossible to automate in my case, because I use multi signature wallets, which means user has to confirm every transaction from his wallets, so I cannot resend the tx automatically if an orphan is detected. As I said, the best way to deal with that would be to use NTXID as an input. Any idea if that's even remotely possible in near future?
    – mav
    Commented Feb 24, 2014 at 1:14
  • 1
    @mav Yeah, it's a real issue. Allowing NTXID to be used as an input would be a painful hard fork that would require everyone to reindex all unspent outputs. I guess another way to do it would be to have a way to specify in a transaction that this specific transaction be referenced by NTXID and still allow "legacy" transactions to be referenced by TXID. Then you could set this option in all your transactions. I don't know if the community has considered that. Commented Feb 24, 2014 at 1:58
  • 1
    @Gracchus The complexity of the transition depends on the nature of the implementation. But basically, the procedure you outlines is how you would do it. Commented Feb 25, 2014 at 4:02
  • @Gracchus, What do you mean by "abrupt"?
    – Pacerier
    Commented May 22, 2014 at 14:03
  • @David, then wouldn't the whole idea of "green addresses" (accept as confirmed if coming from respected address) be rendered unusable?
    – Pacerier
    Commented May 22, 2014 at 14:03
1

Here is a workaround that doesn't solve the core issue but it will solve your problem.

Before you make the transaction check if the destination address is also an address that belongs to the same user. If so, don't create the transaction. Warn the user that the destination address belongs to him and that he cannot make this transfer.

This can also happen if address B belongs to another user on your site. Do the same check and make the transaction off the chain. Just update users' balances but do not create a bitcoin transaction.

Assuming that this scenario actually takes place in an exchange, I think you can comfortably draw the line like this.

Moving balances between two addresses that belong to the same user sounds like a wallet functionality. But you are running an exchange.

Some users might complain, but hey, better to be safe than goxed. They will understand.

3
  • 1
    I run a multi signature wallet scheme, I cannot just "update users' balances" here. It's a full-reserve, on-chain solution with much better security, but has this downside that I'll need to wait for the confirmation between every action to be safe against malleability.
    – mav
    Commented Feb 26, 2014 at 21:59
  • I see. Sounds interesting. May I ask which site?
    – Emre K.
    Commented Feb 27, 2014 at 8:10
  • it's called Bitalo. We launched last month.
    – mav
    Commented Feb 28, 2014 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.