Some months ago there was a enlightening debate about the paper "Two Bitcoins at (sic) the Price of One? Double Spending attacks on Fast Payments in Bitcoin." (
http://eprint.iacr.org/2012/248.pdf) in the thread
https://bitcointalk.org/index.php?topic=79090.0;all.
I recommend anyone who is dealing with 0/unconfirmed payments to read this thread.
The authors of the paper suggest using an alert system to tell nodes if a double-spend has occur. Some have critic the double-spend alert system of being another vector of DoS attacks. First I will describe a modified double-spend alert system does do not suffer from abuse by spamming alerts.
The paper proposes sending (Tx1,Tx2) whenever Tx1 and Tx2 are valid and they share a prevout.
(Tx1,Tx2) may be very large and and it's easy to generate a high number of alerts by combinations of prevouts.
I think the concept of double-spend alert system is not flawed and may add a new layer of certainty for merchants using 0/unconfirmed.
Here is my proposal.
Proposal 1)
Suppose Tx1 refers to the provout p in its input k, with signature script Sign1_p,k, that signs the hash of Tx1 for k, hash1_k
Suppose Tx2 refers to the provout p in its input j, with signature script Sign2_p,j, that signs the hash of Tx2 for j, hash2_j
EDITED: If Tx1 and Tx2 have the same outpoints (addresses and amounts) then no alarm is sent since only fees or previns may have changed. (thanks Etlase2 for pointing out this problem)
Obviously Sign1_p,k != Sign2_p,j and hash1_k !=hash2_j
A node that receives Tx1 and Tx2 builds the alert A=(p,Sign1_p,k,hash1_k, Sign2_p,hash2_j) and sends it to its peers.
This message is, on average, 36+139+32+139+32= 378 bytes
Alerts with length over 512 bytes should be ignored. Merchants can simply accept only standard transactions for 0/unconfirmed.
When a node receives a well-formed alert message A=(p,s1,k,h1, s2,h2)
1) If p is already maked as "double-spended", the client ignores the alert.
2) If p does not yet exists in a block, the client ignores the alert.
3) Alert signatures are checked. If invalid, the client ignores the alert.
4) Mark the outpoint p as "double-spended".
5) Send the alert to the remaining peers.
When a new block arrives, all double-spend marks are removed from previous outpoints.
Also, when a transaction Tx3 is received and refers to a previously marked outpoint, the transaction is ignored and not relayed, no new alert is sent.
(note: The LockTime field was not taken into account in this description)
The crypto part of system works because signatures are non-malleable, so the sole existence of a signature of something, even if the content is unknown, is enough proof.
Proposal 2) Also I'll propose still another layer of security, but this requires a hardfork: If a miner finds two transactions that spend the same prevouts (edit: but have different outputs), both of them can be included in a block (always one after the other), and all the money from prevouts in conflict is given to the miner, the remaining prevouts are untouched. Who will dare to try a double-spend?
Obviously all this measures do not apply to a Finney attack, which is still possible.
Best regards,
Sergio.