94uint64_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;
106std::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];
153std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
159typedef std::vector<uint32_t> KeyPath;
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; }
236class 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);
307class 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);
370enum class DeriveType {
377class 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);
597class 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;
607 const DeriveType m_derive;
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);
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;
1068 size_t GetKeyCount() const final
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());
1087class 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);
1112class 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);
1140class 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);
1180class 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());
1213class 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());
1246class 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());
1273class 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(), providers.begin(), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1314 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1319class 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);
1365class 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());
1415class 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());
1456class 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(), subdescs.begin(), [](
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);
1624class 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;
1653 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1654 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
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());
1707class 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());
1745enum class ParseScriptContext {
1754std::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);
1861static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1863 DeriveType type = DeriveType::NON_RANGED;
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;
1876std::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;
1941 DeriveType type = ParseDeriveType(
split, apostrophe);
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));
1956std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
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));
2145std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
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;
2163std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& 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;
2273std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
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);
2838bool 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);
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");
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)
#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.
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.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) 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 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.
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
static 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.
bool operator<(const CNetAddr &a, const CNetAddr &b)
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
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
static const int MAX_PUBKEYS_PER_MULTISIG
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 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, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
unsigned char fingerprint[4]
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.
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.