2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								<pre>
							 
						 
					
						
							
								
									
										
										
										
											2020-01-23 16:51:50 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  BIP: 119
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  Layer: Consensus (soft fork)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Title: CHECKTEMPLATEVERIFY
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Author: Jeremy Rubin <j@rubin.io>
							 
						 
					
						
							
								
									
										
										
										
											2023-07-28 17:34:38 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          James O'Beirne <vaults@au92.org>
							 
						 
					
						
							
								
									
										
										
										
											2020-01-23 16:51:50 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0119
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  Status: Draft
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Type: Standards Track
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Created: 2020-01-06
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  License: BSD-3-Clause
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								</pre>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								==Abstract==
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								This BIP proposes a new opcode, OP_CHECKTEMPLATEVERIFY, to be activated
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								as a change to the semantics of OP_NOP4.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The new opcode has applications for transaction congestion control and payment
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								channel instantiation, among others, which are described in the Motivation
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								section of this BIP.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								==Summary==
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY uses opcode OP_NOP4 (0xb3) as a soft fork upgrade.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY does the following:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* There is at least one element on the stack, fail otherwise
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* The element on the stack is 32 bytes long, NOP otherwise
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								* The DefaultCheckTemplateVerifyHash of the transaction at the current input index is equal to the element on the stack, fail otherwise
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								The DefaultCheckTemplateVerifyHash commits to the serialized version, locktime, scriptSigs hash (if any
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								non-null scriptSigs), number of inputs, sequences hash, number of outputs, outputs hash, and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								currently executing input index.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The recommended standardness rules additionally:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* Reject non-32 byte as SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								==Motivation==
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 09:09:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Covenants are restrictions on how a coin may be spent beyond key ownership.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								This is a general definition based on the legal definition which even simple
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								scripts using CSV would satisfy. Covenants in Bitcoin transactions usually
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								refer to restrictions on where coins can be transferred. Covenants can be
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:35:04 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								useful to construct smart contracts. Covenants have historically been widely
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								considered to be unfit for Bitcoin because they are too complex to implement
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								and risk reducing the fungibility of coins bound by them.
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 09:09:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								This BIP introduces a simple covenant called a *template* which enables a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								limited set of highly valuable use cases without significant risk. BIP-119
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 10:14:49 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								templates allow for '''non-recursive''' fully-enumerated covenants with no dynamic
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 09:09:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								state. CTV serves as a replacement for a pre-signed transaction oracle, which
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								eliminates the trust and interactivity requirements. Examples of uses include
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 10:14:49 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								vaults, non-interactive payment channel creation, congestion controlled
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 09:09:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								batching, efficient to construct discreet log contracts, and payment pools,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								among many others. For more details on these applications, please see the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								references.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								==Detailed Specification==
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:43:30 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:47:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								in pythonic pseudocode. The canonical specification for the semantics of
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:45:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								be seen in the reference implementation.
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:43:30 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The execution of the opcode is as follows:
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								<source lang="python">
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def execute_bip_119(self):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # Before soft-fork activation / failed activation
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # continue to treat as NOP4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if not self.flags.script_verify_default_check_template_verify_hash:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # Potentially set for node-local policy to discourage premature use
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:43:30 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if self.flags.script_verify_discourage_upgradable_nops:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return self.errors_with(errors.script_err_discourage_upgradable_nops)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return self.return_as_nop()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # CTV always requires at least one stack argument
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if len(self.stack) < 1:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return self.errors_with(errors.script_err_invalid_stack_operation)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # CTV only verifies the hash against a 32 byte argument
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if len(self.stack[-1]) == 32:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # Ensure the precomputed data required for anti-DoS is available,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # or cache it on first use
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if self.context.precomputed_ctv_data == None:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # If the hashes do not match, return error
							 
						 
					
						
							
								
									
										
										
										
											2023-08-15 12:54:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data):
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return self.errors_with(errors.script_err_template_mismatch)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return self.return_as_nop()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # future upgrade can add semantics for this opcode with different length args
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # so discourage use when applicable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if self.flags.script_verify_discourage_upgradable_nops:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return self.errors_with(errors.script_err_discourage_upgradable_nops)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return self.return_as_nop()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								</source>
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:43:30 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The computation of this hash can be implemented as specified below (where self
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								is the transaction type). Care must be taken that in any validation context,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the precomputed data must be initialized to prevent Denial-of-Service attacks.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Any implementation *must* cache these parts of the hash computation to avoid
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								quadratic hashing DoS. All variable length computations must be precomputed
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								including hashes of the scriptsigs, sequences, and outputs. See the section
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								"Denial of Service and Validation Costs" below. This is not a performance
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								optimization.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								<source lang="python">
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def ser_compact_size(l):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    r = b""
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if l < 253:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # Serialize as unsigned char
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r = struct.pack("B", l)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif l < 0x10000:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # Serialize as unsigned char 253 followed by unsigned 2 byte integer (little endian)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r = struct.pack("<BH", 253, l)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif l < 0x100000000:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # Serialize as unsigned char 254 followed by unsigned 4 byte integer (little endian)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r = struct.pack("<BI", 254, l)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        # Serialize as unsigned char 255 followed by unsigned 8 byte integer (little endian)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r = struct.pack("<BQ", 255, l)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return r
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def ser_string(s):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return ser_compact_size(len(s)) + s
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								class CTxOut:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    def serialize(self):
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:51:43 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        r = b""
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        # serialize as signed 8 byte integer (little endian)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r += struct.pack("<q", self.nValue)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r += ser_string(self.scriptPubKey)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return r
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								def get_default_check_template_precomputed_data(self):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result = {}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # If there are no scriptSigs we do not need to precompute a hash
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if any(inp.scriptSig for inp in self.vin):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        result["scriptSigs"] = sha256(b"".join(ser_string(inp.scriptSig) for inp in self.vin))
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:38:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # The same value is also pre-computed for and defined in BIP-341 and can be shared.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # each nSequence is packed as 4 byte unsigned integer (little endian)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    result["sequences"] = sha256(b"".join(struct.pack("<I", inp.nSequence) for inp in self.vin))
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # The same value is also pre-computed for and defined in BIP-341 and can be shared
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # See class CTxOut above for details.
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    result["outputs"] = sha256(b"".join(out.serialize() for out in self.vout))
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return result
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# parameter precomputed must be passed in for DoS resistance
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def get_default_check_template_hash(self, nIn, precomputed = None):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if precomputed == None:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        precomputed = self.get_default_check_template_precomputed_data()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    r = b""
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Serialize as 4 byte signed integer (little endian)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    r += struct.pack("<i", self.nVersion)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Serialize as 4 byte unsigned integer (little endian)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    r += struct.pack("<I", self.nLockTime)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # we do not include the hash in the case where there is no
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # scriptSigs
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if "scriptSigs" in precomputed:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r += precomputed["scriptSigs"]
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Serialize as 4 byte unsigned integer (little endian)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    r += struct.pack("<I", len(self.vin))
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    r += precomputed["sequences"]
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Serialize as 4 byte unsigned integer (little endian)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    r += struct.pack("<I", len(self.vout))
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    r += precomputed["outputs"]
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:45:03 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    # Serialize as 4 byte unsigned integer (little endian)
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    r += struct.pack("<I", nIn)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return sha256(r)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								</source>
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:51:43 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:43:30 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								A PayToBareDefaultCheckTemplateVerifyHash output matches the following template:
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 08:33:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								<source lang="python">
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# Extra-fast test for pay-to-basic-standard-template CScripts:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def is_pay_to_bare_default_check_template_verify_hash(self):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return len(self) == 34 and self[0] == 0x20 and self[-1] == OP_CHECKTEMPLATEVERIFY
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								</source>
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:47:43 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								==Deployment==
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-22 19:18:14 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Deployment could be done via BIP 9 VersionBits deployed through Speedy Trial.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The Bitcoin Core reference implementation includes the below parameters,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								configured to match Speedy Trial, as that is the current activation mechanism
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								implemented in Bitcoin Core. Should another method become favored by the wider
							 
						 
					
						
							
								
									
										
										
										
											2024-05-28 19:25:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Bitcoin community, that might be used instead.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The start time and bit in the implementation are currently set to bit 5 and
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:21:46 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								NEVER_ACTIVE/NO_TIMEOUT, but this is subject to change while the BIP is a draft.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:21:46 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								For the avoidance of unclarity, the parameters to be determined are:
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // Deployment of CTV (BIP 119)
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY].bit = 5;
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:21:46 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    consensus.vDeployments[Consensus::DEPLOYMENT_CHECKTEMPLATEVERIFY].min_activation_height = 0;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Until BIP-119 reaches ACTIVE state and the
							 
						 
					
						
							
								
									
										
										
										
											2022-01-26 15:31:34 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH flag is enforced, node implementations should (are recommended to)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								execute a NOP4 as SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS (to deny entry to the mempool) for policy and must evaluate as
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								a NOP for consensus (during block validation).
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:21:46 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								In order to facilitate using CHECKTEMPLATEVERIFY, the common case of a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PayToBareDefaultCheckTemplateVerifyHash
							 
						 
					
						
							
								
									
										
										
										
											2022-01-26 15:31:34 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								with no scriptSig data may (is recommended to) be made standard to permit relaying. Future template types may be
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								standardized later as policy changes at the preference of the implementor.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-20 20:15:23 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								==Reference Implementation==
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-10 19:55:26 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								A reference implementation and tests are available here in the PR to Bitcoin Core https://github.com/bitcoin/bitcoin/pull/21702.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								It is not ideal to link to a PR, as it may be rebased and changed, but it is the best place to find
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the current implementation and review comments of others.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								A recent commit hash in that PR including tests and vectors can be found here https://github.com/jeremyrubin/bitcoin/commit/3109df5616796282786706738994a5b97b8a5a38.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Once the PR is merged, this BIP should be updated to point to the specific code released.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-25 11:07:33 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Test vectors are available in [/bip-0119/vectors the bip-0119/vectors
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:47:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								directory] for checking compatibility with the reference implementation and BIP.
							 
						 
					
						
							
								
									
										
										
										
											2021-12-25 11:07:33 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								==Rationale==
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The goal of CHECKTEMPLATEVERIFY is to be minimal impact on the existing codebase -- in the
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:47:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								future, as we become aware of more complex but shown to be safe use cases, new template types can be added.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Below we'll discuss the rules one-by-one:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								====The DefaultCheckTemplateVerifyHash of the transaction at the current input index matches the top of the stack====
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The set of data committed to is a superset of data which can impact the TXID of the transaction,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								other than the inputs. This ensures that for a given known input, the TXIDs can also be known ahead
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								of time. Otherwise, CHECKTEMPLATEVERIFY would not be usable for Batched Channel Creation constructions
							 
						 
					
						
							
								
									
										
										
										
											2022-01-12 10:54:03 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								as the redemption TXID could be malleated and pre-signed transactions invalidated, unless the channels
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								are built using an Eltoo-like protocol. Note that there may be other types of pre-signed contracts that
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								may or may not be able to use Eltoo-like constructs, therefore making TXIDs predictable makes CTV more
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								composable with arbitrary sub-protocols.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to the version and locktime=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Were these values not committed, it would be possible to delay the spending of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								an output arbitrarily as well as possible to change the TXID.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Committing these values, rather than restricting them to specific values, is
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:47:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								more flexible as it permits users of CHECKTEMPLATEVERIFY to set the version and
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								locktime as they please.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to the ScriptSigs Hash=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The scriptsig in a segwit transaction must be exactly empty, unless it is a P2SH
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								segwit transaction in which case it must be only the exact redeemscript. P2SH is incompatible
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								(unless the P2SH hash is broken) with CHECKTEMPLATEVERIFY because the template hash must commit
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:47:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								to the ScriptSig, which must contain the redeemscript, which is a hash cycle.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-08-25 09:34:33 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								To prevent malleability when not using a segwit input, we also commit to the
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								scriptsig. This makes it possible to use a 2 input CHECKTEMPLATEVERIFY with a legacy pre-signed
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								spend, as long as the exact scriptsig for the legacy output is committed. This is more robust than
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								simply disallowing any scriptSig to be set with CHECKTEMPLATEVERIFY.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								If no scriptSigs are set in the transaction, there is no purpose in hashing the data or including it
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								in the DefaultCheckTemplateVerifyHash, so we elide it. It is expected to be common that no scriptSigs will be
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								set as segwit mandates that the scriptSig must be empty (to avoid malleability).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								We commit to the hash rather than the values themselves as this is already
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								precomputed for each transaction to optimize SIGHASH_ALL signatures.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Committing to the hash additionally makes it simpler to construct DefaultCheckTemplateVerifyHash safely and unambiguously from
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								script.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to the number of inputs=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								If we allow more than one input to be spent in the transaction then it would be
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								possible for two outputs to request payment to the same set of outputs,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								resulting in half the intended payments being discarded, the "half-spend" problem.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Furthermore, the restriction on which inputs can be co-spent is critical for
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								payments-channel constructs where a stable TXID is a requirement (updates would
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								need to be signed on all combinations of inputs).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								However, there are legitimate use cases for allowing multiple inputs. For
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								example:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Script paths:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Path A: <+24 hours> OP_CHECKSEQUENCEVERIFY OP_CHECKTEMPLATEVERIFY <Pay Alice 1 Bitcoin (1 input) nLockTime for +24 hours>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Path B: OP_CHECKTEMPLATEVERIFY <Pay Bob 2 Bitcoin (2 inputs)>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								In this case, there are 24 hours for the output to, with the addition of a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								second output, pay Bob 2 BTC. If 24 hours lapses, then Alice may redeem her 1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								BTC from the contract. Both input UTXOs may have the exact same Path B, or only one.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The issue with these constructs is that there are N! orders that the inputs can
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								be ordered in and it's not generally possible to restrict the ordering.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								CHECKTEMPLATEVERIFY allows for users to guarantee the exact number of inputs being
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								spent. In general, using CHECKTEMPLATEVERIFY with more than one input is difficult
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								and exposes subtle issues, so multiple inputs should not be used except in
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								specific applications.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-04 16:11:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								In principle, committing to the Sequences Hash (below) implicitly commits to the number of inputs,
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								making this field strictly redundant. However, separately committing to this number makes it easier
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								to construct DefaultCheckTemplateVerifyHash from script.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-04 16:11:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								We treat the number of inputs as a `uint32_t` because Bitcoin's consensus decoding logic limits vectors
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								to `MAX_SIZE=33554432` and that is larger than `uint16_t` and smaller than `uint32_t`. 32 bits is also
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								friendly for manipulation using Bitcoin's current math opcodes, should `OP_CAT` be added. Note that
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the max inputs in a block is further restricted by the block size to around 25,000, which would fit
							 
						 
					
						
							
								
									
										
										
										
											2024-05-28 19:25:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								into a `uint16_t`, but that is an unnecessary abstraction leak.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to the Sequences Hash=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								If we don't commit to the sequences, then the TXID can be malleated. This also allows us to enforce
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								a relative sequence lock without an OP_CSV. It is insufficient to just pair CHECKTEMPLATEVERIFY
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								with OP_CSV because OP_CSV enforces a minimum nSequence value, not a literal value.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								We commit to the hash rather than the values themselves as this is already
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								precomputed for each transaction to optimize SIGHASH_ALL signatures.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Committing to the hash additionally makes it simpler to construct DefaultCheckTemplateVerifyHash safely and unambiguously from
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								script.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to the Number of Outputs=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-04 16:11:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								In principle, committing to the Outputs Hash (below) implicitly commits to the number of outputs,
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								making this field strictly redundant. However, separately committing to this number makes it easier
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								to construct DefaultCheckTemplateVerifyHash from script.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-04 16:11:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								We treat the number of outputs as a `uint32_t` because a `COutpoint` index is a `uint32_t`.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Further, Bitcoin's consensus decoding logic limits vectors to `MAX_SIZE=33554432` and that is
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								larger than `uint16_t` and smaller than `uint32_t`. 32 bits is also friendly for manipulation using
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Bitcoin's current math opcodes, should `OP_CAT` be added.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to the outputs hash=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								This ensures that spending the UTXO is guaranteed to create the exact outputs
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								requested.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								We commit to the hash rather than the values themselves as this is already
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								precomputed for each transaction to optimize SIGHASH_ALL signatures.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Committing to the hash additionally makes it simpler to construct DefaultCheckTemplateVerifyHash safely and unambiguously from
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								script.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to the current input's index=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Committing to the currently executing input's index is not strictly needed for anti-malleability,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								however it does restrict the input orderings eliminating a source of malleability for protocol
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								designers.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								However, committing to the index eliminates key-reuse vulnerability to the half-spend problem.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								As CHECKTEMPLATEVERIFY scripts commit to being spent at particular index, reused instances of these
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								scripts cannot be spent at the same index, which implies that they cannot be spent in the same transaction.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								This makes it safer to design wallet vault contracts without half-spend vulnerabilities.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Committing to the current index doesn't prevent one from expressing a CHECKTEMPLATEVERIFY which can
							 
						 
					
						
							
								
									
										
										
										
											2024-05-28 19:25:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								be spent at multiple indices. In current script, the CHECKTEMPLATEVERIFY operation can be wrapped
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								in an OP_IF for each index (or Tapscript branches in the future). If OP_CAT or OP_SHA256STREAM are
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								added to Bitcoin, the index may simply be passed in by the witness before hashing.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Committing to Values by Hash=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Committing to values by hash makes it easier and more efficient to construct a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								DefaultCheckTemplateVerifyHash
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								from script. Fields which are not intended to be set may be committed to by hash without incurring
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								O(n) overhead to re-hash.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Furthermore, if OP_SHA256STREAM is added in the future, it may be possible to write a script which
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								allows adding a single output to a list of outputs without incurring O(n) overhead by committing to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								a hash midstate in the script.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:45:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								=====Using SHA256=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								SHA256 is a 32 byte hash which meets Bitcoin's security standards and is
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								available already inside of Bitcoin Script for programmatic creation of template
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								programs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								RIPEMD160, a 20 byte hash, might also be a viable hash in some contexts and has some benefits. For fee efficiency,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								RIPEMD160 saves 12 bytes. However, RIPEMD160 was not chosen for BIP-119 because it introduces
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								risks around the verification of programs created by third parties to be subject to a
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:45:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								[birthday-attack https://bitcoin.stackexchange.com/questions/54841/birthday-attack-on-p2sh] on
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								transaction preimages.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Using Non-Tagged Hashes=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The Taproot/Schnorr BIPs use Tagged Hashes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								(`SHA256(SHA256(tag)||SHA256(tag)||msg)`) to prevent taproot leafs, branches,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								tweaks, and signatures from overlapping in a way that might introduce a security
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[vulnerability https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-June/016091.html].
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY is not subject to this sort of vulnerability as the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								hashes are effectively tagged externally, that is, by OP_CHECKTEMPLATEVERIFY
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								itself and therefore cannot be confused for another hash.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								It would be a conservative design decisison to make it a tagged hash even if
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								there was no obvious benefit and no cost. However, in the future, if OP_CAT were
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								to be introduced to Bitcoin, it would make programs which dynamically build
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY hashes less space-efficient. Therefore, bare untagged hashes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								are used in BIP-119.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====The Ordering of Fields=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:19:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Strictly speaking, the ordering of fields is insignificant. However, with a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								carefully selected order, the efficiency of future scripts (e.g., those using a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								OP_CAT or OP_SHA256STREAM) may be improved (as described in the Future Upgrades
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								section).
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								In particular, the order is selected in order of least likely to change to most.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#nVersion
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#nLockTime
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#scriptSig hash (maybe!)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#input count
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#sequences hash
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#output count
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#outputs hash
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#input index
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Several fields are infrequently modified. nVersion should change infrequently. nLockTime should
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								generally be fixed to 0 (in the case of a payment tree, only the *first* lock time is needed to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								prevent fee-sniping the root). scriptSig hash should generally not be set at all.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Since there are many possible sequences hash for a given input count, the input count comes before
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the sequences hash.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Since there are many possible outputs hashes for a given out count, the output count comes before
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the outputs hash.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Since we're generally using a single input to many output design, we're more likely to modify the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								outputs hash than the inputs hash.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								We usually have just a single input on a CHECKTEMPLATEVERIFY script, which would suggest that it
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								does not make sense for input index to be the last field. However, given the desirability of being
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								able to express a "don't care" index easily (e.g., for decentralized kickstarter-type transactions),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								this value is placed last.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								===Design Tradeoffs and Risks===
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Covenants have historically been controversial given their potential for fungibility risks -- coins
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								could be minted which have a permanent restriction on how they may or may not be spent or required
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								to propagate metadata.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								In the CHECKTEMPLATEVERIFY approach, the covenants are severely restricted to simple templates. The
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								structure of CHECKTEMPLATEVERIFY template is such that the outputs must be known exactly at the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								time of construction. Based on a destructuring argument, it is only possible to create templates
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								which expand in a finite number of steps. Thus templated transactions are in theory as safe as
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								transactions which create all the inputs directly in this regard.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Furthermore, templates are restricted to be spendable as a known number of inputs only, preventing
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								unintentional introduction of the 'half spend' problem.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Templates, as restricted as they are, bear some risks.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-10 20:23:07 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								====Denial of Service and Validation Costs====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								CTV is designed to be able to be validated very cheaply without introducing DoS, either by checking a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								precomputed hash or computing a hash of fixed length arguments (some of which may be cached from more
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								expensive computations).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								In particular, CTV requires that clients cache the computation of a hash over all the scriptSigs, sequences,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								and outputs. Before CTV, the hash of the scriptSigs was not required. CTV also requires that the presence of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								any non-empty scriptSig be hashed, but this can be handled as a part of the scriptSigs hash.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								As such, evaluating a CTV hash during consensus is always O(1) computation when the caches are available.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								These caches usually must be available due to similar issues in CHECKSIG behavior. Computing the caches
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								is O(T) (the size of the transaction).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								An example of a script that could experience an DoS issue without caching is:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-28 09:43:30 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    <H> CTV CTV CTV... CTV
							 
						 
					
						
							
								
									
										
										
										
											2022-01-10 20:23:07 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-28 19:25:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Such a script would cause the interpreter to compute hashes (supposing N CTV's) over O(N*T) data.
							 
						 
					
						
							
								
									
										
										
										
											2022-01-10 20:23:07 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								If the scriptSigs non-nullity is not cached, then the O(T) transaction could be scanned over O(N)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								times as well (although cheaper than hashing, still a DoS). As such, CTV caches hashes and computations
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								over all variable length fields in a transaction.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								For CTV, the Denial-of-Service exposure and validation costs are relatively clear. Implementors must be careful
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								to correctly code CTV to make use of existing caches and cache the (new for CTV) computations over scriptSigs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Other more flexible covenant proposals may have a more difficult time solving DoS issues as more complex computations may
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								be less cacheable and expose issues around quadratic hashing, it is a tradeoff CTV makes in favor of cheap and secure
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								validation at the expense of flexibility. For example, if CTV allowed the hashing only select outputs by a bitmask,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								caching of all combinations of outputs would not be possible and would cause a quadratic hashing DoS vulnerability.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								====Permanently Unspendable Outputs====
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								The preimage argument passed to CHECKTEMPLATEVERIFY may be unknown or otherwise unsatisfiable.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								However, requiring knowledge that an address is spendable from is incompatible with sender's ability
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								to spend to any address (especially, OP_RETURN). If a sender needs to know the template can be spent
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from before sending, they may request a signature of an provably non-transaction challenge string
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from the leafs of the CHECKTEMPLATEVERIFY tree.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								====Forwarding Addresses====
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								Key-reuse with CHECKTEMPLATEVERIFY may be used as a form of "forwarding address contract".
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								A forwarding address is an address which can automatically execute in a predefined way.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								For example, a exchange's hot wallet might use an address which can automatically be moved to a cold
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								storage address after a relative timeout.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The issue is that reusing addresses in this way can lead to loss of funds.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Suppose one creates an template address which forwards 1 BTC to cold storage.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Creating an output to this address with less than 1 BTC will be frozen permanently.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Paying more than 1 BTC will lead to the funds in excess of 1BTC to be paid as a large miner fee.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								CHECKTEMPLATEVERIFY could commit to the exact amount of bitcoin provided by the inputs/amount of fee
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								paid, but as this is a user error and not a malleability issue this is not done.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Future soft-forks could introduce opcodes which allow conditionalizing which template or script
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								branches may be used based on inspecting the amount of funds available in a transaction
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								As a general best practice, it is incumbent on Bitcoin users to not reuse any address unless you are
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								certain that the address is acceptable for the payment attempted. This limitation and risk is not
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								unique to CHECKTEMPLATEVERIFY. For example, atomic swap scripts are single use once the hash is
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								revealed. Future Taproot scripts may contain many logical branches that would be unsafe for being
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								spent to multiple times (e.g., a Hash Time Lock branch should be instantiated with unique hashes
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								each time it is used). Keys which have signed a SIGHASH_ANYPREVOUT transaction can similarly become
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								reuse-unsafe.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Because CHECKTEMPLATEVERIFY commits to the input index currently being spent, reused-keys are
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								guaranteed to execute in separate transactions which reduces the risk of "half-spend" type issues.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-26 15:31:34 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								====NOP-Default and Recommended Standardness Rules====
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-26 15:31:34 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								If the argument length is not exactly 32, CHECKTEMPLATEVERIFY treats it as a NOP during
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								consensus validation. Implementations are recommended to fail in such circumstances during non-consensus
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								relaying and mempool validation. In particular, making an invalid-length argument a failure aids future
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								soft-forks upgrades to be able to rely on the tighter standard restrictions to safely loosen
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the restrictions for standardness while tightening them for consensus with the upgrade's rules.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								The standardness rules may lead an unscrupulous script developer to accidentally rely on the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								stricter standardness rules to be enforced during consensus. Should that developer submit a
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								transaction directly to the network relying on standardness rejection, an standardness-invalid but
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								consensus-valid transaction may be caused, leading to a potential loss of funds.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								====Feature Redundancy====
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								CHECKTEMPLATEVERIFY templates are substantially less risky than other covenant systems. If
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								implemented, other covenant systems could make the CHECKTEMPLATEVERIFY's functionality redundant.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								However, given CHECKTEMPLATEVERIFY's simple semantics and low on chain cost it's likely that it
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								would continue to be favored even if redundant with other capabilities.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								More powerful covenants like those proposed by MES16, would also bring some benefits in terms of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								improving the ability to adjust for things like fees rather than relying on child-pays-for-parent or
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								other mechanisms. However, these features come at substantially increased complexity and room for
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								unintended behavior.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Alternatively, SIGHASH_ANYPREVOUTANYSCRIPT based covenant designs can implement
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								something similar to templates, via a scriptPubKey like:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    <sig of desired TX with PK and fixed nonce R || SIGHASH_ANYPREVOUTANYSCRIPT <PK with public SK> OP_CHECKSIG
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:40:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								SIGHASH_ANYPREVOUTANYSCRIPT bears additional technical and implementation risks
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								that may preclude its viability for inclusion in Bitcoin, but the capabilities
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								above are similar to what CHECKTEMPLATEVERIFY offers. The key functional
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								difference between SIGHASH_ANYPREVOUTANYSCRIPT and OP_CHECKTEMPLATEVERIFY is
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								that OP_CHECKTEMPLATEVERIFY restricts the number of additional inputs and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								precludes dynamically determined change outputs while
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								SIGHASH_ANYPREVOUTANYSCRIPT can be combined with SIGHASH_SINGLE or
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								SIGHASH_ANYONECANPAY. For the additional inputs, OP_CHECKTEMPLATEVERIFY also
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								commits to the scriptsig and sequence, which allows for specifying specific P2SH
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								scripts (or segwit v0 P2SH) which have some use cases. Furthermore,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								CHECKTEMPLATEVERIFY has benefits in terms of script size (depending on choice of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PK, SIGHASH_ANYPREVOUTANYSCRIPT may use about 2x-3x the bytes) and verification
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								speed, as OP_CHECKTEMPLATEVERIFY requires only hash computation rather than
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								signature operations. This can be significant when constructing large payment
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								trees or programmatic compilations. CHECKTEMPLATEVERIFY also has a feature-wise
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:40:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								benefit in that it provides a robust pathway for future template upgrades.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:19:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								OP_CHECKSIGFROMSTACKVERIFY along with OP_CAT may also be used to emulate
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								CHECKTEMPLATEVERIFY. However such constructions are more complicated to use
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:40:05 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								than CHECKTEMPLATEVERIFY, and encumbers additional verification overhead absent
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from CHECKTEMPLATEVERIFY. These types of covenants also bear similar potential
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								recursion issues to OP_COV which make it unlikely for inclusion in Bitcoin.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Given the simplicity of this approach to implement and analyze, and the benefits realizable by user
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								applications, CHECKTEMPLATEVERIFY's template based approach is proposed in lieu of more complete
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								covenants system.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-10 20:23:07 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:19:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								====Future Upgrades====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								This section describes updates to OP_CHECKTEMPLATEVERIFY that are possible in
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the future as well as synergies with other possible upgrades.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====CHECKTEMPLATEVERIFY Versions=====
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:19:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY currently only verifies properties of 32 byte arguments.
							 
						 
					
						
							
								
									
										
										
										
											2022-05-23 09:28:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								In the future, meaning could be ascribed to other length arguments. For
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:19:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								example, a 33-byte argument could just the last byte as a control program. In
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								that case, DefaultCheckTemplateVerifyHash could be computed when the flag byte
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								is set to CTVHASH_ALL. Other programs could be added similar to SIGHASH_TYPEs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								For example, CTVHASH_GROUP could read data from the Taproot Annex for
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								compatibility with SIGHASH_GROUP type proposals and allow dynamic malleability
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								of which indexes get hashed for bundling.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====Eltoo with OP_CHECKSIGFROMSTACKVERIFY=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Were both OP_CHECKTEMPLATEVERIFY and OP_CHECKSIGFROMSTACKVERIFY to be added to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Bitcoin, it would be possible to implement a variant of Eltoo's floating
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								transactions using the following script:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    witness(S+n): <sig> <H(tx with nLockTime S+n paying to program(S+n))>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    program(S): OP_CHECKTEMPLATEVERIFY <musig_key(pk_update_a, pk_update_b)> OP_CHECKSIGFROMSTACKVERIFY <S+1> OP_CHECKLOCKTIMEVERIFY
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Compared to SIGHASH_ANYPREVOUTANYSCRIPT, because OP_CHECKTEMPLATEVERIFY does not
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								allow something similar to SIGHASH_ANYONECANPAY or SIGHASH_SINGLE, protocol
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								implementers might elect to sign multiple versions of transactions with CPFP
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Anchor Outputs or Inputs for paying fees or an alternative such as transaction
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								sponsors might be considered.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====OP_AMOUNTVERIFY=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								An opcode which verifies the exact amount that is being spent in the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								transaction, the amount paid as fees, or made available in a given output could
							 
						 
					
						
							
								
									
										
										
										
											2024-05-28 19:25:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								be used to make safer OP_CHECKTEMPLATEVERIFY addresses. For instance, if the
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 12:19:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY program P expects exactly S satoshis, sending S-1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								satoshis would result in a frozen UTXO and sending S+n satoshis would result in
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								n satoshis being paid to fee. A range check could restrict the program to only
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								apply for expected values and default to a keypath otherwise, e.g.:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    IF OP_AMOUNTVERIFY <N> OP_GREATER <PK> CHECKSIG ELSE <H> OP_CHECKTEMPLATEVERIFY
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								=====OP_CAT/OP_SHA256STREAM=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY is (as described in the Ordering of Fields section)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								efficient for building covenants dynamically should Bitcoin get enhanced string
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								manipulation opcodes.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								As an example, the following code checks an input index argument and
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								concatenates it to the template and checks the template matches the transaction.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    OP_SIZE 4 OP_EQUALVERIF
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    <nVersion || nLockTime || input count || sequences hash || output count || outputs hash>
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    OP_SWAP OP_CAT OP_SHA256 OP_CHECKTEMPLATEVERIFY
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-20 20:15:23 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								== Backwards Compatibility ==
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								OP_CHECKTEMPLATEVERIFY replaces a OP_NOP4 with stricter verification semantics. Therefore, scripts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								which previously were valid will cease to be valid with this change. Stricter verification semantics
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								for an OP_NOP are a soft fork, so existing software will be fully functional without upgrade except
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								for mining and block validation. Similar soft forks for OP_CHECKSEQUENCEVERIFY and OP_CHECKLOCKTIMEVERIFY
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								(see BIP-0065 and BIP-0112) have similarly changed OP_NOP semantics without introducing compatibility issues.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-26 15:31:34 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								In contrast to previous forks, OP_CHECKTEMPLATEVERIFY's reference implementation does not allow transactions with spending
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								scripts using it to be accepted to the mempool or relayed under standard policy until the new rule is active. Other implementations
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								are recommended to follow this rule as well, but not required.
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 11:21:46 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-20 20:15:23 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								Older wallet software will be able to accept spends from OP_CHECKTEMPLATEVERIFY outputs, but will
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 10:55:37 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								require an upgrade in order to treat PayToBareDefaultCheckTemplateVerifyHash chains with a confirmed ancestor as
							 
						 
					
						
							
								
									
										
										
										
											2020-01-20 20:15:23 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								being "trusted" (i.e., eligible for spending before the transaction is confirmed).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Backports of OP_CHECKTEMPLATEVERIFY can be trivially prepared (see the reference implementation)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								for older node versions that can be patched but not upgraded to a newer major release.
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								== References ==
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-25 12:10:07 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								*[https://utxos.org utxos.org informational site]
							 
						 
					
						
							
								
									
										
										
										
											2021-12-22 19:15:28 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								*[https://learn.sapio-lang.org Sapio Bitcoin smart contract language]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://rubin.io/advent21 27 Blog Posts on building smart contracts with Sapio and CTV, including examples described here.]
							 
						 
					
						
							
								
									
										
										
										
											2020-01-25 12:10:07 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								*[https://www.youtube.com/watch?v=YxsjdIl0034&t=2451 Scaling Bitcoin Presentation]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://bitcoinops.org/en/newsletters/2019/05/29/ Optech Newsletter Covering OP_CHECKOUTPUTSHASHVERIFY]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://cyber.stanford.edu/sites/g/files/sbiybj9936/f/jeremyrubin.pdf Structuring Multi Transaction Contracts in Bitcoin]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://github.com/jeremyrubin/lazuli Lazuli Notes (ECDSA based N-of-N Signatures for Certified Post-Dated UTXOs)]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://fc16.ifca.ai/bitcoin/papers/MES16.pdf Bitcoin Covenants]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://bitcointalk.org/index.php?topic=278122.0 CoinCovenants using SCIP signatures, an amusingly bad idea.]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://fc17.ifca.ai/bitcoin/papers/bitcoin17-final28.pdf Enhancing Bitcoin Transactions with Covenants]
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 09:09:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								*[https://github.com/jamesob/simple-ctv-vault Simple CTV Vaults]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://github.com/kanzure/python-vaults Python Vaults]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019808.html CTV Dramatically Improves DLCs]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-April/020225.html Calculus of Covenants]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://rubin.io/bitcoin/2021/12/10/advent-13/ Payment Pools with CTV]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://rubin.io/bitcoin/2021/12/11/advent-14/ Channels with CTV]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://rubin.io/bitcoin/2021/12/09/advent-12/ Congestion Control with CTV]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*[https://rubin.io/bitcoin/2021/12/07/advent-10/ Building Vaults on Bitcoin]
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								===Note on Similar Alternatives===
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								An earlier version of CHECKTEMPLATEVERIFY, CHECKOUTPUTSHASHVERIFY, is withdrawn
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								in favor of CHECKTEMPLATEVERIFY. CHECKOUTPUTSHASHVERIFY did not commit to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								version or lock time and was thus insecure.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								CHECKTEMPLATEVERIFY could also be implemented as an extension to Taproot, and was
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								proposed this way earlier. However, given that CHECKTEMPLATEVERIFY has no dependency
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								on Taproot, it is preferable to deploy it independently.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								CHECKTEMPLATEVERIFY has also been previously referred to as OP_SECURETHEBAG, which is mentioned here
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								to aid in searching and referencing discussion on this BIP.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								==Copyright==
							 
						 
					
						
							
								
									
										
										
										
											2021-10-16 09:00:48 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 10:46:10 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								This document is licensed under the 3-clause BSD license.