mirror of https://github.com/lukechilds/bips.git
BtcDrak
9 years ago
2 changed files with 212 additions and 0 deletions
@ -0,0 +1,206 @@ |
|||
<pre> |
|||
BIP: XX |
|||
Title: OP_CHECKSEQUENCEVERIFY |
|||
Authors: BtcDrak <btcdrak@gmail.com> |
|||
Mark Friedenbach <mark@friedenbach.org> |
|||
Status: Draft |
|||
Type: Standards Track |
|||
Created: 2015-08-10 |
|||
</pre> |
|||
|
|||
==Abstract== |
|||
|
|||
This BIP describes a new opcode (OP_CHECKSEQUENCEVERIFY) for the Bitcoin |
|||
scripting system that allows a transaction output to be made unspendable |
|||
until some relative point in the future according to the nSequence field. |
|||
|
|||
|
|||
==Summary== |
|||
|
|||
CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed it |
|||
compares the top item on the stack to the nSequence field of the transaction |
|||
containing the scriptSig. If that top stack item is greater than the |
|||
transaction sequence threshold (1 << 31) the script fails immediately, |
|||
otherwise script evaluation continues as though a NOP was executed. |
|||
|
|||
By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field, |
|||
we indirectly verify that the desired block height or block time has been |
|||
reached (according to BIP68's redefinition of nSequence); until that block |
|||
height or block time has been reached the transaction output remains |
|||
unspendable. |
|||
|
|||
|
|||
==Motivation== |
|||
|
|||
BIP68 repurposes the transaction nSequence field meaning by giving sequence |
|||
numbers new consensus-enforced semantics as a relative lock-time. However, |
|||
there is no way to build Bitcoin scripts to make decisions based on this |
|||
field. |
|||
|
|||
|
|||
==Specification== |
|||
|
|||
Refer to the reference implementation, reproduced below, for the precise |
|||
semantics and detailed rationale for those semantics. |
|||
|
|||
|
|||
case OP_NOP3: |
|||
{ |
|||
if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) { |
|||
// not enabled; treat as a NOP3 |
|||
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { |
|||
return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); |
|||
} |
|||
break; |
|||
} |
|||
|
|||
if (stack.size() < 1) |
|||
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); |
|||
|
|||
// Note that unlike CHECKLOCKTIMEVERIFY we do not need to |
|||
// accept 5-byte bignums since any value greater than or |
|||
// equal to SEQUENCE_THRESHOLD (= 1 << 31) will be rejected |
|||
// anyway. This limitation just happens to coincide with |
|||
// CScriptNum's default 4-byte limit with an explicit sign |
|||
// bit. |
|||
// |
|||
// This means there is a maximum relative lock time of 52 |
|||
// years, even though the nSequence field in transactions |
|||
// themselves is uint32_t and could allow a relative lock |
|||
// time of up to 120 years. |
|||
const CScriptNum nInvSequence(stacktop(-1), fRequireMinimal); |
|||
|
|||
// In the rare event that the argument may be < 0 due to |
|||
// some arithmetic being done first, you can always use |
|||
// 0 MAX CHECKSEQUENCEVERIFY. |
|||
if (nInvSequence < 0) |
|||
return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); |
|||
|
|||
// Actually compare the specified inverse sequence number |
|||
// with the input. |
|||
if (!CheckSequence(nInvSequence)) |
|||
return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); |
|||
|
|||
break; |
|||
} |
|||
|
|||
bool CheckSequence(const CScriptNum& nSequence) const |
|||
{ |
|||
int64_t txToSequence; |
|||
|
|||
// Fail under all circumstances if the transaction's version |
|||
// number is not set high enough to enable enforced sequence |
|||
// number rules. |
|||
if (txTo->nVersion < 3) |
|||
return false; |
|||
|
|||
txToSequence = (int64_t)~txTo->vin[nIn].nSequence; |
|||
if (txToSequence >= SEQUENCE_THRESHOLD) |
|||
return false; |
|||
|
|||
// There are two types of nSequence: lock-by-blockheight |
|||
// and lock-by-blocktime, distinguished by whether |
|||
// nSequence < LOCKTIME_THRESHOLD. |
|||
// |
|||
// We want to compare apples to apples, so fail the script |
|||
// unless the type of nSequence being tested is the same as |
|||
// the nSequence in the transaction. |
|||
if (!( |
|||
(txToSequence < LOCKTIME_THRESHOLD && nSequence < LOCKTIME_THRESHOLD) || |
|||
(txToSequence >= LOCKTIME_THRESHOLD && nSequence >= LOCKTIME_THRESHOLD) |
|||
)) |
|||
return false; |
|||
|
|||
// Now that we know we're comparing apples-to-apples, the |
|||
// comparison is a simple numeric one. |
|||
if (nSequence > txToSequence) |
|||
return false; |
|||
|
|||
return true; |
|||
} |
|||
|
|||
https://github.com/btcdrak/bips/blob/bip-csv/bip-csv/example.cpp |
|||
|
|||
|
|||
==Example: Escrow with Timeout== |
|||
|
|||
An escrow that times out automatically 30 days after being funded can be |
|||
established in the following way. Alice, Bob and Escrow create a 2-of-3 |
|||
address with the following redeemscript. |
|||
|
|||
IF |
|||
2 <Alice's pubkey> <Bob's pubkey> <Escrow's pubkey> 3 CHECKMULTISIGVERIFY |
|||
ELSE |
|||
<30 days> CHECKSEQUENCEVERIFY DROP |
|||
<Alice's pubkey> CHECKSIGVERIFY |
|||
ENDIF |
|||
|
|||
At any time funds can be spent using signatures from any two of Alice, |
|||
Bob or the Escrow. |
|||
|
|||
After 30 days Alice can sign alone. |
|||
|
|||
The clock does not start ticking until the payment to the escrow address |
|||
confirms. |
|||
|
|||
|
|||
==Reference Implementation== |
|||
|
|||
A reference implementation is provided in the following git repository: |
|||
|
|||
https://github.com/maaku/bitcoin/tree/checksequenceverify |
|||
|
|||
|
|||
==Deployment== |
|||
|
|||
We reuse the double-threshold switchover mechanism from BIPs 34 and 66, |
|||
with the same thresholds, but for nVersion = 4. The new rules are in |
|||
effect for every block (at height H) with nVersion = 4 and at least 750 |
|||
out of 1000 blocks preceding it (with heights H-1000..H-1) also have |
|||
nVersion = 4. Furthermore, when 950 out of the 1000 blocks preceding a |
|||
block do have nVersion = 4, nVersion = 3 blocks become invalid, and all |
|||
further blocks enforce the new rules. |
|||
|
|||
It is recommended that this soft-fork deployment trigger include other |
|||
related proposals for improving Bitcoin's lock-time capabilities, including: |
|||
|
|||
[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP 65]: |
|||
OP_CHECKLOCKTIMEVERIFY, |
|||
|
|||
[https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP 68]: |
|||
Consensus-enforced transaction replacement signalled via sequence numbers, |
|||
|
|||
and [https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki BIP XX]: |
|||
Median-Past-Time-Lock. |
|||
|
|||
|
|||
==Upgrade and Testing Plan== |
|||
|
|||
TBD |
|||
|
|||
|
|||
==Credits== |
|||
|
|||
Mark Friedenbach for designing and authoring the actual implementation |
|||
for CHECKSEQUENCEVERIFY. |
|||
|
|||
|
|||
==References== |
|||
|
|||
BIP 68: Consensus-enforced transaction replacement signalled via sequence numbers |
|||
https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki |
|||
|
|||
BIP 65: OP_CHECKLOCKTIMEVERIFY |
|||
https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki |
|||
|
|||
BIP XX: Median-Past-Time-Lock |
|||
https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki |
|||
|
|||
HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and revocation hashes |
|||
http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-July/000021.html |
|||
|
|||
|
|||
==Copyright== |
|||
|
|||
This document is placed in the public domain. |
|||
|
Loading…
Reference in new issue