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;
199 virtual bool IsRange()
const = 0;
202 virtual size_t GetSize()
const = 0;
204 enum class StringType {
210 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
231 GetPrivKey(0, arg, tmp_provider);
232 return !tmp_provider.
keys.empty();
236 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
238 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
241 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
244 virtual bool IsBIP32()
const = 0;
247 virtual size_t GetKeyCount()
const {
return 1; }
250 virtual bool CanSelfExpand()
const = 0;
253class OriginPubkeyProvider final :
public PubkeyProvider
256 std::unique_ptr<PubkeyProvider> m_provider;
259 std::string OriginString(StringType type,
bool normalized=
false)
const
262 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
267 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) {}
273 std::optional<CPubKey> pub = m_provider->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
274 if (!pub)
return std::nullopt;
275 const CKeyID keyid{pub->GetID()};
277 auto& [pubkey, suborigin] = subprovider.
origins[keyid];
279 suborigin.fingerprint = m_origin.fingerprint;
280 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
281 auto origin{subprovider.
origins.extract(keyid)};
282 out.Merge(std::move(subprovider));
284 out.origins.insert_or_assign(keyid, std::move(origin.mapped()));
287 bool IsRange()
const override {
return m_provider->IsRange(); }
288 size_t GetSize()
const override {
return m_provider->GetSize(); }
289 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
290 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
294 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
295 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
301 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
307 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
309 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
315 m_provider->GetPrivKey(pos, arg,
out);
317 std::optional<CPubKey> GetRootPubKey()
const override
319 return m_provider->GetRootPubKey();
321 std::optional<CExtPubKey> GetRootExtPubKey()
const override
323 return m_provider->GetRootExtPubKey();
325 std::unique_ptr<PubkeyProvider> Clone()
const override
327 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
329 bool CanSelfExpand()
const override {
return m_provider->CanSelfExpand(); }
333class ConstPubkeyProvider final :
public PubkeyProvider
342 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
347 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
351 CKeyID keyid = m_pubkey.GetID();
353 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
354 out.pubkeys.emplace(keyid, m_pubkey);
357 bool IsRange()
const override {
return false; }
358 size_t GetSize()
const override {
return m_pubkey.size(); }
359 bool IsBIP32()
const override {
return false; }
360 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
363 std::optional<CKey> key = GetPrivKey(arg);
378 std::optional<CKey> key = GetPrivKey(arg);
380 out.keys.emplace(key->GetPubKey().GetID(), *key);
382 std::optional<CPubKey> GetRootPubKey()
const override
386 std::optional<CExtPubKey> GetRootExtPubKey()
const override
390 std::unique_ptr<PubkeyProvider> Clone()
const override
392 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
394 bool CanSelfExpand() const final {
return true; }
397enum class DeriveType {
404class BIP32PubkeyProvider final :
public PubkeyProvider
416 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
417 ret.nDepth = m_root_extkey.nDepth;
418 ret.fingerprint = m_root_extkey.fingerprint;
419 ret.nChild = m_root_extkey.nChild;
420 ret.chaincode = m_root_extkey.chaincode;
428 if (!GetExtKey(arg, xprv))
return false;
429 for (
auto entry :
m_path) {
430 if (!xprv.
Derive(xprv, entry))
return false;
432 last_hardened = xprv;
438 bool IsHardened()
const
440 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
445 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) {}
446 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
447 size_t GetSize()
const override {
return 33; }
448 bool IsBIP32()
const override {
return true; }
452 info.
fingerprint = m_root_extkey.id_key_fingerprint();
454 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
463 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
464 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
466 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
467 final_extkey = parent_extkey;
468 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
470 }
else if (IsHardened()) {
473 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
474 parent_extkey = xprv.
Neuter();
475 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
477 final_extkey = xprv.
Neuter();
479 last_hardened_extkey = lh_xprv.
Neuter();
482 for (
auto entry :
m_path) {
483 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
485 final_extkey = parent_extkey;
486 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
487 assert(m_derive != DeriveType::HARDENED_RANGED);
489 if (!der)
return std::nullopt;
496 if (m_derive != DeriveType::HARDENED_RANGED) {
497 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
500 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
502 }
else if (info.
path.size() > 0) {
503 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
507 return final_extkey.
pubkey;
509 std::string
ToString(StringType type,
bool normalized)
const
512 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
516 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
520 std::string
ToString(StringType type=StringType::PUBLIC)
const override
527 if (!GetExtKey(arg, key)) {
534 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
540 if (m_derive == DeriveType::HARDENED_RANGED) {
546 int i = (int)
m_path.size() - 1;
547 for (; i >= 0; --i) {
560 for (;
k <= i; ++
k) {
566 for (;
k < (int)
m_path.size(); ++
k) {
567 end_path.push_back(
m_path.at(
k));
569 origin.
fingerprint = m_root_extkey.id_key_fingerprint();
574 if (cache !=
nullptr) {
580 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
590 assert(m_derive == DeriveType::UNHARDENED_RANGED);
598 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
599 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
603 std::optional<CPubKey> GetRootPubKey()
const override
607 std::optional<CExtPubKey> GetRootExtPubKey()
const override
609 return m_root_extkey;
611 std::unique_ptr<PubkeyProvider> Clone()
const override
613 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey,
m_path, m_derive, m_apostrophe);
615 bool CanSelfExpand()
const override {
return !IsHardened(); }
619class MuSigPubkeyProvider final :
public PubkeyProvider
623 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
627 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
628 mutable std::optional<CPubKey> m_aggregate_pubkey;
629 const DeriveType m_derive;
630 const bool m_ranged_participants;
632 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
637 std::vector<std::unique_ptr<PubkeyProvider>> providers,
641 : PubkeyProvider(exp_index),
642 m_participants(
std::move(providers)),
645 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
647 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
648 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
650 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
651 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
659 if (!m_aggregate_provider && !m_ranged_participants) {
661 std::vector<CPubKey> pubkeys;
662 for (
const auto& prov : m_participants) {
663 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
664 if (!pubkey.has_value()) {
667 pubkeys.push_back(pubkey.value());
669 std::sort(pubkeys.begin(), pubkeys.end());
673 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
676 if (IsRangedDerivation() || !
m_path.empty()) {
679 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub,
m_path, m_derive,
false);
681 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
686 std::vector<CPubKey> pubkeys;
687 for (
const auto& prov : m_participants) {
688 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
689 if (!pub)
return std::nullopt;
690 pubkeys.emplace_back(*pub);
692 std::sort(pubkeys.begin(), pubkeys.end());
695 if (m_aggregate_provider) {
699 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
700 if (!pub)
return std::nullopt;
702 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
707 if (!aggregate_pubkey)
return std::nullopt;
708 pubout = *aggregate_pubkey;
710 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
711 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
712 out.aggregate_pubkeys.emplace(pubout, pubkeys);
718 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
720 size_t GetSize()
const override {
return 32; }
722 std::string
ToString(StringType type=StringType::PUBLIC)
const override
724 std::string
out =
"musig(";
725 for (
size_t i = 0; i < m_participants.size(); ++i) {
726 const auto& pubkey = m_participants.at(i);
728 out += pubkey->ToString(type);
732 if (IsRangedDerivation()) {
739 bool any_privkeys =
false;
741 for (
size_t i = 0; i < m_participants.size(); ++i) {
742 const auto& pubkey = m_participants.at(i);
745 if (pubkey->ToPrivateString(arg, tmp)) {
752 if (IsRangedDerivation()) {
760 for (
size_t i = 0; i < m_participants.size(); ++i) {
761 const auto& pubkey = m_participants.at(i);
764 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
771 if (IsRangedDerivation()) {
782 for (
const auto& prov : m_participants) {
783 prov->GetPrivKey(pos, arg,
out);
789 return std::ranges::all_of(m_participants, [&](
const auto& prov) {
return prov->HavePrivateKeys(arg); });
797 std::optional<CPubKey> GetRootPubKey()
const override
801 std::optional<CExtPubKey> GetRootExtPubKey()
const override
806 std::unique_ptr<PubkeyProvider> Clone()
const override
808 std::vector<std::unique_ptr<PubkeyProvider>> providers;
809 providers.reserve(m_participants.size());
810 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
811 providers.emplace_back(p->Clone());
813 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers),
m_path, m_derive);
815 bool IsBIP32()
const override
818 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
820 size_t GetKeyCount()
const override
822 return 1 + m_participants.size();
824 bool CanSelfExpand()
const override
828 for (
const auto& key : m_participants) {
829 if (!key->CanSelfExpand())
return false;
840 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
842 const std::string m_name;
844 std::vector<std::string> m_warnings;
850 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
853 virtual std::string ToStringExtra()
const {
return ""; }
865 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
868 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
869 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))) {}
870 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)) {}
872 enum class StringType
883 for (
const auto& arg : m_subdescriptor_args) {
884 if (!arg->IsSolvable())
return false;
892 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
894 for (
const auto& sub: m_subdescriptor_args) {
895 if (!sub->HavePrivateKeys(arg))
return false;
898 for (
const auto& pubkey : m_pubkey_args) {
899 if (!pubkey->HavePrivateKeys(arg))
return false;
908 for (
const auto& pubkey : m_pubkey_args) {
909 if (pubkey->IsRange())
return true;
911 for (
const auto& arg : m_subdescriptor_args) {
912 if (arg->IsRange())
return true;
921 bool is_private{type == StringType::PRIVATE};
924 bool any_success{!is_private};
925 for (
const auto& scriptarg : m_subdescriptor_args) {
926 if (pos++)
ret +=
",";
928 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
929 if (!is_private && !subscript_res)
return false;
930 any_success = any_success || subscript_res;
939 std::string extra = ToStringExtra();
940 size_t pos = extra.size() > 0 ? 1 : 0;
941 std::string
ret = m_name +
"(" + extra;
942 bool is_private{type == StringType::PRIVATE};
945 bool any_success{!is_private};
947 for (
const auto& pubkey : m_pubkey_args) {
948 if (pos++)
ret +=
",";
951 case StringType::NORMALIZED:
952 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
954 case StringType::PRIVATE:
955 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
957 case StringType::PUBLIC:
958 tmp = pubkey->ToString();
960 case StringType::COMPAT:
961 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
966 std::string subscript;
967 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
968 if (!is_private && !subscript_res)
return false;
969 any_success = any_success || subscript_res;
970 if (pos && subscript.size())
ret +=
',';
971 out = std::move(
ret) + std::move(subscript) +
")";
975 std::string
ToString(
bool compat_format)
const final
978 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
979 return AddChecksum(
ret);
984 bool has_priv_key{ToStringHelper(&arg,
out, StringType::PRIVATE)};
991 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
1000 std::vector<CPubKey> pubkeys;
1001 pubkeys.reserve(m_pubkey_args.size());
1004 for (
const auto& p : m_pubkey_args) {
1005 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
1006 if (!pubkey)
return false;
1007 pubkeys.push_back(pubkey.value());
1009 std::vector<CScript> subscripts;
1010 for (
const auto& subarg : m_subdescriptor_args) {
1011 std::vector<CScript> outscripts;
1012 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
1013 assert(outscripts.size() == 1);
1014 subscripts.emplace_back(std::move(outscripts[0]));
1016 out.Merge(std::move(subprovider));
1018 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
1024 return ExpandHelper(pos,
provider,
nullptr, output_scripts,
out, write_cache);
1035 for (
const auto& p : m_pubkey_args) {
1038 for (
const auto& arg : m_subdescriptor_args) {
1043 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
1045 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
1052 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1059 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
1061 for (
const auto& p : m_pubkey_args) {
1062 std::optional<CPubKey> pub = p->GetRootPubKey();
1063 if (pub) pubkeys.insert(*pub);
1064 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1065 if (ext_pub) ext_pubs.insert(*ext_pub);
1067 for (
const auto& arg : m_subdescriptor_args) {
1068 arg->GetPubKeys(pubkeys, ext_pubs);
1072 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1074 bool HasScripts()
const override {
return true; }
1077 std::vector<std::string>
Warnings()
const override {
1078 std::vector<std::string> all = m_warnings;
1079 for (
const auto& sub : m_subdescriptor_args) {
1080 auto sub_w = sub->Warnings();
1081 all.insert(all.end(), sub_w.begin(), sub_w.end());
1088 uint32_t max_key_expr{0};
1089 std::vector<const DescriptorImpl*> todo = {
this};
1090 while (!todo.empty()) {
1091 const DescriptorImpl* desc = todo.back();
1093 for (
const auto& p : desc->m_pubkey_args) {
1094 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1096 for (
const auto&
s : desc->m_subdescriptor_args) {
1097 todo.push_back(
s.get());
1100 return max_key_expr;
1103 size_t GetKeyCount() const final
1106 std::vector<const DescriptorImpl*> todo = {
this};
1107 while (!todo.empty()) {
1108 const DescriptorImpl* desc = todo.back();
1110 for (
const auto& p : desc->m_pubkey_args) {
1111 count += p->GetKeyCount();
1113 for (
const auto&
s : desc->m_subdescriptor_args) {
1114 todo.push_back(
s.get());
1121 bool CanSelfExpand()
const override
1123 for (
const auto& key : m_pubkey_args) {
1124 if (!key->CanSelfExpand())
return false;
1126 for (
const auto& sub : m_subdescriptor_args) {
1127 if (!sub->CanSelfExpand())
return false;
1134class AddressDescriptor final :
public DescriptorImpl
1138 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1141 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1142 bool IsSolvable() const final {
return false; }
1148 bool IsSingleType() const final {
return true; }
1149 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1152 std::unique_ptr<DescriptorImpl> Clone()
const override
1154 return std::make_unique<AddressDescriptor>(m_destination);
1159class RawDescriptor final :
public DescriptorImpl
1163 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1164 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1167 bool IsSolvable() const final {
return false; }
1175 bool IsSingleType() const final {
return true; }
1176 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1178 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1180 std::unique_ptr<DescriptorImpl> Clone()
const override
1182 return std::make_unique<RawDescriptor>(m_script);
1187class PKDescriptor final :
public DescriptorImpl
1192 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1202 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1203 bool IsSingleType() const final {
return true; }
1205 std::optional<int64_t> ScriptSize()
const override {
1206 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1209 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1210 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1211 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1214 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1218 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1220 std::unique_ptr<DescriptorImpl> Clone()
const override
1222 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1227class PKHDescriptor final :
public DescriptorImpl
1230 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1236 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1238 bool IsSingleType() const final {
return true; }
1240 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1242 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1243 const auto sig_size = use_max_sig ? 72 : 71;
1244 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1247 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1251 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1253 std::unique_ptr<DescriptorImpl> Clone()
const override
1255 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1260class WPKHDescriptor final :
public DescriptorImpl
1263 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1269 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1271 bool IsSingleType() const final {
return true; }
1273 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1275 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1276 const auto sig_size = use_max_sig ? 72 : 71;
1280 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1281 return MaxSatSize(use_max_sig);
1284 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1286 std::unique_ptr<DescriptorImpl> Clone()
const override
1288 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1293class ComboDescriptor final :
public DescriptorImpl
1296 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1298 std::vector<CScript>
ret;
1302 if (
keys[0].IsCompressed()) {
1305 ret.emplace_back(p2wpkh);
1311 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1312 bool IsSingleType() const final {
return false; }
1313 std::unique_ptr<DescriptorImpl> Clone()
const override
1315 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1320class MultisigDescriptor final :
public DescriptorImpl
1322 const int m_threshold;
1323 const bool m_sorted;
1325 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1326 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1328 std::vector<CPubKey> sorted_keys(
keys);
1329 std::sort(sorted_keys.begin(), sorted_keys.end());
1335 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) {}
1336 bool IsSingleType() const final {
return true; }
1338 std::optional<int64_t> ScriptSize()
const override {
1339 const auto n_keys = m_pubkey_args.size();
1340 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1341 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1345 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1346 const auto sig_size = use_max_sig ? 72 : 71;
1347 return (1 + (1 +
sig_size) * m_threshold);
1350 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1354 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1356 std::unique_ptr<DescriptorImpl> Clone()
const override
1358 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1359 providers.reserve(m_pubkey_args.size());
1360 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1361 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1366class MultiADescriptor final :
public DescriptorImpl
1368 const int m_threshold;
1369 const bool m_sorted;
1371 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1372 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1374 std::vector<XOnlyPubKey> xkeys;
1375 xkeys.reserve(
keys.size());
1376 for (
const auto& key :
keys) xkeys.emplace_back(key);
1377 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1379 for (
size_t i = 1; i <
keys.size(); ++i) {
1386 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) {}
1387 bool IsSingleType() const final {
return true; }
1389 std::optional<int64_t> ScriptSize()
const override {
1390 const auto n_keys = m_pubkey_args.size();
1394 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1395 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1398 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1400 std::unique_ptr<DescriptorImpl> Clone()
const override
1402 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1403 providers.reserve(m_pubkey_args.size());
1404 for (
const auto& arg : m_pubkey_args) {
1405 providers.push_back(arg->Clone());
1407 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1412class SHDescriptor final :
public DescriptorImpl
1415 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1418 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1425 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1429 assert(m_subdescriptor_args.size() == 1);
1433 bool IsSingleType() const final {
return true; }
1435 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1437 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1438 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1439 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1443 if (
IsSegwit())
return subscript_weight + *sat_size;
1450 std::optional<int64_t> MaxSatisfactionElems()
const override {
1451 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1455 std::unique_ptr<DescriptorImpl> Clone()
const override
1457 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1462class WSHDescriptor final :
public DescriptorImpl
1465 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1468 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1472 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1474 bool IsSingleType() const final {
return true; }
1476 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1478 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1479 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1480 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1487 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1488 return MaxSatSize(use_max_sig);
1491 std::optional<int64_t> MaxSatisfactionElems()
const override {
1492 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1496 std::unique_ptr<DescriptorImpl> Clone()
const override
1498 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1503class TRDescriptor final :
public DescriptorImpl
1505 std::vector<int> m_depths;
1507 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1510 assert(m_depths.size() == scripts.size());
1511 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1517 if (!xpk.IsFullyValid())
return {};
1520 out.tr_trees[output] = builder;
1525 if (m_depths.empty()) {
1531 return type != StringType::PRIVATE;
1533 std::vector<bool> path;
1534 bool is_private{type == StringType::PRIVATE};
1537 bool any_success{!is_private};
1539 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1540 if (pos)
ret +=
',';
1541 while ((
int)path.size() <= m_depths[pos]) {
1542 if (path.size())
ret +=
'{';
1543 path.push_back(
false);
1546 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1547 if (!is_private && !subscript_res)
return false;
1548 any_success = any_success || subscript_res;
1550 while (!path.empty() && path.back()) {
1551 if (path.size() > 1)
ret +=
'}';
1554 if (!path.empty()) path.back() =
true;
1559 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1560 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1562 assert(m_subdescriptor_args.size() == m_depths.size());
1565 bool IsSingleType() const final {
return true; }
1567 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1569 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1574 std::optional<int64_t> MaxSatisfactionElems()
const override {
1579 std::unique_ptr<DescriptorImpl> Clone()
const override
1581 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1582 subdescs.reserve(m_subdescriptor_args.size());
1583 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1584 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1598 const std::vector<CPubKey>& m_keys;
1605 uint160 GetHash160(uint32_t key)
const {
1609 return m_keys[key].GetID();
1615 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1618 return {m_keys[key].begin(), m_keys[key].end()};
1621 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1624 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1625 auto id = GetHash160(key);
1626 return {
id.begin(),
id.end()};
1637 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1639 const DescriptorImpl::StringType m_type;
1644 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1645 DescriptorImpl::StringType type,
1647 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1649 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const
1652 has_priv_key =
false;
1654 case DescriptorImpl::StringType::PUBLIC:
1655 ret = m_pubkeys[key]->ToString();
1657 case DescriptorImpl::StringType::PRIVATE:
1658 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1660 case DescriptorImpl::StringType::NORMALIZED:
1661 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1663 case DescriptorImpl::StringType::COMPAT:
1664 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1671class MiniscriptDescriptor final :
public DescriptorImpl
1677 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
1680 const auto script_ctx{
m_node.GetMsCtx()};
1681 for (
const auto& key :
keys) {
1685 provider.pubkeys.emplace(key.GetID(), key);
1698 const uint32_t raw = node.K();
1699 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1700 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1701 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1702 if (is_time_based) {
1703 m_warnings.push_back(strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1705 m_warnings.push_back(strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1712 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1715 bool has_priv_key{
false};
1716 auto res =
m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1717 if (res)
out = *res;
1718 if (type == StringType::PRIVATE) {
1720 return has_priv_key;
1722 return res.has_value();
1726 bool IsSolvable()
const override {
return true; }
1727 bool IsSingleType() const final {
return true; }
1729 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1731 std::optional<int64_t> MaxSatSize(
bool)
const override
1734 return m_node.GetWitnessSize();
1737 std::optional<int64_t> MaxSatisfactionElems()
const override
1739 return m_node.GetStackSize();
1742 std::unique_ptr<DescriptorImpl> Clone()
const override
1744 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1745 providers.reserve(m_pubkey_args.size());
1746 for (
const auto& arg : m_pubkey_args) {
1747 providers.push_back(arg->Clone());
1749 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node.Clone());
1754class RawTRDescriptor final :
public DescriptorImpl
1757 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1761 if (!xpk.IsFullyValid())
return {};
1766 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1768 bool IsSingleType() const final {
return true; }
1770 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1772 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1777 std::optional<int64_t> MaxSatisfactionElems()
const override {
1782 std::unique_ptr<DescriptorImpl> Clone()
const override
1784 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1789class UnusedDescriptor final :
public DescriptorImpl
1792 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override {
return {}; }
1794 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"unused") {}
1795 bool IsSingleType() const final {
return true; }
1796 bool HasScripts()
const override {
return false; }
1798 std::unique_ptr<DescriptorImpl> Clone()
const override
1800 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1809enum class ParseScriptContext {
1829[[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)
1831 auto parse_elem = [&](std::span<const char> elem) -> std::optional<uint32_t> {
1834 error = parsed.error();
1835 return std::nullopt;
1837 if (parsed->is_hardened) {
1838 has_hardened =
true;
1839 apostrophe = elem.back() ==
'\'';
1841 return parsed->ChildNumber();
1845 struct MultipathSubstitutes {
1846 size_t placeholder_index;
1847 std::vector<uint32_t>
values;
1849 std::optional<MultipathSubstitutes> substitutes;
1850 has_hardened =
false;
1852 for (
size_t i = 1; i <
split.size(); ++i) {
1853 const std::span<const char>& elem =
split[i];
1856 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1857 if (!allow_multipath) {
1858 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1862 error =
"Multiple multipath key path specifiers found";
1867 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1868 if (nums.size() < 2) {
1869 error =
"Multipath key path specifiers must have at least two items";
1873 substitutes.emplace();
1874 std::unordered_set<uint32_t> seen_substitutes;
1875 for (
const auto& num : nums) {
1876 const auto& op_num = parse_elem(num);
1877 if (!op_num)
return false;
1878 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1880 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1883 substitutes->values.emplace_back(*op_num);
1886 path.emplace_back();
1887 substitutes->placeholder_index = path.size() - 1;
1889 const auto& op_num = parse_elem(elem);
1890 if (!op_num)
return false;
1891 path.emplace_back(*op_num);
1896 out.emplace_back(std::move(path));
1899 for (uint32_t substitute : substitutes->values) {
1900 KeyPath branch_path = path;
1901 branch_path[substitutes->placeholder_index] = substitute;
1902 out.emplace_back(std::move(branch_path));
1908[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1911 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1914static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1916 DeriveType type = DeriveType::NON_RANGED;
1917 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1919 type = DeriveType::UNHARDENED_RANGED;
1920 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1921 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1923 type = DeriveType::HARDENED_RANGED;
1929std::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)
1931 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1932 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1934 std::string str(
split[0].begin(),
split[0].end());
1935 if (str.size() == 0) {
1936 error =
"No key provided";
1940 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1943 if (
split.size() == 1) {
1947 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1948 error =
"Hybrid public keys are not allowed";
1951 if (pubkey.IsFullyValid()) {
1952 if (permit_uncompressed || pubkey.IsCompressed()) {
1953 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1957 error =
"Uncompressed keys are not allowed";
1960 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1961 unsigned char fullkey[33] = {0x02};
1962 std::copy(
data.begin(),
data.end(), fullkey + 1);
1963 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1964 if (pubkey.IsFullyValid()) {
1965 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1970 error =
strprintf(
"Pubkey '%s' is invalid", str);
1977 out.keys.emplace(pubkey.
GetID(), key);
1978 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1982 error =
"Uncompressed keys are not allowed";
1990 error =
strprintf(
"key '%s' is not valid", str);
1993 std::vector<KeyPath> paths;
1994 DeriveType type = ParseDeriveType(
split, apostrophe);
1995 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1997 extpubkey = extkey.
Neuter();
2000 for (
auto& path : paths) {
2001 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
2009std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2011 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
2016 std::span<const char> span = sp;
2017 if (
Const(
"musig(", span,
false)) {
2018 if (ctx != ParseScriptContext::P2TR) {
2019 error =
"musig() is only allowed in tr() and rawtr()";
2026 if (
split.size() > 2) {
2027 error =
"Too many ')' in musig() expression";
2030 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
2031 if (!
Func(
"musig", expr)) {
2032 error =
"Invalid musig() expression";
2037 bool any_ranged =
false;
2038 bool all_bip32 =
true;
2039 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2040 bool any_key_parsed =
false;
2041 size_t max_multipath_len = 0;
2042 while (expr.size()) {
2043 if (any_key_parsed && !
Const(
",", expr)) {
2044 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
2047 auto arg =
Expr(expr);
2048 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
2050 error =
strprintf(
"musig(): %s", error);
2053 any_key_parsed =
true;
2055 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2056 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2058 max_multipath_len = std::max(max_multipath_len,
pk.size());
2060 providers.emplace_back(std::move(
pk));
2062 if (!any_key_parsed) {
2063 error =
"musig(): Must contain key expressions";
2068 DeriveType deriv_type = DeriveType::NON_RANGED;
2069 std::vector<KeyPath> derivation_multipaths;
2072 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2076 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2081 deriv_type = ParseDeriveType(deriv_split, dummy);
2082 if (deriv_type == DeriveType::HARDENED_RANGED) {
2083 error =
"musig(): Cannot have hardened child derivation";
2086 bool has_hardened =
false;
2087 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2088 error =
"musig(): " + error;
2092 error =
"musig(): cannot have hardened derivation steps";
2096 derivation_multipaths.emplace_back();
2101 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2102 for (
auto& multipath_providers : providers) {
2103 if (multipath_providers.size() == 1) {
2104 for (
size_t i = 1; i < length; ++i) {
2105 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2107 }
else if (multipath_providers.size() != length) {
2116 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2117 KeyPath& path = derivation_multipaths.at(path_idx);
2118 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2119 pubs.reserve(providers.size());
2120 for (
auto& vec : providers) {
2121 pubs.emplace_back(std::move(vec.at(vec_idx)));
2123 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2126 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2127 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2129 }
else if (max_multipath_len > 1) {
2130 if (!clone_providers(max_multipath_len)) {
2131 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2134 for (
size_t i = 0; i < max_multipath_len; ++i) {
2136 emplace_final_provider(i, 0);
2138 }
else if (derivation_multipaths.size() > 1) {
2140 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2141 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2144 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2146 emplace_final_provider(i, i);
2150 emplace_final_provider(0, 0);
2156 auto origin_split =
Split(sp,
']');
2157 if (origin_split.size() > 2) {
2158 error =
"Multiple ']' characters found for a single pubkey";
2162 bool apostrophe =
false;
2163 if (origin_split.size() == 1) {
2164 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
2166 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2167 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2168 origin_split[0].empty() ?
']' : origin_split[0][0]);
2171 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2172 if (slash_split[0].size() != 8) {
2173 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2176 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2177 if (!
IsHex(fpr_hex)) {
2178 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2181 auto fpr_bytes =
ParseHex(fpr_hex);
2183 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2184 assert(fpr_bytes.size() == 4);
2186 std::vector<KeyPath> path;
2187 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2188 info.
path = path.at(0);
2189 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2190 if (providers.empty())
return {};
2191 ret.reserve(providers.size());
2192 for (
auto& prov : providers) {
2193 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2205 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2208 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2211 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2213 return key_provider;
2219 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2221 if (
provider.GetKeyOriginByXOnly(xkey, info)) {
2222 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2224 return key_provider;
2232 using Key = uint32_t;
2238 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2240 mutable std::string m_key_parsing_error;
2244 uint32_t& m_expr_index;
2248 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2250 bool KeyCompare(
const Key& a,
const Key& b)
const {
2254 const PubkeyProvider& key_a{*m_keys.at(a).at(0)};
2255 const PubkeyProvider& key_b{*m_keys.at(b).at(0)};
2258 const std::optional<CPubKey> pub_b{key_b.GetPubKey(0,
provider, out_b)};
2259 if (pub_a && pub_b)
return *pub_a < *pub_b;
2262 if (pub_a.has_value() != pub_b.has_value())
return !pub_a.has_value();
2263 return key_a.ToString() < key_b.ToString();
2267 switch (m_script_ctx) {
2274 std::optional<Key>
FromString(std::span<const char>& in)
const
2277 Key key = m_keys.
size();
2278 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2279 if (
pk.empty())
return {};
2280 m_keys.emplace_back(std::move(
pk));
2284 std::optional<std::string>
ToString(
const Key& key,
bool&)
const
2286 return m_keys.at(key).at(0)->ToString();
2289 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2292 Key key = m_keys.size();
2295 std::copy(begin, end, pubkey.
begin());
2296 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2297 m_keys.emplace_back();
2298 m_keys.back().push_back(std::move(pubkey_provider));
2303 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2304 m_keys.emplace_back();
2305 m_keys.back().push_back(std::move(pubkey_provider));
2312 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2314 assert(end - begin == 20);
2317 std::copy(begin, end, hash.
begin());
2321 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2322 Key key = m_keys.
size();
2323 m_keys.emplace_back();
2324 m_keys.back().push_back(std::move(pubkey_provider));
2332 return m_script_ctx;
2338std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2341 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2342 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2343 auto expr =
Expr(sp);
2344 if (
Func(
"pk", expr)) {
2345 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2346 if (pubkeys.empty()) {
2350 for (
auto& pubkey : pubkeys) {
2351 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2355 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2356 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2357 if (pubkeys.empty()) {
2361 for (
auto& pubkey : pubkeys) {
2362 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2366 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2367 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2368 if (pubkeys.empty()) {
2369 error =
strprintf(
"combo(): %s", error);
2372 for (
auto& pubkey : pubkeys) {
2373 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2376 }
else if (
Func(
"combo", expr)) {
2377 error =
"Can only have combo() at top level";
2380 const bool multi =
Func(
"multi", expr);
2381 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2382 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2383 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2384 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2385 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2386 auto threshold =
Expr(expr);
2388 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2389 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2390 thres = *maybe_thres;
2392 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2395 size_t script_size = 0;
2396 size_t max_providers_len = 0;
2397 while (expr.size()) {
2398 if (!
Const(
",", expr)) {
2399 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2402 auto arg =
Expr(expr);
2403 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2408 script_size += pks.at(0)->GetSize() + 1;
2409 max_providers_len = std::max(max_providers_len, pks.size());
2410 providers.emplace_back(std::move(pks));
2418 }
else if (thres < 1) {
2419 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2421 }
else if (thres > providers.size()) {
2422 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2425 if (ctx == ParseScriptContext::TOP) {
2426 if (providers.size() > 3) {
2427 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2431 if (ctx == ParseScriptContext::P2SH) {
2441 for (
auto& vec : providers) {
2442 if (vec.size() == 1) {
2443 for (
size_t i = 1; i < max_providers_len; ++i) {
2444 vec.emplace_back(vec.at(0)->Clone());
2446 }
else if (vec.size() != max_providers_len) {
2447 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2453 for (
size_t i = 0; i < max_providers_len; ++i) {
2455 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2456 pubs.reserve(providers.size());
2457 for (
auto& pub : providers) {
2458 pubs.emplace_back(std::move(pub.at(i)));
2460 if (multi || sortedmulti) {
2461 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2463 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2467 }
else if (multi || sortedmulti) {
2468 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2470 }
else if (multi_a || sortedmulti_a) {
2471 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2474 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2475 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2476 if (pubkeys.empty()) {
2480 for (
auto& pubkey : pubkeys) {
2481 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2484 }
else if (
Func(
"wpkh", expr)) {
2485 error =
"Can only have wpkh() at top level or inside sh()";
2488 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2489 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2490 if (descs.empty() || expr.size())
return {};
2491 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2492 ret.reserve(descs.size());
2493 for (
auto& desc : descs) {
2494 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2497 }
else if (
Func(
"sh", expr)) {
2498 error =
"Can only have sh() at top level";
2501 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2502 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2503 if (descs.empty() || expr.size())
return {};
2504 for (
auto& desc : descs) {
2505 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2508 }
else if (
Func(
"wsh", expr)) {
2509 error =
"Can only have wsh() at top level or inside sh()";
2512 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2515 error =
"Address is not valid";
2518 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2520 }
else if (
Func(
"addr", expr)) {
2521 error =
"Can only have addr() at top level";
2524 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2525 auto arg =
Expr(expr);
2526 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2527 if (internal_keys.empty()) {
2531 size_t max_providers_len = internal_keys.size();
2532 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2533 std::vector<int> depths;
2535 if (!
Const(
",", expr)) {
2536 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2542 std::vector<bool> branches;
2547 while (
Const(
"{", expr)) {
2548 branches.push_back(
false);
2555 auto sarg =
Expr(expr);
2556 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2557 if (subscripts.back().empty())
return {};
2558 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2559 depths.push_back(branches.size());
2561 while (branches.size() && branches.back()) {
2562 if (!
Const(
"}", expr)) {
2563 error =
strprintf(
"tr(): expected '}' after script expression");
2566 branches.pop_back();
2569 if (branches.size() && !branches.back()) {
2570 if (!
Const(
",", expr)) {
2571 error =
strprintf(
"tr(): expected ',' after script expression");
2574 branches.back() =
true;
2576 }
while (branches.size());
2579 error =
strprintf(
"tr(): expected ')' after script expression");
2587 for (
auto& vec : subscripts) {
2588 if (vec.size() == 1) {
2589 for (
size_t i = 1; i < max_providers_len; ++i) {
2590 vec.emplace_back(vec.at(0)->Clone());
2592 }
else if (vec.size() != max_providers_len) {
2593 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2598 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2599 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2603 while (internal_keys.size() < max_providers_len) {
2604 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2608 for (
size_t i = 0; i < max_providers_len; ++i) {
2610 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2611 this_subs.reserve(subscripts.size());
2612 for (
auto& subs : subscripts) {
2613 this_subs.emplace_back(std::move(subs.at(i)));
2615 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2620 }
else if (
Func(
"tr", expr)) {
2621 error =
"Can only have tr at top level";
2624 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2625 auto arg =
Expr(expr);
2627 error =
strprintf(
"rawtr(): only one key expected.");
2630 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2631 if (output_keys.empty()) {
2632 error =
strprintf(
"rawtr(): %s", error);
2635 for (
auto& pubkey : output_keys) {
2636 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2639 }
else if (
Func(
"rawtr", expr)) {
2640 error =
"Can only have rawtr at top level";
2643 if (ctx == ParseScriptContext::TOP &&
Func(
"unused", expr)) {
2645 auto arg =
Expr(expr);
2647 error =
strprintf(
"unused(): only one key expected");
2650 auto keys = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2651 if (
keys.empty())
return {};
2652 for (
auto& pubkey :
keys) {
2653 if (pubkey->IsRange()) {
2654 error =
"unused(): key cannot be ranged";
2657 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2660 }
else if (
Func(
"unused", expr)) {
2661 error =
"Can only have unused at top level";
2664 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2665 std::string str(expr.begin(), expr.end());
2667 error =
"Raw script is not hex";
2671 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2673 }
else if (
Func(
"raw", expr)) {
2674 error =
"Can only have raw() at top level";
2680 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2682 if (parser.m_key_parsing_error !=
"") {
2683 error = std::move(parser.m_key_parsing_error);
2687 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2688 error =
"Miniscript expressions can only be used in wsh or tr.";
2691 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2693 const auto* insane_node = &
node.value();
2694 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2695 error = *insane_node->ToString(parser);
2696 if (!insane_node->IsValid()) {
2697 error +=
" is invalid";
2698 }
else if (!
node->IsSane()) {
2699 error +=
" is not sane";
2700 if (!insane_node->IsNonMalleable()) {
2701 error +=
": malleable witnesses exist";
2702 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2703 error +=
": witnesses without signature exist";
2704 }
else if (!insane_node->CheckTimeLocksMix()) {
2705 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2706 }
else if (!insane_node->CheckDuplicateKey()) {
2707 error +=
": contains duplicate public keys";
2708 }
else if (!insane_node->ValidSatisfactions()) {
2709 error +=
": needs witnesses that may exceed resource limits";
2712 error +=
" is not satisfiable";
2721 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2722 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2723 return a.size() < b.size();
2726 for (
auto& vec : parser.m_keys) {
2727 if (vec.size() == 1) {
2728 for (
size_t i = 1; i < num_multipath; ++i) {
2729 vec.emplace_back(vec.at(0)->Clone());
2731 }
else if (vec.size() != num_multipath) {
2732 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2738 for (
size_t i = 0; i < num_multipath; ++i) {
2740 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2741 pubs.reserve(parser.m_keys.size());
2742 for (
auto& pub : parser.m_keys) {
2743 pubs.emplace_back(std::move(pub.at(i)));
2745 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2750 if (ctx == ParseScriptContext::P2SH) {
2751 error =
"A function is needed within P2SH";
2753 }
else if (ctx == ParseScriptContext::P2WSH) {
2754 error =
"A function is needed within P2WSH";
2757 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2764 if (!match)
return {};
2765 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2766 keys.reserve(match->second.size());
2767 for (
const auto keyspan : match->second) {
2768 if (keyspan.size() != 32)
return {};
2770 if (!key)
return {};
2771 keys.push_back(std::move(key));
2773 return std::make_unique<MultiADescriptor>(match->first, std::move(
keys));
2781 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx,
provider),
true);
2784 if (ctx == ParseScriptContext::P2TR) {
2789 std::vector<std::vector<unsigned char>>
data;
2792 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2794 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2795 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2798 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2802 if (
provider.GetPubKey(keyid, pubkey)) {
2803 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2804 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2812 if (
provider.GetPubKey(keyid, pubkey)) {
2813 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH,
provider)) {
2814 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2818 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2820 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2821 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2823 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2824 providers.push_back(std::move(pubkey_provider));
2830 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2836 if (
provider.GetCScript(scriptid, subscript)) {
2837 auto sub = InferScript(subscript, ParseScriptContext::P2SH,
provider);
2838 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2844 if (
provider.GetCScript(scriptid, subscript)) {
2845 auto sub = InferScript(subscript, ParseScriptContext::P2WSH,
provider);
2846 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2855 if (
provider.GetTaprootSpendData(pubkey, tap)) {
2861 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2862 std::vector<int> depths;
2863 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2864 std::unique_ptr<DescriptorImpl> subdesc;
2872 subscripts.push_back(std::move(subdesc));
2873 depths.push_back(depth);
2878 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2884 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR,
provider);
2886 return std::make_unique<RawTRDescriptor>(std::move(key));
2891 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2893 uint32_t key_exp_index = 0;
2894 KeyParser parser(
nullptr, &
provider, script_ctx, key_exp_index);
2897 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2898 keys.reserve(parser.m_keys.size());
2899 for (
auto& key : parser.m_keys) {
2900 keys.emplace_back(std::move(key.at(0)));
2902 return std::make_unique<MiniscriptDescriptor>(std::move(
keys), std::move(*
node));
2908 if (ctx != ParseScriptContext::TOP)
return nullptr;
2913 return std::make_unique<AddressDescriptor>(std::move(dest));
2917 return std::make_unique<RawDescriptor>(
script);
2924bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2926 auto check_split =
Split(sp,
'#');
2927 if (check_split.size() > 2) {
2928 error =
"Multiple '#' symbols";
2931 if (check_split.size() == 1 && require_checksum){
2932 error =
"Missing checksum";
2935 if (check_split.size() == 2) {
2936 if (check_split[1].size() != 8) {
2937 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2941 auto checksum = DescriptorChecksum(check_split[0]);
2942 if (checksum.empty()) {
2943 error =
"Invalid characters in payload";
2946 if (check_split.size() == 2) {
2947 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2948 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2952 if (out_checksum) *out_checksum = std::move(checksum);
2953 sp = check_split[0];
2959 std::span<const char> sp{descriptor};
2961 uint32_t key_exp_index = 0;
2963 if (sp.empty() && !
ret.empty()) {
2964 std::vector<std::unique_ptr<Descriptor>> descs;
2965 descs.reserve(
ret.size());
2966 for (
auto& r :
ret) {
2967 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2978 std::span<const char> sp{descriptor};
2990 std::string desc_str = desc.
ToString(
true);
3004 xpubs[der_index] = xpub;
3024 const auto& der_it = key_exp_it->second.find(der_index);
3025 if (der_it == key_exp_it->second.end())
return false;
3026 xpub = der_it->second;
3044 if (xpub != parent_xpub_pair.second) {
3045 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
3053 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3056 if (xpub != derived_xpub_pair.second) {
3057 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
3061 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3062 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3068 if (xpub != lh_xpub_pair.second) {
3069 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.
static constexpr uint32_t BIP32_HARDENED_FLAG
BIP32 hardened derivation flag (2^31)
#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.
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
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 GetPubKey(const CKeyID &address, CPubKey &pubkey) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
Utility class to construct Taproot outputs from internal key and script tree.
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 * begin() const
static constexpr size_t size()
CPubKey GetEvenCorrespondingCPubKey() const
bool IsFullyValid() const
Determine if this pubkey is fully valid.
constexpr unsigned char * begin()
A node in a miniscript expression.
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
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)
Compute the full aggregate pubkey from the given participant pubkeys in their current order.
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.
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
std::string ToString(const T &t)
Locale-independent version of std::to_string.
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
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.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
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.
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)
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
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...
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
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.
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::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
virtual void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const =0
Return all (extended) public keys for this descriptor, including any from subdescriptors.
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
virtual std::vector< std::string > Warnings() const =0
Semantic/safety warnings (includes subdescriptors).
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
virtual std::optional< OutputType > GetOutputType() const =0
virtual bool HasScripts() const =0
Whether this descriptor produces any scripts with the Expand functions.
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual uint32_t GetMaxKeyExpr() const =0
Get the maximum key expression index.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool HavePrivateKeys(const SigningProvider &provider) const =0
Whether the given provider has all private keys required by this descriptor.
virtual bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const =0
Expand a descriptor at a specified position using cached expansion data.
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
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.