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">&lt;<a h=
ref=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" target=3D"_blank">bitc=
oin-dev@lists.linuxfoundation.org</a>&gt;</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&#39;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>
&lt;pre&gt;<br>
=C2=A0 BIP: XX<br>
=C2=A0 Title: CHECKSEQUENCEVERIFY<br>
=C2=A0 Authors: BtcDrak &lt;<a href=3D"mailto:btcdrak@gmail.com" target=3D"=
_blank">btcdrak@gmail.com</a>&gt;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Mark Friedenbach &lt;<a href=3D"ma=
ilto:mark@friedenbach.org" target=3D"_blank">mark@friedenbach.org</a>&gt;<b=
r>
=C2=A0 Status: Draft<br>
=C2=A0 Type: Standards Track<br>
=C2=A0 Created: 2015-08-10<br>
&lt;/pre&gt;<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 &lt;&lt; 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&#39;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 &amp; 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 &amp; 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() &lt; 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 &lt;&lt; =
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&#39;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 &lt; 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&amp; 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&#39;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-&gt;nVersion &lt; 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-&gt;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 &gt;=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 &lt; 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 &lt;=C2=A0 LOCKT=
IME_THRESHOLD &amp;&amp; nInvSequence &lt;<br>
LOCKTIME_THRESHOLD) ||<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (txToInvSequence &gt;=3D LOCKTIME=
_THRESHOLD &amp;&amp; nInvSequence &gt;=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&#39;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 &gt; 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 &lt;Alice&#39;s pubkey&gt; &lt;Bob&#39;s pubk=
ey&gt; &lt;Escrow&#39;s pubkey&gt; 3<br>
CHECKMULTISIGVERIFY<br>
=C2=A0 =C2=A0 ELSE<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;LOCKTIME_THRESHOLD + 30*24*60*60&gt; CHECKS=
EQUENCEVERIFY DROP<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;Alice&#39;s pubkey&gt; 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&#39;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--