Den 24 jan. 2018 16:38 skrev "Tim Ruffing via bitcoin-dev" < bitcoin-dev@lists.linuxfoundation.org>: Okay, I think my proposal was wrong... This looks better (feel free to break again): 1. Commit (H(classic_pk, tx), tx) to the blockchain, wait until confirmed 2. Reveal classic_pk in the blockchain Then the tx in the first valid commitment wins. If the attacker intercepts classic_pk, it won't help him. He cannot create the first valid commitment, because it is created already. (The reason is that the decommitment is canonical now; for all commitments, the decommitment is just classic_pk.) That's not the type of attack I'm imagining. Both versions of your scheme are essentially equivalent in terms of this attack. Intended steps: 1: You publish a hash commitment. 2: The hash ends up in the blockchain. 3: You publish the transaction itself, and it matches the hash commitment. 4: Because it matches, miners includes it. It's now in the blockchain. Attack: 1: You publish a hash commitment. 2: The hash ends up the blockchain. 3: You publish the transaction itself, it matches the hash commitment. 4: The attacker mess with the network somehow to prevent your transaction from reaching the miners. 5: The attacker cracks your keypair, and makes his own commitment hash for his own theft transaction. 6: Once that commitment is in the blockchain, he publishes his own theft transaction. 7: The attacker's theft transaction gets into the blockchain. 8 (optionally): The miners finally see your original transaction with the older commitment, but now the theft transaction can't be undone. There's nothing to do about it, nor a way to know if it's intentional or not. Anybody not verifying commitments only sees a doublespend attempt. --- More speculation, not really a serious proposal: I can imagine one way to reduce the probability of success for the attack by publishing encrypted transactions as the commitment, to then publish the key - the effect of this is that the key is easier to propagate quickly across the network than a full transaction, making it harder to succeed with a network based attack. This naive version by itself is however a major DoS vector against the network. You could, in some kind of fork, redefine how blocks are processed such that you can prune all encrypted transactions that have not had the key published within X blocks. The validation rules would work such that to publish the key for an encrypted transaction in a new block, that transaction must both be recent enough, be valid by itself, and also not conflict with any other existing plaintext / decrypted transactions in the blockchain. Blocks wouldn't necessarily even need to include the encrypted transactions during propagation. This works because encrypted transactions have zero effect until the key is published. In this case you'd effectively be required to publish your encrypted transaction twice to ensure the raw data isn't lost, once to get into a block and again together with the key to get it settled. Since miners will likely keep at least the most recent encrypted transactions cached to speed up validation, this is faster to settle than to publish the committed transaction as mentioned in the beginning. This increases your chances to get your key into the blockchain to settle your transaction before the attacker completes his attack, versus pushing a full transaction that miners haven't seen before. This version would still allow DoS against miners caching all encrypted transactions. However, if efficient Zero-knowledge proofs became practical then you can use one to prove your encrypted transaction valid, even against the UTXO set and in terms of not colliding with existing commitments - in this case the DoS attack properties are nearly identical to standard transactions. If you want to change a committed transaction, you'd need to let the commitment expire.