90 uint64_t
PolyMod(uint64_t c,
int val)
93 c = ((c & 0x7ffffffff) << 5) ^ val;
94 if (c0 & 1) c ^= 0xf5dee51989;
95 if (c0 & 2) c ^= 0xa9fdca3312;
96 if (c0 & 4) c ^= 0x1bab10e32d;
97 if (c0 & 8) c ^= 0x3706b1677a;
98 if (c0 & 16) c ^= 0x644d626ffd;
117 static std::string INPUT_CHARSET =
118 "0123456789()[],'/*abcdefgh@:$%{}"
119 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
120 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
123 static std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
128 for (
auto ch : span) {
129 auto pos = INPUT_CHARSET.find(ch);
130 if (pos == std::string::npos)
return "";
132 cls = cls * 3 + (pos >> 5);
133 if (++clscount == 3) {
140 if (clscount > 0) c =
PolyMod(c, cls);
141 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
144 std::string
ret(8,
' ');
145 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
149 std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
155 typedef std::vector<uint32_t> KeyPath;
158 struct PubkeyProvider
163 uint32_t m_expr_index;
166 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
168 virtual ~PubkeyProvider() =
default;
173 bool operator<(PubkeyProvider& other)
const {
179 other.GetPubKey(0, dummy, b, dummy_info);
192 virtual bool IsRange()
const = 0;
195 virtual size_t GetSize()
const = 0;
197 enum class StringType {
203 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
217 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
219 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
222 class OriginPubkeyProvider final :
public PubkeyProvider
225 std::unique_ptr<PubkeyProvider> m_provider;
228 std::string OriginString(StringType type,
bool normalized=
false)
const
231 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
236 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) {}
239 if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache))
return false;
240 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.
fingerprint);
241 info.
path.insert(info.
path.begin(), m_origin.path.begin(), m_origin.path.end());
244 bool IsRange()
const override {
return m_provider->IsRange(); }
245 size_t GetSize()
const override {
return m_provider->GetSize(); }
246 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
250 if (!m_provider->ToPrivateString(arg, sub))
return false;
251 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
257 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
263 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
265 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
271 return m_provider->GetPrivKey(pos, arg, key);
273 std::optional<CPubKey> GetRootPubKey()
const override
275 return m_provider->GetRootPubKey();
277 std::optional<CExtPubKey> GetRootExtPubKey()
const override
279 return m_provider->GetRootExtPubKey();
284 class ConstPubkeyProvider final :
public PubkeyProvider
290 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
295 CKeyID keyid = m_pubkey.GetID();
299 bool IsRange()
const override {
return false; }
300 size_t GetSize()
const override {
return m_pubkey.size(); }
301 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
306 for (
const auto& keyid :
XOnlyPubKey(m_pubkey).GetKeyIDs()) {
311 arg.
GetKey(m_pubkey.GetID(), key);
313 if (!key.
IsValid())
return false;
324 return arg.
GetKey(m_pubkey.GetID(), key);
326 std::optional<CPubKey> GetRootPubKey()
const override
330 std::optional<CExtPubKey> GetRootExtPubKey()
const override
336 enum class DeriveType {
343 class BIP32PubkeyProvider final :
public PubkeyProvider
355 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
356 ret.nDepth = m_root_extkey.nDepth;
357 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
358 ret.nChild = m_root_extkey.nChild;
359 ret.chaincode = m_root_extkey.chaincode;
367 if (!GetExtKey(arg, xprv))
return false;
368 for (
auto entry : m_path) {
369 if (!xprv.
Derive(xprv, entry))
return false;
371 last_hardened = xprv;
377 bool IsHardened()
const
379 if (m_derive == DeriveType::HARDENED)
return true;
380 for (
auto entry : m_path) {
381 if (entry >> 31)
return true;
387 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) {}
388 bool IsRange()
const override {
return m_derive != DeriveType::NO; }
389 size_t GetSize()
const override {
return 33; }
394 CKeyID keyid = m_root_extkey.pubkey.GetID();
396 parent_info.
path = m_path;
400 if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.
path.push_back((uint32_t)pos);
401 if (m_derive == DeriveType::HARDENED) final_info_out_tmp.
path.push_back(((uint32_t)pos) | 0x80000000L);
409 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
410 if (m_derive == DeriveType::HARDENED)
return false;
412 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return false;
413 final_extkey = parent_extkey;
414 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
416 }
else if (IsHardened()) {
419 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
420 parent_extkey = xprv.
Neuter();
421 if (m_derive == DeriveType::UNHARDENED) der = xprv.
Derive(xprv, pos);
422 if (m_derive == DeriveType::HARDENED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
423 final_extkey = xprv.
Neuter();
425 last_hardened_extkey = lh_xprv.
Neuter();
428 for (
auto entry : m_path) {
429 if (!parent_extkey.
Derive(parent_extkey, entry))
return false;
431 final_extkey = parent_extkey;
432 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
433 assert(m_derive != DeriveType::HARDENED);
435 if (!der)
return false;
437 final_info_out = final_info_out_tmp;
438 key_out = final_extkey.
pubkey;
442 if (m_derive != DeriveType::HARDENED) {
443 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
446 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
448 }
else if (final_info_out.
path.size() > 0) {
449 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
455 std::string
ToString(StringType type,
bool normalized)
const
458 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
462 if (m_derive == DeriveType::HARDENED)
ret += use_apostrophe ?
'\'' :
'h';
466 std::string
ToString(StringType type=StringType::PUBLIC)
const override
473 if (!GetExtKey(arg, key))
return false;
477 if (m_derive == DeriveType::HARDENED)
out += m_apostrophe ?
'\'' :
'h';
483 if (m_derive == DeriveType::HARDENED) {
489 int i = (int)m_path.size() - 1;
490 for (; i >= 0; --i) {
491 if (m_path.at(i) >> 31) {
503 for (;
k <= i; ++
k) {
505 origin.
path.push_back(m_path.at(
k));
509 for (;
k < (int)m_path.size(); ++
k) {
510 end_path.push_back(m_path.at(
k));
513 CKeyID id = m_root_extkey.pubkey.GetID();
514 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
519 if (cache !=
nullptr) {
525 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
535 assert(m_derive == DeriveType::UNHARDENED);
543 if (!GetDerivedExtKey(arg, extkey, dummy))
return false;
544 if (m_derive == DeriveType::UNHARDENED && !extkey.
Derive(extkey, pos))
return false;
545 if (m_derive == DeriveType::HARDENED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return false;
549 std::optional<CPubKey> GetRootPubKey()
const override
553 std::optional<CExtPubKey> GetRootExtPubKey()
const override
555 return m_root_extkey;
564 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
566 const std::string m_name;
572 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
575 virtual std::string ToStringExtra()
const {
return ""; }
590 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
591 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))) {}
592 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)) {}
594 enum class StringType
605 for (
const auto& arg : m_subdescriptor_args) {
606 if (!arg->IsSolvable())
return false;
614 for (
const auto& pubkey : m_pubkey_args) {
615 if (pubkey->IsRange())
return true;
617 for (
const auto& arg : m_subdescriptor_args) {
618 if (arg->IsRange())
return true;
627 for (
const auto& scriptarg : m_subdescriptor_args) {
628 if (pos++)
ret +=
",";
630 if (!scriptarg->ToStringHelper(arg, tmp, type, cache))
return false;
639 std::string extra = ToStringExtra();
640 size_t pos = extra.size() > 0 ? 1 : 0;
641 std::string
ret = m_name +
"(" + extra;
642 for (
const auto& pubkey : m_pubkey_args) {
643 if (pos++)
ret +=
",";
646 case StringType::NORMALIZED:
647 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
649 case StringType::PRIVATE:
650 if (!pubkey->ToPrivateString(*arg, tmp))
return false;
652 case StringType::PUBLIC:
653 tmp = pubkey->ToString();
655 case StringType::COMPAT:
656 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
661 std::string subscript;
662 if (!ToStringSubScriptHelper(arg, subscript, type, cache))
return false;
663 if (pos && subscript.size())
ret +=
',';
664 out = std::move(
ret) + std::move(subscript) +
")";
668 std::string
ToString(
bool compat_format)
const final
671 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
672 return AddChecksum(
ret);
677 bool ret = ToStringHelper(&arg,
out, StringType::PRIVATE);
684 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
692 std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
693 entries.reserve(m_pubkey_args.size());
696 for (
const auto& p : m_pubkey_args) {
697 entries.emplace_back();
698 if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache))
return false;
700 std::vector<CScript> subscripts;
702 for (
const auto& subarg : m_subdescriptor_args) {
703 std::vector<CScript> outscripts;
704 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
705 assert(outscripts.size() == 1);
706 subscripts.emplace_back(std::move(outscripts[0]));
708 out.Merge(std::move(subprovider));
710 std::vector<CPubKey> pubkeys;
711 pubkeys.reserve(entries.size());
712 for (
auto& entry : entries) {
713 pubkeys.push_back(entry.first);
714 out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(
CPubKey(entry.first), std::move(entry.second)));
717 output_scripts = MakeScripts(pubkeys,
Span{subscripts},
out);
723 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
734 for (
const auto& p : m_pubkey_args) {
736 if (!p->GetPrivKey(pos, provider, key))
continue;
739 for (
const auto& arg : m_subdescriptor_args) {
740 arg->ExpandPrivate(pos, provider,
out);
744 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
746 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
753 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
760 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
762 for (
const auto& p : m_pubkey_args) {
763 std::optional<CPubKey> pub = p->GetRootPubKey();
764 if (pub) pubkeys.insert(*pub);
765 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
766 if (ext_pub) ext_pubs.insert(*ext_pub);
768 for (
const auto& arg : m_subdescriptor_args) {
769 arg->GetPubKeys(pubkeys, ext_pubs);
775 class AddressDescriptor final :
public DescriptorImpl
779 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
782 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
783 bool IsSolvable() const final {
return false; }
789 bool IsSingleType() const final {
return true; }
790 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
796 class RawDescriptor final :
public DescriptorImpl
800 std::string ToStringExtra()
const override {
return HexStr(m_script); }
803 RawDescriptor(
CScript script) : DescriptorImpl({},
"raw"), m_script(std::move(script)) {}
804 bool IsSolvable() const final {
return false; }
812 bool IsSingleType() const final {
return true; }
813 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
815 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
819 class PKDescriptor final :
public DescriptorImpl
828 return Vector(std::move(script));
834 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
835 bool IsSingleType() const final {
return true; }
837 std::optional<int64_t> ScriptSize()
const override {
838 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
841 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
842 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
843 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
846 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
850 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
854 class PKHDescriptor final :
public DescriptorImpl
859 CKeyID id = keys[0].GetID();
860 out.pubkeys.emplace(
id, keys[0]);
864 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
866 bool IsSingleType() const final {
return true; }
868 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
870 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
871 const auto sig_size = use_max_sig ? 72 : 71;
872 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
875 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
879 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
883 class WPKHDescriptor final :
public DescriptorImpl
888 CKeyID id = keys[0].GetID();
889 out.pubkeys.emplace(
id, keys[0]);
893 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
895 bool IsSingleType() const final {
return true; }
897 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
899 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
900 const auto sig_size = use_max_sig ? 72 : 71;
904 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
905 return MaxSatSize(use_max_sig);
908 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
912 class ComboDescriptor final :
public DescriptorImpl
917 std::vector<CScript>
ret;
918 CKeyID id = keys[0].GetID();
919 out.pubkeys.emplace(
id, keys[0]);
922 if (keys[0].IsCompressed()) {
925 ret.emplace_back(p2wpkh);
931 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
932 bool IsSingleType() const final {
return false; }
936 class MultisigDescriptor final :
public DescriptorImpl
938 const int m_threshold;
941 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
944 std::vector<CPubKey> sorted_keys(keys);
945 std::sort(sorted_keys.begin(), sorted_keys.end());
951 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) {}
952 bool IsSingleType() const final {
return true; }
954 std::optional<int64_t> ScriptSize()
const override {
955 const auto n_keys = m_pubkey_args.size();
956 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
957 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
961 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
962 const auto sig_size = use_max_sig ? 72 : 71;
963 return (1 + (1 +
sig_size) * m_threshold);
966 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
970 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
974 class MultiADescriptor final :
public DescriptorImpl
976 const int m_threshold;
979 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
982 std::vector<XOnlyPubKey> xkeys;
983 xkeys.reserve(keys.size());
984 for (
const auto& key : keys) xkeys.emplace_back(key);
985 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
987 for (
size_t i = 1; i < keys.size(); ++i) {
994 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) {}
995 bool IsSingleType() const final {
return true; }
997 std::optional<int64_t> ScriptSize()
const override {
998 const auto n_keys = m_pubkey_args.size();
1002 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1003 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1006 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1010 class SHDescriptor final :
public DescriptorImpl
1016 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1023 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1027 assert(m_subdescriptor_args.size() == 1);
1031 bool IsSingleType() const final {
return true; }
1033 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1035 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1036 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1037 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1041 if (
IsSegwit())
return subscript_weight + *sat_size;
1048 std::optional<int64_t> MaxSatisfactionElems()
const override {
1049 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1055 class WSHDescriptor final :
public DescriptorImpl
1061 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1065 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1067 bool IsSingleType() const final {
return true; }
1069 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1071 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1072 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1073 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1080 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1081 return MaxSatSize(use_max_sig);
1084 std::optional<int64_t> MaxSatisfactionElems()
const override {
1085 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1091 class TRDescriptor final :
public DescriptorImpl
1093 std::vector<int> m_depths;
1099 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1103 assert(keys.size() == 1);
1105 if (!xpk.IsFullyValid())
return {};
1108 out.tr_trees[output] = builder;
1109 out.pubkeys.emplace(keys[0].GetID(), keys[0]);
1114 if (m_depths.empty())
return true;
1115 std::vector<bool> path;
1116 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1117 if (pos)
ret +=
',';
1118 while ((
int)path.size() <= m_depths[pos]) {
1119 if (path.size())
ret +=
'{';
1120 path.push_back(
false);
1123 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache))
return false;
1125 while (!path.empty() && path.back()) {
1126 if (path.size() > 1)
ret +=
'}';
1129 if (!path.empty()) path.back() =
true;
1134 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1135 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1137 assert(m_subdescriptor_args.size() == m_depths.size());
1140 bool IsSingleType() const final {
return true; }
1142 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1144 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1149 std::optional<int64_t> MaxSatisfactionElems()
const override {
1165 const std::vector<CPubKey>& m_keys;
1172 uint160 GetHash160(uint32_t key)
const {
1176 return m_keys[key].GetID();
1182 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1185 return {m_keys[key].begin(), m_keys[key].end()};
1188 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1191 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1192 auto id = GetHash160(key);
1193 return {
id.begin(),
id.end()};
1204 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1210 : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {}
1212 std::optional<std::string>
ToString(uint32_t key)
const
1216 if (!m_pubkeys[key]->ToPrivateString(*m_arg,
ret))
return {};
1218 ret = m_pubkeys[key]->ToString();
1224 class MiniscriptDescriptor final :
public DescriptorImpl
1230 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys,
Span<const CScript> scripts,
1233 const auto script_ctx{
m_node->GetMsCtx()};
1234 for (
const auto& key : keys) {
1238 provider.
pubkeys.emplace(key.GetID(), key);
1241 return Vector(
m_node->ToScript(ScriptMaker(keys, script_ctx)));
1248 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1251 if (
const auto res =
m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) {
1258 bool IsSolvable()
const override {
return true; }
1259 bool IsSingleType() const final {
return true; }
1261 std::optional<int64_t> ScriptSize()
const override {
return m_node->ScriptSize(); }
1263 std::optional<int64_t> MaxSatSize(
bool)
const override {
1265 return m_node->GetWitnessSize();
1268 std::optional<int64_t> MaxSatisfactionElems()
const override {
1269 return m_node->GetStackSize();
1274 class RawTRDescriptor final :
public DescriptorImpl
1279 assert(keys.size() == 1);
1281 if (!xpk.IsFullyValid())
return {};
1286 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1288 bool IsSingleType() const final {
return true; }
1290 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1292 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1297 std::optional<int64_t> MaxSatisfactionElems()
const override {
1307 enum class ParseScriptContext {
1324 [[nodiscard]]
bool ParseKeyPath(
const std::vector<
Span<const char>>&
split, KeyPath&
out,
bool& apostrophe, std::string& error)
1326 for (
size_t i = 1; i <
split.size(); ++i) {
1328 bool hardened =
false;
1329 if (elem.
size() > 0) {
1330 const char last = elem[elem.
size() - 1];
1331 if (last ==
'\'' || last ==
'h') {
1334 apostrophe = last ==
'\'';
1339 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string(elem.
begin(), elem.
end()));
1341 }
else if (p > 0x7FFFFFFFUL) {
1342 error =
strprintf(
"Key path value %u is out of range", p);
1345 out.push_back(p | (((uint32_t)hardened) << 31));
1351 std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index,
const Span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out,
bool& apostrophe, std::string& error)
1355 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1357 std::string str(
split[0].begin(),
split[0].end());
1358 if (str.size() == 0) {
1359 error =
"No key provided";
1362 if (
split.size() == 1) {
1364 std::vector<unsigned char> data =
ParseHex(str);
1366 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1367 error =
"Hybrid public keys are not allowed";
1370 if (pubkey.IsFullyValid()) {
1371 if (permit_uncompressed || pubkey.IsCompressed()) {
1372 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false);
1374 error =
"Uncompressed keys are not allowed";
1377 }
else if (data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1378 unsigned char fullkey[33] = {0x02};
1379 std::copy(data.begin(), data.end(), fullkey + 1);
1380 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1381 if (pubkey.IsFullyValid()) {
1382 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true);
1385 error =
strprintf(
"Pubkey '%s' is invalid", str);
1392 out.keys.emplace(pubkey.
GetID(), key);
1393 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR);
1395 error =
"Uncompressed keys are not allowed";
1403 error =
strprintf(
"key '%s' is not valid", str);
1407 DeriveType type = DeriveType::NO;
1410 type = DeriveType::UNHARDENED;
1414 type = DeriveType::HARDENED;
1416 if (!ParseKeyPath(
split, path, apostrophe, error))
return nullptr;
1418 extpubkey = extkey.
Neuter();
1421 return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe);
1429 auto origin_split =
Split(sp,
']');
1430 if (origin_split.size() > 2) {
1431 error =
"Multiple ']' characters found for a single pubkey";
1435 bool apostrophe =
false;
1436 if (origin_split.size() == 1) {
1437 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
1439 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
1440 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
1441 origin_split[0].empty() ?
']' : origin_split[0][0]);
1444 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
1445 if (slash_split[0].size() != 8) {
1446 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1449 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1450 if (!
IsHex(fpr_hex)) {
1451 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
1454 auto fpr_bytes =
ParseHex(fpr_hex);
1456 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
1457 assert(fpr_bytes.size() == 4);
1458 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
1459 if (!ParseKeyPath(slash_split, info.
path, apostrophe, error))
return nullptr;
1460 auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
1461 if (!provider)
return nullptr;
1462 return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider), apostrophe);
1465 std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
1472 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
1475 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
1478 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
1480 return key_provider;
1483 std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
1486 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
1489 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
1491 return key_provider;
1499 using Key = uint32_t;
1505 mutable std::vector<std::unique_ptr<PubkeyProvider>> m_keys;
1507 mutable std::string m_key_parsing_error;
1515 : m_out(
out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
1517 bool KeyCompare(
const Key& a,
const Key& b)
const {
1518 return *m_keys.at(a) < *m_keys.at(b);
1522 switch (m_script_ctx) {
1529 template<
typename I> std::optional<Key>
FromString(I begin, I end)
const
1532 Key key = m_keys.
size();
1533 auto pk = ParsePubkey(m_offset + key, {&*begin, &*end},
ParseContext(), *m_out, m_key_parsing_error);
1535 m_keys.push_back(std::move(
pk));
1539 std::optional<std::string>
ToString(
const Key& key)
const
1541 return m_keys.at(key)->ToString();
1544 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
1547 Key key = m_keys.size();
1550 std::copy(begin, end, pubkey.
begin());
1552 m_keys.push_back(std::move(pubkey_provider));
1557 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
1558 m_keys.push_back(std::move(pubkey_provider));
1565 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
1567 assert(end - begin == 20);
1570 std::copy(begin, end, hash.
begin());
1574 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
1575 Key key = m_keys.
size();
1576 m_keys.push_back(std::move(pubkey_provider));
1584 return m_script_ctx;
1594 auto expr =
Expr(sp);
1595 if (
Func(
"pk", expr)) {
1596 auto pubkey = ParsePubkey(key_exp_index, expr, ctx,
out, error);
1602 return std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR);
1604 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
1605 auto pubkey = ParsePubkey(key_exp_index, expr, ctx,
out, error);
1611 return std::make_unique<PKHDescriptor>(std::move(pubkey));
1612 }
else if (ctx != ParseScriptContext::P2TR &&
Func(
"pkh", expr)) {
1614 error =
"Can only have pkh at top level, in sh(), wsh(), or in tr()";
1617 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
1618 auto pubkey = ParsePubkey(key_exp_index, expr, ctx,
out, error);
1620 error =
strprintf(
"combo(): %s", error);
1624 return std::make_unique<ComboDescriptor>(std::move(pubkey));
1625 }
else if (
Func(
"combo", expr)) {
1626 error =
"Can only have combo() at top level";
1629 const bool multi =
Func(
"multi", expr);
1630 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
1631 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
1632 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
1633 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
1634 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
1635 auto threshold =
Expr(expr);
1637 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1638 if (!
ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
1639 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
1642 size_t script_size = 0;
1643 while (expr.size()) {
1644 if (!
Const(
",", expr)) {
1645 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
1648 auto arg =
Expr(expr);
1649 auto pk = ParsePubkey(key_exp_index, arg, ctx,
out, error);
1654 script_size +=
pk->GetSize() + 1;
1655 providers.emplace_back(std::move(
pk));
1664 }
else if (thres < 1) {
1665 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
1667 }
else if (thres > providers.size()) {
1668 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
1671 if (ctx == ParseScriptContext::TOP) {
1672 if (providers.size() > 3) {
1673 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
1677 if (ctx == ParseScriptContext::P2SH) {
1684 if (multi || sortedmulti) {
1685 return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sortedmulti);
1687 return std::make_unique<MultiADescriptor>(thres, std::move(providers), sortedmulti_a);
1689 }
else if (multi || sortedmulti) {
1690 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
1692 }
else if (multi_a || sortedmulti_a) {
1693 error =
"Can only have multi_a/sortedmulti_a inside tr()";
1696 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
1697 auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
1703 return std::make_unique<WPKHDescriptor>(std::move(pubkey));
1704 }
else if (
Func(
"wpkh", expr)) {
1705 error =
"Can only have wpkh() at top level or inside sh()";
1708 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
1709 auto desc =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
1710 if (!desc || expr.size())
return nullptr;
1711 return std::make_unique<SHDescriptor>(std::move(desc));
1712 }
else if (
Func(
"sh", expr)) {
1713 error =
"Can only have sh() at top level";
1716 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
1717 auto desc =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
1718 if (!desc || expr.size())
return nullptr;
1719 return std::make_unique<WSHDescriptor>(std::move(desc));
1720 }
else if (
Func(
"wsh", expr)) {
1721 error =
"Can only have wsh() at top level or inside sh()";
1724 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
1727 error =
"Address is not valid";
1730 return std::make_unique<AddressDescriptor>(std::move(dest));
1731 }
else if (
Func(
"addr", expr)) {
1732 error =
"Can only have addr() at top level";
1735 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
1736 auto arg =
Expr(expr);
1737 auto internal_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
1738 if (!internal_key) {
1743 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1744 std::vector<int> depths;
1746 if (!
Const(
",", expr)) {
1747 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
1753 std::vector<bool> branches;
1758 while (
Const(
"{", expr)) {
1759 branches.push_back(
false);
1766 auto sarg =
Expr(expr);
1767 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
1768 if (!subscripts.back())
return nullptr;
1769 depths.push_back(branches.size());
1771 while (branches.size() && branches.back()) {
1772 if (!
Const(
"}", expr)) {
1773 error =
strprintf(
"tr(): expected '}' after script expression");
1776 branches.pop_back();
1779 if (branches.size() && !branches.back()) {
1780 if (!
Const(
",", expr)) {
1781 error =
strprintf(
"tr(): expected ',' after script expression");
1784 branches.back() =
true;
1786 }
while (branches.size());
1789 error =
strprintf(
"tr(): expected ')' after script expression");
1794 return std::make_unique<TRDescriptor>(std::move(internal_key), std::move(subscripts), std::move(depths));
1795 }
else if (
Func(
"tr", expr)) {
1796 error =
"Can only have tr at top level";
1799 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
1800 auto arg =
Expr(expr);
1802 error =
strprintf(
"rawtr(): only one key expected.");
1805 auto output_key = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
1806 if (!output_key)
return nullptr;
1808 return std::make_unique<RawTRDescriptor>(std::move(output_key));
1809 }
else if (
Func(
"rawtr", expr)) {
1810 error =
"Can only have rawtr at top level";
1813 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
1814 std::string str(expr.begin(), expr.end());
1816 error =
"Raw script is not hex";
1820 return std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end()));
1821 }
else if (
Func(
"raw", expr)) {
1822 error =
"Can only have raw() at top level";
1828 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
1830 if (parser.m_key_parsing_error !=
"") {
1831 error = std::move(parser.m_key_parsing_error);
1835 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
1836 error =
"Miniscript expressions can only be used in wsh or tr.";
1839 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
1841 auto insane_node =
node.get();
1842 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
1843 if (
const auto str = insane_node->ToString(parser)) error = *str;
1844 if (!insane_node->IsValid()) {
1845 error +=
" is invalid";
1846 }
else if (!
node->IsSane()) {
1847 error +=
" is not sane";
1848 if (!insane_node->IsNonMalleable()) {
1849 error +=
": malleable witnesses exist";
1850 }
else if (insane_node ==
node.get() && !insane_node->NeedsSignature()) {
1851 error +=
": witnesses without signature exist";
1852 }
else if (!insane_node->CheckTimeLocksMix()) {
1853 error +=
": contains mixes of timelocks expressed in blocks and seconds";
1854 }
else if (!insane_node->CheckDuplicateKey()) {
1855 error +=
": contains duplicate public keys";
1856 }
else if (!insane_node->ValidSatisfactions()) {
1857 error +=
": needs witnesses that may exceed resource limits";
1860 error +=
" is not satisfiable";
1867 key_exp_index += parser.m_keys.size();
1868 return std::make_unique<MiniscriptDescriptor>(std::move(parser.m_keys), std::move(
node));
1871 if (ctx == ParseScriptContext::P2SH) {
1872 error =
"A function is needed within P2SH";
1874 }
else if (ctx == ParseScriptContext::P2WSH) {
1875 error =
"A function is needed within P2WSH";
1878 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
1882 std::unique_ptr<DescriptorImpl> InferMultiA(
const CScript& script, ParseScriptContext ctx,
const SigningProvider& provider)
1885 if (!match)
return {};
1886 std::vector<std::unique_ptr<PubkeyProvider>> keys;
1887 keys.reserve(match->second.size());
1888 for (
const auto keyspan : match->second) {
1889 if (keyspan.size() != 32)
return {};
1890 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
1891 if (!key)
return {};
1892 keys.push_back(std::move(key));
1894 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
1898 std::unique_ptr<DescriptorImpl> InferScript(
const CScript& script, ParseScriptContext ctx,
const SigningProvider& provider)
1900 if (ctx == ParseScriptContext::P2TR && script.
size() == 34 && script[0] == 32 && script[33] ==
OP_CHECKSIG) {
1902 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
1905 if (ctx == ParseScriptContext::P2TR) {
1906 auto ret = InferMultiA(script, ctx, provider);
1910 std::vector<std::vector<unsigned char>> data;
1913 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1915 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1916 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
1919 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1923 if (provider.
GetPubKey(keyid, pubkey)) {
1924 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1925 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
1933 if (provider.
GetPubKey(keyid, pubkey)) {
1934 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
1935 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
1939 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
1941 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1942 for (
size_t i = 1; i + 1 < data.size(); ++i) {
1944 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
1945 providers.push_back(std::move(pubkey_provider));
1951 if (ok)
return std::make_unique<MultisigDescriptor>((
int)data[0][0], std::move(providers));
1957 if (provider.
GetCScript(scriptid, subscript)) {
1958 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
1959 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
1965 if (provider.
GetCScript(scriptid, subscript)) {
1966 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
1967 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
1973 std::copy(data[0].begin(), data[0].end(), pubkey.
begin());
1982 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
1983 std::vector<int> depths;
1984 for (
const auto& [depth, script, leaf_ver] : *tree) {
1985 std::unique_ptr<DescriptorImpl> subdesc;
1987 subdesc = InferScript(
CScript(script.
begin(), script.
end()), ParseScriptContext::P2TR, provider);
1993 subscripts.push_back(std::move(subdesc));
1994 depths.push_back(depth);
1998 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
1999 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2005 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2007 return std::make_unique<RawTRDescriptor>(std::move(key));
2012 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2014 KeyParser parser(
nullptr, &provider, script_ctx);
2017 return std::make_unique<MiniscriptDescriptor>(std::move(parser.m_keys), std::move(
node));
2023 if (ctx != ParseScriptContext::TOP)
return nullptr;
2028 return std::make_unique<AddressDescriptor>(std::move(dest));
2032 return std::make_unique<RawDescriptor>(script);
2043 auto check_split =
Split(sp,
'#');
2044 if (check_split.size() > 2) {
2045 error =
"Multiple '#' symbols";
2048 if (check_split.size() == 1 && require_checksum){
2049 error =
"Missing checksum";
2052 if (check_split.size() == 2) {
2053 if (check_split[1].size() != 8) {
2054 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2058 auto checksum = DescriptorChecksum(check_split[0]);
2059 if (checksum.empty()) {
2060 error =
"Invalid characters in payload";
2063 if (check_split.size() == 2) {
2064 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2065 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2069 if (out_checksum) *out_checksum = std::move(checksum);
2070 sp = check_split[0];
2077 if (!
CheckChecksum(sp, require_checksum, error))
return nullptr;
2078 uint32_t key_exp_index = 0;
2080 if (sp.
size() == 0 &&
ret)
return std::unique_ptr<Descriptor>(std::move(
ret));
2095 return InferScript(script, ParseScriptContext::TOP, provider);
2100 std::string desc_str = desc.
ToString(
true);
2114 xpubs[der_index] = xpub;
2134 const auto& der_it = key_exp_it->second.find(der_index);
2135 if (der_it == key_exp_it->second.end())
return false;
2136 xpub = der_it->second;
2154 if (xpub != parent_xpub_pair.second) {
2155 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
2163 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2166 if (xpub != derived_xpub_pair.second) {
2167 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
2171 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2172 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2178 if (xpub != lh_xpub_pair.second) {
2179 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, 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.
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
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
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
constexpr C * end() const noexcept
constexpr C * begin() const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
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.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Add(int depth, Span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
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()
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(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
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)
std::shared_ptr< const Node< Key > > NodeRef
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
Span< const char > Expr(Span< const char > &sp)
Extract the expression that sp begins with.
bool Const(const std::string &str, Span< const char > &sp)
Parse a constant.
bool Func(const std::string &str, Span< const char > &sp)
Parse a function call.
std::vector< T > Split(const Span< const char > &sp, std::string_view separators)
Split a string on any char found in separators, returning a vector.
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
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.
bool CheckChecksum(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.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
std::vector< unsigned char > ToByteVector(const T &in)
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
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)
const SigningProvider & DUMMY_SIGNING_PROVIDER
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.
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.
std::optional< std::pair< int, std::vector< Span< const unsigned char > > > > MatchMultiA(const CScript &script)
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
bool Derive(CExtPubKey &out, unsigned int nChild) 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 std::optional< OutputType > GetOutputType() const =0
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 > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
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::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
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 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 bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
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.
std::map< CKeyID, CPubKey > pubkeys
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.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
bool IsHex(std::string_view str)
bool ParseUInt32(std::string_view str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.