diff --git a/README.mediawiki b/README.mediawiki index 1404eb67..d9c8f1bf 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -314,6 +314,12 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Draft |- +| [[bip-0112.mediawiki|112]] +| CHECKSEQUENCEVERIFY +| BtcDrak and Mark Friedenbach +| Standard +| Draft +|- | [[bip-0113.mediawiki|113]] | Median time-past as endpoint for lock-time calculations | Thomas Kerin and Mark Friedenbach diff --git a/bip-csv.mediawiki b/bip-csv.mediawiki new file mode 100644 index 00000000..130c3c9c --- /dev/null +++ b/bip-csv.mediawiki @@ -0,0 +1,206 @@ +
+ BIP: XX + Title: OP_CHECKSEQUENCEVERIFY + Authors: BtcDrak+ +==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+ Mark Friedenbach + Status: Draft + Type: Standards Track + Created: 2015-08-10 +