Add WriteHDKeypath function and move *HDKeypath to util/bip32.{h,cpp}

Creates new files util/bip32.h and util/bip32.cpp for containing
BIP 32 stuff.
Moves FormatKeyPath from descriptor.cpp to util/bip32.
Adds a wrapper around it to prepent the 'm' for when just the
BIP 32 style keypath is needed.
This commit is contained in:
Andrew Chow 2018-11-06 09:23:43 -05:00
parent c45415f73a
commit e7652d3f64
10 changed files with 95 additions and 57 deletions

View file

@ -196,6 +196,7 @@ BITCOIN_CORE_H = \
txmempool.h \
ui_interface.h \
undo.h \
util/bip32.h \
util/bytevectorhash.h \
util/system.h \
util/memory.h \
@ -456,6 +457,7 @@ libbitcoin_util_a_SOURCES = \
support/cleanse.cpp \
sync.cpp \
threadinterrupt.cpp \
util/bip32.cpp \
util/bytevectorhash.cpp \
util/system.cpp \
util/moneystr.cpp \

View file

@ -26,6 +26,7 @@
#include <script/sign.h>
#include <script/standard.h>
#include <uint256.h>
#include <util/bip32.h>
#include <util/strencodings.h>
#include <validation.h>
#include <validationinterface.h>

View file

@ -10,6 +10,7 @@
#include <script/standard.h>
#include <span.h>
#include <util/bip32.h>
#include <util/system.h>
#include <util/strencodings.h>
@ -25,16 +26,6 @@ namespace {
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. */
struct PubkeyProvider
{
@ -63,7 +54,7 @@ class OriginPubkeyProvider final : public PubkeyProvider
std::string OriginString() const
{
return HexStr(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint)) + FormatKeyPath(m_origin.path);
return HexStr(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint)) + FormatHDKeypath(m_origin.path);
}
public:
@ -184,7 +175,7 @@ public:
}
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()) {
ret += "/*";
if (m_derive == DeriveType::HARDENED) ret += '\'';
@ -195,7 +186,7 @@ public:
{
CExtKey key;
if (!GetExtKey(arg, key)) return false;
out = EncodeExtKey(key) + FormatKeyPath(m_path);
out = EncodeExtKey(key) + FormatHDKeypath(m_path);
if (IsRange()) {
out += "/*";
if (m_derive == DeriveType::HARDENED) out += '\'';

66
src/util/bip32.cpp Normal file
View file

@ -0,0 +1,66 @@
// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <sstream>
#include <stdio.h>
#include <tinyformat.h>
#include <util/bip32.h>
#include <util/strencodings.h>
bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath)
{
std::stringstream ss(keypath_str);
std::string item;
bool first = true;
while (std::getline(ss, item, '/')) {
if (item.compare("m") == 0) {
if (first) {
first = false;
continue;
}
return false;
}
// Finds whether it is hardened
uint32_t path = 0;
size_t pos = item.find("'");
if (pos != std::string::npos) {
// The hardened tick can only be in the last index of the string
if (pos != item.size() - 1) {
return false;
}
path |= 0x80000000;
item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick
}
// Ensure this is only numbers
if (item.find_first_not_of( "0123456789" ) != std::string::npos) {
return false;
}
uint32_t number;
if (!ParseUInt32(item, &number)) {
return false;
}
path |= number;
keypath.push_back(path);
first = false;
}
return true;
}
std::string FormatHDKeypath(const std::vector<uint32_t>& path)
{
std::string ret;
for (auto i : path) {
ret += strprintf("/%i", (i << 1) >> 1);
if (i >> 31) ret += '\'';
}
return ret;
}
std::string WriteHDKeypath(const std::vector<uint32_t>& keypath)
{
return "m" + FormatHDKeypath(keypath);
}

19
src/util/bip32.h Normal file
View file

@ -0,0 +1,19 @@
// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UTIL_BIP32_H
#define BITCOIN_UTIL_BIP32_H
#include <attributes.h>
#include <string>
#include <vector>
/** Parse an HD keypaths like "m/7/0'/2000". */
NODISCARD bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
/** Write HD keypaths as strings */
std::string WriteHDKeypath(const std::vector<uint32_t>& keypath);
std::string FormatHDKeypath(const std::vector<uint32_t>& path);
#endif // BITCOIN_UTIL_BIP32_H

View file

@ -546,47 +546,6 @@ bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
return true;
}
bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath)
{
std::stringstream ss(keypath_str);
std::string item;
bool first = true;
while (std::getline(ss, item, '/')) {
if (item.compare("m") == 0) {
if (first) {
first = false;
continue;
}
return false;
}
// Finds whether it is hardened
uint32_t path = 0;
size_t pos = item.find("'");
if (pos != std::string::npos) {
// The hardened tick can only be in the last index of the string
if (pos != item.size() - 1) {
return false;
}
path |= 0x80000000;
item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick
}
// Ensure this is only numbers
if (item.find_first_not_of( "0123456789" ) != std::string::npos) {
return false;
}
uint32_t number;
if (!ParseUInt32(item, &number)) {
return false;
}
path |= number;
keypath.push_back(path);
first = false;
}
return true;
}
void Downcase(std::string& str)
{
std::transform(str.begin(), str.end(), str.begin(), [](char c){return ToLower(c);});

View file

@ -197,9 +197,6 @@ bool ConvertBits(const O& outfn, I it, I end) {
return true;
}
/** Parse an HD keypaths like "m/7/0'/2000". */
NODISCARD bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
/**
* Converts the given character to its lowercase equivalent.
* This function is locale independent. It only converts uppercase

View file

@ -27,6 +27,7 @@
#include <script/sign.h>
#include <shutdown.h>
#include <timedata.h>
#include <util/bip32.h>
#include <util/system.h>
#include <util/moneystr.h>
#include <wallet/coincontrol.h>

View file

@ -4,6 +4,7 @@
#include <key_io.h>
#include <script/sign.h>
#include <util/bip32.h>
#include <util/strencodings.h>
#include <wallet/psbtwallet.h>
#include <wallet/rpcwallet.h>

View file

@ -27,6 +27,7 @@
#include <shutdown.h>
#include <timedata.h>
#include <txmempool.h>
#include <util/bip32.h>
#include <util/moneystr.h>
#include <wallet/fees.h>