Changeset View
Changeset View
Standalone View
Standalone View
src/base58.cpp
Show First 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | bool DecodeBase58Check(const char *psz, std::vector<uint8_t> &vchRet) { | ||||
vchRet.resize(vchRet.size() - 4); | vchRet.resize(vchRet.size() - 4); | ||||
return true; | return true; | ||||
} | } | ||||
bool DecodeBase58Check(const std::string &str, std::vector<uint8_t> &vchRet) { | bool DecodeBase58Check(const std::string &str, std::vector<uint8_t> &vchRet) { | ||||
return DecodeBase58Check(str.c_str(), vchRet); | return DecodeBase58Check(str.c_str(), vchRet); | ||||
} | } | ||||
CBase58Data::CBase58Data() { | |||||
vchVersion.clear(); | |||||
vchData.clear(); | |||||
} | |||||
void CBase58Data::SetData(const std::vector<uint8_t> &vchVersionIn, | |||||
const void *pdata, size_t nSize) { | |||||
vchVersion = vchVersionIn; | |||||
vchData.resize(nSize); | |||||
if (!vchData.empty()) { | |||||
memcpy(vchData.data(), pdata, nSize); | |||||
} | |||||
} | |||||
void CBase58Data::SetData(const std::vector<uint8_t> &vchVersionIn, | |||||
const uint8_t *pbegin, const uint8_t *pend) { | |||||
SetData(vchVersionIn, (void *)pbegin, pend - pbegin); | |||||
} | |||||
bool CBase58Data::SetString(const char *psz, unsigned int nVersionBytes) { | |||||
std::vector<uint8_t> vchTemp; | |||||
bool rc58 = DecodeBase58Check(psz, vchTemp); | |||||
if ((!rc58) || (vchTemp.size() < nVersionBytes)) { | |||||
vchData.clear(); | |||||
vchVersion.clear(); | |||||
return false; | |||||
} | |||||
vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes); | |||||
vchData.resize(vchTemp.size() - nVersionBytes); | |||||
if (!vchData.empty()) { | |||||
memcpy(vchData.data(), vchTemp.data() + nVersionBytes, vchData.size()); | |||||
} | |||||
memory_cleanse(vchTemp.data(), vchTemp.size()); | |||||
return true; | |||||
} | |||||
bool CBase58Data::SetString(const std::string &str) { | |||||
return SetString(str.c_str()); | |||||
} | |||||
std::string CBase58Data::ToString() const { | |||||
std::vector<uint8_t> vch = vchVersion; | |||||
vch.insert(vch.end(), vchData.begin(), vchData.end()); | |||||
return EncodeBase58Check(vch); | |||||
} | |||||
int CBase58Data::CompareTo(const CBase58Data &b58) const { | |||||
if (vchVersion < b58.vchVersion) return -1; | |||||
if (vchVersion > b58.vchVersion) return 1; | |||||
if (vchData < b58.vchData) return -1; | |||||
if (vchData > b58.vchData) return 1; | |||||
return 0; | |||||
} | |||||
namespace { | namespace { | ||||
class DestinationEncoder : public boost::static_visitor<std::string> { | class DestinationEncoder : public boost::static_visitor<std::string> { | ||||
private: | private: | ||||
const CChainParams &m_params; | const CChainParams &m_params; | ||||
public: | public: | ||||
explicit DestinationEncoder(const CChainParams ¶ms) | explicit DestinationEncoder(const CChainParams ¶ms) | ||||
: m_params(params) {} | : m_params(params) {} | ||||
Show All 38 Lines | if (data.size() == 20 + script_prefix.size() && | ||||
return CScriptID(hash); | return CScriptID(hash); | ||||
} | } | ||||
return CNoDestination(); | return CNoDestination(); | ||||
} | } | ||||
} // namespace | } // namespace | ||||
CKey DecodeSecret(const std::string &str) { | CKey DecodeSecret(const std::string &str) { | ||||
CKey key; | CKey key; | ||||
std::vector<unsigned char> data; | std::vector<uint8_t> data; | ||||
if (DecodeBase58Check(str, data)) { | if (DecodeBase58Check(str, data)) { | ||||
const std::vector<unsigned char> &privkey_prefix = | const std::vector<uint8_t> &privkey_prefix = | ||||
Params().Base58Prefix(CChainParams::SECRET_KEY); | Params().Base58Prefix(CChainParams::SECRET_KEY); | ||||
if ((data.size() == 32 + privkey_prefix.size() || | if ((data.size() == 32 + privkey_prefix.size() || | ||||
(data.size() == 33 + privkey_prefix.size() && data.back() == 1)) && | (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) && | ||||
std::equal(privkey_prefix.begin(), privkey_prefix.end(), | std::equal(privkey_prefix.begin(), privkey_prefix.end(), | ||||
data.begin())) { | data.begin())) { | ||||
bool compressed = data.size() == 33 + privkey_prefix.size(); | bool compressed = data.size() == 33 + privkey_prefix.size(); | ||||
key.Set(data.begin() + privkey_prefix.size(), | key.Set(data.begin() + privkey_prefix.size(), | ||||
data.begin() + privkey_prefix.size() + 32, compressed); | data.begin() + privkey_prefix.size() + 32, compressed); | ||||
} | } | ||||
} | } | ||||
memory_cleanse(data.data(), data.size()); | memory_cleanse(data.data(), data.size()); | ||||
return key; | return key; | ||||
} | } | ||||
std::string EncodeSecret(const CKey &key) { | std::string EncodeSecret(const CKey &key) { | ||||
assert(key.IsValid()); | assert(key.IsValid()); | ||||
std::vector<unsigned char> data = | std::vector<uint8_t> data = Params().Base58Prefix(CChainParams::SECRET_KEY); | ||||
Params().Base58Prefix(CChainParams::SECRET_KEY); | |||||
data.insert(data.end(), key.begin(), key.end()); | data.insert(data.end(), key.begin(), key.end()); | ||||
if (key.IsCompressed()) { | if (key.IsCompressed()) { | ||||
data.push_back(1); | data.push_back(1); | ||||
} | } | ||||
std::string ret = EncodeBase58Check(data); | std::string ret = EncodeBase58Check(data); | ||||
memory_cleanse(data.data(), data.size()); | memory_cleanse(data.data(), data.size()); | ||||
return ret; | return ret; | ||||
} | } | ||||
CExtPubKey DecodeExtPubKey(const std::string &str) { | |||||
CExtPubKey key; | |||||
std::vector<uint8_t> data; | |||||
if (DecodeBase58Check(str, data)) { | |||||
const std::vector<uint8_t> &prefix = | |||||
Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); | |||||
if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && | |||||
std::equal(prefix.begin(), prefix.end(), data.begin())) { | |||||
key.Decode(data.data() + prefix.size()); | |||||
} | |||||
} | |||||
return key; | |||||
} | |||||
std::string EncodeExtPubKey(const CExtPubKey &key) { | |||||
std::vector<uint8_t> data = | |||||
Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY); | |||||
size_t size = data.size(); | |||||
data.resize(size + BIP32_EXTKEY_SIZE); | |||||
key.Encode(data.data() + size); | |||||
std::string ret = EncodeBase58Check(data); | |||||
return ret; | |||||
} | |||||
CExtKey DecodeExtKey(const std::string &str) { | |||||
CExtKey key; | |||||
std::vector<uint8_t> data; | |||||
if (DecodeBase58Check(str, data)) { | |||||
const std::vector<uint8_t> &prefix = | |||||
Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); | |||||
if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && | |||||
std::equal(prefix.begin(), prefix.end(), data.begin())) { | |||||
key.Decode(data.data() + prefix.size()); | |||||
} | |||||
} | |||||
return key; | |||||
} | |||||
std::string EncodeExtKey(const CExtKey &key) { | |||||
std::vector<uint8_t> data = | |||||
Params().Base58Prefix(CChainParams::EXT_SECRET_KEY); | |||||
size_t size = data.size(); | |||||
data.resize(size + BIP32_EXTKEY_SIZE); | |||||
key.Encode(data.data() + size); | |||||
std::string ret = EncodeBase58Check(data); | |||||
memory_cleanse(data.data(), data.size()); | |||||
return ret; | |||||
} | |||||
std::string EncodeLegacyAddr(const CTxDestination &dest, | std::string EncodeLegacyAddr(const CTxDestination &dest, | ||||
const CChainParams ¶ms) { | const CChainParams ¶ms) { | ||||
return boost::apply_visitor(DestinationEncoder(params), dest); | return boost::apply_visitor(DestinationEncoder(params), dest); | ||||
} | } | ||||
CTxDestination DecodeLegacyAddr(const std::string &str, | CTxDestination DecodeLegacyAddr(const std::string &str, | ||||
const CChainParams ¶ms) { | const CChainParams ¶ms) { | ||||
return DecodeLegacyDestination(str, params); | return DecodeLegacyDestination(str, params); | ||||
} | } |