Changeset View
Changeset View
Standalone View
Standalone View
src/script/descriptor.cpp
// Copyright (c) 2018 The Bitcoin Core developers | // Copyright (c) 2018 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <script/descriptor.h> | #include <script/descriptor.h> | ||||
#include <chainparams.h> // For Params() | #include <chainparams.h> // For Params() | ||||
#include <config.h> | #include <config.h> | ||||
#include <key_io.h> | #include <key_io.h> | ||||
#include <pubkey.h> | #include <pubkey.h> | ||||
#include <script/script.h> | #include <script/script.h> | ||||
#include <script/standard.h> | #include <script/standard.h> | ||||
#include <span.h> | #include <span.h> | ||||
#include <util/bip32.h> | |||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <memory> | #include <memory> | ||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
namespace { | namespace { | ||||
//////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////// | ||||
// Internal representation // | // Internal representation // | ||||
//////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////// | ||||
typedef std::vector<uint32_t> KeyPath; | typedef std::vector<uint32_t> KeyPath; | ||||
std::string FormatKeyPath(const KeyPath &path) { | |||||
std::string ret; | |||||
for (auto i : path) { | |||||
ret += strprintf("/%i", (i << 1) >> 1); | |||||
if (i >> 31) { | |||||
ret += '\''; | |||||
} | |||||
} | |||||
return ret; | |||||
} | |||||
/** Interface for public key objects in descriptors. */ | /** Interface for public key objects in descriptors. */ | ||||
struct PubkeyProvider { | struct PubkeyProvider { | ||||
virtual ~PubkeyProvider() = default; | virtual ~PubkeyProvider() = default; | ||||
/** Derive a public key. If key==nullptr, only info is desired. */ | /** Derive a public key. If key==nullptr, only info is desired. */ | ||||
virtual bool GetPubKey(int pos, const SigningProvider &arg, CPubKey *key, | virtual bool GetPubKey(int pos, const SigningProvider &arg, CPubKey *key, | ||||
KeyOriginInfo &info) const = 0; | KeyOriginInfo &info) const = 0; | ||||
Show All 16 Lines | |||||
class OriginPubkeyProvider final : public PubkeyProvider { | class OriginPubkeyProvider final : public PubkeyProvider { | ||||
KeyOriginInfo m_origin; | KeyOriginInfo m_origin; | ||||
std::unique_ptr<PubkeyProvider> m_provider; | std::unique_ptr<PubkeyProvider> m_provider; | ||||
std::string OriginString() const { | std::string OriginString() const { | ||||
return HexStr(std::begin(m_origin.fingerprint), | return HexStr(std::begin(m_origin.fingerprint), | ||||
std::end(m_origin.fingerprint)) + | std::end(m_origin.fingerprint)) + | ||||
FormatKeyPath(m_origin.path); | FormatHDKeypath(m_origin.path); | ||||
} | } | ||||
public: | public: | ||||
OriginPubkeyProvider(KeyOriginInfo info, | OriginPubkeyProvider(KeyOriginInfo info, | ||||
std::unique_ptr<PubkeyProvider> provider) | std::unique_ptr<PubkeyProvider> provider) | ||||
: m_origin(std::move(info)), m_provider(std::move(provider)) {} | : m_origin(std::move(info)), m_provider(std::move(provider)) {} | ||||
bool GetPubKey(int pos, const SigningProvider &arg, CPubKey *key, | bool GetPubKey(int pos, const SigningProvider &arg, CPubKey *key, | ||||
KeyOriginInfo &info) const override { | KeyOriginInfo &info) const override { | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | bool GetPubKey(int pos, const SigningProvider &arg, CPubKey *key, | ||||
info.path.push_back(uint32_t(pos)); | info.path.push_back(uint32_t(pos)); | ||||
} | } | ||||
if (m_derive == DeriveType::HARDENED) { | if (m_derive == DeriveType::HARDENED) { | ||||
info.path.push_back(uint32_t(pos) | 0x80000000L); | info.path.push_back(uint32_t(pos) | 0x80000000L); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
std::string ToString() const override { | std::string ToString() const override { | ||||
std::string ret = EncodeExtPubKey(m_extkey) + FormatKeyPath(m_path); | std::string ret = EncodeExtPubKey(m_extkey) + FormatHDKeypath(m_path); | ||||
if (IsRange()) { | if (IsRange()) { | ||||
ret += "/*"; | ret += "/*"; | ||||
if (m_derive == DeriveType::HARDENED) { | if (m_derive == DeriveType::HARDENED) { | ||||
ret += '\''; | ret += '\''; | ||||
} | } | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
bool ToPrivateString(const SigningProvider &arg, | bool ToPrivateString(const SigningProvider &arg, | ||||
std::string &out) const override { | std::string &out) const override { | ||||
CExtKey key; | CExtKey key; | ||||
if (!GetExtKey(arg, key)) { | if (!GetExtKey(arg, key)) { | ||||
return false; | return false; | ||||
} | } | ||||
out = EncodeExtKey(key) + FormatKeyPath(m_path); | out = EncodeExtKey(key) + FormatHDKeypath(m_path); | ||||
if (IsRange()) { | if (IsRange()) { | ||||
out += "/*"; | out += "/*"; | ||||
if (m_derive == DeriveType::HARDENED) { | if (m_derive == DeriveType::HARDENED) { | ||||
out += '\''; | out += '\''; | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 686 Lines • Show Last 20 Lines |