<oembed><type>rich</type><version>1.0</version><author_name>npub1r3san9v5njl6798hvauyu9ntm6r9c7u8s0t65wls58gpfdcvqp5sa48d0u</author_name><author_url>https://nostr.ae/npub1r3san9v5njl6798hvauyu9ntm6r9c7u8s0t65wls58gpfdcvqp5sa48d0u</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2015-08-13&#xA;📝 Original message:As per the rules of BIP 1, I hereby request that the BIP editor please&#xA;assign an official number to this work. The idea has been discussed before&#xA;on the bitcoin-dev mailing list:&#xA;&#xA;http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008452.html&#xA;&#xA;And a reference implementation is available here:&#xA;&#xA;https://github.com/maaku/bitcoin/tree/checksequenceverify&#xA;&#xA;&#xA;On Thu, Aug 13, 2015 at 4:06 AM, Btc Drak via bitcoin-dev &lt;&#xA;bitcoin-dev at lists.linuxfoundation.org&gt; wrote:&#xA;&#xA;&gt; I have written the following draft BIP for a new opcode&#xA;&gt; CHECKSEQUENCEVERIFY by Mark Friedenbach, which introduces a form of&#xA;&gt; relative-locktime to Bitcoin&#39;s scripting language.&#xA;&gt;&#xA;&gt;&#xA;&gt; https://github.com/btcdrak/bips/blob/bip-checksequenceverify/bip-csv.mediawiki&#xA;&gt;&#xA;&gt; &lt;pre&gt;&#xA;&gt;   BIP: XX&#xA;&gt;   Title: CHECKSEQUENCEVERIFY&#xA;&gt;   Authors: BtcDrak &lt;btcdrak at gmail.com&gt;&#xA;&gt;            Mark Friedenbach &lt;mark at friedenbach.org&gt;&#xA;&gt;   Status: Draft&#xA;&gt;   Type: Standards Track&#xA;&gt;   Created: 2015-08-10&#xA;&gt; &lt;/pre&gt;&#xA;&gt;&#xA;&gt; ==Abstract==&#xA;&gt;&#xA;&gt; This BIP describes a new opcode (CHECKSEQUENCEVERIFY) for the Bitcoin&#xA;&gt; scripting system that in combination with BIP 68 allows execution&#xA;&gt; pathways of a script to be restricted based on the age of the output&#xA;&gt; being spent.&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Summary==&#xA;&gt;&#xA;&gt; CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed&#xA;&gt; it compares the top item on the stack to the inverse of the nSequence&#xA;&gt; field of the transaction input containing the scriptSig. If the&#xA;&gt; inverse of nSequence is less than the sequence threshold (1 &lt;&lt; 31),&#xA;&gt; the transaction version is greater than or equal to 2, and the top&#xA;&gt; item on the stack is less than or equal to the inverted nSequence,&#xA;&gt; script evaluation continues as though a NOP was executed. Otherwise&#xA;&gt; the script fails immediately.&#xA;&gt;&#xA;&gt; BIP 68&#39;s redefinition of nSequence prevents a non-final transaction&#xA;&gt; from being selected for inclusion in a block until the corresponding&#xA;&gt; input has reached the specified age, as measured in block heiht or&#xA;&gt; block time. By comparing the argument to CHECKSEQUENCEVERIFY against&#xA;&gt; the nSequence field, we indirectly verify a desired minimum age of the&#xA;&gt; the output being spent; until that relative age has been reached any&#xA;&gt; script execution pathway including the CHECKSEQUENCEVERIFY will fail&#xA;&gt; to validate, causing the transaction not to be selected for inclusion&#xA;&gt; in a block.&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Motivation==&#xA;&gt;&#xA;&gt; BIP 68 repurposes the transaction nSequence field meaning by giving&#xA;&gt; sequence numbers new consensus-enforced semantics as a relative&#xA;&gt; lock-time. However, there is no way to build Bitcoin scripts to make&#xA;&gt; decisions based on this field.&#xA;&gt;&#xA;&gt; By making the nSequence field accessible to script, it becomes&#xA;&gt; possible to construct code pathways that only become accessible some&#xA;&gt; minimum time after proof-of-publication. This enables a wide variety&#xA;&gt; of applications in phased protocols such as escrow, payment channels,&#xA;&gt; or bidirectional pegs.&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Specification==&#xA;&gt;&#xA;&gt; Refer to the reference implementation, reproduced below, for the precise&#xA;&gt; semantics and detailed rationale for those semantics.&#xA;&gt;&#xA;&gt;&#xA;&gt;     case OP_NOP3:&#xA;&gt;     {&#xA;&gt;         if (!(flags &amp; SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {&#xA;&gt;             // not enabled; treat as a NOP3&#xA;&gt;             if (flags &amp; SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {&#xA;&gt;                 return set_error(serror,&#xA;&gt; SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);&#xA;&gt;             }&#xA;&gt;             break;&#xA;&gt;         }&#xA;&gt;&#xA;&gt;         if (stack.size() &lt; 1)&#xA;&gt;             return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);&#xA;&gt;&#xA;&gt;         // Note that unlike CHECKLOCKTIMEVERIFY we do not need to&#xA;&gt;         // accept 5-byte bignums since any value greater than or&#xA;&gt;         // equal to SEQUENCE_THRESHOLD (= 1 &lt;&lt; 31) will be rejected&#xA;&gt;         // anyway. This limitation just happens to coincide with&#xA;&gt;         // CScriptNum&#39;s default 4-byte limit with an explicit sign&#xA;&gt;         // bit.&#xA;&gt;         //&#xA;&gt;         // This means there is a maximum relative lock time of 52&#xA;&gt;         // years, even though the nSequence field in transactions&#xA;&gt;         // themselves is uint32_t and could allow a relative lock&#xA;&gt;         // time of up to 120 years.&#xA;&gt;         const CScriptNum nInvSequence(stacktop(-1), fRequireMinimal);&#xA;&gt;&#xA;&gt;         // In the rare event that the argument may be &lt; 0 due to&#xA;&gt;         // some arithmetic being done first, you can always use&#xA;&gt;         // 0 MAX CHECKSEQUENCEVERIFY.&#xA;&gt;         if (nInvSequence &lt; 0)&#xA;&gt;             return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME);&#xA;&gt;&#xA;&gt;         // Actually compare the specified inverse sequence number&#xA;&gt;         // with the input.&#xA;&gt;         if (!CheckSequence(nInvSequence))&#xA;&gt;             return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME);&#xA;&gt;&#xA;&gt;         break;&#xA;&gt;     }&#xA;&gt;&#xA;&gt;     bool CheckSequence(const CScriptNum&amp; nInvSequence) const&#xA;&gt;     {&#xA;&gt;         int64_t txToInvSequence;&#xA;&gt;&#xA;&gt;         // Fail under all circumstances if the transaction&#39;s version&#xA;&gt;         // number is not set high enough to enable enforced sequence&#xA;&gt;         // number rules.&#xA;&gt;         if (txTo-&gt;nVersion &lt; 2)&#xA;&gt;             return false;&#xA;&gt;&#xA;&gt;         // Sequence number must be inverted to convert it into a&#xA;&gt;         // relative lock-time.&#xA;&gt;         txToInvSequence = (int64_t)~txTo-&gt;vin[nIn].nSequence;&#xA;&gt;&#xA;&gt;         // Sequence numbers under SEQUENCE_THRESHOLD are not consensus&#xA;&gt;         // constrained.&#xA;&gt;         if (txToInvSequence &gt;= SEQUENCE_THRESHOLD)&#xA;&gt;             return false;&#xA;&gt;&#xA;&gt;         // There are two types of relative lock-time: lock-by-&#xA;&gt;         // blockheight and lock-by-blocktime, distinguished by&#xA;&gt;         // whether txToInvSequence &lt; LOCKTIME_THRESHOLD.&#xA;&gt;         //&#xA;&gt;         // We want to compare apples to apples, so fail the script&#xA;&gt;         // unless the type of lock-time being tested is the same as&#xA;&gt;         // the lock-time in the transaction input.&#xA;&gt;         if (!(&#xA;&gt;             (txToInvSequence &lt;  LOCKTIME_THRESHOLD &amp;&amp; nInvSequence &lt;&#xA;&gt; LOCKTIME_THRESHOLD) ||&#xA;&gt;             (txToInvSequence &gt;= LOCKTIME_THRESHOLD &amp;&amp; nInvSequence &gt;=&#xA;&gt; LOCKTIME_THRESHOLD)&#xA;&gt;         ))&#xA;&gt;             return false;&#xA;&gt;&#xA;&gt;         // Now that we know we&#39;re comparing apples-to-apples, the&#xA;&gt;         // comparison is a simple numeric one.&#xA;&gt;         if (nInvSequence &gt; txInvToSequence)&#xA;&gt;             return false;&#xA;&gt;&#xA;&gt;         return true;&#xA;&gt;     }&#xA;&gt;&#xA;&gt;&#xA;&gt; https://github.com/maaku/bitcoin/commit/33be476a60fcc2afbe6be0ca7b93a84209173eb2&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Example: Escrow with Timeout==&#xA;&gt;&#xA;&gt; An escrow that times out automatically 30 days after being funded can be&#xA;&gt; established in the following way. Alice, Bob and Escrow create a 2-of-3&#xA;&gt; address with the following redeemscript.&#xA;&gt;&#xA;&gt;     IF&#xA;&gt;         2 &lt;Alice&#39;s pubkey&gt; &lt;Bob&#39;s pubkey&gt; &lt;Escrow&#39;s pubkey&gt; 3&#xA;&gt; CHECKMULTISIGVERIFY&#xA;&gt;     ELSE&#xA;&gt;         &lt;LOCKTIME_THRESHOLD + 30*24*60*60&gt; CHECKSEQUENCEVERIFY DROP&#xA;&gt;         &lt;Alice&#39;s pubkey&gt; CHECKSIGVERIFY&#xA;&gt;     ENDIF&#xA;&gt;&#xA;&gt; At any time funds can be spent using signatures from any two of Alice,&#xA;&gt; Bob or the Escrow.&#xA;&gt;&#xA;&gt; After 30 days Alice can sign alone.&#xA;&gt;&#xA;&gt; The clock does not start ticking until the payment to the escrow address&#xA;&gt; confirms.&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Reference Implementation==&#xA;&gt;&#xA;&gt; A reference implementation is provided in the following git repository:&#xA;&gt;&#xA;&gt; https://github.com/maaku/bitcoin/tree/checksequenceverify&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Deployment==&#xA;&gt;&#xA;&gt; We reuse the double-threshold switchover mechanism from BIPs 34 and&#xA;&gt; 66, with the same thresholds, but for nVersion = 4. The new rules are&#xA;&gt; in effect for every block (at height H) with nVersion = 4 and at least&#xA;&gt; 750 out of 1000 blocks preceding it (with heights H-1000..H-1) also&#xA;&gt; have nVersion = 4. Furthermore, when 950 out of the 1000 blocks&#xA;&gt; preceding a block do have nVersion = 4, nVersion = 3 blocks become&#xA;&gt; invalid, and all further blocks enforce the new rules.&#xA;&gt;&#xA;&gt; It is recommended that this soft-fork deployment trigger include other&#xA;&gt; related proposals for improving Bitcoin&#39;s lock-time capabilities,&#xA;&gt; including:&#xA;&gt;&#xA;&gt; [https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP 65]:&#xA;&gt; OP_CHECKLOCKTIMEVERIFY,&#xA;&gt;&#xA;&gt; [https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP 68]:&#xA;&gt; Consensus-enforced transaction replacement signalled via sequence numbers,&#xA;&gt;&#xA;&gt; and [https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki BIP&#xA;&gt; XX]:&#xA;&gt; Median-Past-Time-Lock.&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Credits==&#xA;&gt;&#xA;&gt; Mark Friedenbach invented the application of sequence numbers to&#xA;&gt; achieve relative lock-time, and wrote the reference implementation of&#xA;&gt; CHECKSEQUENCEVERIFY.&#xA;&gt;&#xA;&gt; The reference implementation and this BIP was based heavily on work&#xA;&gt; done by Peter Todd for the closely related BIP 65.&#xA;&gt;&#xA;&gt; BtcDrak authored this BIP document.&#xA;&gt;&#xA;&gt;&#xA;&gt; ==References==&#xA;&gt;&#xA;&gt; BIP 68: Consensus-enforced transaction replacement signalled via&#xA;&gt; sequence numbers&#xA;&gt; https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki&#xA;&gt;&#xA;&gt; BIP 65: OP_CHECKLOCKTIMEVERIFY&#xA;&gt; https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki&#xA;&gt;&#xA;&gt; BIP XX: Median past block time for time-lock constraints&#xA;&gt; https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki&#xA;&gt;&#xA;&gt; HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and&#xA;&gt; revocation hashes&#xA;&gt;&#xA;&gt; http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-July/000021.html&#xA;&gt;&#xA;&gt;&#xA;&gt; ==Copyright==&#xA;&gt;&#xA;&gt; This document is placed in the public domain.&#xA;&gt; _______________________________________________&#xA;&gt; bitcoin-dev mailing list&#xA;&gt; bitcoin-dev at lists.linuxfoundation.org&#xA;&gt; https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev&#xA;&gt;&#xA;-------------- next part --------------&#xA;An HTML attachment was scrubbed...&#xA;URL: &lt;http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20150813/0d50ce22/attachment-0001.html&gt;</html></oembed>