1
0
mirror of https://github.com/bitcoin/bips.git synced 2025-05-12 12:03:29 +00:00

[BIP-119] Remove C++ Spec from BIP-119 entirely.

This commit is contained in:
Jeremy Rubin 2022-04-28 09:45:13 -07:00
parent fa09f7f857
commit cad2b3ee77

View File

@ -163,7 +163,8 @@ forming a "Payment Pool".
The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described
in pythonic pseduocode. The canonical specification for the semantics of in pythonic pseduocode. The canonical specification for the semantics of
OP_CHECKTEMPLATEVERIFY can be seen in the reference implementations. OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can
be seen in the reference implementation.
The execution of the opcode is as follows: The execution of the opcode is as follows:
def execute_bip_119(self): def execute_bip_119(self):
@ -236,128 +237,6 @@ optimization.
return sha256(r) return sha256(r)
The C++ is below:
case OP_CHECKTEMPLATEVERIFY:
{
// if flags not enabled; treat as a NOP4
if (!(flags & SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH)) {
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
break;
}
if (stack.size() < 1)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
// If the argument was not 32 bytes, treat as OP_NOP4:
switch (stack.back().size()) {
case 32:
if (!checker.CheckDefaultCheckTemplateVerifyHash(stack.back())) {
return set_error(serror, SCRIPT_ERR_TEMPLATE_MISMATCH);
}
break;
default:
// future upgrade can add semantics for this opcode with different length args
// so discourage use when applicable
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
}
}
}
break;
Where
bool CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) {
return GetDefaultCheckTemplateVerifyHash(current_tx, current_input_index) == uint256(hash);
}
The hash is computed as follows, where the outputs_hash and sequences_hash are computed as defined in BIP-341.
/** Compute the (single) SHA256 of the concatenation of all scriptSigs in a tx. */
template <class T>
uint256 GetScriptSigsSHA256(const T& txTo)
{
CHashWriter ss(SER_GETHASH, 0);
for (const auto& in : txTo.vin) {
ss << in.scriptSig;
}
return ss.GetSHA256();
}
// not DoS safe, for reference/testing!
uint256 GetDefaultCheckTemplateVerifyHash(const CTransaction& tx, uint32_t input_index) {
return GetDefaultCheckTemplateVerifyHash(tx, GetOutputsSHA256(tx), GetSequenceSHA256(tx), input_index);
}
// not DoS safe for reference/testing!
uint256 GetDefaultCheckTemplateVerifyHash(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
const uint32_t input_index) {
bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(),
[](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end();
return skip_scriptSigs ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) :
GetDefaultCheckTemplateVerifyHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index);
}
// DoS safe, fixed length hash!
uint256 GetDefaultCheckTemplateVerifyHashWithScript(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
const uint256& scriptSig_hash, const uint32_t input_index) {
auto h = CHashWriter(SER_GETHASH, 0)
<< tx.nVersion
<< tx.nLockTime
<< scriptSig_hash
<< uint32_t(tx.vin.size())
<< sequences_hash
<< uint32_t(tx.vout.size())
<< outputs_hash
<< input_index;
return h.GetSHA256();
}
// DoS safe, fixed length hash!
uint256 GetDefaultCheckTemplateVerifyHashEmptyScript(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
const uint32_t input_index) {
auto h = CHashWriter(SER_GETHASH, 0)
<< tx.nVersion
<< tx.nLockTime
<< uint32_t(tx.vin.size())
<< sequences_hash
<< uint32_t(tx.vout.size())
<< outputs_hash
<< input_index;
return h.GetSHA256();
}
case OP_CHECKTEMPLATEVERIFY:
{
// if flags not enabled; treat as a NOP4
if (!(flags & SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH)) {
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
break;
}
if (stack.size() < 1)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
// If the argument was not 32 bytes, treat as OP_NOP4:
switch (stack.back().size()) {
case 32:
if (!checker.CheckDefaultCheckTemplateVerifyHash(stack.back())) {
return set_error(serror, SCRIPT_ERR_TEMPLATE_MISMATCH);
}
break;
default:
// future upgrade can add semantics for this opcode with different length args
// so discourage use when applicable
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
}
}
}
A PayToBareDefaultCheckTemplateVerifyHash output matches the following template: A PayToBareDefaultCheckTemplateVerifyHash output matches the following template:
bool CScript::IsPayToBareDefaultCheckTemplateVerifyHash() const bool CScript::IsPayToBareDefaultCheckTemplateVerifyHash() const