mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-08 13:49:35 +02:00
Implement Tapscript script validation rules (BIP 342)
This adds a new `SigVersion::TAPSCRIPT`, makes the necessary interpreter changes to make it implement BIP342, and uses them for leaf version 0xc0 in Taproot script path spends.
This commit is contained in:
committed by
Pieter Wuille
parent
330de894a9
commit
72422ce396
@@ -86,6 +86,8 @@ enum
|
||||
// "Exactly one stack element must remain, and when interpreted as a boolean, it must be true".
|
||||
// (BIP62 rule 6)
|
||||
// Note: CLEANSTACK should never be used without P2SH or WITNESS.
|
||||
// Note: WITNESS_V0 and TAPSCRIPT script execution have behavior similar to CLEANSTACK as part of their
|
||||
// consensus rules. It is automatic there and does not need this flag.
|
||||
SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
|
||||
|
||||
// Verify CHECKLOCKTIMEVERIFY
|
||||
@@ -108,6 +110,8 @@ enum
|
||||
|
||||
// Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector
|
||||
//
|
||||
// Note: TAPSCRIPT script execution has behavior similar to MINIMALIF as part of its consensus
|
||||
// rules. It is automatic there and does not depend on this flag.
|
||||
SCRIPT_VERIFY_MINIMALIF = (1U << 13),
|
||||
|
||||
// Signature(s) must be empty vector if a CHECK(MULTI)SIG operation failed
|
||||
@@ -122,13 +126,19 @@ enum
|
||||
//
|
||||
SCRIPT_VERIFY_CONST_SCRIPTCODE = (1U << 16),
|
||||
|
||||
// Taproot validation (BIP 341)
|
||||
// Taproot/Tapscript validation (BIPs 341 & 342)
|
||||
//
|
||||
SCRIPT_VERIFY_TAPROOT = (1U << 17),
|
||||
|
||||
// Making unknown Taproot leaf versions non-standard
|
||||
//
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION = (1U << 18),
|
||||
|
||||
// Making unknown OP_SUCCESS non-standard
|
||||
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS = (1U << 19),
|
||||
|
||||
// Making unknown public key versions (in BIP 342 scripts) non-standard
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1U << 20),
|
||||
};
|
||||
|
||||
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);
|
||||
@@ -168,16 +178,32 @@ enum class SigVersion
|
||||
BASE = 0, //!< Bare scripts and BIP16 P2SH-wrapped redeemscripts
|
||||
WITNESS_V0 = 1, //!< Witness v0 (P2WPKH and P2WSH); see BIP 141
|
||||
TAPROOT = 2, //!< Witness v1 with 32-byte program, not BIP16 P2SH-wrapped, key path spending; see BIP 341
|
||||
TAPSCRIPT = 3, //!< Witness v1 with 32-byte program, not BIP16 P2SH-wrapped, script path spending, leaf version 0xc0; see BIP 342
|
||||
};
|
||||
|
||||
struct ScriptExecutionData
|
||||
{
|
||||
//! Whether m_tapleaf_hash is initialized.
|
||||
bool m_tapleaf_hash_init = false;
|
||||
//! The tapleaf hash.
|
||||
uint256 m_tapleaf_hash;
|
||||
|
||||
//! Whether m_codeseparator_pos is initialized.
|
||||
bool m_codeseparator_pos_init = false;
|
||||
//! Opcode position of the last executed OP_CODESEPARATOR (or 0xFFFFFFFF if none executed).
|
||||
uint32_t m_codeseparator_pos;
|
||||
|
||||
//! Whether m_annex_present and (when needed) m_annex_hash are initialized.
|
||||
bool m_annex_init = false;
|
||||
//! Whether an annex is present.
|
||||
bool m_annex_present;
|
||||
//! Hash of the annex data.
|
||||
uint256 m_annex_hash;
|
||||
|
||||
//! Whether m_validation_weight_left is initialized.
|
||||
bool m_validation_weight_left_init = false;
|
||||
//! How much validation weight is left (decremented for every successful non-empty signature check).
|
||||
int64_t m_validation_weight_left;
|
||||
};
|
||||
|
||||
/** Signature hash sizes */
|
||||
@@ -186,6 +212,7 @@ static constexpr size_t WITNESS_V0_KEYHASH_SIZE = 20;
|
||||
static constexpr size_t WITNESS_V1_TAPROOT_SIZE = 32;
|
||||
|
||||
static constexpr uint8_t TAPROOT_LEAF_MASK = 0xfe;
|
||||
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT = 0xc0;
|
||||
static constexpr size_t TAPROOT_CONTROL_BASE_SIZE = 33;
|
||||
static constexpr size_t TAPROOT_CONTROL_NODE_SIZE = 32;
|
||||
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT = 128;
|
||||
|
||||
Reference in New Issue
Block a user