94 uint64_t
PolyMod(uint64_t c,
int val)
97 c = ((c & 0x7ffffffff) << 5) ^ val;
98 if (c0 & 1) c ^= 0xf5dee51989;
99 if (c0 & 2) c ^= 0xa9fdca3312;
100 if (c0 & 4) c ^= 0x1bab10e32d;
101 if (c0 & 8) c ^= 0x3706b1677a;
102 if (c0 & 16) c ^= 0x644d626ffd;
106 std::string DescriptorChecksum(
const std::span<const char>& span)
121 static const std::string INPUT_CHARSET =
122 "0123456789()[],'/*abcdefgh@:$%{}" 123 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~" 124 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
127 static const std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
132 for (
auto ch : span) {
133 auto pos = INPUT_CHARSET.find(ch);
134 if (pos == std::string::npos)
return "";
136 cls = cls * 3 + (pos >> 5);
137 if (++clscount == 3) {
144 if (clscount > 0) c =
PolyMod(c, cls);
145 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
148 std::string
ret(8,
' ');
149 for (
int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
153 std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
159 typedef std::vector<uint32_t> KeyPath;
162 struct PubkeyProvider
167 const uint32_t m_expr_index;
169 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
171 virtual ~PubkeyProvider() =
default;
176 bool operator<(PubkeyProvider& other)
const {
179 std::optional<CPubKey> a =
GetPubKey(0, dummy, dummy);
180 std::optional<CPubKey> b = other.GetPubKey(0, dummy, dummy);
193 virtual bool IsRange()
const = 0;
196 virtual size_t GetSize()
const = 0;
198 enum class StringType {
204 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
222 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
224 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
227 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
230 virtual bool IsBIP32()
const = 0;
233 virtual size_t GetKeyCount()
const {
return 1; }
236 class OriginPubkeyProvider final :
public PubkeyProvider
239 std::unique_ptr<PubkeyProvider> m_provider;
242 std::string OriginString(StringType type,
bool normalized=
false)
const 245 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
250 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) {}
253 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg,
out, read_cache, write_cache);
254 if (!pub)
return std::nullopt;
255 Assert(
out.pubkeys.contains(pub->GetID()));
256 auto& [pubkey, suborigin] =
out.origins[pub->GetID()];
258 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), suborigin.fingerprint);
259 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
262 bool IsRange()
const override {
return m_provider->IsRange(); }
263 size_t GetSize()
const override {
return m_provider->GetSize(); }
264 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
265 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
269 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
270 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
276 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
282 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
284 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
290 m_provider->GetPrivKey(pos, arg,
out);
292 std::optional<CPubKey> GetRootPubKey()
const override 294 return m_provider->GetRootPubKey();
296 std::optional<CExtPubKey> GetRootExtPubKey()
const override 298 return m_provider->GetRootExtPubKey();
300 std::unique_ptr<PubkeyProvider> Clone()
const override 302 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
307 class ConstPubkeyProvider final :
public PubkeyProvider
316 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
321 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
325 CKeyID keyid = m_pubkey.GetID();
327 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
328 out.pubkeys.emplace(keyid, m_pubkey);
331 bool IsRange()
const override {
return false; }
332 size_t GetSize()
const override {
return m_pubkey.size(); }
333 bool IsBIP32()
const override {
return false; }
334 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
337 std::optional<CKey> key = GetPrivKey(arg);
352 std::optional<CKey> key = GetPrivKey(arg);
354 out.keys.emplace(key->GetPubKey().GetID(), *key);
356 std::optional<CPubKey> GetRootPubKey()
const override 360 std::optional<CExtPubKey> GetRootExtPubKey()
const override 364 std::unique_ptr<PubkeyProvider> Clone()
const override 366 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
377 class BIP32PubkeyProvider final :
public PubkeyProvider
389 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
390 ret.nDepth = m_root_extkey.nDepth;
391 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
392 ret.nChild = m_root_extkey.nChild;
393 ret.chaincode = m_root_extkey.chaincode;
401 if (!GetExtKey(arg, xprv))
return false;
402 for (
auto entry : m_path) {
403 if (!xprv.
Derive(xprv, entry))
return false;
405 last_hardened = xprv;
411 bool IsHardened()
const 413 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
414 for (
auto entry : m_path) {
415 if (entry >> 31)
return true;
421 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) {}
422 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
423 size_t GetSize()
const override {
return 33; }
424 bool IsBIP32()
const override {
return true; }
428 CKeyID keyid = m_root_extkey.pubkey.GetID();
431 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
432 if (m_derive == DeriveType::HARDENED_RANGED) info.
path.push_back(((uint32_t)pos) | 0x80000000L);
440 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
441 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
443 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
444 final_extkey = parent_extkey;
445 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
447 }
else if (IsHardened()) {
450 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
451 parent_extkey = xprv.
Neuter();
452 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
453 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
454 final_extkey = xprv.
Neuter();
456 last_hardened_extkey = lh_xprv.
Neuter();
459 for (
auto entry : m_path) {
460 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
462 final_extkey = parent_extkey;
463 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
464 assert(m_derive != DeriveType::HARDENED_RANGED);
466 if (!der)
return std::nullopt;
473 if (m_derive != DeriveType::HARDENED_RANGED) {
474 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
477 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
479 }
else if (info.
path.size() > 0) {
480 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
484 return final_extkey.
pubkey;
486 std::string
ToString(StringType type,
bool normalized)
const 489 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
493 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
497 std::string
ToString(StringType type=StringType::PUBLIC)
const override 504 if (!GetExtKey(arg, key)) {
511 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
517 if (m_derive == DeriveType::HARDENED_RANGED) {
523 int i = (int)m_path.size() - 1;
524 for (; i >= 0; --i) {
525 if (m_path.at(i) >> 31) {
537 for (;
k <= i; ++
k) {
539 origin.
path.push_back(m_path.at(
k));
543 for (;
k < (int)m_path.size(); ++
k) {
544 end_path.push_back(m_path.at(
k));
547 CKeyID id = m_root_extkey.pubkey.GetID();
548 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
553 if (cache !=
nullptr) {
559 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
569 assert(m_derive == DeriveType::UNHARDENED_RANGED);
577 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
578 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
579 if (m_derive == DeriveType::HARDENED_RANGED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return;
582 std::optional<CPubKey> GetRootPubKey()
const override 586 std::optional<CExtPubKey> GetRootExtPubKey()
const override 588 return m_root_extkey;
590 std::unique_ptr<PubkeyProvider> Clone()
const override 592 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
597 class MuSigPubkeyProvider final :
public PubkeyProvider
601 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
603 const KeyPath m_path;
605 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
606 mutable std::optional<CPubKey> m_aggregate_pubkey;
608 const bool m_ranged_participants;
610 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
615 std::vector<std::unique_ptr<PubkeyProvider>> providers,
619 : PubkeyProvider(exp_index),
620 m_participants(
std::move(providers)),
621 m_path(
std::move(path)),
623 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
625 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
626 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
628 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
629 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
637 if (!m_aggregate_provider && !m_ranged_participants) {
639 std::vector<CPubKey> pubkeys;
640 for (
const auto& prov : m_participants) {
641 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
642 if (!pubkey.has_value()) {
645 pubkeys.push_back(pubkey.value());
647 std::sort(pubkeys.begin(), pubkeys.end());
651 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
654 if (IsRangedDerivation() || !m_path.empty()) {
657 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive,
false);
659 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
664 std::vector<CPubKey> pubkeys;
665 for (
const auto& prov : m_participants) {
666 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
667 if (!pub)
return std::nullopt;
668 pubkeys.emplace_back(*pub);
670 std::sort(pubkeys.begin(), pubkeys.end());
673 if (m_aggregate_provider) {
677 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
678 if (!pub)
return std::nullopt;
680 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
682 if (!
Assume(m_ranged_participants) || !
Assume(m_path.empty()))
return std::nullopt;
685 if (!aggregate_pubkey)
return std::nullopt;
686 pubout = *aggregate_pubkey;
688 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
689 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
690 out.aggregate_pubkeys.emplace(pubout, pubkeys);
693 if (!
Assume(pubout.IsValid()))
return std::nullopt;
696 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
698 size_t GetSize()
const override {
return 32; }
700 std::string
ToString(StringType type=StringType::PUBLIC)
const override 702 std::string
out =
"musig(";
703 for (
size_t i = 0; i < m_participants.size(); ++i) {
704 const auto& pubkey = m_participants.at(i);
706 out += pubkey->ToString(type);
710 if (IsRangedDerivation()) {
717 bool any_privkeys =
false;
719 for (
size_t i = 0; i < m_participants.size(); ++i) {
720 const auto& pubkey = m_participants.at(i);
723 if (pubkey->ToPrivateString(arg, tmp)) {
730 if (IsRangedDerivation()) {
738 for (
size_t i = 0; i < m_participants.size(); ++i) {
739 const auto& pubkey = m_participants.at(i);
742 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
749 if (IsRangedDerivation()) {
760 for (
const auto& prov : m_participants) {
761 prov->GetPrivKey(pos, arg,
out);
770 std::optional<CPubKey> GetRootPubKey()
const override 774 std::optional<CExtPubKey> GetRootExtPubKey()
const override 779 std::unique_ptr<PubkeyProvider> Clone()
const override 781 std::vector<std::unique_ptr<PubkeyProvider>> providers;
782 providers.reserve(m_participants.size());
783 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
784 providers.emplace_back(p->Clone());
786 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
788 bool IsBIP32()
const override 791 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) {
return pubkey->IsBIP32(); });
793 size_t GetKeyCount()
const override 795 return 1 + m_participants.size();
804 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
806 const std::string m_name;
808 std::vector<std::string> m_warnings;
814 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
817 virtual std::string ToStringExtra()
const {
return ""; }
829 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
832 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
833 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))) {}
834 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)) {}
836 enum class StringType
847 for (
const auto& arg : m_subdescriptor_args) {
848 if (!arg->IsSolvable())
return false;
856 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
858 for (
const auto& sub: m_subdescriptor_args) {
859 if (!sub->HavePrivateKeys(arg))
return false;
863 for (
const auto& pubkey : m_pubkey_args) {
864 tmp_provider.
keys.clear();
865 pubkey->GetPrivKey(0, arg, tmp_provider);
866 if (tmp_provider.
keys.empty())
return false;
875 for (
const auto& pubkey : m_pubkey_args) {
876 if (pubkey->IsRange())
return true;
878 for (
const auto& arg : m_subdescriptor_args) {
879 if (arg->IsRange())
return true;
888 bool is_private{type == StringType::PRIVATE};
891 bool any_success{!is_private};
892 for (
const auto& scriptarg : m_subdescriptor_args) {
893 if (pos++)
ret +=
",";
895 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
896 if (!is_private && !subscript_res)
return false;
897 any_success = any_success || subscript_res;
906 std::string extra = ToStringExtra();
907 size_t pos = extra.size() > 0 ? 1 : 0;
908 std::string
ret = m_name +
"(" + extra;
909 bool is_private{type == StringType::PRIVATE};
912 bool any_success{!is_private};
914 for (
const auto& pubkey : m_pubkey_args) {
915 if (pos++)
ret +=
",";
918 case StringType::NORMALIZED:
919 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
921 case StringType::PRIVATE:
922 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
924 case StringType::PUBLIC:
925 tmp = pubkey->ToString();
927 case StringType::COMPAT:
928 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
933 std::string subscript;
934 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
935 if (!is_private && !subscript_res)
return false;
936 any_success = any_success || subscript_res;
937 if (pos && subscript.size())
ret +=
',';
938 out = std::move(
ret) + std::move(subscript) +
")";
942 std::string
ToString(
bool compat_format)
const final 945 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
946 return AddChecksum(
ret);
951 bool has_priv_key{ToStringHelper(&arg,
out, StringType::PRIVATE)};
958 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
967 std::vector<CPubKey> pubkeys;
968 pubkeys.reserve(m_pubkey_args.size());
971 for (
const auto& p : m_pubkey_args) {
972 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
973 if (!pubkey)
return false;
974 pubkeys.push_back(pubkey.value());
976 std::vector<CScript> subscripts;
977 for (
const auto& subarg : m_subdescriptor_args) {
978 std::vector<CScript> outscripts;
979 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
980 assert(outscripts.size() == 1);
981 subscripts.emplace_back(std::move(outscripts[0]));
983 out.Merge(std::move(subprovider));
985 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
991 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
1002 for (
const auto& p : m_pubkey_args) {
1003 p->GetPrivKey(pos, provider,
out);
1005 for (
const auto& arg : m_subdescriptor_args) {
1006 arg->ExpandPrivate(pos, provider,
out);
1010 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
1012 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
1019 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1026 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override 1028 for (
const auto& p : m_pubkey_args) {
1029 std::optional<CPubKey> pub = p->GetRootPubKey();
1030 if (pub) pubkeys.insert(*pub);
1031 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1032 if (ext_pub) ext_pubs.insert(*ext_pub);
1034 for (
const auto& arg : m_subdescriptor_args) {
1035 arg->GetPubKeys(pubkeys, ext_pubs);
1039 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1042 std::vector<std::string>
Warnings()
const override {
1043 std::vector<std::string> all = m_warnings;
1044 for (
const auto& sub : m_subdescriptor_args) {
1045 auto sub_w = sub->Warnings();
1046 all.insert(all.end(), sub_w.begin(), sub_w.end());
1053 uint32_t max_key_expr{0};
1054 std::vector<const DescriptorImpl*> todo = {
this};
1055 while (!todo.empty()) {
1056 const DescriptorImpl* desc = todo.back();
1058 for (
const auto& p : desc->m_pubkey_args) {
1059 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1061 for (
const auto&
s : desc->m_subdescriptor_args) {
1062 todo.push_back(
s.get());
1065 return max_key_expr;
1071 std::vector<const DescriptorImpl*> todo = {
this};
1072 while (!todo.empty()) {
1073 const DescriptorImpl* desc = todo.back();
1075 for (
const auto& p : desc->m_pubkey_args) {
1076 count += p->GetKeyCount();
1078 for (
const auto&
s : desc->m_subdescriptor_args) {
1079 todo.push_back(
s.get());
1087 class AddressDescriptor final :
public DescriptorImpl
1091 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1094 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1095 bool IsSolvable() const final {
return false; }
1101 bool IsSingleType() const final {
return true; }
1102 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1105 std::unique_ptr<DescriptorImpl> Clone()
const override 1107 return std::make_unique<AddressDescriptor>(m_destination);
1112 class RawDescriptor final :
public DescriptorImpl
1116 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1117 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1120 bool IsSolvable() const final {
return false; }
1128 bool IsSingleType() const final {
return true; }
1129 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1131 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1133 std::unique_ptr<DescriptorImpl> Clone()
const override 1135 return std::make_unique<RawDescriptor>(m_script);
1140 class PKDescriptor final :
public DescriptorImpl
1145 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override 1155 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1156 bool IsSingleType() const final {
return true; }
1158 std::optional<int64_t> ScriptSize()
const override {
1159 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1162 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1163 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1164 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1167 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1171 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1173 std::unique_ptr<DescriptorImpl> Clone()
const override 1175 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1180 class PKHDescriptor final :
public DescriptorImpl
1183 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override 1185 CKeyID id = keys[0].GetID();
1189 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1191 bool IsSingleType() const final {
return true; }
1193 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1195 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1196 const auto sig_size = use_max_sig ? 72 : 71;
1197 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1200 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1204 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1206 std::unique_ptr<DescriptorImpl> Clone()
const override 1208 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1213 class WPKHDescriptor final :
public DescriptorImpl
1216 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override 1218 CKeyID id = keys[0].GetID();
1222 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1224 bool IsSingleType() const final {
return true; }
1226 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1228 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1229 const auto sig_size = use_max_sig ? 72 : 71;
1233 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1234 return MaxSatSize(use_max_sig);
1237 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1239 std::unique_ptr<DescriptorImpl> Clone()
const override 1241 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1246 class ComboDescriptor final :
public DescriptorImpl
1249 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override 1251 std::vector<CScript>
ret;
1252 CKeyID id = keys[0].GetID();
1255 if (keys[0].IsCompressed()) {
1258 ret.emplace_back(p2wpkh);
1264 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1265 bool IsSingleType() const final {
return false; }
1266 std::unique_ptr<DescriptorImpl> Clone()
const override 1268 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1273 class MultisigDescriptor final :
public DescriptorImpl
1275 const int m_threshold;
1276 const bool m_sorted;
1278 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1279 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1281 std::vector<CPubKey> sorted_keys(keys);
1282 std::sort(sorted_keys.begin(), sorted_keys.end());
1288 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) {}
1289 bool IsSingleType() const final {
return true; }
1291 std::optional<int64_t> ScriptSize()
const override {
1292 const auto n_keys = m_pubkey_args.size();
1293 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1294 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1298 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1299 const auto sig_size = use_max_sig ? 72 : 71;
1300 return (1 + (1 +
sig_size) * m_threshold);
1303 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1307 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1309 std::unique_ptr<DescriptorImpl> Clone()
const override 1311 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1312 providers.reserve(m_pubkey_args.size());
1313 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) {
return p->Clone(); });
1314 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1319 class MultiADescriptor final :
public DescriptorImpl
1321 const int m_threshold;
1322 const bool m_sorted;
1324 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1325 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1327 std::vector<XOnlyPubKey> xkeys;
1328 xkeys.reserve(keys.size());
1329 for (
const auto& key : keys) xkeys.emplace_back(key);
1330 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1332 for (
size_t i = 1; i < keys.size(); ++i) {
1339 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) {}
1340 bool IsSingleType() const final {
return true; }
1342 std::optional<int64_t> ScriptSize()
const override {
1343 const auto n_keys = m_pubkey_args.size();
1347 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1348 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1351 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1353 std::unique_ptr<DescriptorImpl> Clone()
const override 1355 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1356 providers.reserve(m_pubkey_args.size());
1357 for (
const auto& arg : m_pubkey_args) {
1358 providers.push_back(arg->Clone());
1360 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1365 class SHDescriptor final :
public DescriptorImpl
1368 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override 1371 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1378 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1382 assert(m_subdescriptor_args.size() == 1);
1386 bool IsSingleType() const final {
return true; }
1388 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1390 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1391 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1392 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1396 if (
IsSegwit())
return subscript_weight + *sat_size;
1403 std::optional<int64_t> MaxSatisfactionElems()
const override {
1404 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1408 std::unique_ptr<DescriptorImpl> Clone()
const override 1410 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1415 class WSHDescriptor final :
public DescriptorImpl
1418 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override 1421 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1425 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1427 bool IsSingleType() const final {
return true; }
1429 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1431 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1432 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1433 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1440 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1441 return MaxSatSize(use_max_sig);
1444 std::optional<int64_t> MaxSatisfactionElems()
const override {
1445 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1449 std::unique_ptr<DescriptorImpl> Clone()
const override 1451 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1456 class TRDescriptor final :
public DescriptorImpl
1458 std::vector<int> m_depths;
1460 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override 1463 assert(m_depths.size() == scripts.size());
1464 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1468 assert(keys.size() == 1);
1470 if (!xpk.IsFullyValid())
return {};
1473 out.tr_trees[output] = builder;
1478 if (m_depths.empty()) {
1484 return type != StringType::PRIVATE;
1486 std::vector<bool> path;
1487 bool is_private{type == StringType::PRIVATE};
1490 bool any_success{!is_private};
1492 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1493 if (pos)
ret +=
',';
1494 while ((
int)path.size() <= m_depths[pos]) {
1495 if (path.size())
ret +=
'{';
1496 path.push_back(
false);
1499 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1500 if (!is_private && !subscript_res)
return false;
1501 any_success = any_success || subscript_res;
1503 while (!path.empty() && path.back()) {
1504 if (path.size() > 1)
ret +=
'}';
1507 if (!path.empty()) path.back() =
true;
1512 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1513 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1515 assert(m_subdescriptor_args.size() == m_depths.size());
1518 bool IsSingleType() const final {
return true; }
1520 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1522 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1527 std::optional<int64_t> MaxSatisfactionElems()
const override {
1532 std::unique_ptr<DescriptorImpl> Clone()
const override 1534 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1535 subdescs.reserve(m_subdescriptor_args.size());
1536 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) {
return d->Clone(); });
1537 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1551 const std::vector<CPubKey>& m_keys;
1558 uint160 GetHash160(uint32_t key)
const {
1562 return m_keys[key].GetID();
1568 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1571 return {m_keys[key].begin(), m_keys[key].end()};
1574 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1577 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1578 auto id = GetHash160(key);
1579 return {
id.begin(),
id.end()};
1590 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1592 const DescriptorImpl::StringType m_type;
1597 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1598 DescriptorImpl::StringType type,
1600 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1602 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const 1605 has_priv_key =
false;
1607 case DescriptorImpl::StringType::PUBLIC:
1608 ret = m_pubkeys[key]->ToString();
1610 case DescriptorImpl::StringType::PRIVATE:
1611 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1613 case DescriptorImpl::StringType::NORMALIZED:
1614 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1616 case DescriptorImpl::StringType::COMPAT:
1617 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1624 class MiniscriptDescriptor final :
public DescriptorImpl
1630 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1633 const auto script_ctx{
m_node.GetMsCtx()};
1634 for (
const auto& key : keys) {
1638 provider.
pubkeys.emplace(key.GetID(), key);
1641 return Vector(
m_node.ToScript(ScriptMaker(keys, script_ctx)));
1651 const uint32_t raw =
node.K();
1652 const uint32_t value_part = raw & ~
CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1655 if (is_time_based) {
1656 m_warnings.push_back(
strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1658 m_warnings.push_back(
strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1665 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1668 bool has_priv_key{
false};
1669 auto res =
m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1670 if (res)
out = *res;
1671 if (type == StringType::PRIVATE) {
1673 return has_priv_key;
1675 return res.has_value();
1679 bool IsSolvable()
const override {
return true; }
1680 bool IsSingleType() const final {
return true; }
1682 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1684 std::optional<int64_t> MaxSatSize(
bool)
const override 1687 return m_node.GetWitnessSize();
1690 std::optional<int64_t> MaxSatisfactionElems()
const override 1692 return m_node.GetStackSize();
1695 std::unique_ptr<DescriptorImpl> Clone()
const override 1697 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1698 providers.reserve(m_pubkey_args.size());
1699 for (
const auto& arg : m_pubkey_args) {
1700 providers.push_back(arg->Clone());
1702 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node.Clone());
1707 class RawTRDescriptor final :
public DescriptorImpl
1710 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override 1712 assert(keys.size() == 1);
1714 if (!xpk.IsFullyValid())
return {};
1719 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1721 bool IsSingleType() const final {
return true; }
1723 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1725 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1730 std::optional<int64_t> MaxSatisfactionElems()
const override {
1735 std::unique_ptr<DescriptorImpl> Clone()
const override 1737 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1754 std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1756 bool hardened =
false;
1757 if (elem.size() > 0) {
1758 const char last = elem[elem.size() - 1];
1759 if (last ==
'\'' || last ==
'h') {
1760 elem = elem.first(elem.size() - 1);
1762 apostrophe = last ==
'\'';
1765 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1767 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1768 return std::nullopt;
1769 }
else if (*p > 0x7FFFFFFFUL) {
1770 error =
strprintf(
"Key path value %u is out of range", *p);
1771 return std::nullopt;
1773 has_hardened = has_hardened || hardened;
1775 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1789 [[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)
1792 struct MultipathSubstitutes {
1793 size_t placeholder_index;
1794 std::vector<uint32_t>
values;
1796 std::optional<MultipathSubstitutes> substitutes;
1797 has_hardened =
false;
1799 for (
size_t i = 1; i <
split.size(); ++i) {
1800 const std::span<const char>& elem =
split[i];
1803 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1804 if (!allow_multipath) {
1805 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1809 error =
"Multiple multipath key path specifiers found";
1814 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1815 if (nums.size() < 2) {
1816 error =
"Multipath key path specifiers must have at least two items";
1820 substitutes.emplace();
1821 std::unordered_set<uint32_t> seen_substitutes;
1822 for (
const auto& num : nums) {
1823 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1824 if (!op_num)
return false;
1825 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1827 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1830 substitutes->values.emplace_back(*op_num);
1833 path.emplace_back();
1834 substitutes->placeholder_index = path.size() - 1;
1836 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1837 if (!op_num)
return false;
1838 path.emplace_back(*op_num);
1843 out.emplace_back(std::move(path));
1846 for (uint32_t substitute : substitutes->values) {
1847 KeyPath branch_path = path;
1848 branch_path[substitutes->placeholder_index] = substitute;
1849 out.emplace_back(std::move(branch_path));
1855 [[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1858 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1861 static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1864 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1866 type = DeriveType::UNHARDENED_RANGED;
1867 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1868 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1870 type = DeriveType::HARDENED_RANGED;
1876 std::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)
1878 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1879 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1881 std::string str(
split[0].begin(),
split[0].end());
1882 if (str.size() == 0) {
1883 error =
"No key provided";
1887 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1890 if (
split.size() == 1) {
1894 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1895 error =
"Hybrid public keys are not allowed";
1898 if (pubkey.IsFullyValid()) {
1899 if (permit_uncompressed || pubkey.IsCompressed()) {
1900 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1904 error =
"Uncompressed keys are not allowed";
1907 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1908 unsigned char fullkey[33] = {0x02};
1909 std::copy(
data.begin(),
data.end(), fullkey + 1);
1910 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1911 if (pubkey.IsFullyValid()) {
1912 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1917 error =
strprintf(
"Pubkey '%s' is invalid", str);
1924 out.keys.emplace(pubkey.
GetID(), key);
1925 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1929 error =
"Uncompressed keys are not allowed";
1937 error =
strprintf(
"key '%s' is not valid", str);
1940 std::vector<KeyPath> paths;
1942 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1944 extpubkey = extkey.
Neuter();
1947 for (
auto& path : paths) {
1948 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1958 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1963 std::span<const char> span = sp;
1964 if (
Const(
"musig(", span,
false)) {
1965 if (ctx != ParseScriptContext::P2TR) {
1966 error =
"musig() is only allowed in tr() and rawtr()";
1973 if (
split.size() > 2) {
1974 error =
"Too many ')' in musig() expression";
1977 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
1978 if (!
Func(
"musig", expr)) {
1979 error =
"Invalid musig() expression";
1984 bool any_ranged =
false;
1985 bool all_bip32 =
true;
1986 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
1987 bool any_key_parsed =
false;
1988 size_t max_multipath_len = 0;
1989 while (expr.size()) {
1990 if (any_key_parsed && !
Const(
",", expr)) {
1991 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
1994 auto arg =
Expr(expr);
1995 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
1997 error =
strprintf(
"musig(): %s", error);
2000 any_key_parsed =
true;
2002 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2003 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2005 max_multipath_len = std::max(max_multipath_len,
pk.size());
2007 providers.emplace_back(std::move(
pk));
2009 if (!any_key_parsed) {
2010 error =
"musig(): Must contain key expressions";
2015 DeriveType deriv_type = DeriveType::NON_RANGED;
2016 std::vector<KeyPath> derivation_multipaths;
2019 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2023 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2028 deriv_type = ParseDeriveType(deriv_split, dummy);
2029 if (deriv_type == DeriveType::HARDENED_RANGED) {
2030 error =
"musig(): Cannot have hardened child derivation";
2033 bool has_hardened =
false;
2034 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2035 error =
"musig(): " + error;
2039 error =
"musig(): cannot have hardened derivation steps";
2043 derivation_multipaths.emplace_back();
2048 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2049 for (
auto& multipath_providers : providers) {
2050 if (multipath_providers.size() == 1) {
2051 for (
size_t i = 1; i < length; ++i) {
2052 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2054 }
else if (multipath_providers.size() != length) {
2063 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2064 KeyPath& path = derivation_multipaths.at(path_idx);
2065 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2066 pubs.reserve(providers.size());
2067 for (
auto& vec : providers) {
2068 pubs.emplace_back(std::move(vec.at(vec_idx)));
2070 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2073 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2074 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2076 }
else if (max_multipath_len > 1) {
2077 if (!clone_providers(max_multipath_len)) {
2078 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2081 for (
size_t i = 0; i < max_multipath_len; ++i) {
2083 emplace_final_provider(i, 0);
2085 }
else if (derivation_multipaths.size() > 1) {
2087 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2088 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2091 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2093 emplace_final_provider(i, i);
2097 emplace_final_provider(0, 0);
2103 auto origin_split =
Split(sp,
']');
2104 if (origin_split.size() > 2) {
2105 error =
"Multiple ']' characters found for a single pubkey";
2109 bool apostrophe =
false;
2110 if (origin_split.size() == 1) {
2111 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
2113 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2114 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2115 origin_split[0].empty() ?
']' : origin_split[0][0]);
2118 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2119 if (slash_split[0].size() != 8) {
2120 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2123 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2124 if (!
IsHex(fpr_hex)) {
2125 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2128 auto fpr_bytes =
ParseHex(fpr_hex);
2130 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2131 assert(fpr_bytes.size() == 4);
2132 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
2133 std::vector<KeyPath> path;
2134 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2135 info.
path = path.at(0);
2136 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2137 if (providers.empty())
return {};
2138 ret.reserve(providers.size());
2139 for (
auto& prov : providers) {
2140 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2152 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2155 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2158 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2160 return key_provider;
2166 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2169 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2171 return key_provider;
2179 using Key = uint32_t;
2185 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2187 mutable std::string m_key_parsing_error;
2191 uint32_t& m_expr_index;
2195 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2197 bool KeyCompare(
const Key& a,
const Key& b)
const {
2198 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2202 switch (m_script_ctx) {
2209 std::optional<Key>
FromString(std::span<const char>& in)
const 2212 Key key = m_keys.
size();
2213 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2214 if (
pk.empty())
return {};
2215 m_keys.emplace_back(std::move(
pk));
2219 std::optional<std::string>
ToString(
const Key& key,
bool&)
const 2221 return m_keys.at(key).at(0)->ToString();
2224 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const 2227 Key key = m_keys.size();
2230 std::copy(begin, end, pubkey.
begin());
2231 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2232 m_keys.emplace_back();
2233 m_keys.back().push_back(std::move(pubkey_provider));
2238 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2239 m_keys.emplace_back();
2240 m_keys.back().push_back(std::move(pubkey_provider));
2247 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const 2249 assert(end - begin == 20);
2252 std::copy(begin, end, hash.
begin());
2256 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2257 Key key = m_keys.
size();
2258 m_keys.emplace_back();
2259 m_keys.back().push_back(std::move(pubkey_provider));
2267 return m_script_ctx;
2276 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2277 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2278 auto expr =
Expr(sp);
2279 if (
Func(
"pk", expr)) {
2280 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2281 if (pubkeys.empty()) {
2285 for (
auto& pubkey : pubkeys) {
2286 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2290 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2291 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2292 if (pubkeys.empty()) {
2296 for (
auto& pubkey : pubkeys) {
2297 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2301 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2302 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2303 if (pubkeys.empty()) {
2304 error =
strprintf(
"combo(): %s", error);
2307 for (
auto& pubkey : pubkeys) {
2308 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2311 }
else if (
Func(
"combo", expr)) {
2312 error =
"Can only have combo() at top level";
2315 const bool multi =
Func(
"multi", expr);
2316 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2317 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2318 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2319 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2320 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2321 auto threshold =
Expr(expr);
2323 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2324 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2325 thres = *maybe_thres;
2327 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2330 size_t script_size = 0;
2331 size_t max_providers_len = 0;
2332 while (expr.size()) {
2333 if (!
Const(
",", expr)) {
2334 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2337 auto arg =
Expr(expr);
2338 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2343 script_size += pks.at(0)->GetSize() + 1;
2344 max_providers_len = std::max(max_providers_len, pks.size());
2345 providers.emplace_back(std::move(pks));
2353 }
else if (thres < 1) {
2354 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2356 }
else if (thres > providers.size()) {
2357 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2360 if (ctx == ParseScriptContext::TOP) {
2361 if (providers.size() > 3) {
2362 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2366 if (ctx == ParseScriptContext::P2SH) {
2376 for (
auto& vec : providers) {
2377 if (vec.size() == 1) {
2378 for (
size_t i = 1; i < max_providers_len; ++i) {
2379 vec.emplace_back(vec.at(0)->Clone());
2381 }
else if (vec.size() != max_providers_len) {
2382 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2388 for (
size_t i = 0; i < max_providers_len; ++i) {
2390 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2391 pubs.reserve(providers.size());
2392 for (
auto& pub : providers) {
2393 pubs.emplace_back(std::move(pub.at(i)));
2395 if (multi || sortedmulti) {
2396 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2398 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2402 }
else if (multi || sortedmulti) {
2403 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2405 }
else if (multi_a || sortedmulti_a) {
2406 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2409 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2410 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2411 if (pubkeys.empty()) {
2415 for (
auto& pubkey : pubkeys) {
2416 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2419 }
else if (
Func(
"wpkh", expr)) {
2420 error =
"Can only have wpkh() at top level or inside sh()";
2423 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2424 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2425 if (descs.empty() || expr.size())
return {};
2426 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2427 ret.reserve(descs.size());
2428 for (
auto& desc : descs) {
2429 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2432 }
else if (
Func(
"sh", expr)) {
2433 error =
"Can only have sh() at top level";
2436 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2437 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2438 if (descs.empty() || expr.size())
return {};
2439 for (
auto& desc : descs) {
2440 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2443 }
else if (
Func(
"wsh", expr)) {
2444 error =
"Can only have wsh() at top level or inside sh()";
2447 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2450 error =
"Address is not valid";
2453 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2455 }
else if (
Func(
"addr", expr)) {
2456 error =
"Can only have addr() at top level";
2459 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2460 auto arg =
Expr(expr);
2461 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2462 if (internal_keys.empty()) {
2466 size_t max_providers_len = internal_keys.size();
2467 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2468 std::vector<int> depths;
2470 if (!
Const(
",", expr)) {
2471 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2477 std::vector<bool> branches;
2482 while (
Const(
"{", expr)) {
2483 branches.push_back(
false);
2490 auto sarg =
Expr(expr);
2491 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2492 if (subscripts.back().empty())
return {};
2493 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2494 depths.push_back(branches.size());
2496 while (branches.size() && branches.back()) {
2497 if (!
Const(
"}", expr)) {
2498 error =
strprintf(
"tr(): expected '}' after script expression");
2501 branches.pop_back();
2504 if (branches.size() && !branches.back()) {
2505 if (!
Const(
",", expr)) {
2506 error =
strprintf(
"tr(): expected ',' after script expression");
2509 branches.back() =
true;
2511 }
while (branches.size());
2514 error =
strprintf(
"tr(): expected ')' after script expression");
2522 for (
auto& vec : subscripts) {
2523 if (vec.size() == 1) {
2524 for (
size_t i = 1; i < max_providers_len; ++i) {
2525 vec.emplace_back(vec.at(0)->Clone());
2527 }
else if (vec.size() != max_providers_len) {
2528 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2533 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2534 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2538 while (internal_keys.size() < max_providers_len) {
2539 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2543 for (
size_t i = 0; i < max_providers_len; ++i) {
2545 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2546 this_subs.reserve(subscripts.size());
2547 for (
auto& subs : subscripts) {
2548 this_subs.emplace_back(std::move(subs.at(i)));
2550 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2555 }
else if (
Func(
"tr", expr)) {
2556 error =
"Can only have tr at top level";
2559 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2560 auto arg =
Expr(expr);
2562 error =
strprintf(
"rawtr(): only one key expected.");
2565 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2566 if (output_keys.empty()) {
2567 error =
strprintf(
"rawtr(): %s", error);
2570 for (
auto& pubkey : output_keys) {
2571 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2574 }
else if (
Func(
"rawtr", expr)) {
2575 error =
"Can only have rawtr at top level";
2578 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2579 std::string str(expr.begin(), expr.end());
2581 error =
"Raw script is not hex";
2585 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2587 }
else if (
Func(
"raw", expr)) {
2588 error =
"Can only have raw() at top level";
2594 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2596 if (parser.m_key_parsing_error !=
"") {
2597 error = std::move(parser.m_key_parsing_error);
2601 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2602 error =
"Miniscript expressions can only be used in wsh or tr.";
2605 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2607 const auto* insane_node = &
node.value();
2608 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2609 error = *insane_node->ToString(parser);
2610 if (!insane_node->IsValid()) {
2611 error +=
" is invalid";
2612 }
else if (!
node->IsSane()) {
2613 error +=
" is not sane";
2614 if (!insane_node->IsNonMalleable()) {
2615 error +=
": malleable witnesses exist";
2616 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2617 error +=
": witnesses without signature exist";
2618 }
else if (!insane_node->CheckTimeLocksMix()) {
2619 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2620 }
else if (!insane_node->CheckDuplicateKey()) {
2621 error +=
": contains duplicate public keys";
2622 }
else if (!insane_node->ValidSatisfactions()) {
2623 error +=
": needs witnesses that may exceed resource limits";
2626 error +=
" is not satisfiable";
2635 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2636 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2637 return a.size() < b.size();
2640 for (
auto& vec : parser.m_keys) {
2641 if (vec.size() == 1) {
2642 for (
size_t i = 1; i < num_multipath; ++i) {
2643 vec.emplace_back(vec.at(0)->Clone());
2645 }
else if (vec.size() != num_multipath) {
2646 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2652 for (
size_t i = 0; i < num_multipath; ++i) {
2654 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2655 pubs.reserve(parser.m_keys.size());
2656 for (
auto& pub : parser.m_keys) {
2657 pubs.emplace_back(std::move(pub.at(i)));
2659 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2664 if (ctx == ParseScriptContext::P2SH) {
2665 error =
"A function is needed within P2SH";
2667 }
else if (ctx == ParseScriptContext::P2WSH) {
2668 error =
"A function is needed within P2WSH";
2671 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2678 if (!match)
return {};
2679 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2680 keys.reserve(match->second.size());
2681 for (
const auto keyspan : match->second) {
2682 if (keyspan.size() != 32)
return {};
2683 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
2684 if (!key)
return {};
2685 keys.push_back(std::move(key));
2687 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2695 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
2698 if (ctx == ParseScriptContext::P2TR) {
2699 auto ret = InferMultiA(
script, ctx, provider);
2703 std::vector<std::vector<unsigned char>>
data;
2706 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2708 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2709 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2712 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2716 if (provider.
GetPubKey(keyid, pubkey)) {
2717 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2718 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2726 if (provider.
GetPubKey(keyid, pubkey)) {
2727 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2728 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2732 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2734 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2735 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2737 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2738 providers.push_back(std::move(pubkey_provider));
2744 if (ok)
return std::make_unique<MultisigDescriptor>((int)
data[0][0], std::move(providers));
2750 if (provider.
GetCScript(scriptid, subscript)) {
2751 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2752 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2758 if (provider.
GetCScript(scriptid, subscript)) {
2759 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2760 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2775 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2776 std::vector<int> depths;
2777 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2778 std::unique_ptr<DescriptorImpl> subdesc;
2780 subdesc = InferScript(
CScript(
script.begin(),
script.end()), ParseScriptContext::P2TR, provider);
2786 subscripts.push_back(std::move(subdesc));
2787 depths.push_back(depth);
2791 auto key = InferXOnlyPubkey(tap.internal_key, ParseScriptContext::P2TR, provider);
2792 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2798 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2800 return std::make_unique<RawTRDescriptor>(std::move(key));
2805 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2807 uint32_t key_exp_index = 0;
2808 KeyParser parser(
nullptr, &provider, script_ctx, key_exp_index);
2811 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2812 keys.reserve(parser.m_keys.size());
2813 for (
auto& key : parser.m_keys) {
2814 keys.emplace_back(std::move(key.at(0)));
2816 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(*
node));
2822 if (ctx != ParseScriptContext::TOP)
return nullptr;
2827 return std::make_unique<AddressDescriptor>(std::move(dest));
2831 return std::make_unique<RawDescriptor>(
script);
2838 bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2840 auto check_split =
Split(sp,
'#');
2841 if (check_split.size() > 2) {
2842 error =
"Multiple '#' symbols";
2845 if (check_split.size() == 1 && require_checksum){
2846 error =
"Missing checksum";
2849 if (check_split.size() == 2) {
2850 if (check_split[1].size() != 8) {
2851 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2855 auto checksum = DescriptorChecksum(check_split[0]);
2856 if (checksum.empty()) {
2857 error =
"Invalid characters in payload";
2860 if (check_split.size() == 2) {
2861 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2862 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2866 if (out_checksum) *out_checksum = std::move(checksum);
2867 sp = check_split[0];
2873 std::span<const char> sp{descriptor};
2875 uint32_t key_exp_index = 0;
2877 if (sp.empty() && !
ret.empty()) {
2878 std::vector<std::unique_ptr<Descriptor>> descs;
2879 descs.reserve(
ret.size());
2880 for (
auto& r :
ret) {
2881 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2892 std::span<const char> sp{descriptor};
2899 return InferScript(
script, ParseScriptContext::TOP, provider);
2904 std::string desc_str = desc.
ToString(
true);
2906 CSHA256().
Write((
unsigned char*)desc_str.data(), desc_str.size()).Finalize(
id.begin());
2918 xpubs[der_index] = xpub;
2938 const auto& der_it = key_exp_it->second.find(der_index);
2939 if (der_it == key_exp_it->second.end())
return false;
2940 xpub = der_it->second;
2958 if (xpub != parent_xpub_pair.second) {
2959 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
2967 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2970 if (xpub != derived_xpub_pair.second) {
2971 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
2975 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2976 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2982 if (xpub != lh_xpub_pair.second) {
2983 throw std::runtime_error(std::string(__func__) +
": New cached last hardened xpub does not match already cached last hardened xpub");
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
virtual bool HavePrivateKeys(const SigningProvider &provider) const =0
Whether the given provider has all private keys required by this descriptor.
CSHA256 & Write(const unsigned char *data, size_t len)
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
ExtPubKeyMap m_last_hardened_xpubs
Map key expression index -> last hardened xpub.
static constexpr size_t size()
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.
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
static const int WITNESS_SCALE_FACTOR
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
bool Derive(CExtKey &out, unsigned int nChild) const
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
CPubKey GetPubKey() const
Compute the public key from a private key.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
std::map< CKeyID, CKey > keys
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.
CExtKey DecodeExtKey(const std::string &str)
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
#define CHECK_NONFATAL(condition)
Identity function.
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
bool IsHex(std::string_view str)
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.
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys...
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
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.
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
std::optional< Node< typename Ctx::Key > > FromString(const std::string &str, const Ctx &ctx)
consteval auto _(util::TranslatedLiteral str)
static const int MAX_PUBKEYS_PER_MULTISIG
CExtPubKey DecodeExtPubKey(const std::string &str)
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.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible...
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.
virtual std::vector< std::string > Warnings() const =0
Semantic/safety warnings (includes subdescriptors).
constexpr unsigned char * begin()
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
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.
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
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.
const unsigned char * begin() const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
virtual uint32_t GetMaxKeyExpr() const =0
Get the maximum key expression index.
[n] OP_CHECKSEQUENCEVERIFY
An input of a transaction.
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
const SigningProvider & DUMMY_SIGNING_PROVIDER
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
An encapsulated public key.
std::map< CKeyID, CPubKey > pubkeys
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
bool Derive(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
unsigned int size() const
Simple read-only vector-like interface.
void ForEachNode(const Node< Key > &root, Fn &&fn)
Unordered traversal of a miniscript node tree.
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
static const 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...
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey &pubkey)
Construct the BIP 328 synthetic xpub for a pubkey.
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
CPubKey GetEvenCorrespondingCPubKey() const
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
#define Assume(val)
Assume is the identity function.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
bool IsFullyValid() const
Determine if this pubkey is fully valid.
virtual bool GetKey(const CKeyID &address, CKey &key) const
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
virtual size_t GetKeyCount() const =0
Get the number of key expressions in this descriptor.
CScript ParseScript(const std::string &s)
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...
Utility class to construct Taproot outputs from internal key and script tree.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
bool operator<(const CNetAddr &a, const CNetAddr &b)
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
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...
std::vector< unsigned char > ToByteVector(const T &in)
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.
std::optional< Node< typename Ctx::Key > > FromScript(const CScript &script, const Ctx &ctx)
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 constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
std::string EncodeExtPubKey(const CExtPubKey &key)
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
An interface to be implemented by keystores that support signing.
static const uint32_t SEQUENCE_LOCKTIME_MASK
If CTxIn::nSequence encodes a relative lock-time, this mask is applied to extract that lock-time from...
CExtPubKey Neuter() const
Cache for single descriptor's derived extended pubkeys.
Serialized script, used inside transaction inputs and outputs.
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
A reference to a CKey: the Hash160 of its serialized public key.
std::vector< std::unique_ptr< Descriptor > > Parse(std::string_view descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \)
A reference to a CScript: the Hash160 of its serialization.
std::string EncodeDestination(const CTxDestination &dest)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
An encapsulated private key.
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
A node in a miniscript expression.
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
CKey DecodeSecret(const std::string &str)
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual std::optional< OutputType > GetOutputType() const =0
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
A hasher class for SHA-256.
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
std::string EncodeSecret(const CKey &key)
std::vector< uint32_t > path
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
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 ...
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
std::string EncodeExtKey(const CExtKey &key)
std::unordered_map< uint32_t, ExtPubKeyMap > m_derived_xpubs
Map key expression index -> map of (key derivation index -> xpub)
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Interface for parsed descriptor objects.
#define Assert(val)
Identity function.
bool IsValid() const
Check whether this private key is valid.
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
bool IsCompressed() const
Check whether this is a compressed public key.
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.