17 typedef std::vector<unsigned char>
valtype;
79 pubkeyhash =
valtype(script.begin () + 3, script.begin() + 23);
108 if (count < min || count > max)
return {};
120 if (!script.
GetOp(it, opcode, data))
return false;
122 if (!req_sigs)
return false;
123 required_sigs = *req_sigs;
125 pubkeys.emplace_back(std::move(data));
128 if (!num_keys)
return false;
129 if (pubkeys.size() !=
static_cast<unsigned long>(*num_keys))
return false;
131 return (it + 1 == script.
end());
134 std::optional<std::pair<int, std::vector<Span<const unsigned char>>>>
MatchMultiA(
const CScript& script)
136 std::vector<Span<const unsigned char>> keyspans;
142 auto it = script.
begin();
143 while (script.
end() - it >= 34) {
144 if (*it != 32)
return {};
146 keyspans.emplace_back(&*it, 32);
155 std::vector<unsigned char> data;
156 if (!script.
GetOp(it, opcode, data))
return {};
157 if (it == script.
end())
return {};
160 if (it != script.
end())
return {};
161 auto threshold =
GetScriptNumber(opcode, data, 1, (
int)keyspans.size());
162 if (!threshold)
return {};
165 return std::pair{*threshold, std::move(keyspans)};
170 vSolutionsRet.clear();
176 std::vector<unsigned char> hashBytes(scriptPubKey.
begin()+2, scriptPubKey.
begin()+22);
177 vSolutionsRet.push_back(hashBytes);
182 std::vector<unsigned char> witnessprogram;
185 vSolutionsRet.push_back(std::move(witnessprogram));
189 vSolutionsRet.push_back(std::move(witnessprogram));
193 vSolutionsRet.push_back(std::move(witnessprogram));
196 if (witnessversion != 0) {
197 vSolutionsRet.push_back(std::vector<unsigned char>{(
unsigned char)witnessversion});
198 vSolutionsRet.push_back(std::move(witnessprogram));
213 std::vector<unsigned char> data;
215 vSolutionsRet.push_back(std::move(data));
220 vSolutionsRet.push_back(std::move(data));
225 std::vector<std::vector<unsigned char>> keys;
227 vSolutionsRet.push_back({
static_cast<unsigned char>(required)});
228 vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
229 vSolutionsRet.push_back({
static_cast<unsigned char>(keys.size())});
233 vSolutionsRet.clear();
239 std::vector<valtype> vSolutions;
248 addressRet =
PKHash(pubKey);
261 std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.
begin());
267 std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.
begin());
273 std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.
begin());
279 unk.
version = vSolutions[0][0];
280 std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.
program);
281 unk.
length = vSolutions[1].size();
336 return std::visit(CScriptVisitor(), dest);
349 for (
const CPubKey& key : keys)
357 return dest.index() != 0;
364 for (
auto& leaf : a.leaves) {
365 leaf.merkle_branch.push_back(b.hash);
366 ret.leaves.emplace_back(std::move(leaf));
369 for (
auto& leaf : b.leaves) {
370 leaf.merkle_branch.push_back(a.hash);
371 ret.leaves.emplace_back(std::move(leaf));
374 if (a.hash < b.hash) {
392 for (
auto& [key, control_blocks] : other.
scripts) {
393 scripts[key].merge(std::move(control_blocks));
403 if ((
size_t)depth + 1 <
m_branch.size()) {
412 if (depth == 0)
m_valid =
false;
425 std::vector<bool> branch;
426 for (
int depth : depths) {
432 if ((
size_t)depth + 1 < branch.size())
return false;
433 while (branch.size() > (size_t)depth && branch[depth]) {
435 if (depth == 0)
return false;
438 if (branch.size() <= (size_t)depth) branch.resize((
size_t)depth + 1);
440 branch[depth] =
true;
443 return branch.size() == 0 || (branch.size() == 1 && branch[0]);
453 if (track)
node.leaves.emplace_back(
LeafInfo{script, leaf_version, {}});
493 for (
const auto& leaf :
m_branch[0]->leaves) {
494 std::vector<unsigned char> control_block;
496 control_block[0] = leaf.leaf_version | (
m_parity ? 1 : 0);
498 if (leaf.merkle_branch.size()) {
499 std::copy(leaf.merkle_branch[0].begin(),
503 spd.scripts[{leaf.script, leaf.leaf_version}].insert(std::move(control_block));
513 if (!tweak || tweak->first != output)
return std::nullopt;
515 std::vector<std::tuple<int, CScript, int>>
ret;
523 std::unique_ptr<TreeNode> sub[2];
526 const std::pair<CScript, int>* leaf =
nullptr;
528 bool explored =
false;
538 for (
const auto& [key, control_blocks] : spenddata.
scripts) {
539 const auto& [script, leaf_ver] = key;
540 for (
const auto& control : control_blocks) {
542 if (leaf_ver < 0 || leaf_ver >= 0x100 || leaf_ver & 1)
continue;
551 if (merkle_root != spenddata.
merkle_root)
continue;
553 TreeNode*
node = &root;
555 for (
size_t depth = 0; depth < levels; ++depth) {
557 if (
node->explored && !
node->inner)
return std::nullopt;
568 for (
int i = 0; i < 2; ++i) {
569 if (
node->sub[i]->hash == hash || (
node->sub[i]->hash.IsNull() &&
node->sub[1-i]->hash != hash)) {
570 node->sub[i]->hash = hash;
576 if (!desc)
return std::nullopt;
579 node->explored =
true;
581 node->sub[0] = std::make_unique<TreeNode>();
582 node->sub[1] = std::make_unique<TreeNode>();
583 node->sub[1]->hash = hash;
588 if (
node->sub[0])
return std::nullopt;
589 node->explored =
true;
592 node->hash = leaf_hash;
598 std::vector<TreeNode*> stack{&root};
599 while (!stack.empty()) {
600 TreeNode&
node = *stack.back();
601 if (!
node.explored) {
604 }
else if (!
node.inner) {
606 ret.emplace_back(stack.size() - 1,
node.leaf->first,
node.leaf->second);
609 }
else if (
node.sub[0]->done && !
node.sub[1]->done && !
node.sub[1]->explored && !
node.sub[1]->hash.IsNull() &&
624 node.sub[0]->done =
false;
625 node.sub[1]->done =
true;
626 }
else if (
node.sub[0]->done &&
node.sub[1]->done) {
628 node.sub[0]->done =
false;
629 node.sub[1]->done =
false;
632 }
else if (!
node.sub[0]->done) {
634 stack.push_back(&*
node.sub[0]);
635 }
else if (!
node.sub[1]->done) {
637 stack.push_back(&*
node.sub[1]);
647 std::vector<std::tuple<uint8_t, uint8_t, CScript>> tuples;
649 const auto& leaves =
m_branch[0]->leaves;
650 for (
const auto& leaf : leaves) {
652 uint8_t depth = (uint8_t)leaf.merkle_branch.size();
653 uint8_t leaf_ver = (uint8_t)leaf.leaf_version;
654 tuples.push_back(std::make_tuple(depth, leaf_ver, leaf.script));
CSHA256 & Write(const unsigned char *data, size_t len)
std::vector< std::tuple< uint8_t, uint8_t, CScript > > GetTreeTuples() const
Returns a vector of tuples representing the depth, leaf version, and script.
static constexpr unsigned int SIZE
secp256k1:
static int DecodeOP_N(opcodetype opcode)
Encode/decode small integers:
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
bool CheckMinimalPush(const std::vector< unsigned char > &data, opcodetype opcode)
bool IsNull() const
Test whether this is the 0 key (the result of default construction).
unsigned char program[40]
static constexpr size_t WITNESS_V1_TAPROOT_SIZE
bool GetOp(const_iterator &pc, opcodetype &opcodeRet, std::vector< unsigned char > &vchRet) const
bool IsPayToScriptHash() const
Information associated with a node in the Merkle tree.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
TaprootBuilder & AddOmitted(int depth, const uint256 &hash)
Like Add(), but for a Merkle node with a given hash to the tree.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
std::optional< std::vector< std::tuple< int, CScript, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
static constexpr size_t TAPROOT_CONTROL_BASE_SIZE
static const int MAX_PUBKEYS_PER_MULTISIG
unspendable OP_RETURN script that carries data
const unsigned char * begin() const
std::vector< std::optional< NodeInfo > > m_branch
The current state of the builder.
static constexpr size_t TAPROOT_CONTROL_NODE_SIZE
XOnlyPubKey m_internal_key
The internal key, set when finalizing.
static bool ValidSize(const std::vector< unsigned char > &vch)
static constexpr unsigned int COMPRESSED_SIZE
const unsigned char * begin() const
const unsigned char * end() const
std::string GetTxnOutputType(TxoutType t)
Get the name of a TxoutType as a string.
CTxDestination subtype to encode any future Witness version.
bool IsPushOnly(const_iterator pc) const
Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical).
constexpr bool IsPushdataOp(opcodetype opcode)
TaprootBuilder & Add(int depth, const CScript &script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static constexpr uint8_t TAPROOT_LEAF_MASK
A writer stream (for serialization) that computes a 256-bit hash.
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
XOnlyPubKey m_output_key
The output key, computed when finalizing.
An encapsulated public key.
opcodetype
Script opcodes.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
std::vector< unsigned char > valtype
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
const HashWriter HASHER_TAPBRANCH
Hasher with tag "TapBranch" pre-fed to it.
uint256 ComputeTaprootMerkleRoot(Span< const unsigned char > control, const uint256 &tapleaf_hash)
Compute the BIP341 taproot script tree Merkle root from control block and leaf hash.
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
static constexpr size_t WITNESS_V0_SCRIPTHASH_SIZE
Signature hash sizes.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
uint256 merkle_root
The Merkle root of the script tree (0 if no scripts).
static constexpr size_t TAPROOT_CONTROL_MAX_SIZE
static bool MatchPayToPubkeyHash(const CScript &script, valtype &pubkeyhash)
bool IsFullyValid() const
Determine if this pubkey is fully valid.
TaprootSpendData GetSpendData() const
Compute spending data (after Finalize()).
Utility class to construct Taproot outputs from internal key and script tree.
bool m_parity
The tweak parity, computed when finalizing.
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
std::vector< unsigned char > ToByteVector(const T &in)
void Insert(NodeInfo &&node, int depth)
Insert information about a node at a certain depth, and propagate information up. ...
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
std::map< std::pair< CScript, int >, std::set< std::vector< unsigned char >, ShortestVectorFirstComparator > > scripts
Map from (script, leaf_version) to (sets of) control blocks.
static opcodetype EncodeOP_N(int n)
Serialized script, used inside transaction inputs and outputs.
XOnlyPubKey internal_key
The BIP341 internal key.
static constexpr size_t WITNESS_V0_KEYHASH_SIZE
static bool MatchPayToPubkey(const CScript &script, valtype &pubkey)
std::optional< std::pair< int, std::vector< Span< const unsigned char > > > > MatchMultiA(const CScript &script)
A reference to a CKey: the Hash160 of its serialized public key.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Only for Witness versions not already defined above.
std::vector< unsigned char > valtype
static std::optional< int > GetScriptNumber(opcodetype opcode, valtype data, int min, int max)
Retrieve a minimally-encoded number in range [min,max] from an (opcode, data) pair, whether it's OP_n or through a push.
A reference to a CScript: the Hash160 of its serialization (see script.h)
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
static NodeInfo Combine(NodeInfo &&a, NodeInfo &&b)
Combine information about a parent Merkle tree node from its child nodes.
bool IsValid() const
Return true if so far all input was valid.
A hasher class for SHA-256.
const unsigned char * end() const
std::optional< std::pair< XOnlyPubKey, bool > > CreateTapTweak(const uint256 *merkle_root) const
Construct a Taproot tweaked output point with this point as internal key.
Information about a tracked leaf in the Merkle tree.
uint256 ComputeTapleafHash(uint8_t leaf_version, const CScript &script)
Compute the BIP341 tapleaf hash from leaf version & script.
CKeyID ToKeyID(const PKHash &key_hash)
void Merge(TaprootSpendData other)
Merge other TaprootSpendData (for the same scriptPubKey) into this.
const HashWriter HASHER_TAPLEAF
Hasher with tag "TapLeaf" pre-fed to it.
static bool MatchMultisig(const CScript &script, int &required_sigs, std::vector< valtype > &pubkeys)
bool m_valid
Whether the builder is in a valid state so far.
static constexpr bool IsSmallInteger(opcodetype opcode)
Test for "small positive integer" script opcodes - OP_1 through OP_16.