As per the rules of BIP 1, I hereby request that the BIP editor please assign an official number to this work. The idea has been discussed before on the bitcoin-dev mailing list: http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008452.html And a reference implementation is available here: https://github.com/maaku/bitcoin/tree/checksequenceverify On Thu, Aug 13, 2015 at 4:06 AM, Btc Drak via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > I have written the following draft BIP for a new opcode > CHECKSEQUENCEVERIFY by Mark Friedenbach, which introduces a form of > relative-locktime to Bitcoin's scripting language. > > > https://github.com/btcdrak/bips/blob/bip-checksequenceverify/bip-csv.mediawiki > >
>   BIP: XX
>   Title: CHECKSEQUENCEVERIFY
>   Authors: BtcDrak 
>            Mark Friedenbach 
>   Status: Draft
>   Type: Standards Track
>   Created: 2015-08-10
> 
> > ==Abstract== > > This BIP describes a new opcode (CHECKSEQUENCEVERIFY) for the Bitcoin > scripting system that in combination with BIP 68 allows execution > pathways of a script to be restricted based on the age of the output > being spent. > > > ==Summary== > > CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed > it compares the top item on the stack to the inverse of the nSequence > field of the transaction input containing the scriptSig. If the > inverse of nSequence is less than the sequence threshold (1 << 31), > the transaction version is greater than or equal to 2, and the top > item on the stack is less than or equal to the inverted nSequence, > script evaluation continues as though a NOP was executed. Otherwise > the script fails immediately. > > BIP 68's redefinition of nSequence prevents a non-final transaction > from being selected for inclusion in a block until the corresponding > input has reached the specified age, as measured in block heiht or > block time. By comparing the argument to CHECKSEQUENCEVERIFY against > the nSequence field, we indirectly verify a desired minimum age of the > the output being spent; until that relative age has been reached any > script execution pathway including the CHECKSEQUENCEVERIFY will fail > to validate, causing the transaction not to be selected for inclusion > in a block. > > > ==Motivation== > > BIP 68 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. > > By making the nSequence field accessible to script, it becomes > possible to construct code pathways that only become accessible some > minimum time after proof-of-publication. This enables a wide variety > of applications in phased protocols such as escrow, payment channels, > or bidirectional pegs. > > > ==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& nInvSequence) const > { > int64_t txToInvSequence; > > // Fail under all circumstances if the transaction's version > // number is not set high enough to enable enforced sequence > // number rules. > if (txTo->nVersion < 2) > return false; > > // Sequence number must be inverted to convert it into a > // relative lock-time. > txToInvSequence = (int64_t)~txTo->vin[nIn].nSequence; > > // Sequence numbers under SEQUENCE_THRESHOLD are not consensus > // constrained. > if (txToInvSequence >= SEQUENCE_THRESHOLD) > return false; > > // There are two types of relative lock-time: lock-by- > // blockheight and lock-by-blocktime, distinguished by > // whether txToInvSequence < LOCKTIME_THRESHOLD. > // > // We want to compare apples to apples, so fail the script > // unless the type of lock-time being tested is the same as > // the lock-time in the transaction input. > if (!( > (txToInvSequence < LOCKTIME_THRESHOLD && nInvSequence < > LOCKTIME_THRESHOLD) || > (txToInvSequence >= LOCKTIME_THRESHOLD && nInvSequence >= > LOCKTIME_THRESHOLD) > )) > return false; > > // Now that we know we're comparing apples-to-apples, the > // comparison is a simple numeric one. > if (nInvSequence > txInvToSequence) > return false; > > return true; > } > > > https://github.com/maaku/bitcoin/commit/33be476a60fcc2afbe6be0ca7b93a84209173eb2 > > > ==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 3 > CHECKMULTISIGVERIFY > ELSE > CHECKSEQUENCEVERIFY DROP > 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. > > > ==Credits== > > Mark Friedenbach invented the application of sequence numbers to > achieve relative lock-time, and wrote the reference implementation of > CHECKSEQUENCEVERIFY. > > The reference implementation and this BIP was based heavily on work > done by Peter Todd for the closely related BIP 65. > > BtcDrak authored this BIP document. > > > ==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 block time for time-lock constraints > 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. > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >