Return-Path: <mark@friedenbach.org> Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id B7AE1826 for <bitcoin-dev@lists.linuxfoundation.org>; Thu, 13 Aug 2015 18:13:04 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-io0-f172.google.com (mail-io0-f172.google.com [209.85.223.172]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 62DFD292 for <bitcoin-dev@lists.linuxfoundation.org>; Thu, 13 Aug 2015 18:13:03 +0000 (UTC) Received: by iodt126 with SMTP id t126so60934273iod.2 for <bitcoin-dev@lists.linuxfoundation.org>; Thu, 13 Aug 2015 11:13:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=2ihc7J0wqBmkJZVrUTW+583FDcS9f1c/5tRXiy3hnJg=; b=UA/m3Br1O6vZTK1/AsgpSHeWO1uzu8XdXfgpm7LzYtdVA255BwHrq8ShRnWyVIRv5O 0XnVrBm/blrZFQyqBc80b7Z+r7e1QroSSXsHAVW7HRlDB6bKekxI/eV5GcOIN3y4G+rx q7BXStHGm5ZcT2S3/MutZIABfzB9g/mlA26laELQ4vgGejt0xk0NFYFBm8VnaeLvaYm0 kN9idUqWyM7Pff+2Llj3ZFONci7dHhDm46UXP+ZmNdy0kuT6qSI9gGuS0GaH1Qgr+t3F BMC4FbAdBIfJ8KBOlGzVneEnadvcMMgl+tvJVXhVwWtuGXYXgetycElLDrOcwkrQSNxR G7Aw== X-Gm-Message-State: ALoCoQlCL1cix9QxzYRhAUdp3l62ix/rFXKsVzTpgxeHR52y8cKw4cAX0V99Oq6pxSvpU89VhXAh X-Received: by 10.107.35.138 with SMTP id j132mr45327471ioj.159.1439489582642; Thu, 13 Aug 2015 11:13:02 -0700 (PDT) MIME-Version: 1.0 Received: by 10.107.138.14 with HTTP; Thu, 13 Aug 2015 11:12:43 -0700 (PDT) X-Originating-IP: [173.228.107.141] In-Reply-To: <CADJgMztgE_GkbrsP7zCEHNPA3P6T=aSFfhkcN-q=gVhWP0vKXg@mail.gmail.com> References: <CADJgMztgE_GkbrsP7zCEHNPA3P6T=aSFfhkcN-q=gVhWP0vKXg@mail.gmail.com> From: Mark Friedenbach <mark@friedenbach.org> Date: Thu, 13 Aug 2015 11:12:43 -0700 Message-ID: <CAOG=w-tLsDtNcXtYU=J7mNWYd8-4VGMVDGJp7Fm_BiVw-LXwhQ@mail.gmail.com> To: Btc Drak <btcdrak@gmail.com>, Gregory Maxwell <gmaxwell@gmail.com> Content-Type: multipart/alternative; boundary=001a1140f4e63b56d9051d354985 X-Spam-Status: No, score=-1.6 required=5.0 tests=BAYES_00,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,UC_GIBBERISH_OBFU autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Bitcoin Dev <bitcoin-dev@lists.linuxfoundation.org> Subject: Re: [bitcoin-dev] [BIP-draft] CHECKSEQUENCEVERIFY - An opcode for relative locktime X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Bitcoin Development Discussion <bitcoin-dev.lists.linuxfoundation.org> List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe> List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/> List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org> List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help> List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe> X-List-Received-Date: Thu, 13 Aug 2015 18:13:04 -0000 --001a1140f4e63b56d9051d354985 Content-Type: text/plain; charset=UTF-8 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 > > <pre> > BIP: XX > Title: 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 (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 <Alice's pubkey> <Bob's pubkey> <Escrow's pubkey> 3 > CHECKMULTISIGVERIFY > ELSE > <LOCKTIME_THRESHOLD + 30*24*60*60> 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. > > > ==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 > --001a1140f4e63b56d9051d354985 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div><div>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:<br><br><a href=3D"h= ttp://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008452.html= ">http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008452.h= tml</a><br><br></div>And a reference implementation is available here:<br><= br><a href=3D"https://github.com/maaku/bitcoin/tree/checksequenceverify">ht= tps://github.com/maaku/bitcoin/tree/checksequenceverify</a><br><br></div><d= iv><div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Thu, A= ug 13, 2015 at 4:06 AM, Btc Drak via bitcoin-dev <span dir=3D"ltr"><<a h= ref=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" target=3D"_blank">bitc= oin-dev@lists.linuxfoundation.org</a>></span> wrote:<br><blockquote clas= s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad= ding-left:1ex">I have written the following draft BIP for a new opcode<br> CHECKSEQUENCEVERIFY by Mark Friedenbach, which introduces a form of<br> relative-locktime to Bitcoin's scripting language.<br> <br> <a href=3D"https://github.com/btcdrak/bips/blob/bip-checksequenceverify/bip= -csv.mediawiki" rel=3D"noreferrer" target=3D"_blank">https://github.com/btc= drak/bips/blob/bip-checksequenceverify/bip-csv.mediawiki</a><br> <br> <pre><br> =C2=A0 BIP: XX<br> =C2=A0 Title: CHECKSEQUENCEVERIFY<br> =C2=A0 Authors: BtcDrak <<a href=3D"mailto:btcdrak@gmail.com" target=3D"= _blank">btcdrak@gmail.com</a>><br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Mark Friedenbach <<a href=3D"ma= ilto:mark@friedenbach.org" target=3D"_blank">mark@friedenbach.org</a>><b= r> =C2=A0 Status: Draft<br> =C2=A0 Type: Standards Track<br> =C2=A0 Created: 2015-08-10<br> </pre><br> <br> =3D=3DAbstract=3D=3D<br> <br> This BIP describes a new opcode (CHECKSEQUENCEVERIFY) for the Bitcoin<br> scripting system that in combination with BIP 68 allows execution<br> pathways of a script to be restricted based on the age of the output<br> being spent.<br> <br> <br> =3D=3DSummary=3D=3D<br> <br> CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed<br> it compares the top item on the stack to the inverse of the nSequence<br> field of the transaction input containing the scriptSig. If the<br> inverse of nSequence is less than the sequence threshold (1 << 31),<b= r> the transaction version is greater than or equal to 2, and the top<br> item on the stack is less than or equal to the inverted nSequence,<br> script evaluation continues as though a NOP was executed. Otherwise<br> the script fails immediately.<br> <br> BIP 68's redefinition of nSequence prevents a non-final transaction<br> from being selected for inclusion in a block until the corresponding<br> input has reached the specified age, as measured in block heiht or<br> block time. By comparing the argument to CHECKSEQUENCEVERIFY against<br> the nSequence field, we indirectly verify a desired minimum age of the<br> the output being spent; until that relative age has been reached any<br> script execution pathway including the CHECKSEQUENCEVERIFY will fail<br> to validate, causing the transaction not to be selected for inclusion<br> in a block.<br> <br> <br> =3D=3DMotivation=3D=3D<br> <br> BIP 68 repurposes the transaction nSequence field meaning by giving<br> sequence numbers new consensus-enforced semantics as a relative<br> lock-time. However, there is no way to build Bitcoin scripts to make<br> decisions based on this field.<br> <br> By making the nSequence field accessible to script, it becomes<br> possible to construct code pathways that only become accessible some<br> minimum time after proof-of-publication. This enables a wide variety<br> of applications in phased protocols such as escrow, payment channels,<br> or bidirectional pegs.<br> <br> <br> =3D=3DSpecification=3D=3D<br> <br> Refer to the reference implementation, reproduced below, for the precise<br= > semantics and detailed rationale for those semantics.<br> <br> <br> =C2=A0 =C2=A0 case OP_NOP3:<br> =C2=A0 =C2=A0 {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVE= RIFY)) {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // not enabled; treat as a NOP3<b= r> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (flags & SCRIPT_VERIFY_DIS= COURAGE_UPGRADABLE_NOPS) {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return set_error(se= rror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (stack.size() < 1)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return set_error(serror, SCRIPT_E= RR_INVALID_STACK_OPERATION);<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Note that unlike CHECKLOCKTIMEVERIFY we do n= ot need to<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // accept 5-byte bignums since any value greate= r than or<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // equal to SEQUENCE_THRESHOLD (=3D 1 << = 31) will be rejected<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // anyway. This limitation just happens to coin= cide with<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // CScriptNum's default 4-byte limit with a= n explicit sign<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // bit.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 //<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // This means there is a maximum relative lock = time of 52<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // years, even though the nSequence field in tr= ansactions<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // themselves is uint32_t and could allow a rel= ative lock<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // time of up to 120 years.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 const CScriptNum nInvSequence(stacktop(-1), fRe= quireMinimal);<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // In the rare event that the argument may be &= lt; 0 due to<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // some arithmetic being done first, you can al= ways use<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // 0 MAX CHECKSEQUENCEVERIFY.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (nInvSequence < 0)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return set_error(serror, SCRIPT_E= RR_NEGATIVE_LOCKTIME);<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Actually compare the specified inverse seque= nce number<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // with the input.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!CheckSequence(nInvSequence))<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return set_error(serror, SCRIPT_E= RR_UNSATISFIED_LOCKTIME);<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br> =C2=A0 =C2=A0 }<br> <br> =C2=A0 =C2=A0 bool CheckSequence(const CScriptNum& nInvSequence) const<= br> =C2=A0 =C2=A0 {<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 int64_t txToInvSequence;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Fail under all circumstances if the transact= ion's version<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // number is not set high enough to enable enfo= rced sequence<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // number rules.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (txTo->nVersion < 2)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return false;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Sequence number must be inverted to convert = it into a<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // relative lock-time.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 txToInvSequence =3D (int64_t)~txTo->vin[nIn]= .nSequence;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Sequence numbers under SEQUENCE_THRESHOLD ar= e not consensus<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // constrained.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (txToInvSequence >=3D SEQUENCE_THRESHOLD)= <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return false;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // There are two types of relative lock-time: l= ock-by-<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // blockheight and lock-by-blocktime, distingui= shed by<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // whether txToInvSequence < LOCKTIME_THRESH= OLD.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 //<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // We want to compare apples to apples, so fail= the script<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // unless the type of lock-time being tested is= the same as<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // the lock-time in the transaction input.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!(<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (txToInvSequence <=C2=A0 LOCKT= IME_THRESHOLD && nInvSequence <<br> LOCKTIME_THRESHOLD) ||<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (txToInvSequence >=3D LOCKTIME= _THRESHOLD && nInvSequence >=3D<br> LOCKTIME_THRESHOLD)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 ))<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return false;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Now that we know we're comparing apples-= to-apples, the<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 // comparison is a simple numeric one.<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (nInvSequence > txInvToSequence)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return false;<br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 return true;<br> =C2=A0 =C2=A0 }<br> <br> <a href=3D"https://github.com/maaku/bitcoin/commit/33be476a60fcc2afbe6be0ca= 7b93a84209173eb2" rel=3D"noreferrer" target=3D"_blank">https://github.com/m= aaku/bitcoin/commit/33be476a60fcc2afbe6be0ca7b93a84209173eb2</a><br> <br> <br> =3D=3DExample: Escrow with Timeout=3D=3D<br> <br> An escrow that times out automatically 30 days after being funded can be<br= > established in the following way. Alice, Bob and Escrow create a 2-of-3<br> address with the following redeemscript.<br> <br> =C2=A0 =C2=A0 IF<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 2 <Alice's pubkey> <Bob's pubk= ey> <Escrow's pubkey> 3<br> CHECKMULTISIGVERIFY<br> =C2=A0 =C2=A0 ELSE<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 <LOCKTIME_THRESHOLD + 30*24*60*60> CHECKS= EQUENCEVERIFY DROP<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 <Alice's pubkey> CHECKSIGVERIFY<br> =C2=A0 =C2=A0 ENDIF<br> <br> At any time funds can be spent using signatures from any two of Alice,<br> Bob or the Escrow.<br> <br> After 30 days Alice can sign alone.<br> <br> The clock does not start ticking until the payment to the escrow address<br= > confirms.<br> <br> <br> =3D=3DReference Implementation=3D=3D<br> <br> A reference implementation is provided in the following git repository:<br> <br> <a href=3D"https://github.com/maaku/bitcoin/tree/checksequenceverify" rel= =3D"noreferrer" target=3D"_blank">https://github.com/maaku/bitcoin/tree/che= cksequenceverify</a><br> <br> <br> =3D=3DDeployment=3D=3D<br> <br> We reuse the double-threshold switchover mechanism from BIPs 34 and<br> 66, with the same thresholds, but for nVersion =3D 4. The new rules are<br> in effect for every block (at height H) with nVersion =3D 4 and at least<br= > 750 out of 1000 blocks preceding it (with heights H-1000..H-1) also<br> have nVersion =3D 4. Furthermore, when 950 out of the 1000 blocks<br> preceding a block do have nVersion =3D 4, nVersion =3D 3 blocks become<br> invalid, and all further blocks enforce the new rules.<br> <br> It is recommended that this soft-fork deployment trigger include other<br> related proposals for improving Bitcoin's lock-time capabilities, inclu= ding:<br> <br> [<a href=3D"https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki"= rel=3D"noreferrer" target=3D"_blank">https://github.com/bitcoin/bips/blob/= master/bip-0065.mediawiki</a> BIP 65]:<br> OP_CHECKLOCKTIMEVERIFY,<br> <br> [<a href=3D"https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki"= rel=3D"noreferrer" target=3D"_blank">https://github.com/bitcoin/bips/blob/= master/bip-0068.mediawiki</a> BIP 68]:<br> Consensus-enforced transaction replacement signalled via sequence numbers,<= br> <br> and [<a href=3D"https://github.com/bitcoin/bips/blob/master/bip-00XX.mediaw= iki" rel=3D"noreferrer" target=3D"_blank">https://github.com/bitcoin/bips/b= lob/master/bip-00XX.mediawiki</a> BIP XX]:<br> Median-Past-Time-Lock.<br> <br> <br> =3D=3DCredits=3D=3D<br> <br> Mark Friedenbach invented the application of sequence numbers to<br> achieve relative lock-time, and wrote the reference implementation of<br> CHECKSEQUENCEVERIFY.<br> <br> The reference implementation and this BIP was based heavily on work<br> done by Peter Todd for the closely related BIP 65.<br> <br> BtcDrak authored this BIP document.<br> <br> <br> =3D=3DReferences=3D=3D<br> <br> BIP 68: Consensus-enforced transaction replacement signalled via<br> sequence numbers<br> <a href=3D"https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki" = rel=3D"noreferrer" target=3D"_blank">https://github.com/bitcoin/bips/blob/m= aster/bip-0068.mediawiki</a><br> <br> BIP 65: OP_CHECKLOCKTIMEVERIFY<br> <a href=3D"https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki" = rel=3D"noreferrer" target=3D"_blank">https://github.com/bitcoin/bips/blob/m= aster/bip-0065.mediawiki</a><br> <br> BIP XX: Median past block time for time-lock constraints<br> <a href=3D"https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki" = rel=3D"noreferrer" target=3D"_blank">https://github.com/bitcoin/bips/blob/m= aster/bip-00XX.mediawiki</a><br> <br> HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and<br> revocation hashes<br> <a href=3D"http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-Ju= ly/000021.html" rel=3D"noreferrer" target=3D"_blank">http://lists.linuxfoun= dation.org/pipermail/lightning-dev/2015-July/000021.html</a><br> <br> <br> =3D=3DCopyright=3D=3D<br> <br> This document is placed in the public domain.<br> _______________________________________________<br> bitcoin-dev mailing list<br> <a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" target=3D"_blank">= bitcoin-dev@lists.linuxfoundation.org</a><br> <a href=3D"https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev" = rel=3D"noreferrer" target=3D"_blank">https://lists.linuxfoundation.org/mail= man/listinfo/bitcoin-dev</a><br> </blockquote></div><br></div></div></div></div> --001a1140f4e63b56d9051d354985--