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:
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);});
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user