46#include <unordered_set>
112uint64_t
PolyMod(uint64_t c,
int val)
114 uint8_t c0 = c >> 35;
115 c = ((c & 0x7ffffffff) << 5) ^ val;
116 if (c0 & 1) c ^= 0xf5dee51989;
117 if (c0 & 2) c ^= 0xa9fdca3312;
118 if (c0 & 4) c ^= 0x1bab10e32d;
119 if (c0 & 8) c ^= 0x3706b1677a;
120 if (c0 & 16) c ^= 0x644d626ffd;
124std::string DescriptorChecksum(
const std::span<const char>& span)
139 static const std::string INPUT_CHARSET =
140 "0123456789()[],'/*abcdefgh@:$%{}"
141 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
142 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
145 static const std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
150 for (
auto ch : span) {
151 auto pos = INPUT_CHARSET.find(ch);
152 if (pos == std::string::npos)
return "";
154 cls = cls * 3 + (pos >> 5);
155 if (++clscount == 3) {
162 if (clscount > 0) c =
PolyMod(c, cls);
163 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
166 std::string
ret(8,
' ');
167 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
171std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
177typedef std::vector<uint32_t> KeyPath;
185 const uint32_t m_expr_index;
187 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
189 virtual ~PubkeyProvider() =
default;
196 virtual std::optional<CPubKey> GetPubKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out,
const DescriptorCache* read_cache =
nullptr, DescriptorCache* write_cache =
nullptr)
const = 0;
199 virtual bool IsRange()
const = 0;
202 virtual size_t GetSize()
const = 0;
204 enum class StringType {
211 virtual std::string
ToString(StringType type)
const = 0;
218 virtual bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const = 0;
223 virtual bool ToNormalizedString(
const SigningProvider& arg, std::string& out,
const DescriptorCache* cache =
nullptr)
const = 0;
226 virtual void GetPrivKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out)
const = 0;
229 virtual bool HavePrivateKeys(
const SigningProvider& arg)
const
231 FlatSigningProvider tmp_provider;
232 GetPrivKey(0, arg, tmp_provider);
233 return !tmp_provider.
keys.empty();
237 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
239 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
242 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
245 virtual bool IsBIP32()
const = 0;
248 virtual size_t GetKeyCount()
const {
return 1; }
251 virtual bool CanSelfExpand()
const = 0;
254 static bool DetermineApostropheUse(StringType type,
bool normalized,
bool public_apostrophe)
256 bool use_apostrophe{
false};
258 case StringType::COMPAT:
260 use_apostrophe =
true;
262 case StringType::CANONICAL:
264 use_apostrophe =
false;
266 case StringType::PUBLIC:
267 use_apostrophe = !normalized && public_apostrophe;
270 return use_apostrophe;
274class OriginPubkeyProvider final :
public PubkeyProvider
276 KeyOriginInfo m_origin;
277 std::unique_ptr<PubkeyProvider> m_provider;
280 std::string OriginString(StringType type,
bool normalized=
false)
const
282 bool use_apostrophe{DetermineApostropheUse(type, normalized, m_apostrophe)};
287 OriginPubkeyProvider(uint32_t exp_index, KeyOriginInfo info, std::unique_ptr<PubkeyProvider>
provider,
bool apostrophe) : PubkeyProvider(exp_index), m_origin(std::move(info)), m_provider(std::move(
provider)), m_apostrophe(apostrophe) {}
288 std::optional<CPubKey> GetPubKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out,
const DescriptorCache* read_cache =
nullptr, DescriptorCache* write_cache =
nullptr)
const override
292 FlatSigningProvider subprovider;
293 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg, subprovider, read_cache, write_cache);
294 if (!pub)
return std::nullopt;
295 const CKeyID keyid{pub->GetID()};
297 auto& [pubkey, suborigin] = subprovider.
origins[keyid];
299 suborigin.fingerprint = m_origin.fingerprint;
300 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
301 auto origin{subprovider.
origins.extract(keyid)};
302 out.Merge(std::move(subprovider));
304 out.origins.insert_or_assign(keyid, std::move(origin.mapped()));
307 bool IsRange()
const override {
return m_provider->IsRange(); }
308 size_t GetSize()
const override {
return m_provider->GetSize(); }
309 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
310 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
311 bool ToPrivateString(
const SigningProvider& arg, std::string&
ret)
const override
314 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
315 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
318 bool ToNormalizedString(
const SigningProvider& arg, std::string&
ret,
const DescriptorCache* cache)
const override
321 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
327 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
329 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
333 void GetPrivKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out)
const override
335 m_provider->GetPrivKey(pos, arg, out);
337 std::optional<CPubKey> GetRootPubKey()
const override
339 return m_provider->GetRootPubKey();
341 std::optional<CExtPubKey> GetRootExtPubKey()
const override
343 return m_provider->GetRootExtPubKey();
345 std::unique_ptr<PubkeyProvider> Clone()
const override
347 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
349 bool CanSelfExpand()
const override {
return m_provider->CanSelfExpand(); }
353class ConstPubkeyProvider final :
public PubkeyProvider
358 std::optional<CKey> GetPrivKey(
const SigningProvider& arg)
const
361 if (!(m_xonly ? arg.
GetKeyByXOnly(XOnlyPubKey(m_pubkey), key) :
362 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
367 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
368 std::optional<CPubKey> GetPubKey(
int pos,
const SigningProvider&, FlatSigningProvider& out,
const DescriptorCache* read_cache =
nullptr, DescriptorCache* write_cache =
nullptr)
const override
371 CKeyID keyid = m_pubkey.GetID();
373 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
374 out.pubkeys.emplace(keyid, m_pubkey);
377 bool IsRange()
const override {
return false; }
378 size_t GetSize()
const override {
return m_pubkey.size(); }
379 bool IsBIP32()
const override {
return false; }
380 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
381 bool ToPrivateString(
const SigningProvider& arg, std::string&
ret)
const override
383 std::optional<CKey> key = GetPrivKey(arg);
391 bool ToNormalizedString(
const SigningProvider& arg, std::string&
ret,
const DescriptorCache* cache)
const override
396 void GetPrivKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out)
const override
398 std::optional<CKey> key = GetPrivKey(arg);
400 out.keys.emplace(key->GetPubKey().GetID(), *key);
402 std::optional<CPubKey> GetRootPubKey()
const override
406 std::optional<CExtPubKey> GetRootExtPubKey()
const override
410 std::unique_ptr<PubkeyProvider> Clone()
const override
412 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
414 bool CanSelfExpand() const final {
return true; }
417enum class DeriveType {
424class BIP32PubkeyProvider final :
public PubkeyProvider
427 CExtPubKey m_root_extkey;
433 bool GetExtKey(
const SigningProvider& arg, CExtKey&
ret)
const
436 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
437 ret.nDepth = m_root_extkey.nDepth;
438 ret.fingerprint = m_root_extkey.fingerprint;
439 ret.nChild = m_root_extkey.nChild;
440 ret.chaincode = m_root_extkey.chaincode;
446 bool GetDerivedExtKey(
const SigningProvider& arg, CExtKey& xprv, CExtKey& last_hardened)
const
448 if (!GetExtKey(arg, xprv))
return false;
449 for (
auto entry : m_path) {
450 if (!xprv.
Derive(xprv, entry))
return false;
452 last_hardened = xprv;
458 bool IsHardened()
const
460 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
465 BIP32PubkeyProvider(uint32_t exp_index,
const CExtPubKey& extkey, KeyPath path, DeriveType derive,
bool apostrophe) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive), m_apostrophe(apostrophe) {}
466 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
467 size_t GetSize()
const override {
return 33; }
468 bool IsBIP32()
const override {
return true; }
469 std::optional<CPubKey> GetPubKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out,
const DescriptorCache* read_cache =
nullptr, DescriptorCache* write_cache =
nullptr)
const override
472 info.
fingerprint = m_root_extkey.id_key_fingerprint();
474 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
475 if (m_derive == DeriveType::HARDENED_RANGED) info.
path.push_back(((uint32_t)pos) | BIP32_HARDENED_FLAG);
478 CExtPubKey final_extkey = m_root_extkey;
479 CExtPubKey parent_extkey = m_root_extkey;
480 CExtPubKey last_hardened_extkey;
483 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
484 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
486 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
487 final_extkey = parent_extkey;
488 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
490 }
else if (IsHardened()) {
493 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
494 parent_extkey = xprv.
Neuter();
495 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
496 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.
Derive(xprv, pos | BIP32_HARDENED_FLAG);
497 final_extkey = xprv.
Neuter();
499 last_hardened_extkey = lh_xprv.
Neuter();
502 for (
auto entry : m_path) {
503 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
505 final_extkey = parent_extkey;
506 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
507 assert(m_derive != DeriveType::HARDENED_RANGED);
509 if (!der)
return std::nullopt;
516 if (m_derive != DeriveType::HARDENED_RANGED) {
517 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
520 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
522 }
else if (info.
path.size() > 0) {
523 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
527 return final_extkey.
pubkey;
529 std::string
ToString(StringType type,
bool normalized)
const
531 bool use_apostrophe{DetermineApostropheUse(type, normalized, m_apostrophe)};
535 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
539 std::string
ToString(StringType type)
const override
543 bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const override
546 if (!GetExtKey(arg, key)) {
553 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
557 bool ToNormalizedString(
const SigningProvider& arg, std::string& out,
const DescriptorCache* cache)
const override
559 if (m_derive == DeriveType::HARDENED_RANGED) {
565 int i = (int)m_path.size() - 1;
566 for (; i >= 0; --i) {
567 if (m_path.at(i) >> 31) {
577 KeyOriginInfo origin;
579 for (;
k <= i; ++
k) {
581 origin.
path.push_back(m_path.at(k));
585 for (;
k < (int)m_path.size(); ++
k) {
586 end_path.push_back(m_path.at(k));
588 origin.
fingerprint = m_root_extkey.id_key_fingerprint();
593 if (cache !=
nullptr) {
599 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
609 assert(m_derive == DeriveType::UNHARDENED_RANGED);
613 void GetPrivKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out)
const override
617 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
618 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
619 if (m_derive == DeriveType::HARDENED_RANGED && !extkey.
Derive(extkey, pos | BIP32_HARDENED_FLAG))
return;
622 std::optional<CPubKey> GetRootPubKey()
const override
626 std::optional<CExtPubKey> GetRootExtPubKey()
const override
628 return m_root_extkey;
630 std::unique_ptr<PubkeyProvider> Clone()
const override
632 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
634 bool CanSelfExpand()
const override {
return !IsHardened(); }
638class MuSigPubkeyProvider final :
public PubkeyProvider
642 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
644 const KeyPath m_path;
646 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
647 mutable std::optional<CPubKey> m_aggregate_pubkey;
648 const DeriveType m_derive;
649 const bool m_ranged_participants;
651 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
656 std::vector<std::unique_ptr<PubkeyProvider>> providers,
660 : PubkeyProvider(exp_index),
661 m_participants(std::move(providers)),
662 m_path(std::move(path)),
664 m_ranged_participants(std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
666 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
667 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
669 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
670 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
674 std::optional<CPubKey> GetPubKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out,
const DescriptorCache* read_cache =
nullptr, DescriptorCache* write_cache =
nullptr)
const override
676 FlatSigningProvider dummy;
678 if (!m_aggregate_provider && !m_ranged_participants) {
680 std::vector<CPubKey> pubkeys;
681 for (
const auto& prov : m_participants) {
682 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
683 if (!pubkey.has_value()) {
686 pubkeys.push_back(pubkey.value());
688 std::sort(pubkeys.begin(), pubkeys.end());
692 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
695 if (IsRangedDerivation() || !m_path.empty()) {
698 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive,
false);
700 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
705 std::vector<CPubKey> pubkeys;
706 for (
const auto& prov : m_participants) {
707 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg, out, read_cache, write_cache);
708 if (!pub)
return std::nullopt;
709 pubkeys.emplace_back(*pub);
711 std::sort(pubkeys.begin(), pubkeys.end());
714 if (m_aggregate_provider) {
718 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy, out, read_cache, write_cache);
719 if (!pub)
return std::nullopt;
721 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
723 if (!
Assume(m_ranged_participants) || !
Assume(m_path.empty()))
return std::nullopt;
726 if (!aggregate_pubkey)
return std::nullopt;
727 pubout = *aggregate_pubkey;
729 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
730 this_agg_provider->GetPubKey(0, dummy, out, read_cache, write_cache);
731 out.aggregate_pubkeys.emplace(pubout, pubkeys);
737 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
739 size_t GetSize()
const override {
return 32; }
741 std::string
ToString(StringType type)
const override
743 std::string
out =
"musig(";
744 for (
size_t i = 0; i < m_participants.size(); ++i) {
745 const auto& pubkey = m_participants.at(i);
747 out += pubkey->ToString(type);
751 if (IsRangedDerivation()) {
756 bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const override
758 bool any_privkeys =
false;
760 for (
size_t i = 0; i < m_participants.size(); ++i) {
761 const auto& pubkey = m_participants.at(i);
764 if (pubkey->ToPrivateString(arg, tmp)) {
771 if (IsRangedDerivation()) {
776 bool ToNormalizedString(
const SigningProvider& arg, std::string& out,
const DescriptorCache* cache =
nullptr)
const override
779 for (
size_t i = 0; i < m_participants.size(); ++i) {
780 const auto& pubkey = m_participants.at(i);
783 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
790 if (IsRangedDerivation()) {
796 void GetPrivKey(
int pos,
const SigningProvider& arg, FlatSigningProvider& out)
const override
801 for (
const auto& prov : m_participants) {
802 prov->GetPrivKey(pos, arg, out);
806 bool HavePrivateKeys(
const SigningProvider& arg)
const override
808 return std::ranges::all_of(m_participants, [&](
const auto& prov) {
return prov->HavePrivateKeys(arg); });
816 std::optional<CPubKey> GetRootPubKey()
const override
820 std::optional<CExtPubKey> GetRootExtPubKey()
const override
825 std::unique_ptr<PubkeyProvider> Clone()
const override
827 std::vector<std::unique_ptr<PubkeyProvider>> providers;
828 providers.reserve(m_participants.size());
829 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
830 providers.emplace_back(p->Clone());
832 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
834 bool IsBIP32()
const override
837 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
839 size_t GetKeyCount()
const override
841 return 1 + m_participants.size();
843 bool CanSelfExpand()
const override
847 for (
const auto& key : m_participants) {
848 if (!key->CanSelfExpand())
return false;
859 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
861 const std::string m_name;
863 std::vector<std::string> m_warnings;
869 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
872 virtual std::string ToStringExtra()
const {
return ""; }
884 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts, FlatSigningProvider& out)
const = 0;
887 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
888 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script,
const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(
Vector(std::move(script))) {}
889 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::vector<std::unique_ptr<DescriptorImpl>> scripts,
const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(std::move(scripts)) {}
891 enum class StringType
901 bool IsSolvable()
const override
903 for (
const auto& arg : m_subdescriptor_args) {
904 if (!arg->IsSolvable())
return false;
910 bool HavePrivateKeys(
const SigningProvider& arg)
const override
912 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
914 for (
const auto& sub: m_subdescriptor_args) {
915 if (!sub->HavePrivateKeys(arg))
return false;
918 for (
const auto& pubkey : m_pubkey_args) {
919 if (!pubkey->HavePrivateKeys(arg))
return false;
926 bool IsRange() const final
928 for (
const auto& pubkey : m_pubkey_args) {
929 if (pubkey->IsRange())
return true;
931 for (
const auto& arg : m_subdescriptor_args) {
932 if (arg->IsRange())
return true;
938 virtual bool ToStringSubScriptHelper(
const SigningProvider* arg, std::string&
ret,
const StringType type,
const DescriptorCache* cache =
nullptr)
const
941 bool is_private{type == StringType::PRIVATE};
944 bool any_success{!is_private};
945 for (
const auto& scriptarg : m_subdescriptor_args) {
946 if (pos++)
ret +=
",";
948 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
949 if (!is_private && !subscript_res)
return false;
950 any_success = any_success || subscript_res;
957 virtual bool ToStringHelper(
const SigningProvider* arg, std::string& out,
const StringType type,
const DescriptorCache* cache =
nullptr)
const
959 std::string extra = ToStringExtra();
960 size_t pos = extra.size() > 0 ? 1 : 0;
961 std::string
ret = m_name +
"(" + extra;
962 bool is_private{type == StringType::PRIVATE};
965 bool any_success{!is_private};
967 for (
const auto& pubkey : m_pubkey_args) {
968 if (pos++)
ret +=
",";
971 case StringType::NORMALIZED:
972 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
974 case StringType::PRIVATE:
975 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
977 case StringType::PUBLIC:
978 tmp = pubkey->ToString(PubkeyProvider::StringType::PUBLIC);
980 case StringType::COMPAT:
981 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
983 case StringType::CANONICAL:
984 tmp = pubkey->ToString(PubkeyProvider::StringType::CANONICAL);
989 std::string subscript;
990 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
991 if (!is_private && !subscript_res)
return false;
992 any_success = any_success || subscript_res;
993 if (pos && subscript.size())
ret +=
',';
994 out = std::move(
ret) + std::move(subscript) +
")";
998 std::string
ToString(
bool compat_format)
const final
1001 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
1002 return AddChecksum(
ret);
1005 std::string ToCanonicalString() const final
1008 ToStringHelper(
nullptr,
ret, StringType::CANONICAL);
1009 return AddChecksum(
ret);
1012 bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const override
1014 bool has_priv_key{ToStringHelper(&arg, out, StringType::PRIVATE)};
1015 out = AddChecksum(out);
1016 return has_priv_key;
1019 bool ToNormalizedString(
const SigningProvider& arg, std::string& out,
const DescriptorCache* cache)
const override final
1021 bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
1022 out = AddChecksum(out);
1027 bool ExpandHelper(
int pos,
const SigningProvider& arg,
const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache)
const
1029 FlatSigningProvider subprovider;
1030 std::vector<CPubKey> pubkeys;
1031 pubkeys.reserve(m_pubkey_args.size());
1034 for (
const auto& p : m_pubkey_args) {
1035 std::optional<CPubKey> pubkey = p->GetPubKey(pos, arg, subprovider, read_cache, write_cache);
1036 if (!pubkey)
return false;
1037 pubkeys.push_back(pubkey.value());
1039 std::vector<CScript> subscripts;
1040 for (
const auto& subarg : m_subdescriptor_args) {
1041 std::vector<CScript> outscripts;
1042 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
1043 assert(outscripts.size() == 1);
1044 subscripts.emplace_back(std::move(outscripts[0]));
1046 out.Merge(std::move(subprovider));
1048 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
1052 bool Expand(
int pos,
const SigningProvider&
provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache =
nullptr) const final
1054 return ExpandHelper(pos,
provider,
nullptr, output_scripts, out, write_cache);
1057 bool ExpandFromCache(
int pos,
const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out)
const final
1063 void ExpandPrivate(
int pos,
const SigningProvider&
provider, FlatSigningProvider& out)
const final
1065 for (
const auto& p : m_pubkey_args) {
1068 for (
const auto& arg : m_subdescriptor_args) {
1069 arg->ExpandPrivate(pos,
provider, out);
1073 std::optional<OutputType> GetOutputType()
const override {
return std::nullopt; }
1075 std::optional<int64_t> ScriptSize()
const override {
return {}; }
1082 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1084 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
return {}; }
1086 std::optional<int64_t> MaxSatisfactionElems()
const override {
return {}; }
1089 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
1091 for (
const auto& p : m_pubkey_args) {
1092 std::optional<CPubKey> pub = p->GetRootPubKey();
1093 if (pub) pubkeys.insert(*pub);
1094 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1095 if (ext_pub) ext_pubs.insert(*ext_pub);
1097 for (
const auto& arg : m_subdescriptor_args) {
1098 arg->GetPubKeys(pubkeys, ext_pubs);
1102 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1104 bool HasScripts()
const override {
return true; }
1107 std::vector<std::string> Warnings()
const override {
1108 std::vector<std::string> all = m_warnings;
1109 for (
const auto& sub : m_subdescriptor_args) {
1110 auto sub_w = sub->Warnings();
1111 all.insert(all.end(), sub_w.begin(), sub_w.end());
1116 uint32_t GetMaxKeyExpr() const final
1118 uint32_t max_key_expr{0};
1119 std::vector<const DescriptorImpl*> todo = {
this};
1120 while (!todo.empty()) {
1121 const DescriptorImpl* desc = todo.back();
1123 for (
const auto& p : desc->m_pubkey_args) {
1124 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1126 for (
const auto& s : desc->m_subdescriptor_args) {
1127 todo.push_back(
s.get());
1130 return max_key_expr;
1133 size_t GetKeyCount() const final
1136 std::vector<const DescriptorImpl*> todo = {
this};
1137 while (!todo.empty()) {
1138 const DescriptorImpl* desc = todo.back();
1140 for (
const auto& p : desc->m_pubkey_args) {
1141 count += p->GetKeyCount();
1143 for (
const auto& s : desc->m_subdescriptor_args) {
1144 todo.push_back(
s.get());
1151 bool CanSelfExpand()
const override
1153 for (
const auto& key : m_pubkey_args) {
1154 if (!key->CanSelfExpand())
return false;
1156 for (
const auto& sub : m_subdescriptor_args) {
1157 if (!sub->CanSelfExpand())
return false;
1164class AddressDescriptor final :
public DescriptorImpl
1168 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1169 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&)
const override {
return Vector(
GetScriptForDestination(m_destination)); }
1171 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1172 bool IsSolvable() const final {
return false; }
1174 std::optional<OutputType> GetOutputType()
const override
1178 bool IsSingleType() const final {
return true; }
1179 bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const final {
return false; }
1182 std::unique_ptr<DescriptorImpl> Clone()
const override
1184 return std::make_unique<AddressDescriptor>(m_destination);
1189class RawDescriptor final :
public DescriptorImpl
1191 const CScript m_script;
1193 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1194 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&)
const override {
return Vector(m_script); }
1196 RawDescriptor(CScript script) : DescriptorImpl({},
"raw"), m_script(std::move(script)) {}
1197 bool IsSolvable() const final {
return false; }
1199 std::optional<OutputType> GetOutputType()
const override
1205 bool IsSingleType() const final {
return true; }
1206 bool ToPrivateString(
const SigningProvider& arg, std::string& out)
const final {
return false; }
1208 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1210 std::unique_ptr<DescriptorImpl> Clone()
const override
1212 return std::make_unique<RawDescriptor>(m_script);
1217class PKDescriptor final :
public DescriptorImpl
1222 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>, FlatSigningProvider&)
const override
1226 return Vector(std::move(script));
1232 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(std::move(prov)),
"pk"), m_xonly(xonly) {}
1233 bool IsSingleType() const final {
return true; }
1235 std::optional<int64_t> ScriptSize()
const override {
1236 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1239 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1240 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1241 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1244 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1248 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1250 std::unique_ptr<DescriptorImpl> Clone()
const override
1252 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1257class PKHDescriptor final :
public DescriptorImpl
1260 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>, FlatSigningProvider&)
const override
1262 CKeyID
id =
keys[0].GetID();
1266 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)),
"pkh") {}
1267 std::optional<OutputType> GetOutputType()
const override {
return OutputType::LEGACY; }
1268 bool IsSingleType() const final {
return true; }
1270 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1272 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1273 const auto sig_size = use_max_sig ? 72 : 71;
1274 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1277 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1281 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1283 std::unique_ptr<DescriptorImpl> Clone()
const override
1285 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1290class WPKHDescriptor final :
public DescriptorImpl
1293 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>, FlatSigningProvider&)
const override
1295 CKeyID
id =
keys[0].GetID();
1299 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)),
"wpkh") {}
1300 std::optional<OutputType> GetOutputType()
const override {
return OutputType::BECH32; }
1301 bool IsSingleType() const final {
return true; }
1303 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1305 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1306 const auto sig_size = use_max_sig ? 72 : 71;
1307 return (1 + sig_size + 1 + 33);
1310 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1311 return MaxSatSize(use_max_sig);
1314 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1316 std::unique_ptr<DescriptorImpl> Clone()
const override
1318 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1323class ComboDescriptor final :
public DescriptorImpl
1326 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>, FlatSigningProvider& out)
const override
1328 std::vector<CScript>
ret;
1329 CKeyID
id =
keys[0].GetID();
1332 if (
keys[0].IsCompressed()) {
1335 ret.emplace_back(p2wpkh);
1341 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)),
"combo") {}
1342 bool IsSingleType() const final {
return false; }
1343 std::unique_ptr<DescriptorImpl> Clone()
const override
1345 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1350class MultisigDescriptor final :
public DescriptorImpl
1352 const int m_threshold;
1353 const bool m_sorted;
1355 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1356 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>, FlatSigningProvider&)
const override {
1358 std::vector<CPubKey> sorted_keys(
keys);
1359 std::sort(sorted_keys.begin(), sorted_keys.end());
1365 MultisigDescriptor(
int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers,
bool sorted =
false) : DescriptorImpl(std::move(providers), sorted ?
"sortedmulti" :
"multi"), m_threshold(threshold), m_sorted(sorted) {}
1366 bool IsSingleType() const final {
return true; }
1368 std::optional<int64_t> ScriptSize()
const override {
1369 const auto n_keys = m_pubkey_args.size();
1370 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1371 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1375 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1376 const auto sig_size = use_max_sig ? 72 : 71;
1377 return (1 + (1 + sig_size) * m_threshold);
1380 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1384 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1386 std::unique_ptr<DescriptorImpl> Clone()
const override
1388 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1389 providers.reserve(m_pubkey_args.size());
1390 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1391 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1396class MultiADescriptor final :
public DescriptorImpl
1398 const int m_threshold;
1399 const bool m_sorted;
1401 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1402 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>, FlatSigningProvider&)
const override {
1404 std::vector<XOnlyPubKey> xkeys;
1405 xkeys.reserve(
keys.size());
1406 for (
const auto& key :
keys) xkeys.emplace_back(key);
1407 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1409 for (
size_t i = 1; i <
keys.size(); ++i) {
1416 MultiADescriptor(
int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers,
bool sorted =
false) : DescriptorImpl(std::move(providers), sorted ?
"sortedmulti_a" :
"multi_a"), m_threshold(threshold), m_sorted(sorted) {}
1417 bool IsSingleType() const final {
return true; }
1419 std::optional<int64_t> ScriptSize()
const override {
1420 const auto n_keys = m_pubkey_args.size();
1424 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1425 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1428 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1430 std::unique_ptr<DescriptorImpl> Clone()
const override
1432 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1433 providers.reserve(m_pubkey_args.size());
1434 for (
const auto& arg : m_pubkey_args) {
1435 providers.push_back(arg->Clone());
1437 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1442class SHDescriptor final :
public DescriptorImpl
1445 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out)
const override
1448 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1452 bool IsSegwit()
const {
return m_subdescriptor_args[0]->GetOutputType() ==
OutputType::BECH32; }
1455 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1457 std::optional<OutputType> GetOutputType()
const override
1459 assert(m_subdescriptor_args.size() == 1);
1463 bool IsSingleType() const final {
return true; }
1465 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1467 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1468 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1469 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1473 if (IsSegwit())
return subscript_weight + *sat_size;
1480 std::optional<int64_t> MaxSatisfactionElems()
const override {
1481 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1485 std::unique_ptr<DescriptorImpl> Clone()
const override
1487 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1492class WSHDescriptor final :
public DescriptorImpl
1495 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out)
const override
1498 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1502 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1503 std::optional<OutputType> GetOutputType()
const override {
return OutputType::BECH32; }
1504 bool IsSingleType() const final {
return true; }
1506 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1508 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1509 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1510 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1517 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1518 return MaxSatSize(use_max_sig);
1521 std::optional<int64_t> MaxSatisfactionElems()
const override {
1522 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1526 std::unique_ptr<DescriptorImpl> Clone()
const override
1528 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1533class TRDescriptor final :
public DescriptorImpl
1535 std::vector<int> m_depths;
1537 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts, FlatSigningProvider& out)
const override
1539 TaprootBuilder builder;
1540 assert(m_depths.size() == scripts.size());
1541 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1546 XOnlyPubKey xpk(
keys[0]);
1547 if (!xpk.IsFullyValid())
return {};
1549 WitnessV1Taproot output = builder.
GetOutput();
1550 out.tr_trees[output] = builder;
1553 bool ToStringSubScriptHelper(
const SigningProvider* arg, std::string&
ret,
const StringType type,
const DescriptorCache* cache =
nullptr)
const override
1555 if (m_depths.empty()) {
1561 return type != StringType::PRIVATE;
1563 std::vector<bool> path;
1564 bool is_private{type == StringType::PRIVATE};
1567 bool any_success{!is_private};
1569 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1570 if (pos)
ret +=
',';
1571 while ((
int)path.size() <= m_depths[pos]) {
1572 if (path.size())
ret +=
'{';
1573 path.push_back(
false);
1576 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1577 if (!is_private && !subscript_res)
return false;
1578 any_success = any_success || subscript_res;
1580 while (!path.empty() && path.back()) {
1581 if (path.size() > 1)
ret +=
'}';
1584 if (!path.empty()) path.back() =
true;
1589 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1590 DescriptorImpl(
Vector(std::move(internal_key)), std::move(descs),
"tr"), m_depths(std::move(depths))
1592 assert(m_subdescriptor_args.size() == m_depths.size());
1595 bool IsSingleType() const final {
return true; }
1597 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1599 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1604 std::optional<int64_t> MaxSatisfactionElems()
const override {
1609 std::unique_ptr<DescriptorImpl> Clone()
const override
1611 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1612 subdescs.reserve(m_subdescriptor_args.size());
1613 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1614 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1628 const std::vector<CPubKey>& m_keys;
1635 uint160 GetHash160(uint32_t key)
const {
1637 return Hash160(XOnlyPubKey{m_keys[key]});
1639 return m_keys[key].GetID();
1645 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1648 return {m_keys[key].begin(), m_keys[key].end()};
1650 const XOnlyPubKey xonly_pubkey{m_keys[key]};
1651 return {xonly_pubkey.
begin(), xonly_pubkey.
end()};
1654 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1655 auto id = GetHash160(key);
1656 return {
id.begin(),
id.end()};
1665 const SigningProvider* m_arg;
1667 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1669 const DescriptorImpl::StringType m_type;
1670 const DescriptorCache* m_cache;
1674 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1675 DescriptorImpl::StringType type,
1677 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1679 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const
1682 has_priv_key =
false;
1684 case DescriptorImpl::StringType::PUBLIC:
1685 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::PUBLIC);
1687 case DescriptorImpl::StringType::PRIVATE:
1688 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1690 case DescriptorImpl::StringType::NORMALIZED:
1691 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1693 case DescriptorImpl::StringType::COMPAT:
1698 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::PUBLIC);
1700 case DescriptorImpl::StringType::CANONICAL:
1701 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::CANONICAL);
1708class MiniscriptDescriptor final :
public DescriptorImpl
1711 miniscript::Node<uint32_t> m_node;
1714 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
1715 FlatSigningProvider&
provider)
const override
1717 const auto script_ctx{m_node.GetMsCtx()};
1718 for (
const auto& key :
keys) {
1722 provider.pubkeys.emplace(key.GetID(), key);
1725 return Vector(m_node.ToScript(ScriptMaker(
keys, script_ctx)));
1729 MiniscriptDescriptor(std::vector<std::unique_ptr<PubkeyProvider>> providers, miniscript::Node<uint32_t>&& node)
1730 : DescriptorImpl(std::move(providers),
"?"), m_node(std::move(node))
1735 const uint32_t raw = node.
K();
1736 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1739 if (is_time_based) {
1740 m_warnings.push_back(
strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1742 m_warnings.push_back(
strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1749 bool ToStringHelper(
const SigningProvider* arg, std::string& out,
const StringType type,
1750 const DescriptorCache* cache =
nullptr)
const override
1752 bool has_priv_key{
false};
1753 auto res = m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1754 if (res)
out = *res;
1755 if (type == StringType::PRIVATE) {
1757 return has_priv_key;
1759 return res.has_value();
1763 bool IsSolvable()
const override {
return true; }
1764 bool IsSingleType() const final {
return true; }
1766 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1768 std::optional<int64_t> MaxSatSize(
bool)
const override
1771 return m_node.GetWitnessSize();
1774 std::optional<int64_t> MaxSatisfactionElems()
const override
1776 return m_node.GetStackSize();
1779 std::unique_ptr<DescriptorImpl> Clone()
const override
1781 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1782 providers.reserve(m_pubkey_args.size());
1783 for (
const auto& arg : m_pubkey_args) {
1784 providers.push_back(arg->Clone());
1786 return std::make_unique<MiniscriptDescriptor>(std::move(providers), m_node.Clone());
1791class RawTRDescriptor final :
public DescriptorImpl
1794 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts, FlatSigningProvider& out)
const override
1797 XOnlyPubKey xpk(
keys[0]);
1798 if (!xpk.IsFullyValid())
return {};
1799 WitnessV1Taproot output{xpk};
1803 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(std::move(output_key)),
"rawtr") {}
1805 bool IsSingleType() const final {
return true; }
1807 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1809 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1814 std::optional<int64_t> MaxSatisfactionElems()
const override {
1819 std::unique_ptr<DescriptorImpl> Clone()
const override
1821 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1826class UnusedDescriptor final :
public DescriptorImpl
1829 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts, FlatSigningProvider& out)
const override {
return {}; }
1831 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(std::move(prov)),
"unused") {}
1832 bool IsSingleType() const final {
return true; }
1833 bool HasScripts()
const override {
return false; }
1835 std::unique_ptr<DescriptorImpl> Clone()
const override
1837 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1846enum class ParseScriptContext {
1866[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out,
bool& apostrophe, std::string& error,
bool allow_multipath,
bool& has_hardened)
1868 auto parse_elem = [&](std::span<const char> elem) -> std::optional<uint32_t> {
1871 error = parsed.error();
1872 return std::nullopt;
1874 if (parsed->is_hardened) {
1875 has_hardened =
true;
1876 apostrophe = elem.back() ==
'\'';
1878 return parsed->ChildNumber();
1882 struct MultipathSubstitutes {
1883 size_t placeholder_index;
1884 std::vector<uint32_t> values;
1886 std::optional<MultipathSubstitutes> substitutes;
1887 has_hardened =
false;
1889 for (
size_t i = 1; i < split.size(); ++i) {
1890 const std::span<const char>& elem = split[i];
1893 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1894 if (!allow_multipath) {
1895 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1899 error =
"Multiple multipath key path specifiers found";
1904 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1905 if (nums.size() < 2) {
1906 error =
"Multipath key path specifiers must have at least two items";
1910 substitutes.emplace();
1911 std::unordered_set<uint32_t> seen_substitutes;
1912 for (
const auto& num : nums) {
1913 const auto& op_num = parse_elem(num);
1914 if (!op_num)
return false;
1915 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1917 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1920 substitutes->values.emplace_back(*op_num);
1923 path.emplace_back();
1924 substitutes->placeholder_index = path.size() - 1;
1926 const auto& op_num = parse_elem(elem);
1927 if (!op_num)
return false;
1928 path.emplace_back(*op_num);
1933 out.emplace_back(std::move(path));
1936 for (uint32_t substitute : substitutes->values) {
1937 KeyPath branch_path = path;
1938 branch_path[substitutes->placeholder_index] = substitute;
1939 out.emplace_back(std::move(branch_path));
1945[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1948 return ParseKeyPath(split, out, apostrophe, error, allow_multipath, dummy);
1951static DeriveType ParseDeriveType(std::vector<std::span<const char>>& split,
bool& apostrophe)
1953 DeriveType type = DeriveType::NON_RANGED;
1954 if (std::ranges::equal(split.back(), std::span{
"*"}.first(1))) {
1956 type = DeriveType::UNHARDENED_RANGED;
1957 }
else if (std::ranges::equal(split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(split.back(), std::span{
"*h"}.first(2))) {
1958 apostrophe = std::ranges::equal(split.back(), std::span{
"*'"}.first(2));
1960 type = DeriveType::HARDENED_RANGED;
1966std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider& out,
bool& apostrophe, std::string& error)
1968 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1969 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1970 auto split =
Split(sp,
'/');
1971 std::string str(split[0].begin(), split[0].end());
1972 if (str.size() == 0) {
1973 error =
"No key provided";
1977 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1980 if (split.size() == 1) {
1984 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1985 error =
"Hybrid public keys are not allowed";
1988 if (pubkey.IsFullyValid()) {
1989 if (permit_uncompressed || pubkey.IsCompressed()) {
1990 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1994 error =
"Uncompressed keys are not allowed";
1997 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1998 unsigned char fullkey[33] = {0x02};
1999 std::copy(
data.begin(),
data.end(), fullkey + 1);
2000 pubkey.Set(std::begin(fullkey), std::end(fullkey));
2001 if (pubkey.IsFullyValid()) {
2002 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
2007 error =
strprintf(
"Pubkey '%s' is invalid", str);
2014 out.keys.emplace(pubkey.
GetID(), key);
2015 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
2019 error =
"Uncompressed keys are not allowed";
2027 error =
strprintf(
"key '%s' is not valid", str);
2030 std::vector<KeyPath> paths;
2031 DeriveType type = ParseDeriveType(split, apostrophe);
2032 if (!ParseKeyPath(split, paths, apostrophe, error,
true))
return {};
2034 extpubkey = extkey.
Neuter();
2037 for (
auto& path : paths) {
2038 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
2046std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider& out, std::string& error)
2048 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
2053 std::span<const char> span = sp;
2054 if (
Const(
"musig(", span,
false)) {
2055 if (ctx != ParseScriptContext::P2TR) {
2056 error =
"musig() is only allowed in tr() and rawtr()";
2062 auto split =
Split(sp,
')',
true);
2063 if (split.size() > 2) {
2064 error =
"Too many ')' in musig() expression";
2067 std::span<const char> expr(split.at(0).begin(), split.at(0).end());
2068 if (!
Func(
"musig", expr)) {
2069 error =
"Invalid musig() expression";
2074 bool any_ranged =
false;
2075 bool all_bip32 =
true;
2076 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2077 bool any_key_parsed =
false;
2078 size_t max_multipath_len = 0;
2079 while (expr.size()) {
2080 if (any_key_parsed && !
Const(
",", expr)) {
2081 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
2084 auto arg =
Expr(expr);
2085 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG, out, error);
2087 error =
strprintf(
"musig(): %s", error);
2090 any_key_parsed =
true;
2092 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2093 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2095 max_multipath_len = std::max(max_multipath_len,
pk.size());
2097 providers.emplace_back(std::move(pk));
2099 if (!any_key_parsed) {
2100 error =
"musig(): Must contain key expressions";
2105 DeriveType deriv_type = DeriveType::NON_RANGED;
2106 std::vector<KeyPath> derivation_multipaths;
2107 if (split.size() == 2 &&
Const(
"/", split.at(1),
false)) {
2109 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2113 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2117 auto deriv_split =
Split(split.at(1),
'/');
2118 deriv_type = ParseDeriveType(deriv_split, dummy);
2119 if (deriv_type == DeriveType::HARDENED_RANGED) {
2120 error =
"musig(): Cannot have hardened child derivation";
2123 bool has_hardened =
false;
2124 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2125 error =
"musig(): " + error;
2129 error =
"musig(): cannot have hardened derivation steps";
2133 derivation_multipaths.emplace_back();
2138 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2139 for (
auto& multipath_providers : providers) {
2140 if (multipath_providers.size() == 1) {
2141 for (
size_t i = 1; i < length; ++i) {
2142 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2144 }
else if (multipath_providers.size() != length) {
2153 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2154 KeyPath& path = derivation_multipaths.at(path_idx);
2155 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2156 pubs.reserve(providers.size());
2157 for (
auto& vec : providers) {
2158 pubs.emplace_back(std::move(vec.at(vec_idx)));
2160 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2163 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2164 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2166 }
else if (max_multipath_len > 1) {
2167 if (!clone_providers(max_multipath_len)) {
2168 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2171 for (
size_t i = 0; i < max_multipath_len; ++i) {
2173 emplace_final_provider(i, 0);
2175 }
else if (derivation_multipaths.size() > 1) {
2177 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2178 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2181 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2183 emplace_final_provider(i, i);
2187 emplace_final_provider(0, 0);
2193 auto origin_split =
Split(sp,
']');
2194 if (origin_split.size() > 2) {
2195 error =
"Multiple ']' characters found for a single pubkey";
2199 bool apostrophe =
false;
2200 if (origin_split.size() == 1) {
2201 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, apostrophe, error);
2203 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2204 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2205 origin_split[0].empty() ?
']' : origin_split[0][0]);
2208 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2209 if (slash_split[0].size() != 8) {
2210 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2213 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2214 if (!
IsHex(fpr_hex)) {
2215 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2218 auto fpr_bytes =
ParseHex(fpr_hex);
2220 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2221 assert(fpr_bytes.size() == 4);
2223 std::vector<KeyPath> path;
2224 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2225 info.
path = path.at(0);
2226 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, apostrophe, error);
2227 if (providers.empty())
return {};
2228 ret.reserve(providers.size());
2229 for (
auto& prov : providers) {
2230 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2242 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2245 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2248 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2250 return key_provider;
2256 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2258 if (
provider.GetKeyOriginByXOnly(xkey, info)) {
2259 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2261 return key_provider;
2269 using Key = uint32_t;
2271 FlatSigningProvider* m_out;
2273 const SigningProvider* m_in;
2275 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2277 mutable std::string m_key_parsing_error;
2281 uint32_t& m_expr_index;
2285 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2287 bool KeyCompare(
const Key& a,
const Key& b)
const {
2291 const PubkeyProvider& key_a{*m_keys.at(a).at(0)};
2292 const PubkeyProvider& key_b{*m_keys.at(b).at(0)};
2293 FlatSigningProvider out_a, out_b;
2294 const std::optional<CPubKey> pub_a{key_a.GetPubKey(0,
provider, out_a)};
2295 const std::optional<CPubKey> pub_b{key_b.GetPubKey(0,
provider, out_b)};
2296 if (pub_a && pub_b)
return *pub_a < *pub_b;
2299 if (pub_a.has_value() != pub_b.has_value())
return !pub_a.has_value();
2300 return key_a.ToString(PubkeyProvider::StringType::PUBLIC) < key_b.ToString(PubkeyProvider::StringType::PUBLIC);
2304 switch (m_script_ctx) {
2311 std::optional<Key>
FromString(std::span<const char>& in)
const
2314 Key key = m_keys.
size();
2315 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2316 if (
pk.empty())
return {};
2317 m_keys.emplace_back(std::move(pk));
2321 std::optional<std::string>
ToString(
const Key& key,
bool&)
const
2323 return m_keys.at(key).at(0)->ToString(PubkeyProvider::StringType::PUBLIC);
2326 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2329 Key key = m_keys.size();
2332 std::copy(begin, end, pubkey.
begin());
2333 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2334 m_keys.emplace_back();
2335 m_keys.back().push_back(std::move(pubkey_provider));
2339 CPubKey pubkey(begin, end);
2340 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2341 m_keys.emplace_back();
2342 m_keys.back().push_back(std::move(pubkey_provider));
2349 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2351 assert(end - begin == 20);
2354 std::copy(begin, end, hash.
begin());
2357 if (m_in->GetPubKey(keyid, pubkey)) {
2358 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2359 Key key = m_keys.size();
2360 m_keys.emplace_back();
2361 m_keys.back().push_back(std::move(pubkey_provider));
2369 return m_script_ctx;
2375std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider& out, std::string& error)
2378 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2379 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2380 auto expr =
Expr(sp);
2381 if (
Func(
"pk", expr)) {
2382 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2383 if (pubkeys.empty()) {
2387 for (
auto& pubkey : pubkeys) {
2388 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2392 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2393 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2394 if (pubkeys.empty()) {
2398 for (
auto& pubkey : pubkeys) {
2399 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2403 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2404 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2405 if (pubkeys.empty()) {
2406 error =
strprintf(
"combo(): %s", error);
2409 for (
auto& pubkey : pubkeys) {
2410 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2413 }
else if (
Func(
"combo", expr)) {
2414 error =
"Can only have combo() at top level";
2417 const bool multi =
Func(
"multi", expr);
2418 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2419 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2420 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2421 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2422 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2423 auto threshold =
Expr(expr);
2425 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2426 if (
const auto maybe_thres{
ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2427 thres = *maybe_thres;
2429 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2432 size_t script_size = 0;
2433 size_t max_providers_len = 0;
2434 while (expr.size()) {
2435 if (!
Const(
",", expr)) {
2436 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2439 auto arg =
Expr(expr);
2440 auto pks = ParsePubkey(key_exp_index, arg, ctx, out, error);
2445 script_size += pks.at(0)->GetSize() + 1;
2446 max_providers_len = std::max(max_providers_len, pks.size());
2447 providers.emplace_back(std::move(pks));
2455 }
else if (thres < 1) {
2456 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2458 }
else if (thres > providers.size()) {
2459 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2462 if (ctx == ParseScriptContext::TOP) {
2463 if (providers.size() > 3) {
2464 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2468 if (ctx == ParseScriptContext::P2SH) {
2478 for (
auto& vec : providers) {
2479 if (vec.size() == 1) {
2480 for (
size_t i = 1; i < max_providers_len; ++i) {
2481 vec.emplace_back(vec.at(0)->Clone());
2483 }
else if (vec.size() != max_providers_len) {
2484 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2490 for (
size_t i = 0; i < max_providers_len; ++i) {
2492 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2493 pubs.reserve(providers.size());
2494 for (
auto& pub : providers) {
2495 pubs.emplace_back(std::move(pub.at(i)));
2497 if (multi || sortedmulti) {
2498 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2500 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2504 }
else if (multi || sortedmulti) {
2505 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2507 }
else if (multi_a || sortedmulti_a) {
2508 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2511 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2512 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
2513 if (pubkeys.empty()) {
2517 for (
auto& pubkey : pubkeys) {
2518 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2521 }
else if (
Func(
"wpkh", expr)) {
2522 error =
"Can only have wpkh() at top level or inside sh()";
2525 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2526 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
2527 if (descs.empty() || expr.size())
return {};
2528 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2529 ret.reserve(descs.size());
2530 for (
auto& desc : descs) {
2531 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2534 }
else if (
Func(
"sh", expr)) {
2535 error =
"Can only have sh() at top level";
2538 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2539 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
2540 if (descs.empty() || expr.size())
return {};
2541 for (
auto& desc : descs) {
2542 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2545 }
else if (
Func(
"wsh", expr)) {
2546 error =
"Can only have wsh() at top level or inside sh()";
2549 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2552 error =
"Address is not valid";
2555 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2557 }
else if (
Func(
"addr", expr)) {
2558 error =
"Can only have addr() at top level";
2561 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2562 auto arg =
Expr(expr);
2563 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2564 if (internal_keys.empty()) {
2568 size_t max_providers_len = internal_keys.size();
2569 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2570 std::vector<int> depths;
2572 if (!
Const(
",", expr)) {
2573 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2579 std::vector<bool> branches;
2584 while (
Const(
"{", expr)) {
2585 branches.push_back(
false);
2592 auto sarg =
Expr(expr);
2593 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR, out, error));
2594 if (subscripts.back().empty())
return {};
2595 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2596 depths.push_back(branches.size());
2598 while (branches.size() && branches.back()) {
2599 if (!
Const(
"}", expr)) {
2600 error =
strprintf(
"tr(): expected '}' after script expression");
2603 branches.pop_back();
2606 if (branches.size() && !branches.back()) {
2607 if (!
Const(
",", expr)) {
2608 error =
strprintf(
"tr(): expected ',' after script expression");
2611 branches.back() =
true;
2613 }
while (branches.size());
2616 error =
strprintf(
"tr(): expected ')' after script expression");
2624 for (
auto& vec : subscripts) {
2625 if (vec.size() == 1) {
2626 for (
size_t i = 1; i < max_providers_len; ++i) {
2627 vec.emplace_back(vec.at(0)->Clone());
2629 }
else if (vec.size() != max_providers_len) {
2630 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2635 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2636 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2640 while (internal_keys.size() < max_providers_len) {
2641 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2645 for (
size_t i = 0; i < max_providers_len; ++i) {
2647 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2648 this_subs.reserve(subscripts.size());
2649 for (
auto& subs : subscripts) {
2650 this_subs.emplace_back(std::move(subs.at(i)));
2652 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2657 }
else if (
Func(
"tr", expr)) {
2658 error =
"Can only have tr at top level";
2661 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2662 auto arg =
Expr(expr);
2664 error =
strprintf(
"rawtr(): only one key expected.");
2667 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2668 if (output_keys.empty()) {
2669 error =
strprintf(
"rawtr(): %s", error);
2672 for (
auto& pubkey : output_keys) {
2673 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2676 }
else if (
Func(
"rawtr", expr)) {
2677 error =
"Can only have rawtr at top level";
2680 if (ctx == ParseScriptContext::TOP &&
Func(
"unused", expr)) {
2682 auto arg =
Expr(expr);
2684 error =
strprintf(
"unused(): only one key expected");
2687 auto keys = ParsePubkey(key_exp_index, arg, ctx, out, error);
2688 if (
keys.empty())
return {};
2689 for (
auto& pubkey :
keys) {
2690 if (pubkey->IsRange()) {
2691 error =
"unused(): key cannot be ranged";
2694 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2697 }
else if (
Func(
"unused", expr)) {
2698 error =
"Can only have unused at top level";
2701 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2702 std::string str(expr.begin(), expr.end());
2704 error =
"Raw script is not hex";
2708 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2710 }
else if (
Func(
"raw", expr)) {
2711 error =
"Can only have raw() at top level";
2717 KeyParser parser(&out,
nullptr, script_ctx, key_exp_index);
2719 if (parser.m_key_parsing_error !=
"") {
2720 error = std::move(parser.m_key_parsing_error);
2724 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2725 error =
"Miniscript expressions can only be used in wsh or tr.";
2728 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2730 const auto* insane_node = &
node.value();
2731 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2732 error = *insane_node->ToString(parser);
2733 if (!insane_node->IsValid()) {
2734 error +=
" is invalid";
2735 }
else if (!
node->IsSane()) {
2736 error +=
" is not sane";
2737 if (!insane_node->IsNonMalleable()) {
2738 error +=
": malleable witnesses exist";
2739 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2740 error +=
": witnesses without signature exist";
2741 }
else if (!insane_node->CheckTimeLocksMix()) {
2742 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2743 }
else if (!insane_node->CheckDuplicateKey()) {
2744 error +=
": contains duplicate public keys";
2745 }
else if (!insane_node->ValidSatisfactions()) {
2746 error +=
": needs witnesses that may exceed resource limits";
2749 error +=
" is not satisfiable";
2758 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2759 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2760 return a.size() < b.size();
2763 for (
auto& vec : parser.m_keys) {
2764 if (vec.size() == 1) {
2765 for (
size_t i = 1; i < num_multipath; ++i) {
2766 vec.emplace_back(vec.at(0)->Clone());
2768 }
else if (vec.size() != num_multipath) {
2769 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2775 for (
size_t i = 0; i < num_multipath; ++i) {
2777 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2778 pubs.reserve(parser.m_keys.size());
2779 for (
auto& pub : parser.m_keys) {
2780 pubs.emplace_back(std::move(pub.at(i)));
2782 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2787 if (ctx == ParseScriptContext::P2SH) {
2788 error =
"A function is needed within P2SH";
2790 }
else if (ctx == ParseScriptContext::P2WSH) {
2791 error =
"A function is needed within P2WSH";
2794 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2801 if (!match)
return {};
2802 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2803 keys.reserve(match->second.size());
2804 for (
const auto keyspan : match->second) {
2805 if (keyspan.size() != 32)
return {};
2807 if (!key)
return {};
2808 keys.push_back(std::move(key));
2810 return std::make_unique<MultiADescriptor>(match->first, std::move(
keys));
2818 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx,
provider),
true);
2821 if (ctx == ParseScriptContext::P2TR) {
2826 std::vector<std::vector<unsigned char>>
data;
2829 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2831 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2832 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2835 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2839 if (
provider.GetPubKey(keyid, pubkey)) {
2840 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2841 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2849 if (
provider.GetPubKey(keyid, pubkey)) {
2850 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH,
provider)) {
2851 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2855 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2857 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2858 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2860 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2861 providers.push_back(std::move(pubkey_provider));
2867 if (ok)
return std::make_unique<MultisigDescriptor>((
int)data[0][0], std::move(providers));
2873 if (
provider.GetCScript(scriptid, subscript)) {
2874 auto sub = InferScript(subscript, ParseScriptContext::P2SH,
provider);
2875 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2881 if (
provider.GetCScript(scriptid, subscript)) {
2882 auto sub = InferScript(subscript, ParseScriptContext::P2WSH,
provider);
2883 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2889 std::copy(data[0].begin(), data[0].end(), pubkey.
begin());
2892 if (
provider.GetTaprootSpendData(pubkey, tap)) {
2898 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2899 std::vector<int> depths;
2900 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2901 std::unique_ptr<DescriptorImpl> subdesc;
2909 subscripts.push_back(std::move(subdesc));
2910 depths.push_back(depth);
2915 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2921 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR,
provider);
2923 return std::make_unique<RawTRDescriptor>(std::move(key));
2928 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2930 uint32_t key_exp_index = 0;
2931 KeyParser parser(
nullptr, &
provider, script_ctx, key_exp_index);
2934 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2935 keys.reserve(parser.m_keys.size());
2936 for (
auto& key : parser.m_keys) {
2937 keys.emplace_back(std::move(key.at(0)));
2939 return std::make_unique<MiniscriptDescriptor>(std::move(
keys), std::move(*
node));
2945 if (ctx != ParseScriptContext::TOP)
return nullptr;
2950 return std::make_unique<AddressDescriptor>(std::move(dest));
2954 return std::make_unique<RawDescriptor>(
script);
2961bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2963 auto check_split = Split(sp,
'#');
2964 if (check_split.size() > 2) {
2965 error =
"Multiple '#' symbols";
2968 if (check_split.size() == 1 && require_checksum){
2969 error =
"Missing checksum";
2972 if (check_split.size() == 2) {
2973 if (check_split[1].size() != 8) {
2974 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2978 auto checksum = DescriptorChecksum(check_split[0]);
2979 if (checksum.empty()) {
2980 error =
"Invalid characters in payload";
2983 if (check_split.size() == 2) {
2984 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2985 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2989 if (out_checksum) *out_checksum = std::move(checksum);
2990 sp = check_split[0];
2994std::vector<std::unique_ptr<Descriptor>>
Parse(std::string_view descriptor,
FlatSigningProvider& out, std::string& error,
bool require_checksum)
2996 std::span<const char> sp{descriptor};
2998 uint32_t key_exp_index = 0;
2999 auto ret =
ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
3000 if (sp.empty() && !
ret.empty()) {
3001 std::vector<std::unique_ptr<Descriptor>> descs;
3002 descs.reserve(
ret.size());
3003 for (
auto& r :
ret) {
3004 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
3015 std::span<const char> sp{descriptor};
3027 std::string desc_str = desc.
ToString(
true);
3029 CSHA256().Write((
unsigned char*)desc_str.data(), desc_str.size()).Finalize(
id.begin());
3041 xpubs[der_index] = xpub;
3061 const auto& der_it = key_exp_it->second.find(der_index);
3062 if (der_it == key_exp_it->second.end())
return false;
3063 xpub = der_it->second;
3081 if (xpub != parent_xpub_pair.second) {
3082 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
3090 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3093 if (xpub != derived_xpub_pair.second) {
3094 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
3098 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3099 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3105 if (xpub != lh_xpub_pair.second) {
3106 throw std::runtime_error(std::string(__func__) +
": New cached last hardened xpub does not match already cached last hardened xpub");
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
util::Expected< KeyPathElement, std::string > ParseKeyPathElement(std::span< const char > elem)
Parse a single key path element like "0", "0'", or "0h".
bool HasHardenedDerivation(std::span< const uint32_t > keypath)
Whether a parsed HD keypath contains at least one hardened derivation step.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
#define CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
unsigned int size() const
Simple read-only vector-like interface.
bool IsValid() const
Check whether this private key is valid.
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
CPubKey GetPubKey() const
Compute the public key from a private key.
A reference to a CKey: the Hash160 of its serialized public key.
KeyFingerprint fingerprint() const
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization).
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
static constexpr uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG
If CTxIn::nSequence encodes a relative lock-time and this flag is set, the relative lock-time has uni...
static constexpr uint32_t SEQUENCE_LOCKTIME_MASK
If CTxIn::nSequence encodes a relative lock-time, this mask is applied to extract that lock-time from...
Cache for single descriptor's derived extended pubkeys.
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
ExtPubKeyMap m_last_hardened_xpubs
Map key expression index -> last hardened xpub.
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
std::unordered_map< uint32_t, ExtPubKeyMap > m_derived_xpubs
Map key expression index -> map of (key derivation index -> xpub).
bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached last hardened xpub.
ExtPubKeyMap m_parent_xpubs
Map key expression index -> parent xpub.
An interface to be implemented by keystores that support signing.
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
TaprootBuilder & Add(int depth, std::span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * end() const
const unsigned char * begin() const
CPubKey GetEvenCorrespondingCPubKey() const
bool IsFullyValid() const
Determine if this pubkey is fully valid.
XOnlyPubKey()=default
Construct an empty x-only pubkey.
constexpr unsigned char * begin()
enum Fragment Fragment() const
constexpr int WITNESS_SCALE_FACTOR
CScript ParseScript(const std::string &s)
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
std::string EncodeExtKey(const CExtKey &key)
CExtPubKey DecodeExtPubKey(const std::string &str)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
std::string EncodeSecret(const CKey &key)
std::string EncodeDestination(const CTxDestination &dest)
CKey DecodeSecret(const std::string &str)
std::string EncodeExtPubKey(const CExtPubKey &key)
CExtKey DecodeExtKey(const std::string &str)
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey &pubkey)
Construct the BIP 328 synthetic xpub for a pubkey.
std::optional< CPubKey > MuSig2AggregatePubkeys(const std::vector< CPubKey > &pubkeys, secp256k1_musig_keyagg_cache &keyagg_cache, const std::optional< CPubKey > &expected_aggregate)
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
std::optional< Node< typename Ctx::Key > > FromScript(const CScript &script, const Ctx &ctx)
void ForEachNode(const Node< Key > &root, Fn &&fn)
Unordered traversal of a miniscript node tree.
std::optional< Node< typename Ctx::Key > > FromString(const std::string &str, const Ctx &ctx)
@ OLDER
[n] OP_CHECKSEQUENCEVERIFY
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
std::vector< T > Split(std::span< const char > sp LIFETIMEBOUND, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(std::string_view descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
uint256 CompatDescriptorHash(const Descriptor &desc)
Hash of the COMPAT string representation of the descriptor that is not supposed to change over time.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
constexpr unsigned int MAX_SCRIPT_ELEMENT_SIZE
constexpr int MAX_PUBKEYS_PER_MULTISIG
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
std::vector< unsigned char > ToByteVector(const T &in)
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
const SigningProvider & DUMMY_SIGNING_PROVIDER
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::optional< T > ToIntegral(std::string_view str, size_t base=10)
Convert string to integral type T.
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
bool Derive(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
Interface for parsed descriptor objects.
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
KeyFingerprint fingerprint
First 32 bits of the Hash160 of the public key at the root of the path.
std::vector< uint32_t > path
XOnlyPubKey internal_key
The BIP341 internal key.
std::vector< uint16_t > keys
FuzzedDataProvider provider
consteval auto _(util::TranslatedLiteral str)
bool IsHex(std::string_view str)
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.