From 1554541db444a375c0453e3c7cc3510be31a32bb Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 26 Jan 2017 21:48:59 +0000 Subject: bip-noreplay: Initial draft of an anti-replay BIP --- bip-noreplay.mediawiki | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 bip-noreplay.mediawiki diff --git a/bip-noreplay.mediawiki b/bip-noreplay.mediawiki new file mode 100644 index 0000000..efd1a2c --- /dev/null +++ b/bip-noreplay.mediawiki @@ -0,0 +1,61 @@ +
+  BIP: ?
+  Layer: Consensus (soft fork)
+  Title: Generic anti-replay protection using Script
+  Author: Luke Dashjr 
+  Comments-Summary: No comments yet.
+  Comments-URI: FIXME
+  Status: Draft
+  Type: Standards Track
+  Created: 2017-01-26
+  License: BSD-2-Clause
+
+ +==Abstract== + +This BIP describes a new opcode (OP_CHECKBLOCKATHEIGHT) for the Bitcoin scripting system that allows construction of transactions which are valid only on specific blockchains. + +==Copyright== + +This BIP is licensed under the BSD 2-clause license. + +==Specification== + +OP_CHECKBLOCKATHEIGHT redefines the existing NOP5 opcode. + +When executed, if any of the following conditions are true, the script interpreter will terminate with an error: + +* the stack has fewer than 2 elements; or +* the top item on the stack is not interpretable as a minimal-length CScriptNum; or +* the top item on the stack, when interpreted as a block height (see below) is not within the range of allowed blocks; or +* the second-to-top item on the stack, when interpreted as a block hash, has leading zeros; or +* the second-to-top item on the stack does not match the block hash of the block specified by the top item on the stack interpreted as a height. + +Otherwise, script execution will continue as if a NOP had been executed. + +FIXME: some way to mask out parts of the block hash for gambling/deterministic-random applications? + +===Block height interpretation and limits=== + +The specified block height may be either a negative number to specify a relative height, or a positive number for an absolute height. +A value of -1 refers to the block immediately preceding the block the transaction is mined it (but this is not a valid value, note). + +The specified height must not be more recent than the previous 100 blocks (that is, the largest negative value allowed is -101), nor older than 262144 blocks prior (ie, the smallest negative value is -262144). + +===Deployment=== + +This BIP will be deployed by "version bits" BIP9 with the '''name''' TBD and using '''bit''' TBD. + +For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp TBD) and BIP9 '''timeout''' will be TBD (Epoch timestamp TBD). + +For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp TBD) and BIP9 '''timeout''' will be TBD (Epoch timestamp TBD). + +==Motivation== + +In the event of a permanent blockchain split, some mechanism is desired by which the UTXOs valid in either chain may be spent without the transaction being validly replayable on the other chain. + +Additionally, there are some cases in normal Bitcoin operation wherein a wallet may need to respend a payment, but must guarantee its respend cannot be mined in the same block as a previous payment which has been recently conflicted by a double-spend. + +==Reference Implementation== + +TODO -- cgit v1.2.3 From c624f9bfa57de55759a23621ff1e088164b1e07c Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 11 May 2017 21:15:29 +0000 Subject: bip-noreplay: Merge in older no-cbah proposal which covers the same opcode --- bip-noreplay.mediawiki | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/bip-noreplay.mediawiki b/bip-noreplay.mediawiki index efd1a2c..127d7c8 100644 --- a/bip-noreplay.mediawiki +++ b/bip-noreplay.mediawiki @@ -7,13 +7,13 @@ Comments-URI: FIXME Status: Draft Type: Standards Track - Created: 2017-01-26 + Created: 2016-09-23 License: BSD-2-Clause ==Abstract== -This BIP describes a new opcode (OP_CHECKBLOCKATHEIGHT) for the Bitcoin scripting system that allows construction of transactions which are valid only on specific blockchains. +This BIP describes a new opcode (OP_CHECKBLOCKATHEIGHT) for the Bitcoin scripting system that allows construction of transactions which are valid only on specific blockchains. ==Copyright== @@ -21,15 +21,18 @@ This BIP is licensed under the BSD 2-clause license. ==Specification== -OP_CHECKBLOCKATHEIGHT redefines the existing NOP5 opcode. +OP_CHECKBLOCKATHEIGHT redefines the existing OP_NOP5 opcode. -When executed, if any of the following conditions are true, the script interpreter will terminate with an error: +When this opcode is executed: -* the stack has fewer than 2 elements; or -* the top item on the stack is not interpretable as a minimal-length CScriptNum; or -* the top item on the stack, when interpreted as a block height (see below) is not within the range of allowed blocks; or -* the second-to-top item on the stack, when interpreted as a block hash, has leading zeros; or -* the second-to-top item on the stack does not match the block hash of the block specified by the top item on the stack interpreted as a height. +* If the stack has fewer than 2 elements, the script fails. +* If the top item on the stack cannot be interpreted as a minimal-length 32-bit CScriptNum, the script fails. +* The top item on the stack is interpreted as a block height (ParamHeight, see below). +* If the blockchain (in the context of the execution) does not have ParamHeight blocks, the script fails (this failure must not be cached across blocks; it is equivalent to non-final status). +* If ParamHeight is not within the range of allowed blocks, the script fails. +* The second-to-top item on the stack is interpreted as a block hash (ParamBlockHash). +* If ParamBlockHash is longer than 28 bytes or has leading zeros, the script fails. +* If ParamBlockHash does not match the block hash of the block specified by ParamHeight, the script fails. Otherwise, script execution will continue as if a NOP had been executed. @@ -44,7 +47,7 @@ The specified height must not be more recent than the previous 100 blocks (that ===Deployment=== -This BIP will be deployed by "version bits" BIP9 with the '''name''' TBD and using '''bit''' TBD. +This BIP will be deployed by "version bits" [[bip-0009.mediawiki|BIP9]] with the '''name''' "cbah" and using '''bit''' TBD. For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp TBD) and BIP9 '''timeout''' will be TBD (Epoch timestamp TBD). @@ -52,9 +55,32 @@ For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp ==Motivation== -In the event of a permanent blockchain split, some mechanism is desired by which the UTXOs valid in either chain may be spent without the transaction being validly replayable on the other chain. +===Securely recovering from double spends=== -Additionally, there are some cases in normal Bitcoin operation wherein a wallet may need to respend a payment, but must guarantee its respend cannot be mined in the same block as a previous payment which has been recently conflicted by a double-spend. +In some circumstances, users may wish to spend received bitcoins before they have confirmed on the blockchain (Tx B1). +However, if the transaction sending them those bitcoins (Tx A1) is double-spent, the wallet must re-issue their own transaction spending them (Tx B2). +So long as the double-spend of the incoming transaction (Tx A2) also pays the wallet, this can be managed by simply updating the outgoing transaction with the new outpoint and resigning. +However, if the double-spend does not pay the wallet, the situation is presently irrecoverable: +it must spend different, non-conflicting TXOs in Tx B2, which allows an attacker to then reorganise the chain (reversing the incoming transaction's double-spend) and confirm both of his transactions Tx B1 and Tx B2. + +By adding OP_CHECKBLOCKATHEIGHT, the wallet can issue Tx B2 with a condition that the block confirming Tx A2 is in the history, thus eliminating this risk. + +===Replay protection in the event of a persistent blockchain split=== + +In the event of a persistent blockchain split, some mechanism is desired by which the UTXOs valid in either chain may be spent without the transaction being validly replayable on the other chain. + +This can be guaranteed by choosing a block which exists only on either side of the split, and pinning (using OP_CHECKBLOCKATHEIGHT) common UTXOs to be spent only on chains based on that block. + +==Rationale== + +TODO + +==Backwards Compatibility== + +OP_NOP5 ought to be forbidden by policy by all miners for future extensions such as this, so old miners will under no circumstances produce blocks which would now be considered invalid under the new rules. +However, miners must still upgrade to avoid accepting and building on top of such a possible invalid block as part of an attack. + +Old nodes will likely also not relay transactions using this opcode for the same extensibility reasons, but this is not important since the rule cannot be verified deterministically outside the context of a block. ==Reference Implementation== -- cgit v1.2.3 From d7abc41bb62e4d43f16f6e89704cb90d77cc26b4 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 11 May 2017 21:57:35 +0000 Subject: bip-noreplay: Remove relative height and redo depth limit --- bip-noreplay.mediawiki | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/bip-noreplay.mediawiki b/bip-noreplay.mediawiki index 127d7c8..5fac80c 100644 --- a/bip-noreplay.mediawiki +++ b/bip-noreplay.mediawiki @@ -27,9 +27,9 @@ When this opcode is executed: * If the stack has fewer than 2 elements, the script fails. * If the top item on the stack cannot be interpreted as a minimal-length 32-bit CScriptNum, the script fails. -* The top item on the stack is interpreted as a block height (ParamHeight, see below). +* The top item on the stack is interpreted as a block height (ParamHeight). * If the blockchain (in the context of the execution) does not have ParamHeight blocks, the script fails (this failure must not be cached across blocks; it is equivalent to non-final status). -* If ParamHeight is not within the range of allowed blocks, the script fails. +* If ParamHeight specifies a block deeper than 52596 blocks in the chain (including negative values), the opcode completes successfully and script continues as normal. * The second-to-top item on the stack is interpreted as a block hash (ParamBlockHash). * If ParamBlockHash is longer than 28 bytes or has leading zeros, the script fails. * If ParamBlockHash does not match the block hash of the block specified by ParamHeight, the script fails. @@ -38,13 +38,6 @@ Otherwise, script execution will continue as if a NOP had been executed. FIXME: some way to mask out parts of the block hash for gambling/deterministic-random applications? -===Block height interpretation and limits=== - -The specified block height may be either a negative number to specify a relative height, or a positive number for an absolute height. -A value of -1 refers to the block immediately preceding the block the transaction is mined it (but this is not a valid value, note). - -The specified height must not be more recent than the previous 100 blocks (that is, the largest negative value allowed is -101), nor older than 262144 blocks prior (ie, the smallest negative value is -262144). - ===Deployment=== This BIP will be deployed by "version bits" [[bip-0009.mediawiki|BIP9]] with the '''name''' "cbah" and using '''bit''' TBD. @@ -73,6 +66,17 @@ This can be guaranteed by choosing a block which exists only on either side of t ==Rationale== +Why are block heights required to be absolute, rather than relative? + +* A relative block height would allow for creation of transactions which are valid at block N, but not N+1. This is carefully avoided by Bitcoin to ensure that if any given block is reorganised out, non-malicious transactions can be simply re-confirmed in a later block. + +Why are blocks older than 52596 deep in the chain not verified? + +* This is to avoid creating an infinite storage requirement from all full nodes which would be necessary to maintain all the block headers indefinitely. 52596 block headers requires a fixed size of approximately 4 MB. +* In any case where you might want to specify a deeper block, you can also just as well specify a more recent one that decends from it. +* It is assumed that 1 year is sufficient time to double-spend any common UTXOs on all blockchains of interest. +* If a deeper check is needed, it can be softforked in. Making the check more shallow, on the other hand, is a hardfork. + TODO ==Backwards Compatibility== -- cgit v1.2.3 From b582f4e9a9f4e8580a934e60898ad1c7630c9fd1 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 11 May 2017 22:12:49 +0000 Subject: bip-noreplay: Redo leading zero logic and allow truncated block hashes --- bip-noreplay.mediawiki | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/bip-noreplay.mediawiki b/bip-noreplay.mediawiki index 5fac80c..947c611 100644 --- a/bip-noreplay.mediawiki +++ b/bip-noreplay.mediawiki @@ -31,13 +31,11 @@ When this opcode is executed: * If the blockchain (in the context of the execution) does not have ParamHeight blocks, the script fails (this failure must not be cached across blocks; it is equivalent to non-final status). * If ParamHeight specifies a block deeper than 52596 blocks in the chain (including negative values), the opcode completes successfully and script continues as normal. * The second-to-top item on the stack is interpreted as a block hash (ParamBlockHash). -* If ParamBlockHash is longer than 28 bytes or has leading zeros, the script fails. -* If ParamBlockHash does not match the block hash of the block specified by ParamHeight, the script fails. +* If ParamBlockHash is longer than 28 bytes, the script fails. +* If ParamBlockHash does not match the equivalent ending bytes of the block hash specified by ParamHeight, the script fails. Otherwise, script execution will continue as if a NOP had been executed. -FIXME: some way to mask out parts of the block hash for gambling/deterministic-random applications? - ===Deployment=== This BIP will be deployed by "version bits" [[bip-0009.mediawiki|BIP9]] with the '''name''' "cbah" and using '''bit''' TBD. @@ -77,6 +75,19 @@ Why are blocks older than 52596 deep in the chain not verified? * It is assumed that 1 year is sufficient time to double-spend any common UTXOs on all blockchains of interest. * If a deeper check is needed, it can be softforked in. Making the check more shallow, on the other hand, is a hardfork. +Why is ParamBlockHash allowed to match less than the full block hash? + +* In a chain split, it is sufficient to check only a few bytes to avoid replay. +* In all scenarios, it is likely sufficient to check only a minority of the full hash to avoid any realistic chance of replay. +* Allowing less than the full hash to be specified saves space in transaction data. +* Using a single byte can be combined with other opcodes (such as OP_LESSTHAN) to enable on-chain gambling logic. + +What if ParamBlockHash has leading zeros? Should this be prevented? + +* If leading zeros are included, they should be compared to the actual block hash. (If they were truncated, fewer bytes would be compared.) +* It is unlikely that the leading zeros will ever be necessary for sufficient precision, so the additional space is not a concern. +* Since all block hashes are in principle shorter than than 29 bytes, ParamBlockHash may not be larger than 28 bytes. + TODO ==Backwards Compatibility== -- cgit v1.2.3 From 27b1d4944f5c4487f7567b45c0beb310fec8cbcc Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 12 May 2017 04:05:06 +0000 Subject: bip-noreplay: Link reference implementation --- bip-noreplay.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-noreplay.mediawiki b/bip-noreplay.mediawiki index 947c611..83680e3 100644 --- a/bip-noreplay.mediawiki +++ b/bip-noreplay.mediawiki @@ -99,4 +99,4 @@ Old nodes will likely also not relay transactions using this opcode for the same ==Reference Implementation== -TODO +https://github.com/bitcoin/bitcoin/compare/master...luke-jr:cbah -- cgit v1.2.3 From 28621f70b53597ac7eab3e1f4a032a73019a6847 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 12 May 2017 04:08:40 +0000 Subject: bip-noreplay: Explain same-block and recent-block cases --- bip-noreplay.mediawiki | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bip-noreplay.mediawiki b/bip-noreplay.mediawiki index 83680e3..e5b725f 100644 --- a/bip-noreplay.mediawiki +++ b/bip-noreplay.mediawiki @@ -28,7 +28,7 @@ When this opcode is executed: * If the stack has fewer than 2 elements, the script fails. * If the top item on the stack cannot be interpreted as a minimal-length 32-bit CScriptNum, the script fails. * The top item on the stack is interpreted as a block height (ParamHeight). -* If the blockchain (in the context of the execution) does not have ParamHeight blocks, the script fails (this failure must not be cached across blocks; it is equivalent to non-final status). +* If the blockchain (in the context of the execution) does not have ParamHeight blocks prior to the one including this transaction, the script fails (this failure must not be cached across blocks; it is equivalent to non-final status). * If ParamHeight specifies a block deeper than 52596 blocks in the chain (including negative values), the opcode completes successfully and script continues as normal. * The second-to-top item on the stack is interpreted as a block hash (ParamBlockHash). * If ParamBlockHash is longer than 28 bytes, the script fails. @@ -88,7 +88,10 @@ What if ParamBlockHash has leading zeros? Should this be prevented? * It is unlikely that the leading zeros will ever be necessary for sufficient precision, so the additional space is not a concern. * Since all block hashes are in principle shorter than than 29 bytes, ParamBlockHash may not be larger than 28 bytes. -TODO +Why is it safe to allow checking blocks as recently as the immediate previous block? + +* This should only be used when necessary (ie, the deeper block is not sufficient), and when the wallet can actively issue updates should the blockchain reorganise. +* While this allows intentionally creating a transaction which may be invalid in a reorganization, the same can already be accomplished by creating double spends. ==Backwards Compatibility== -- cgit v1.2.3 From f09485e3d81f034a9a48b199562777fa9c0314fd Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 12 May 2017 04:12:37 +0000 Subject: Assign BIP 115: Generic anti-replay protection using Script --- README.mediawiki | 7 ++++ bip-0115.mediawiki | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ bip-noreplay.mediawiki | 105 ------------------------------------------------- 3 files changed, 112 insertions(+), 105 deletions(-) create mode 100644 bip-0115.mediawiki delete mode 100644 bip-noreplay.mediawiki diff --git a/README.mediawiki b/README.mediawiki index 1398ca3..b8fa3f3 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -498,6 +498,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Draft |- +| [[bip-0115.mediawiki|115]] +| Consensus (soft fork) +| Generic anti-replay protection using Script +| Luke Dashjr +| Standard +| Draft +|- | [[bip-0120.mediawiki|120]] | Applications | Proof of Payment diff --git a/bip-0115.mediawiki b/bip-0115.mediawiki new file mode 100644 index 0000000..f4c8777 --- /dev/null +++ b/bip-0115.mediawiki @@ -0,0 +1,105 @@ +
+  BIP: 115
+  Layer: Consensus (soft fork)
+  Title: Generic anti-replay protection using Script
+  Author: Luke Dashjr 
+  Comments-Summary: No comments yet.
+  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0115
+  Status: Draft
+  Type: Standards Track
+  Created: 2016-09-23
+  License: BSD-2-Clause
+
+ +==Abstract== + +This BIP describes a new opcode (OP_CHECKBLOCKATHEIGHT) for the Bitcoin scripting system that allows construction of transactions which are valid only on specific blockchains. + +==Copyright== + +This BIP is licensed under the BSD 2-clause license. + +==Specification== + +OP_CHECKBLOCKATHEIGHT redefines the existing OP_NOP5 opcode. + +When this opcode is executed: + +* If the stack has fewer than 2 elements, the script fails. +* If the top item on the stack cannot be interpreted as a minimal-length 32-bit CScriptNum, the script fails. +* The top item on the stack is interpreted as a block height (ParamHeight). +* If the blockchain (in the context of the execution) does not have ParamHeight blocks prior to the one including this transaction, the script fails (this failure must not be cached across blocks; it is equivalent to non-final status). +* If ParamHeight specifies a block deeper than 52596 blocks in the chain (including negative values), the opcode completes successfully and script continues as normal. +* The second-to-top item on the stack is interpreted as a block hash (ParamBlockHash). +* If ParamBlockHash is longer than 28 bytes, the script fails. +* If ParamBlockHash does not match the equivalent ending bytes of the block hash specified by ParamHeight, the script fails. + +Otherwise, script execution will continue as if a NOP had been executed. + +===Deployment=== + +This BIP will be deployed by "version bits" [[bip-0009.mediawiki|BIP9]] with the '''name''' "cbah" and using '''bit''' TBD. + +For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp TBD) and BIP9 '''timeout''' will be TBD (Epoch timestamp TBD). + +For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp TBD) and BIP9 '''timeout''' will be TBD (Epoch timestamp TBD). + +==Motivation== + +===Securely recovering from double spends=== + +In some circumstances, users may wish to spend received bitcoins before they have confirmed on the blockchain (Tx B1). +However, if the transaction sending them those bitcoins (Tx A1) is double-spent, the wallet must re-issue their own transaction spending them (Tx B2). +So long as the double-spend of the incoming transaction (Tx A2) also pays the wallet, this can be managed by simply updating the outgoing transaction with the new outpoint and resigning. +However, if the double-spend does not pay the wallet, the situation is presently irrecoverable: +it must spend different, non-conflicting TXOs in Tx B2, which allows an attacker to then reorganise the chain (reversing the incoming transaction's double-spend) and confirm both of his transactions Tx B1 and Tx B2. + +By adding OP_CHECKBLOCKATHEIGHT, the wallet can issue Tx B2 with a condition that the block confirming Tx A2 is in the history, thus eliminating this risk. + +===Replay protection in the event of a persistent blockchain split=== + +In the event of a persistent blockchain split, some mechanism is desired by which the UTXOs valid in either chain may be spent without the transaction being validly replayable on the other chain. + +This can be guaranteed by choosing a block which exists only on either side of the split, and pinning (using OP_CHECKBLOCKATHEIGHT) common UTXOs to be spent only on chains based on that block. + +==Rationale== + +Why are block heights required to be absolute, rather than relative? + +* A relative block height would allow for creation of transactions which are valid at block N, but not N+1. This is carefully avoided by Bitcoin to ensure that if any given block is reorganised out, non-malicious transactions can be simply re-confirmed in a later block. + +Why are blocks older than 52596 deep in the chain not verified? + +* This is to avoid creating an infinite storage requirement from all full nodes which would be necessary to maintain all the block headers indefinitely. 52596 block headers requires a fixed size of approximately 4 MB. +* In any case where you might want to specify a deeper block, you can also just as well specify a more recent one that decends from it. +* It is assumed that 1 year is sufficient time to double-spend any common UTXOs on all blockchains of interest. +* If a deeper check is needed, it can be softforked in. Making the check more shallow, on the other hand, is a hardfork. + +Why is ParamBlockHash allowed to match less than the full block hash? + +* In a chain split, it is sufficient to check only a few bytes to avoid replay. +* In all scenarios, it is likely sufficient to check only a minority of the full hash to avoid any realistic chance of replay. +* Allowing less than the full hash to be specified saves space in transaction data. +* Using a single byte can be combined with other opcodes (such as OP_LESSTHAN) to enable on-chain gambling logic. + +What if ParamBlockHash has leading zeros? Should this be prevented? + +* If leading zeros are included, they should be compared to the actual block hash. (If they were truncated, fewer bytes would be compared.) +* It is unlikely that the leading zeros will ever be necessary for sufficient precision, so the additional space is not a concern. +* Since all block hashes are in principle shorter than than 29 bytes, ParamBlockHash may not be larger than 28 bytes. + +Why is it safe to allow checking blocks as recently as the immediate previous block? + +* This should only be used when necessary (ie, the deeper block is not sufficient), and when the wallet can actively issue updates should the blockchain reorganise. +* While this allows intentionally creating a transaction which may be invalid in a reorganization, the same can already be accomplished by creating double spends. + +==Backwards Compatibility== + +OP_NOP5 ought to be forbidden by policy by all miners for future extensions such as this, so old miners will under no circumstances produce blocks which would now be considered invalid under the new rules. +However, miners must still upgrade to avoid accepting and building on top of such a possible invalid block as part of an attack. + +Old nodes will likely also not relay transactions using this opcode for the same extensibility reasons, but this is not important since the rule cannot be verified deterministically outside the context of a block. + +==Reference Implementation== + +https://github.com/bitcoin/bitcoin/compare/master...luke-jr:cbah diff --git a/bip-noreplay.mediawiki b/bip-noreplay.mediawiki deleted file mode 100644 index e5b725f..0000000 --- a/bip-noreplay.mediawiki +++ /dev/null @@ -1,105 +0,0 @@ -
-  BIP: ?
-  Layer: Consensus (soft fork)
-  Title: Generic anti-replay protection using Script
-  Author: Luke Dashjr 
-  Comments-Summary: No comments yet.
-  Comments-URI: FIXME
-  Status: Draft
-  Type: Standards Track
-  Created: 2016-09-23
-  License: BSD-2-Clause
-
- -==Abstract== - -This BIP describes a new opcode (OP_CHECKBLOCKATHEIGHT) for the Bitcoin scripting system that allows construction of transactions which are valid only on specific blockchains. - -==Copyright== - -This BIP is licensed under the BSD 2-clause license. - -==Specification== - -OP_CHECKBLOCKATHEIGHT redefines the existing OP_NOP5 opcode. - -When this opcode is executed: - -* If the stack has fewer than 2 elements, the script fails. -* If the top item on the stack cannot be interpreted as a minimal-length 32-bit CScriptNum, the script fails. -* The top item on the stack is interpreted as a block height (ParamHeight). -* If the blockchain (in the context of the execution) does not have ParamHeight blocks prior to the one including this transaction, the script fails (this failure must not be cached across blocks; it is equivalent to non-final status). -* If ParamHeight specifies a block deeper than 52596 blocks in the chain (including negative values), the opcode completes successfully and script continues as normal. -* The second-to-top item on the stack is interpreted as a block hash (ParamBlockHash). -* If ParamBlockHash is longer than 28 bytes, the script fails. -* If ParamBlockHash does not match the equivalent ending bytes of the block hash specified by ParamHeight, the script fails. - -Otherwise, script execution will continue as if a NOP had been executed. - -===Deployment=== - -This BIP will be deployed by "version bits" [[bip-0009.mediawiki|BIP9]] with the '''name''' "cbah" and using '''bit''' TBD. - -For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp TBD) and BIP9 '''timeout''' will be TBD (Epoch timestamp TBD). - -For Bitcoin '''mainnet''', the BIP9 '''starttime''' will be TBD (Epoch timestamp TBD) and BIP9 '''timeout''' will be TBD (Epoch timestamp TBD). - -==Motivation== - -===Securely recovering from double spends=== - -In some circumstances, users may wish to spend received bitcoins before they have confirmed on the blockchain (Tx B1). -However, if the transaction sending them those bitcoins (Tx A1) is double-spent, the wallet must re-issue their own transaction spending them (Tx B2). -So long as the double-spend of the incoming transaction (Tx A2) also pays the wallet, this can be managed by simply updating the outgoing transaction with the new outpoint and resigning. -However, if the double-spend does not pay the wallet, the situation is presently irrecoverable: -it must spend different, non-conflicting TXOs in Tx B2, which allows an attacker to then reorganise the chain (reversing the incoming transaction's double-spend) and confirm both of his transactions Tx B1 and Tx B2. - -By adding OP_CHECKBLOCKATHEIGHT, the wallet can issue Tx B2 with a condition that the block confirming Tx A2 is in the history, thus eliminating this risk. - -===Replay protection in the event of a persistent blockchain split=== - -In the event of a persistent blockchain split, some mechanism is desired by which the UTXOs valid in either chain may be spent without the transaction being validly replayable on the other chain. - -This can be guaranteed by choosing a block which exists only on either side of the split, and pinning (using OP_CHECKBLOCKATHEIGHT) common UTXOs to be spent only on chains based on that block. - -==Rationale== - -Why are block heights required to be absolute, rather than relative? - -* A relative block height would allow for creation of transactions which are valid at block N, but not N+1. This is carefully avoided by Bitcoin to ensure that if any given block is reorganised out, non-malicious transactions can be simply re-confirmed in a later block. - -Why are blocks older than 52596 deep in the chain not verified? - -* This is to avoid creating an infinite storage requirement from all full nodes which would be necessary to maintain all the block headers indefinitely. 52596 block headers requires a fixed size of approximately 4 MB. -* In any case where you might want to specify a deeper block, you can also just as well specify a more recent one that decends from it. -* It is assumed that 1 year is sufficient time to double-spend any common UTXOs on all blockchains of interest. -* If a deeper check is needed, it can be softforked in. Making the check more shallow, on the other hand, is a hardfork. - -Why is ParamBlockHash allowed to match less than the full block hash? - -* In a chain split, it is sufficient to check only a few bytes to avoid replay. -* In all scenarios, it is likely sufficient to check only a minority of the full hash to avoid any realistic chance of replay. -* Allowing less than the full hash to be specified saves space in transaction data. -* Using a single byte can be combined with other opcodes (such as OP_LESSTHAN) to enable on-chain gambling logic. - -What if ParamBlockHash has leading zeros? Should this be prevented? - -* If leading zeros are included, they should be compared to the actual block hash. (If they were truncated, fewer bytes would be compared.) -* It is unlikely that the leading zeros will ever be necessary for sufficient precision, so the additional space is not a concern. -* Since all block hashes are in principle shorter than than 29 bytes, ParamBlockHash may not be larger than 28 bytes. - -Why is it safe to allow checking blocks as recently as the immediate previous block? - -* This should only be used when necessary (ie, the deeper block is not sufficient), and when the wallet can actively issue updates should the blockchain reorganise. -* While this allows intentionally creating a transaction which may be invalid in a reorganization, the same can already be accomplished by creating double spends. - -==Backwards Compatibility== - -OP_NOP5 ought to be forbidden by policy by all miners for future extensions such as this, so old miners will under no circumstances produce blocks which would now be considered invalid under the new rules. -However, miners must still upgrade to avoid accepting and building on top of such a possible invalid block as part of an attack. - -Old nodes will likely also not relay transactions using this opcode for the same extensibility reasons, but this is not important since the rule cannot be verified deterministically outside the context of a block. - -==Reference Implementation== - -https://github.com/bitcoin/bitcoin/compare/master...luke-jr:cbah -- cgit v1.2.3