Skip to content

Commit 43a48ec

Browse files
authored
Merge pull request bitcoin#1319 from JeremyRubin/119-syntax
[BIP-119] Use mediawiki syntax highlighting, add comment to spec
2 parents 7d30956 + aa1871b commit 43a48ec

File tree

1 file changed

+101
-58
lines changed

1 file changed

+101
-58
lines changed

bip-0119.mediawiki

Lines changed: 101 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -66,31 +66,40 @@ OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can
6666
be seen in the reference implementation.
6767

6868
The execution of the opcode is as follows:
69-
def execute_bip_119(self):
70-
# Before soft-fork activation / failed activation
71-
if not self.flags.script_verify_default_check_template_verify_hash:
72-
# Potentially set for node-local policy to discourage premature use
73-
if self.flags.script_verify_discourage_upgradable_nops:
74-
return self.errors_with(errors.script_err_discourage_upgradable_nops)
75-
return self.return_as_nop()
76-
# CTV always requires at least one stack argument
77-
if len(self.stack) < 1:
78-
return self.errors_with(errors.script_err_invalid_stack_operation)
79-
# CTV only verifies the hash against a 32 byte argument
80-
if len(self.stack[-1]) == 32:
81-
# Ensure the precomputed data required for anti-DoS is available,
82-
# or cache it on first use
83-
if self.context.precomputed_ctv_data == None:
84-
self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data()
85-
if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data)
86-
return self.errors_with(errors.script_err_template_mismatch)
87-
return self.return_as_nop()
88-
# future upgrade can add semantics for this opcode with different length args
89-
# so discourage use when applicable
69+
<source lang="python">
70+
def execute_bip_119(self):
71+
# Before soft-fork activation / failed activation
72+
# continue to treat as NOP4
73+
if not self.flags.script_verify_default_check_template_verify_hash:
74+
# Potentially set for node-local policy to discourage premature use
9075
if self.flags.script_verify_discourage_upgradable_nops:
9176
return self.errors_with(errors.script_err_discourage_upgradable_nops)
92-
else:
93-
return self.return_as_nop()
77+
return self.return_as_nop()
78+
79+
# CTV always requires at least one stack argument
80+
if len(self.stack) < 1:
81+
return self.errors_with(errors.script_err_invalid_stack_operation)
82+
83+
# CTV only verifies the hash against a 32 byte argument
84+
if len(self.stack[-1]) == 32:
85+
# Ensure the precomputed data required for anti-DoS is available,
86+
# or cache it on first use
87+
if self.context.precomputed_ctv_data == None:
88+
self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data()
89+
90+
# If the hashes do not match, return error
91+
if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data)
92+
return self.errors_with(errors.script_err_template_mismatch)
93+
94+
return self.return_as_nop()
95+
96+
# future upgrade can add semantics for this opcode with different length args
97+
# so discourage use when applicable
98+
if self.flags.script_verify_discourage_upgradable_nops:
99+
return self.errors_with(errors.script_err_discourage_upgradable_nops)
100+
else:
101+
return self.return_as_nop()
102+
</source>
94103

95104
The computation of this hash can be implemented as specified below (where self
96105
is the transaction type). Care must be taken that in any validation context,
@@ -101,46 +110,80 @@ including hashes of the scriptsigs, sequences, and outputs. See the section
101110
"Denial of Service and Validation Costs" below. This is not a performance
102111
optimization.
103112

104-
def get_default_check_template_precomputed_data(self):
105-
result = {}
106-
# If there are no scriptSigs we do not need to precompute a hash
107-
if any(inp.scriptSig for inp in self.vin):
108-
result["scriptSigs"] = sha256(b"".join(ser_string(inp.scriptSig) for inp in self.vin))
109-
# The same value is also pre-computed for and defined in BIP-341 and can be shared
110-
result["sequences"] = sha256(b"".join(struct.pack("<I", inp.nSequence) for inp in self.vin))
111-
# The same value is also pre-computed for and defined in BIP-341 and can be shared
112-
result["outputs"] = sha256(b"".join(out.serialize() for out in self.vout))
113-
return result
114-
115-
# parameter precomputed must be passed in for DoS resistance
116-
def get_default_check_template_hash(self, nIn, precomputed = None):
117-
if precomputed == None:
118-
precomputed = self.get_default_check_template_precomputed_data()
113+
<source lang="python">
114+
115+
def ser_compact_size(l):
116+
r = b""
117+
if l < 253:
118+
# Serialize as unsigned char
119+
r = struct.pack("B", l)
120+
elif l < 0x10000:
121+
# Serialize as unsigned char 253 followed by unsigned 2 byte integer (little endian)
122+
r = struct.pack("<BH", 253, l)
123+
elif l < 0x100000000:
124+
# Serialize as unsigned char 254 followed by unsigned 4 byte integer (little endian)
125+
r = struct.pack("<BI", 254, l)
126+
else:
127+
# Serialize as unsigned char 255 followed by unsigned 8 byte integer (little endian)
128+
r = struct.pack("<BQ", 255, l)
129+
return r
130+
131+
def ser_string(s):
132+
return ser_compact_size(len(s)) + s
133+
134+
class CTxOut:
135+
def serialize(self):
119136
r = b""
120-
# pack as 4 byte signed integer
121-
r += struct.pack("<i", self.nVersion)
122-
# pack as 4 byte unsigned integer
123-
r += struct.pack("<I", self.nLockTime)
124-
# we do not include the hash in the case where there is no
125-
# scriptSigs
126-
if "scriptSigs" in precomputed:
127-
r += precomputed["scriptSigs"]
128-
# pack as 4 byte unsigned integer
129-
r += struct.pack("<I", len(self.vin))
130-
r += precomputed["sequences"]
131-
# pack as 4 byte unsigned integer
132-
r += struct.pack("<I", len(self.vout))
133-
r += precomputed["outputs"]
134-
# pack as 4 byte unsigned integer
135-
r += struct.pack("<I", nIn)
136-
return sha256(r)
137+
# serialize as signed 8 byte integer (little endian)
138+
r += struct.pack("<q", self.nValue)
139+
r += ser_string(self.scriptPubKey)
140+
return r
141+
142+
def get_default_check_template_precomputed_data(self):
143+
result = {}
144+
# If there are no scriptSigs we do not need to precompute a hash
145+
if any(inp.scriptSig for inp in self.vin):
146+
result["scriptSigs"] = sha256(b"".join(ser_string(inp.scriptSig) for inp in self.vin))
147+
# The same value is also pre-computed for and defined in BIP-341 and can be shared.
148+
# each nSequence is packed as 4 byte unsigned integer (little endian)
149+
result["sequences"] = sha256(b"".join(struct.pack("<I", inp.nSequence) for inp in self.vin))
150+
# The same value is also pre-computed for and defined in BIP-341 and can be shared
151+
# See class CTxOut above for details.
152+
result["outputs"] = sha256(b"".join(out.serialize() for out in self.vout))
153+
return result
154+
155+
# parameter precomputed must be passed in for DoS resistance
156+
def get_default_check_template_hash(self, nIn, precomputed = None):
157+
if precomputed == None:
158+
precomputed = self.get_default_check_template_precomputed_data()
159+
r = b""
160+
# Serialize as 4 byte signed integer (little endian)
161+
r += struct.pack("<i", self.nVersion)
162+
# Serialize as 4 byte unsigned integer (little endian)
163+
r += struct.pack("<I", self.nLockTime)
164+
# we do not include the hash in the case where there is no
165+
# scriptSigs
166+
if "scriptSigs" in precomputed:
167+
r += precomputed["scriptSigs"]
168+
# Serialize as 4 byte unsigned integer (little endian)
169+
r += struct.pack("<I", len(self.vin))
170+
r += precomputed["sequences"]
171+
# Serialize as 4 byte unsigned integer (little endian)
172+
r += struct.pack("<I", len(self.vout))
173+
r += precomputed["outputs"]
174+
# Serialize as 4 byte unsigned integer (little endian)
175+
r += struct.pack("<I", nIn)
176+
return sha256(r)
177+
</source>
137178

138179

139180
A PayToBareDefaultCheckTemplateVerifyHash output matches the following template:
140181

141-
# Extra-fast test for pay-to-basic-standard-template CScripts:
142-
def is_pay_to_bare_default_check_template_verify_hash(self):
143-
return len(self) == 34 and self[0] == 0x20 and self[-1] == OP_CHECKTEMPLATEVERIFY
182+
<source lang="python">
183+
# Extra-fast test for pay-to-basic-standard-template CScripts:
184+
def is_pay_to_bare_default_check_template_verify_hash(self):
185+
return len(self) == 34 and self[0] == 0x20 and self[-1] == OP_CHECKTEMPLATEVERIFY
186+
</source>
144187

145188

146189
==Deployment==

0 commit comments

Comments
 (0)