Auto merge of #3242 - str4d:3058-key-encoding-refactor, r=str4d
Key encoding refactor Includes code cherry-picked from the following upstream PRs: - bitcoin/bitcoin#11372 - Only the first three commits (the fourth commit depends on #2390) Part of #3058.
This commit is contained in:
@@ -152,6 +152,7 @@ BITCOIN_CORE_H = \
|
||||
httpserver.h \
|
||||
init.h \
|
||||
key.h \
|
||||
key_io.h \
|
||||
keystore.h \
|
||||
dbwrapper.h \
|
||||
limitedmap.h \
|
||||
@@ -368,6 +369,7 @@ libbitcoin_common_a_SOURCES = \
|
||||
core_write.cpp \
|
||||
hash.cpp \
|
||||
key.cpp \
|
||||
key_io.cpp \
|
||||
keystore.cpp \
|
||||
netbase.cpp \
|
||||
primitives/block.cpp \
|
||||
|
||||
237
src/base58.cpp
237
src/base58.cpp
@@ -4,21 +4,12 @@
|
||||
|
||||
#include "base58.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "script/script.h"
|
||||
#include "uint256.h"
|
||||
#include <hash.h>
|
||||
#include <uint256.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "streams.h"
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/** All alphanumeric characters except for "0", "I", "O", and "l" */
|
||||
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
@@ -143,227 +134,3 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
|
||||
{
|
||||
return DecodeBase58Check(str.c_str(), vchRet);
|
||||
}
|
||||
|
||||
CBase58Data::CBase58Data()
|
||||
{
|
||||
vchVersion.clear();
|
||||
vchData.clear();
|
||||
}
|
||||
|
||||
void CBase58Data::SetData(const std::vector<unsigned char>& 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<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
|
||||
{
|
||||
SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
|
||||
}
|
||||
|
||||
bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
|
||||
{
|
||||
std::vector<unsigned char> 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, unsigned int nVersionBytes)
|
||||
{
|
||||
return SetString(str.c_str(), nVersionBytes);
|
||||
}
|
||||
|
||||
std::string CBase58Data::ToString() const
|
||||
{
|
||||
std::vector<unsigned char> 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
|
||||
{
|
||||
class DestinationEncoder : public boost::static_visitor<std::string>
|
||||
{
|
||||
private:
|
||||
const CChainParams& m_params;
|
||||
|
||||
public:
|
||||
DestinationEncoder(const CChainParams& params) : m_params(params) {}
|
||||
|
||||
std::string operator()(const CKeyID& id) const
|
||||
{
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
|
||||
data.insert(data.end(), id.begin(), id.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
||||
std::string operator()(const CScriptID& id) const
|
||||
{
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
|
||||
data.insert(data.end(), id.begin(), id.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
||||
std::string operator()(const CNoDestination& no) const { return ""; }
|
||||
};
|
||||
|
||||
CTxDestination DecodeDestination(const std::string& str, const CChainParams& params)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
uint160 hash;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
// base58-encoded Bitcoin addresses.
|
||||
// Public-key-hash-addresses have version 0 (or 111 testnet).
|
||||
// The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
|
||||
const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
|
||||
if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
|
||||
std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
|
||||
return CKeyID(hash);
|
||||
}
|
||||
// Script-hash-addresses have version 5 (or 196 testnet).
|
||||
// The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
|
||||
const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
|
||||
if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
|
||||
std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
|
||||
return CScriptID(hash);
|
||||
}
|
||||
}
|
||||
return CNoDestination();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void CBitcoinSecret::SetKey(const CKey& vchSecret)
|
||||
{
|
||||
assert(vchSecret.IsValid());
|
||||
SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
|
||||
if (vchSecret.IsCompressed())
|
||||
vchData.push_back(1);
|
||||
}
|
||||
|
||||
CKey CBitcoinSecret::GetKey()
|
||||
{
|
||||
CKey ret;
|
||||
assert(vchData.size() >= 32);
|
||||
ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::IsValid() const
|
||||
{
|
||||
bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
|
||||
bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
return fExpectedFormat && fCorrectVersion;
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::SetString(const char* pszSecret)
|
||||
{
|
||||
return CBase58Data::SetString(pszSecret, 1) && IsValid();
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::SetString(const std::string& strSecret)
|
||||
{
|
||||
return SetString(strSecret.c_str());
|
||||
}
|
||||
|
||||
std::string EncodeDestination(const CTxDestination& dest)
|
||||
{
|
||||
return boost::apply_visitor(DestinationEncoder(Params()), dest);
|
||||
}
|
||||
|
||||
CTxDestination DecodeDestination(const std::string& str)
|
||||
{
|
||||
return DecodeDestination(str, Params());
|
||||
}
|
||||
|
||||
bool IsValidDestinationString(const std::string& str, const CChainParams& params)
|
||||
{
|
||||
return IsValidDestination(DecodeDestination(str, params));
|
||||
}
|
||||
|
||||
bool IsValidDestinationString(const std::string& str)
|
||||
{
|
||||
return IsValidDestinationString(str, Params());
|
||||
}
|
||||
|
||||
template<class DATA_TYPE, CChainParams::Base58Type PREFIX, size_t SER_SIZE>
|
||||
bool CZCEncoding<DATA_TYPE, PREFIX, SER_SIZE>::Set(const DATA_TYPE& addr)
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << addr;
|
||||
std::vector<unsigned char> addrSerialized(ss.begin(), ss.end());
|
||||
assert(addrSerialized.size() == SER_SIZE);
|
||||
SetData(Params().Base58Prefix(PREFIX), &addrSerialized[0], SER_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class DATA_TYPE, CChainParams::Base58Type PREFIX, size_t SER_SIZE>
|
||||
DATA_TYPE CZCEncoding<DATA_TYPE, PREFIX, SER_SIZE>::Get() const
|
||||
{
|
||||
if (vchData.size() != SER_SIZE) {
|
||||
throw std::runtime_error(
|
||||
PrependName(" is invalid")
|
||||
);
|
||||
}
|
||||
|
||||
if (vchVersion != Params().Base58Prefix(PREFIX)) {
|
||||
throw std::runtime_error(
|
||||
PrependName(" is for wrong network type")
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<unsigned char> serialized(vchData.begin(), vchData.end());
|
||||
|
||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||
DATA_TYPE ret;
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Explicit instantiations for libzcash::PaymentAddress
|
||||
template bool CZCEncoding<libzcash::PaymentAddress,
|
||||
CChainParams::ZCPAYMENT_ADDRRESS,
|
||||
libzcash::SerializedPaymentAddressSize>::Set(const libzcash::PaymentAddress& addr);
|
||||
template libzcash::PaymentAddress CZCEncoding<libzcash::PaymentAddress,
|
||||
CChainParams::ZCPAYMENT_ADDRRESS,
|
||||
libzcash::SerializedPaymentAddressSize>::Get() const;
|
||||
|
||||
// Explicit instantiations for libzcash::ViewingKey
|
||||
template bool CZCEncoding<libzcash::ViewingKey,
|
||||
CChainParams::ZCVIEWING_KEY,
|
||||
libzcash::SerializedViewingKeySize>::Set(const libzcash::ViewingKey& vk);
|
||||
template libzcash::ViewingKey CZCEncoding<libzcash::ViewingKey,
|
||||
CChainParams::ZCVIEWING_KEY,
|
||||
libzcash::SerializedViewingKeySize>::Get() const;
|
||||
|
||||
// Explicit instantiations for libzcash::SpendingKey
|
||||
template bool CZCEncoding<libzcash::SpendingKey,
|
||||
CChainParams::ZCSPENDING_KEY,
|
||||
libzcash::SerializedSpendingKeySize>::Set(const libzcash::SpendingKey& sk);
|
||||
template libzcash::SpendingKey CZCEncoding<libzcash::SpendingKey,
|
||||
CChainParams::ZCSPENDING_KEY,
|
||||
libzcash::SerializedSpendingKeySize>::Get() const;
|
||||
|
||||
138
src/base58.h
138
src/base58.h
@@ -14,13 +14,6 @@
|
||||
#ifndef BITCOIN_BASE58_H
|
||||
#define BITCOIN_BASE58_H
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "key.h"
|
||||
#include "pubkey.h"
|
||||
#include "script/standard.h"
|
||||
#include "support/allocators/zeroafterfree.h"
|
||||
#include "zcash/Address.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -57,139 +50,12 @@ std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn);
|
||||
* Decode a base58-encoded string (psz) that includes a checksum into a byte
|
||||
* vector (vchRet), return true if decoding is successful
|
||||
*/
|
||||
inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
|
||||
bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Decode a base58-encoded string (str) that includes a checksum into a byte
|
||||
* vector (vchRet), return true if decoding is successful
|
||||
*/
|
||||
inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
|
||||
|
||||
/**
|
||||
* Base class for all base58-encoded data
|
||||
*/
|
||||
class CBase58Data
|
||||
{
|
||||
protected:
|
||||
//! the version byte(s)
|
||||
std::vector<unsigned char> vchVersion;
|
||||
|
||||
//! the actually encoded data
|
||||
typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar;
|
||||
vector_uchar vchData;
|
||||
|
||||
CBase58Data();
|
||||
void SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize);
|
||||
void SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend);
|
||||
|
||||
public:
|
||||
bool SetString(const char* psz, unsigned int nVersionBytes);
|
||||
bool SetString(const std::string& str, unsigned int nVersionBytes);
|
||||
std::string ToString() const;
|
||||
int CompareTo(const CBase58Data& b58) const;
|
||||
|
||||
bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
|
||||
bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
|
||||
bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
|
||||
bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; }
|
||||
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
|
||||
};
|
||||
|
||||
template<class DATA_TYPE, CChainParams::Base58Type PREFIX, size_t SER_SIZE>
|
||||
class CZCEncoding : public CBase58Data {
|
||||
protected:
|
||||
virtual std::string PrependName(const std::string& s) const = 0;
|
||||
|
||||
public:
|
||||
bool Set(const DATA_TYPE& addr);
|
||||
|
||||
DATA_TYPE Get() const;
|
||||
};
|
||||
|
||||
class CZCPaymentAddress : public CZCEncoding<libzcash::PaymentAddress, CChainParams::ZCPAYMENT_ADDRRESS, libzcash::SerializedPaymentAddressSize> {
|
||||
protected:
|
||||
std::string PrependName(const std::string& s) const { return "payment address" + s; }
|
||||
|
||||
public:
|
||||
CZCPaymentAddress() {}
|
||||
|
||||
CZCPaymentAddress(const std::string& strAddress) { SetString(strAddress.c_str(), 2); }
|
||||
CZCPaymentAddress(const libzcash::PaymentAddress& addr) { Set(addr); }
|
||||
};
|
||||
|
||||
class CZCViewingKey : public CZCEncoding<libzcash::ViewingKey, CChainParams::ZCVIEWING_KEY, libzcash::SerializedViewingKeySize> {
|
||||
protected:
|
||||
std::string PrependName(const std::string& s) const { return "viewing key" + s; }
|
||||
|
||||
public:
|
||||
CZCViewingKey() {}
|
||||
|
||||
CZCViewingKey(const std::string& strViewingKey) { SetString(strViewingKey.c_str(), 3); }
|
||||
CZCViewingKey(const libzcash::ViewingKey& vk) { Set(vk); }
|
||||
};
|
||||
|
||||
class CZCSpendingKey : public CZCEncoding<libzcash::SpendingKey, CChainParams::ZCSPENDING_KEY, libzcash::SerializedSpendingKeySize> {
|
||||
protected:
|
||||
std::string PrependName(const std::string& s) const { return "spending key" + s; }
|
||||
|
||||
public:
|
||||
CZCSpendingKey() {}
|
||||
|
||||
CZCSpendingKey(const std::string& strAddress) { SetString(strAddress.c_str(), 2); }
|
||||
CZCSpendingKey(const libzcash::SpendingKey& addr) { Set(addr); }
|
||||
};
|
||||
|
||||
/**
|
||||
* A base58-encoded secret key
|
||||
*/
|
||||
class CBitcoinSecret : public CBase58Data
|
||||
{
|
||||
public:
|
||||
void SetKey(const CKey& vchSecret);
|
||||
CKey GetKey();
|
||||
bool IsValid() const;
|
||||
bool SetString(const char* pszSecret);
|
||||
bool SetString(const std::string& strSecret);
|
||||
|
||||
CBitcoinSecret(const CKey& vchSecret) { SetKey(vchSecret); }
|
||||
CBitcoinSecret() {}
|
||||
};
|
||||
|
||||
template<typename K, int Size, CChainParams::Base58Type Type> class CBitcoinExtKeyBase : public CBase58Data
|
||||
{
|
||||
public:
|
||||
void SetKey(const K &key) {
|
||||
unsigned char vch[Size];
|
||||
key.Encode(vch);
|
||||
SetData(Params().Base58Prefix(Type), vch, vch+Size);
|
||||
}
|
||||
|
||||
K GetKey() {
|
||||
K ret;
|
||||
if (vchData.size() == Size) {
|
||||
// If base58 encoded data does not hold an ext key, return a !IsValid() key
|
||||
ret.Decode(vchData.data());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CBitcoinExtKeyBase(const K &key) {
|
||||
SetKey(key);
|
||||
}
|
||||
|
||||
CBitcoinExtKeyBase(const std::string& strBase58c) {
|
||||
SetString(strBase58c.c_str(), Params().Base58Prefix(Type).size());
|
||||
}
|
||||
|
||||
CBitcoinExtKeyBase() {}
|
||||
};
|
||||
|
||||
typedef CBitcoinExtKeyBase<CExtKey, BIP32_EXTKEY_SIZE, CChainParams::EXT_SECRET_KEY> CBitcoinExtKey;
|
||||
typedef CBitcoinExtKeyBase<CExtPubKey, BIP32_EXTKEY_SIZE, CChainParams::EXT_PUBLIC_KEY> CBitcoinExtPubKey;
|
||||
|
||||
std::string EncodeDestination(const CTxDestination& dest);
|
||||
CTxDestination DecodeDestination(const std::string& str);
|
||||
bool IsValidDestinationString(const std::string& str);
|
||||
bool IsValidDestinationString(const std::string& str, const CChainParams& params);
|
||||
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
|
||||
|
||||
#endif // BITCOIN_BASE58_H
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "base58.h"
|
||||
#include "clientversion.h"
|
||||
#include "coins.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "core_io.h"
|
||||
#include "key_io.h"
|
||||
#include "keystore.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
@@ -400,12 +400,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& strInput)
|
||||
for (size_t kidx = 0; kidx < keysObj.size(); kidx++) {
|
||||
if (!keysObj[kidx].isStr())
|
||||
throw std::runtime_error("privatekey not a std::string");
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(keysObj[kidx].getValStr());
|
||||
if (!fGood)
|
||||
CKey key = DecodeSecret(keysObj[kidx].getValStr());
|
||||
if (!key.IsValid()) {
|
||||
throw std::runtime_error("privatekey not valid");
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
}
|
||||
tempKeystore.AddKey(key);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "crypto/equihash.h"
|
||||
|
||||
@@ -13,8 +14,6 @@
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include "base58.h"
|
||||
|
||||
#include "chainparamsseeds.h"
|
||||
|
||||
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, const uint256& nNonce, const std::vector<unsigned char>& nSolution, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "core_io.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "key_io.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "httprpc.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "chainparams.h"
|
||||
#include "httpserver.h"
|
||||
#include "key_io.h"
|
||||
#include "rpcprotocol.h"
|
||||
#include "rpcserver.h"
|
||||
#include "random.h"
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
#include "crypto/common.h"
|
||||
#include "addrman.h"
|
||||
#include "amount.h"
|
||||
#ifdef ENABLE_MINING
|
||||
#include "base58.h"
|
||||
#endif
|
||||
#include "checkpoints.h"
|
||||
#include "compat/sanity.h"
|
||||
#include "consensus/upgrades.h"
|
||||
@@ -21,6 +18,9 @@
|
||||
#include "httpserver.h"
|
||||
#include "httprpc.h"
|
||||
#include "key.h"
|
||||
#ifdef ENABLE_MINING
|
||||
#include "key_io.h"
|
||||
#endif
|
||||
#include "main.h"
|
||||
#include "metrics.h"
|
||||
#include "miner.h"
|
||||
|
||||
254
src/key_io.cpp
Normal file
254
src/key_io.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
// Copyright (c) 2014-2016 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-2018 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <key_io.h>
|
||||
|
||||
#include <base58.h>
|
||||
#include <bech32.h>
|
||||
#include <script/script.h>
|
||||
#include <utilstrencodings.h>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
class DestinationEncoder : public boost::static_visitor<std::string>
|
||||
{
|
||||
private:
|
||||
const CChainParams& m_params;
|
||||
|
||||
public:
|
||||
DestinationEncoder(const CChainParams& params) : m_params(params) {}
|
||||
|
||||
std::string operator()(const CKeyID& id) const
|
||||
{
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
|
||||
data.insert(data.end(), id.begin(), id.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
||||
std::string operator()(const CScriptID& id) const
|
||||
{
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
|
||||
data.insert(data.end(), id.begin(), id.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
||||
std::string operator()(const CNoDestination& no) const { return {}; }
|
||||
};
|
||||
|
||||
CTxDestination DecodeDestination(const std::string& str, const CChainParams& params)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
uint160 hash;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
// base58-encoded Bitcoin addresses.
|
||||
// Public-key-hash-addresses have version 0 (or 111 testnet).
|
||||
// The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
|
||||
const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
|
||||
if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
|
||||
std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
|
||||
return CKeyID(hash);
|
||||
}
|
||||
// Script-hash-addresses have version 5 (or 196 testnet).
|
||||
// The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
|
||||
const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
|
||||
if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
|
||||
std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
|
||||
return CScriptID(hash);
|
||||
}
|
||||
}
|
||||
return CNoDestination();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
CKey DecodeSecret(const std::string& str)
|
||||
{
|
||||
CKey key;
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
|
||||
std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
|
||||
bool compressed = data.size() == 33 + privkey_prefix.size();
|
||||
key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
|
||||
}
|
||||
}
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return key;
|
||||
}
|
||||
|
||||
std::string EncodeSecret(const CKey& key)
|
||||
{
|
||||
assert(key.IsValid());
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
data.insert(data.end(), key.begin(), key.end());
|
||||
if (key.IsCompressed()) {
|
||||
data.push_back(1);
|
||||
}
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
CExtPubKey DecodeExtPubKey(const std::string& str)
|
||||
{
|
||||
CExtPubKey key;
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& 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<unsigned char> 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<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& 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<unsigned char> 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 EncodeDestination(const CTxDestination& dest)
|
||||
{
|
||||
return boost::apply_visitor(DestinationEncoder(Params()), dest);
|
||||
}
|
||||
|
||||
CTxDestination DecodeDestination(const std::string& str)
|
||||
{
|
||||
return DecodeDestination(str, Params());
|
||||
}
|
||||
|
||||
bool IsValidDestinationString(const std::string& str, const CChainParams& params)
|
||||
{
|
||||
return IsValidDestination(DecodeDestination(str, params));
|
||||
}
|
||||
|
||||
bool IsValidDestinationString(const std::string& str)
|
||||
{
|
||||
return IsValidDestinationString(str, Params());
|
||||
}
|
||||
|
||||
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << zaddr;
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
||||
boost::optional<libzcash::PaymentAddress> DecodePaymentAddress(const std::string& str)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
||||
if ((data.size() == libzcash::SerializedPaymentAddressSize + zaddr_prefix.size()) &&
|
||||
std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
|
||||
CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
|
||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||
libzcash::PaymentAddress ret;
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << vk;
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
||||
if ((data.size() == libzcash::SerializedViewingKeySize + vk_prefix.size()) &&
|
||||
std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
|
||||
CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
|
||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||
libzcash::ViewingKey ret;
|
||||
ss >> ret;
|
||||
memory_cleanse(serialized.data(), serialized.size());
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << zkey;
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
||||
if ((data.size() == libzcash::SerializedSpendingKeySize + zkey_prefix.size()) &&
|
||||
std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
|
||||
CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
|
||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||
libzcash::SpendingKey ret;
|
||||
ss >> ret;
|
||||
memory_cleanse(serialized.data(), serialized.size());
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return boost::none;
|
||||
}
|
||||
40
src/key_io.h
Normal file
40
src/key_io.h
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-2018 The Zcash developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_KEYIO_H
|
||||
#define BITCOIN_KEYIO_H
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <key.h>
|
||||
#include <pubkey.h>
|
||||
#include <script/standard.h>
|
||||
#include <zcash/Address.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
CKey DecodeSecret(const std::string& str);
|
||||
std::string EncodeSecret(const CKey& key);
|
||||
|
||||
CExtKey DecodeExtKey(const std::string& str);
|
||||
std::string EncodeExtKey(const CExtKey& extkey);
|
||||
CExtPubKey DecodeExtPubKey(const std::string& str);
|
||||
std::string EncodeExtPubKey(const CExtPubKey& extpubkey);
|
||||
|
||||
std::string EncodeDestination(const CTxDestination& dest);
|
||||
CTxDestination DecodeDestination(const std::string& str);
|
||||
bool IsValidDestinationString(const std::string& str);
|
||||
bool IsValidDestinationString(const std::string& str, const CChainParams& params);
|
||||
|
||||
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr);
|
||||
boost::optional<libzcash::PaymentAddress> DecodePaymentAddress(const std::string& str);
|
||||
|
||||
std::string EncodeViewingKey(const libzcash::ViewingKey& vk);
|
||||
boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str);
|
||||
|
||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey);
|
||||
boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str);
|
||||
|
||||
#endif // BITCOIN_KEYIO_H
|
||||
@@ -9,7 +9,6 @@
|
||||
#endif
|
||||
|
||||
#include "amount.h"
|
||||
#include "base58.h"
|
||||
#include "chainparams.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "consensus/upgrades.h"
|
||||
@@ -18,6 +17,7 @@
|
||||
#include "crypto/equihash.h"
|
||||
#endif
|
||||
#include "hash.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "metrics.h"
|
||||
#include "net.h"
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "paymentdisclosure.h"
|
||||
|
||||
#include "key_io.h"
|
||||
#include "util.h"
|
||||
|
||||
std::string PaymentDisclosureInfo::ToString() const {
|
||||
return strprintf("PaymentDisclosureInfo(version=%d, esk=%s, joinSplitPrivKey=<omitted>, address=%s)",
|
||||
version, esk.ToString(), CZCPaymentAddress(zaddr).ToString());
|
||||
version, esk.ToString(), EncodePaymentAddress(zaddr));
|
||||
}
|
||||
|
||||
std::string PaymentDisclosure::ToString() const {
|
||||
@@ -17,7 +19,7 @@ std::string PaymentDisclosure::ToString() const {
|
||||
|
||||
std::string PaymentDisclosurePayload::ToString() const {
|
||||
return strprintf("PaymentDisclosurePayload(version=%d, esk=%s, txid=%s, js=%d, n=%d, address=%s, message=%s)",
|
||||
version, esk.ToString(), txid.ToString(), js, n, CZCPaymentAddress(zaddr).ToString(), message);
|
||||
version, esk.ToString(), txid.ToString(), js, n, EncodePaymentAddress(zaddr), message);
|
||||
}
|
||||
|
||||
PaymentDisclosure::PaymentDisclosure(const uint256 &joinSplitPubKey, const PaymentDisclosureKey &key, const PaymentDisclosureInfo &info, const std::string &message)
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "base58.h"
|
||||
#include "clientversion.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "netbase.h"
|
||||
@@ -235,27 +235,23 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp)
|
||||
LOCK(cs_main);
|
||||
#endif
|
||||
|
||||
bool isValid = false;
|
||||
bool isMine = false;
|
||||
std::string payingKey, transmissionKey;
|
||||
|
||||
string strAddress = params[0].get_str();
|
||||
try {
|
||||
CZCPaymentAddress address(strAddress);
|
||||
libzcash::PaymentAddress addr = address.Get();
|
||||
auto isValid = DecodePaymentAddress(strAddress);
|
||||
if (isValid) {
|
||||
libzcash::PaymentAddress addr = *isValid;
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
isMine = pwalletMain->HaveSpendingKey(addr);
|
||||
#endif
|
||||
payingKey = addr.a_pk.GetHex();
|
||||
transmissionKey = addr.pk_enc.GetHex();
|
||||
isValid = true;
|
||||
} catch (std::runtime_error e) {
|
||||
// address is invalid, nop here as isValid is false.
|
||||
}
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("isvalid", isValid));
|
||||
ret.push_back(Pair("isvalid", static_cast<bool>(isValid)));
|
||||
if (isValid)
|
||||
{
|
||||
ret.push_back(Pair("address", strAddress));
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "base58.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "keystore.h"
|
||||
#include "main.h"
|
||||
#include "merkleblock.h"
|
||||
@@ -777,13 +777,9 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
|
||||
UniValue keys = params[2].get_array();
|
||||
for (size_t idx = 0; idx < keys.size(); idx++) {
|
||||
UniValue k = keys[idx];
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(k.get_str());
|
||||
if (!fGood)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||
CKey key = vchSecret.GetKey();
|
||||
CKey key = DecodeSecret(k.get_str());
|
||||
if (!key.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||
tempKeystore.AddKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include "rpcserver.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "random.h"
|
||||
#include "sync.h"
|
||||
#include "ui_interface.h"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "data/base58_keys_valid.json.h"
|
||||
|
||||
#include "key.h"
|
||||
#include "key_io.h"
|
||||
#include "script/script.h"
|
||||
#include "test/test_bitcoin.h"
|
||||
#include "uint256.h"
|
||||
@@ -78,7 +79,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
|
||||
BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
||||
{
|
||||
UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
|
||||
CBitcoinSecret secret;
|
||||
CKey privkey;
|
||||
CTxDestination destination;
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
|
||||
@@ -102,9 +103,8 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
||||
if (isPrivkey) {
|
||||
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
|
||||
// Must be valid private key
|
||||
BOOST_CHECK_MESSAGE(secret.SetString(exp_base58string), "!SetString:"+ strTest);
|
||||
BOOST_CHECK_MESSAGE(secret.IsValid(), "!IsValid:" + strTest);
|
||||
CKey privkey = secret.GetKey();
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest);
|
||||
BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
|
||||
BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest);
|
||||
|
||||
@@ -119,8 +119,8 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
||||
BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload));
|
||||
|
||||
// Public key must be invalid private key
|
||||
secret.SetString(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid pubkey as privkey:" + strTest);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,9 +153,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
||||
CKey key;
|
||||
key.Set(exp_payload.begin(), exp_payload.end(), isCompressed);
|
||||
assert(key.IsValid());
|
||||
CBitcoinSecret secret;
|
||||
secret.SetKey(key);
|
||||
BOOST_CHECK_MESSAGE(secret.ToString() == exp_base58string, "result mismatch: " + strTest);
|
||||
BOOST_CHECK_MESSAGE(EncodeSecret(key) == exp_base58string, "result mismatch: " + strTest);
|
||||
} else {
|
||||
CTxDestination dest;
|
||||
CScript exp_script(exp_payload.begin(), exp_payload.end());
|
||||
@@ -172,7 +170,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
||||
BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
||||
{
|
||||
UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases
|
||||
CBitcoinSecret secret;
|
||||
CKey privkey;
|
||||
CTxDestination destination;
|
||||
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
@@ -188,8 +186,8 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
||||
// must be invalid as public and as private key
|
||||
destination = DecodeDestination(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey:" + strTest);
|
||||
secret.SetString(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid privkey:" + strTest);
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid privkey:" + strTest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "base58.h"
|
||||
#include "key.h"
|
||||
#include "key_io.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
@@ -90,20 +90,12 @@ void RunTest(const TestVector &test) {
|
||||
pubkey.Encode(data);
|
||||
|
||||
// Test private key
|
||||
CBitcoinExtKey b58key; b58key.SetKey(key);
|
||||
BOOST_CHECK(b58key.ToString() == derive.prv);
|
||||
|
||||
CBitcoinExtKey b58keyDecodeCheck(derive.prv);
|
||||
CExtKey checkKey = b58keyDecodeCheck.GetKey();
|
||||
assert(checkKey == key); //ensure a base58 decoded key also matches
|
||||
BOOST_CHECK(EncodeExtKey(key) == derive.prv);
|
||||
BOOST_CHECK(DecodeExtKey(derive.prv) == key); //ensure a base58 decoded key also matches
|
||||
|
||||
// Test public key
|
||||
CBitcoinExtPubKey b58pubkey; b58pubkey.SetKey(pubkey);
|
||||
BOOST_CHECK(b58pubkey.ToString() == derive.pub);
|
||||
|
||||
CBitcoinExtPubKey b58PubkeyDecodeCheck(derive.pub);
|
||||
CExtPubKey checkPubKey = b58PubkeyDecodeCheck.GetKey();
|
||||
assert(checkPubKey == pubkey); //ensure a base58 decoded pubkey also matches
|
||||
BOOST_CHECK(EncodeExtPubKey(pubkey) == derive.pub);
|
||||
BOOST_CHECK(DecodeExtPubKey(derive.pub) == pubkey); //ensure a base58 decoded pubkey also matches
|
||||
|
||||
// Derive new keys
|
||||
CExtKey keyNew;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "bloom.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "clientversion.h"
|
||||
#include "key.h"
|
||||
#include "key_io.h"
|
||||
#include "merkleblock.h"
|
||||
#include "random.h"
|
||||
#include "serialize.h"
|
||||
@@ -86,11 +86,8 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
|
||||
{
|
||||
string strSecret = string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
|
||||
CBitcoinSecret vchSecret;
|
||||
BOOST_CHECK(vchSecret.SetString(strSecret));
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
std::string strSecret = std::string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
|
||||
CKey key = DecodeSecret(strSecret);
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end());
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "key.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "key_io.h"
|
||||
#include "script/script.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
@@ -65,21 +65,16 @@ BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(key_test1)
|
||||
{
|
||||
CBitcoinSecret bsecret1, bsecret2, bsecret1C, bsecret2C, baddress1;
|
||||
BOOST_CHECK( bsecret1.SetString (strSecret1));
|
||||
BOOST_CHECK( bsecret2.SetString (strSecret2));
|
||||
BOOST_CHECK( bsecret1C.SetString(strSecret1C));
|
||||
BOOST_CHECK( bsecret2C.SetString(strSecret2C));
|
||||
BOOST_CHECK(!baddress1.SetString(strAddressBad));
|
||||
|
||||
CKey key1 = bsecret1.GetKey();
|
||||
BOOST_CHECK(key1.IsCompressed() == false);
|
||||
CKey key2 = bsecret2.GetKey();
|
||||
BOOST_CHECK(key2.IsCompressed() == false);
|
||||
CKey key1C = bsecret1C.GetKey();
|
||||
BOOST_CHECK(key1C.IsCompressed() == true);
|
||||
CKey key2C = bsecret2C.GetKey();
|
||||
BOOST_CHECK(key2C.IsCompressed() == true);
|
||||
CKey key1 = DecodeSecret(strSecret1);
|
||||
BOOST_CHECK(key1.IsValid() && !key1.IsCompressed());
|
||||
CKey key2 = DecodeSecret(strSecret2);
|
||||
BOOST_CHECK(key2.IsValid() && !key2.IsCompressed());
|
||||
CKey key1C = DecodeSecret(strSecret1C);
|
||||
BOOST_CHECK(key1C.IsValid() && key1C.IsCompressed());
|
||||
CKey key2C = DecodeSecret(strSecret2C);
|
||||
BOOST_CHECK(key2C.IsValid() && key2C.IsCompressed());
|
||||
CKey bad_key = DecodeSecret(strAddressBad);
|
||||
BOOST_CHECK(!bad_key.IsValid());
|
||||
|
||||
CPubKey pubkey1 = key1. GetPubKey();
|
||||
CPubKey pubkey2 = key2. GetPubKey();
|
||||
@@ -195,28 +190,28 @@ BOOST_AUTO_TEST_CASE(zc_address_test)
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
auto sk = SpendingKey::random();
|
||||
{
|
||||
CZCSpendingKey spendingkey(sk);
|
||||
string sk_string = spendingkey.ToString();
|
||||
string sk_string = EncodeSpendingKey(sk);
|
||||
|
||||
BOOST_CHECK(sk_string[0] == 'S');
|
||||
BOOST_CHECK(sk_string[1] == 'K');
|
||||
|
||||
CZCSpendingKey spendingkey2(sk_string);
|
||||
SpendingKey sk2 = spendingkey2.Get();
|
||||
auto spendingkey2 = DecodeSpendingKey(sk_string);
|
||||
BOOST_ASSERT(static_cast<bool>(spendingkey2));
|
||||
SpendingKey sk2 = *spendingkey2;
|
||||
BOOST_CHECK(sk.inner() == sk2.inner());
|
||||
}
|
||||
{
|
||||
auto addr = sk.address();
|
||||
|
||||
CZCPaymentAddress paymentaddr(addr);
|
||||
string addr_string = paymentaddr.ToString();
|
||||
std::string addr_string = EncodePaymentAddress(addr);
|
||||
|
||||
BOOST_CHECK(addr_string[0] == 'z');
|
||||
BOOST_CHECK(addr_string[1] == 'c');
|
||||
|
||||
CZCPaymentAddress paymentaddr2(addr_string);
|
||||
auto paymentaddr2 = DecodePaymentAddress(addr_string);
|
||||
BOOST_ASSERT(static_cast<bool>(paymentaddr2));
|
||||
|
||||
PaymentAddress addr2 = paymentaddr2.Get();
|
||||
PaymentAddress addr2 = *paymentaddr2;
|
||||
BOOST_CHECK(addr.a_pk == addr2.a_pk);
|
||||
BOOST_CHECK(addr.pk_enc == addr2.pk_enc);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "rpcserver.h"
|
||||
#include "rpcclient.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "key_io.h"
|
||||
#include "netbase.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "rpcserver.h"
|
||||
#include "rpcclient.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
@@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
|
||||
BOOST_CHECK(addrs.size()==0);
|
||||
|
||||
// wallet should have one key
|
||||
CZCPaymentAddress paymentAddress = pwalletMain->GenerateNewZKey();
|
||||
auto addr = pwalletMain->GenerateNewZKey();
|
||||
pwalletMain->GetPaymentAddresses(addrs);
|
||||
BOOST_CHECK(addrs.size()==1);
|
||||
|
||||
@@ -411,12 +411,11 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("z_exportwallet ") + tmpfilename.string()));
|
||||
|
||||
|
||||
auto addr = paymentAddress.Get();
|
||||
libzcash::SpendingKey key;
|
||||
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, key));
|
||||
|
||||
std::string s1 = paymentAddress.ToString();
|
||||
std::string s2 = CZCSpendingKey(key).ToString();
|
||||
std::string s1 = EncodePaymentAddress(addr);
|
||||
std::string s2 = EncodeSpendingKey(key);
|
||||
|
||||
// There's no way to really delete a private key so we will read in the
|
||||
// exported wallet file and search for the spending key and payment address.
|
||||
@@ -459,8 +458,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
||||
// create a random key locally
|
||||
auto testSpendingKey = libzcash::SpendingKey::random();
|
||||
auto testPaymentAddress = testSpendingKey.address();
|
||||
std::string testAddr = CZCPaymentAddress(testPaymentAddress).ToString();
|
||||
std::string testKey = CZCSpendingKey(testSpendingKey).ToString();
|
||||
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
||||
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
||||
|
||||
// create test data using the random key
|
||||
std::string format_str = "# Wallet dump created by Zcash v0.11.2.0.z8-9155cc6-dirty (2016-08-11 11:37:00 -0700)\n"
|
||||
@@ -498,15 +497,13 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
||||
BOOST_CHECK(addrs.size()==1);
|
||||
|
||||
// check that we have the spending key for the address
|
||||
CZCPaymentAddress address(testAddr);
|
||||
auto addr = address.Get();
|
||||
auto addr = *DecodePaymentAddress(testAddr);
|
||||
BOOST_CHECK(pwalletMain->HaveSpendingKey(addr));
|
||||
|
||||
// Verify the spending key is the same as the test data
|
||||
libzcash::SpendingKey k;
|
||||
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, k));
|
||||
CZCSpendingKey spendingkey(k);
|
||||
BOOST_CHECK_EQUAL(testKey, spendingkey.ToString());
|
||||
BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k));
|
||||
}
|
||||
|
||||
|
||||
@@ -530,7 +527,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||
|
||||
// error if invalid args
|
||||
auto sk = libzcash::SpendingKey::random();
|
||||
std::string prefix = std::string("z_importkey ") + CZCSpendingKey(sk).ToString() + " yes ";
|
||||
std::string prefix = std::string("z_importkey ") + EncodeSpendingKey(sk) + " yes ";
|
||||
BOOST_CHECK_THROW(CallRPC(prefix + "-1"), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC(prefix + "2147483647"), runtime_error); // allowed, but > height of active chain tip
|
||||
BOOST_CHECK_THROW(CallRPC(prefix + "2147483648"), runtime_error); // not allowed, > int32 used for nHeight
|
||||
@@ -546,8 +543,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||
// create a random key locally
|
||||
auto testSpendingKey = libzcash::SpendingKey::random();
|
||||
auto testPaymentAddress = testSpendingKey.address();
|
||||
std::string testAddr = CZCPaymentAddress(testPaymentAddress).ToString();
|
||||
std::string testKey = CZCSpendingKey(testSpendingKey).ToString();
|
||||
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
||||
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("z_importkey ") + testKey));
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC(string("z_exportkey ") + testAddr));
|
||||
BOOST_CHECK_EQUAL(retValue.get_str(), testKey);
|
||||
@@ -566,7 +563,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||
|
||||
// Make new addresses for the set
|
||||
for (int i=0; i<n2; i++) {
|
||||
myaddrs.insert((pwalletMain->GenerateNewZKey()).ToString());
|
||||
myaddrs.insert(EncodePaymentAddress(pwalletMain->GenerateNewZKey()));
|
||||
}
|
||||
|
||||
// Verify number of addresses stored in wallet is n1+n2
|
||||
@@ -593,8 +590,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||
// Add one more address
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getnewaddress"));
|
||||
std::string newaddress = retValue.get_str();
|
||||
CZCPaymentAddress pa(newaddress);
|
||||
auto newAddr = pa.Get();
|
||||
auto newAddr = *DecodePaymentAddress(newaddress);
|
||||
BOOST_CHECK(pwalletMain->HaveSpendingKey(newAddr));
|
||||
|
||||
// Check if too many args
|
||||
@@ -916,8 +912,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
|
||||
std::vector<char> v (2 * (ZC_MEMO_SIZE+1)); // x2 for hexadecimal string format
|
||||
std::fill(v.begin(),v.end(), 'A');
|
||||
std::string badmemo(v.begin(), v.end());
|
||||
CZCPaymentAddress pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr1 = pa.ToString();
|
||||
auto pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr1 = EncodePaymentAddress(pa);
|
||||
BOOST_CHECK_THROW(CallRPC(string("z_sendmany tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ ")
|
||||
+ "[{\"address\":\"" + zaddr1 + "\", \"amount\":123.456}]"), runtime_error);
|
||||
|
||||
@@ -952,7 +948,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
|
||||
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(mtx, "INVALID", recipients, {}, 1) );
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "payment address is invalid"));
|
||||
BOOST_CHECK( find_error(objError, "Invalid from address"));
|
||||
}
|
||||
|
||||
// Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix.
|
||||
@@ -960,7 +956,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
|
||||
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany(mtx, "zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", recipients, {}, 1) );
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "payment address is for wrong network type"));
|
||||
BOOST_CHECK( find_error(objError, "Invalid from address"));
|
||||
}
|
||||
|
||||
// Note: The following will crash as a google test because AsyncRPCOperation_sendmany
|
||||
@@ -994,8 +990,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
||||
// add keys manually
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress"));
|
||||
std::string taddr1 = retValue.get_str();
|
||||
CZCPaymentAddress pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr1 = pa.ToString();
|
||||
auto pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr1 = EncodePaymentAddress(pa);
|
||||
|
||||
// there are no utxos to spend
|
||||
{
|
||||
@@ -1392,7 +1388,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_shieldcoinbase_parameters)
|
||||
std::vector<ShieldCoinbaseUTXO> inputs = { ShieldCoinbaseUTXO{uint256(),0,0} };
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_shieldcoinbase(mtx, inputs, mainnetzaddr, 1) );
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "payment address is for wrong network type"));
|
||||
BOOST_CHECK( find_error(objError, "Invalid to address"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1417,8 +1413,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_shieldcoinbase_internals)
|
||||
mapArgs["-mempooltxinputlimit"] = "1";
|
||||
|
||||
// Add keys manually
|
||||
CZCPaymentAddress pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr = pa.ToString();
|
||||
auto pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr = EncodePaymentAddress(pa);
|
||||
|
||||
// Supply 2 inputs when mempool limit is 1
|
||||
{
|
||||
@@ -1542,8 +1538,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters)
|
||||
std::vector<char> v (2 * (ZC_MEMO_SIZE+1)); // x2 for hexadecimal string format
|
||||
std::fill(v.begin(),v.end(), 'A');
|
||||
std::string badmemo(v.begin(), v.end());
|
||||
CZCPaymentAddress pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr1 = pa.ToString();
|
||||
auto pa = pwalletMain->GenerateNewZKey();
|
||||
std::string zaddr1 = EncodePaymentAddress(pa);
|
||||
BOOST_CHECK_THROW(CallRPC(string("z_mergetoaddress [\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] ")
|
||||
+ zaddr1 + " 0.0001 100 100 " + badmemo), runtime_error);
|
||||
|
||||
@@ -1590,7 +1586,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters)
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, mainnetzaddr, 1) );
|
||||
BOOST_FAIL("Should have caused an error");
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "payment address is for wrong network type"));
|
||||
BOOST_CHECK( find_error(objError, "Invalid recipient address"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1613,8 +1609,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals)
|
||||
// Add keys manually
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress"));
|
||||
MergeToAddressRecipient taddr1(retValue.get_str(), "");
|
||||
CZCPaymentAddress pa = pwalletMain->GenerateNewZKey();
|
||||
MergeToAddressRecipient zaddr1(pa.ToString(), "DEADBEEF");
|
||||
auto pa = pwalletMain->GenerateNewZKey();
|
||||
MergeToAddressRecipient zaddr1(EncodePaymentAddress(pa), "DEADBEEF");
|
||||
|
||||
// Supply 2 inputs when mempool limit is 1
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "asyncrpcqueue.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "miner.h"
|
||||
#include "net.h"
|
||||
@@ -78,14 +79,12 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
||||
isToZaddr_ = false;
|
||||
|
||||
if (!isToTaddr_) {
|
||||
CZCPaymentAddress address(std::get<0>(recipient));
|
||||
try {
|
||||
PaymentAddress addr = address.Get();
|
||||
|
||||
auto address = DecodePaymentAddress(std::get<0>(recipient));
|
||||
if (address) {
|
||||
isToZaddr_ = true;
|
||||
toPaymentAddress_ = addr;
|
||||
} catch (const std::runtime_error& e) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("runtime error: ") + e.what());
|
||||
toPaymentAddress_ = *address;
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,8 +856,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
||||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
CZCPaymentAddress address(zaddr);
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "amount.h"
|
||||
#include "asyncrpcoperation.h"
|
||||
#include "base58.h"
|
||||
#include "paymentdisclosure.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "wallet.h"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "consensus/upgrades.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "netbase.h"
|
||||
@@ -79,9 +80,9 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
||||
isfromzaddr_ = false;
|
||||
|
||||
if (!isfromtaddr_) {
|
||||
CZCPaymentAddress address(fromAddress);
|
||||
try {
|
||||
PaymentAddress addr = address.Get();
|
||||
auto address = DecodePaymentAddress(fromAddress);
|
||||
if (address) {
|
||||
PaymentAddress addr = *address;
|
||||
|
||||
// We don't need to lock on the wallet as spending key related methods are thread-safe
|
||||
SpendingKey key;
|
||||
@@ -92,8 +93,8 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
||||
isfromzaddr_ = true;
|
||||
frompaymentaddress_ = addr;
|
||||
spendingkey_ = key;
|
||||
} catch (const std::runtime_error& e) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("runtime error: ") + e.what());
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +468,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
std::string hexMemo = std::get<2>(smr);
|
||||
zOutputsDeque.pop_front();
|
||||
|
||||
PaymentAddress pa = CZCPaymentAddress(address).Get();
|
||||
PaymentAddress pa = *DecodePaymentAddress(address);
|
||||
JSOutput jso = JSOutput(pa, value);
|
||||
if (hexMemo.size() > 0) {
|
||||
jso.memo = get_memo_from_hex_string(hexMemo);
|
||||
@@ -726,7 +727,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
assert(value==0);
|
||||
info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new
|
||||
} else {
|
||||
PaymentAddress pa = CZCPaymentAddress(address).Get();
|
||||
PaymentAddress pa = *DecodePaymentAddress(address);
|
||||
JSOutput jso = JSOutput(pa, value);
|
||||
if (hexMemo.size() > 0) {
|
||||
jso.memo = get_memo_from_hex_string(hexMemo);
|
||||
@@ -1080,8 +1081,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
CZCPaymentAddress address(zaddr);
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "asyncrpcoperation.h"
|
||||
#include "amount.h"
|
||||
#include "base58.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
#include "zcash/Address.hpp"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "consensus/upgrades.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "netbase.h"
|
||||
@@ -71,11 +72,11 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
|
||||
}
|
||||
|
||||
// Check the destination address is valid for this network i.e. not testnet being used on mainnet
|
||||
CZCPaymentAddress address(toAddress);
|
||||
try {
|
||||
tozaddr_ = address.Get();
|
||||
} catch (const std::runtime_error& e) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("runtime error: ") + e.what());
|
||||
auto address = DecodePaymentAddress(toAddress);
|
||||
if (address) {
|
||||
tozaddr_ = *address;
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid to address");
|
||||
}
|
||||
|
||||
// Log the context info
|
||||
@@ -451,8 +452,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
CZCPaymentAddress address(zaddr);
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString());
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "asyncrpcoperation.h"
|
||||
#include "amount.h"
|
||||
#include "base58.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
#include "zcash/Address.hpp"
|
||||
|
||||
@@ -25,12 +25,11 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
|
||||
ASSERT_EQ(0, addrs.size());
|
||||
|
||||
// wallet should have one key
|
||||
CZCPaymentAddress paymentAddress = wallet.GenerateNewZKey();
|
||||
auto addr = wallet.GenerateNewZKey();
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
|
||||
// verify wallet has spending key for the address
|
||||
auto addr = paymentAddress.Get();
|
||||
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
||||
|
||||
// manually add new spending key to wallet
|
||||
@@ -289,22 +288,22 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
|
||||
ASSERT_EQ(2, addrs.size());
|
||||
|
||||
// check we have entries for our payment addresses
|
||||
ASSERT_TRUE(addrs.count(paymentAddress.Get()));
|
||||
ASSERT_TRUE(addrs.count(paymentAddress2.Get()));
|
||||
ASSERT_TRUE(addrs.count(paymentAddress));
|
||||
ASSERT_TRUE(addrs.count(paymentAddress2));
|
||||
|
||||
// spending key is crypted, so we can't extract valid payment address
|
||||
libzcash::SpendingKey keyOut;
|
||||
wallet2.GetSpendingKey(paymentAddress.Get(), keyOut);
|
||||
ASSERT_FALSE(paymentAddress.Get() == keyOut.address());
|
||||
wallet2.GetSpendingKey(paymentAddress, keyOut);
|
||||
ASSERT_FALSE(paymentAddress == keyOut.address());
|
||||
|
||||
// unlock wallet to get spending keys and verify payment addresses
|
||||
wallet2.Unlock(strWalletPass);
|
||||
|
||||
wallet2.GetSpendingKey(paymentAddress.Get(), keyOut);
|
||||
ASSERT_EQ(paymentAddress.Get(), keyOut.address());
|
||||
wallet2.GetSpendingKey(paymentAddress, keyOut);
|
||||
ASSERT_EQ(paymentAddress, keyOut.address());
|
||||
|
||||
wallet2.GetSpendingKey(paymentAddress2.Get(), keyOut);
|
||||
ASSERT_EQ(paymentAddress2.Get(), keyOut.address());
|
||||
wallet2.GetSpendingKey(paymentAddress2, keyOut);
|
||||
ASSERT_EQ(paymentAddress2, keyOut.address());
|
||||
|
||||
ECC_Stop();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "base58.h"
|
||||
#include "rpcserver.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
@@ -254,11 +254,8 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp)
|
||||
|
||||
// Check the payment address is valid
|
||||
PaymentAddress zaddr = pd.payload.zaddr;
|
||||
CZCPaymentAddress address;
|
||||
if (!address.Set(zaddr)) {
|
||||
errs.push_back("Payment disclosure refers to an invalid payment address");
|
||||
} else {
|
||||
o.push_back(Pair("paymentAddress", address.ToString()));
|
||||
{
|
||||
o.push_back(Pair("paymentAddress", EncodePaymentAddress(zaddr)));
|
||||
|
||||
try {
|
||||
// Decrypt the note to get value and memo field
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "base58.h"
|
||||
#include "key_io.h"
|
||||
#include "rpcserver.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
@@ -112,13 +112,8 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
|
||||
if (params.size() > 2)
|
||||
fRescan = params[2].get_bool();
|
||||
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(strSecret);
|
||||
|
||||
if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
|
||||
CKey key = DecodeSecret(strSecret);
|
||||
if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
assert(key.VerifyPubKey(pubkey));
|
||||
@@ -300,16 +295,16 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
|
||||
|
||||
// Let's see if the address is a valid Zcash spending key
|
||||
if (fImportZKeys) {
|
||||
try {
|
||||
CZCSpendingKey spendingkey(vstr[0]);
|
||||
libzcash::SpendingKey key = spendingkey.Get();
|
||||
auto spendingkey = DecodeSpendingKey(vstr[0]);
|
||||
if (spendingkey) {
|
||||
libzcash::SpendingKey key = *spendingkey;
|
||||
libzcash::PaymentAddress addr = key.address();
|
||||
if (pwalletMain->HaveSpendingKey(addr)) {
|
||||
LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", CZCPaymentAddress(addr).ToString());
|
||||
LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr));
|
||||
continue;
|
||||
}
|
||||
int64_t nTime = DecodeDumpTime(vstr[1]);
|
||||
LogPrint("zrpc", "Importing zaddr %s...\n", CZCPaymentAddress(addr).ToString());
|
||||
LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
|
||||
if (!pwalletMain->AddZKey(key)) {
|
||||
// Something went wrong
|
||||
fGood = false;
|
||||
@@ -318,17 +313,15 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
|
||||
// Successfully imported zaddr. Now import the metadata.
|
||||
pwalletMain->mapZKeyMetadata[addr].nCreateTime = nTime;
|
||||
continue;
|
||||
}
|
||||
catch (const std::runtime_error &e) {
|
||||
LogPrint("zrpc","Importing detected an error: %s\n", e.what());
|
||||
} else {
|
||||
LogPrint("zrpc", "Importing detected an error: invalid spending key. Trying as a transparent key...\n");
|
||||
// Not a valid spending key, so carry on and see if it's a Zcash style address.
|
||||
}
|
||||
}
|
||||
|
||||
CBitcoinSecret vchSecret;
|
||||
if (!vchSecret.SetString(vstr[0]))
|
||||
CKey key = DecodeSecret(vstr[0]);
|
||||
if (!key.IsValid())
|
||||
continue;
|
||||
CKey key = vchSecret.GetKey();
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
assert(key.VerifyPubKey(pubkey));
|
||||
CKeyID keyid = pubkey.GetID();
|
||||
@@ -418,7 +411,7 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp)
|
||||
if (!pwalletMain->GetKey(*keyID, vchSecret)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
|
||||
}
|
||||
return CBitcoinSecret(vchSecret).ToString();
|
||||
return EncodeSecret(vchSecret);
|
||||
}
|
||||
|
||||
|
||||
@@ -522,11 +515,11 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
|
||||
CKey key;
|
||||
if (pwalletMain->GetKey(keyid, key)) {
|
||||
if (pwalletMain->mapAddressBook.count(keyid)) {
|
||||
file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr);
|
||||
file << strprintf("%s %s label=%s # addr=%s\n", EncodeSecret(key), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr);
|
||||
} else if (setKeyPool.count(keyid)) {
|
||||
file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
|
||||
file << strprintf("%s %s reserve=1 # addr=%s\n", EncodeSecret(key), strTime, strAddr);
|
||||
} else {
|
||||
file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
|
||||
file << strprintf("%s %s change=1 # addr=%s\n", EncodeSecret(key), strTime, strAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -542,7 +535,7 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
|
||||
libzcash::SpendingKey key;
|
||||
if (pwalletMain->GetSpendingKey(addr, key)) {
|
||||
std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime);
|
||||
file << strprintf("%s %s # zaddr=%s\n", CZCSpendingKey(key).ToString(), strTime, CZCPaymentAddress(addr).ToString());
|
||||
file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr));
|
||||
}
|
||||
}
|
||||
file << "\n";
|
||||
@@ -620,8 +613,11 @@ UniValue z_importkey(const UniValue& params, bool fHelp)
|
||||
}
|
||||
|
||||
string strSecret = params[0].get_str();
|
||||
CZCSpendingKey spendingkey(strSecret);
|
||||
auto key = spendingkey.Get();
|
||||
auto spendingkey = DecodeSpendingKey(strSecret);
|
||||
if (!spendingkey) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||
}
|
||||
auto key = *spendingkey;
|
||||
auto addr = key.address();
|
||||
|
||||
{
|
||||
@@ -709,8 +705,11 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp)
|
||||
}
|
||||
|
||||
string strVKey = params[0].get_str();
|
||||
CZCViewingKey viewingkey(strVKey);
|
||||
auto vkey = viewingkey.Get();
|
||||
auto viewingkey = DecodeViewingKey(strVKey);
|
||||
if (!viewingkey) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid viewing key");
|
||||
}
|
||||
auto vkey = *viewingkey;
|
||||
auto addr = vkey.address();
|
||||
|
||||
{
|
||||
@@ -766,15 +765,17 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
|
||||
|
||||
string strAddress = params[0].get_str();
|
||||
|
||||
CZCPaymentAddress address(strAddress);
|
||||
auto addr = address.Get();
|
||||
auto address = DecodePaymentAddress(strAddress);
|
||||
if (!address) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
||||
}
|
||||
auto addr = *address;
|
||||
|
||||
libzcash::SpendingKey k;
|
||||
if (!pwalletMain->GetSpendingKey(addr, k))
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
|
||||
|
||||
CZCSpendingKey spendingkey(k);
|
||||
return spendingkey.ToString();
|
||||
return EncodeSpendingKey(k);
|
||||
}
|
||||
|
||||
UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
|
||||
@@ -802,8 +803,11 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
|
||||
|
||||
string strAddress = params[0].get_str();
|
||||
|
||||
CZCPaymentAddress address(strAddress);
|
||||
auto addr = address.Get();
|
||||
auto address = DecodePaymentAddress(strAddress);
|
||||
if (!address) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
||||
}
|
||||
auto addr = *address;
|
||||
|
||||
libzcash::ViewingKey vk;
|
||||
if (!pwalletMain->GetViewingKey(addr, vk)) {
|
||||
@@ -814,6 +818,5 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
|
||||
vk = k.viewing_key();
|
||||
}
|
||||
|
||||
CZCViewingKey viewingkey(vk);
|
||||
return viewingkey.ToString();
|
||||
return EncodeViewingKey(vk);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "amount.h"
|
||||
#include "base58.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "netbase.h"
|
||||
@@ -2521,14 +2521,14 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string");
|
||||
}
|
||||
string address = o.get_str();
|
||||
try {
|
||||
CZCPaymentAddress zaddr(address);
|
||||
libzcash::PaymentAddress addr = zaddr.Get();
|
||||
auto zaddr = DecodePaymentAddress(address);
|
||||
if (zaddr) {
|
||||
libzcash::PaymentAddress addr = *zaddr;
|
||||
if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address);
|
||||
}
|
||||
zaddrs.insert(addr);
|
||||
} catch (const std::runtime_error&) {
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, address is not a valid zaddr: ") + address);
|
||||
}
|
||||
|
||||
@@ -2555,7 +2555,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||
obj.push_back(Pair("jsoutindex", (int)entry.jsop.n));
|
||||
obj.push_back(Pair("confirmations", entry.nHeight));
|
||||
obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(entry.address)));
|
||||
obj.push_back(Pair("address", CZCPaymentAddress(entry.address).ToString()));
|
||||
obj.push_back(Pair("address", EncodePaymentAddress(entry.address)));
|
||||
obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value()))));
|
||||
std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end());
|
||||
obj.push_back(Pair("memo", HexStr(data)));
|
||||
@@ -2792,8 +2792,11 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp)
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
CZCSpendingKey spendingkey(params[0].get_str());
|
||||
SpendingKey k = spendingkey.Get();
|
||||
auto spendingkey = DecodeSpendingKey(params[0].get_str());
|
||||
if (!spendingkey) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||
}
|
||||
SpendingKey k = *spendingkey;
|
||||
|
||||
uint256 epk;
|
||||
unsigned char nonce;
|
||||
@@ -2903,8 +2906,11 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
||||
std::vector<uint256> commitments;
|
||||
|
||||
for (const string& name_ : inputs.getKeys()) {
|
||||
CZCSpendingKey spendingkey(inputs[name_].get_str());
|
||||
SpendingKey k = spendingkey.Get();
|
||||
auto spendingkey = DecodeSpendingKey(inputs[name_].get_str());
|
||||
if (!spendingkey) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||
}
|
||||
SpendingKey k = *spendingkey;
|
||||
|
||||
keys.push_back(k);
|
||||
|
||||
@@ -2945,11 +2951,13 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
||||
}
|
||||
|
||||
for (const string& name_ : outputs.getKeys()) {
|
||||
CZCPaymentAddress pubaddr(name_);
|
||||
PaymentAddress addrTo = pubaddr.Get();
|
||||
auto addrTo = DecodePaymentAddress(name_);
|
||||
if (!addrTo) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address.");
|
||||
}
|
||||
CAmount nAmount = AmountFromValue(outputs[name_]);
|
||||
|
||||
vjsout.push_back(JSOutput(addrTo, nAmount));
|
||||
vjsout.push_back(JSOutput(*addrTo, nAmount));
|
||||
}
|
||||
|
||||
while (vjsout.size() < ZC_NUM_JS_OUTPUTS) {
|
||||
@@ -3059,14 +3067,10 @@ UniValue zc_raw_keygen(const UniValue& params, bool fHelp)
|
||||
auto addr = k.address();
|
||||
auto viewing_key = k.viewing_key();
|
||||
|
||||
CZCPaymentAddress pubaddr(addr);
|
||||
CZCSpendingKey spendingkey(k);
|
||||
CZCViewingKey viewingkey(viewing_key);
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("zcaddress", pubaddr.ToString()));
|
||||
result.push_back(Pair("zcsecretkey", spendingkey.ToString()));
|
||||
result.push_back(Pair("zcviewingkey", viewingkey.ToString()));
|
||||
result.push_back(Pair("zcaddress", EncodePaymentAddress(addr)));
|
||||
result.push_back(Pair("zcsecretkey", EncodeSpendingKey(k)));
|
||||
result.push_back(Pair("zcviewingkey", EncodeViewingKey(viewing_key)));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3092,9 +3096,8 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp)
|
||||
|
||||
EnsureWalletIsUnlocked();
|
||||
|
||||
CZCPaymentAddress pubaddr = pwalletMain->GenerateNewZKey();
|
||||
std::string result = pubaddr.ToString();
|
||||
return result;
|
||||
auto zaddr = pwalletMain->GenerateNewZKey();
|
||||
return EncodePaymentAddress(zaddr);
|
||||
}
|
||||
|
||||
|
||||
@@ -3131,7 +3134,7 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp)
|
||||
pwalletMain->GetPaymentAddresses(addresses);
|
||||
for (auto addr : addresses ) {
|
||||
if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) {
|
||||
ret.push_back(CZCPaymentAddress(addr).ToString());
|
||||
ret.push_back(EncodePaymentAddress(addr));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@@ -3228,15 +3231,12 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
||||
// Check that the from address is valid.
|
||||
auto fromaddress = params[0].get_str();
|
||||
|
||||
libzcash::PaymentAddress zaddr;
|
||||
CZCPaymentAddress address(fromaddress);
|
||||
try {
|
||||
zaddr = address.Get();
|
||||
} catch (const std::runtime_error&) {
|
||||
auto zaddr = DecodePaymentAddress(fromaddress);
|
||||
if (!zaddr) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr.");
|
||||
}
|
||||
|
||||
if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) {
|
||||
if (!(pwalletMain->HaveSpendingKey(*zaddr) || pwalletMain->HaveViewingKey(*zaddr))) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
|
||||
}
|
||||
|
||||
@@ -3301,12 +3301,11 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
|
||||
fromTaddr = IsValidDestination(taddr);
|
||||
libzcash::PaymentAddress zaddr;
|
||||
if (!fromTaddr) {
|
||||
CZCPaymentAddress address(fromaddress);
|
||||
try {
|
||||
zaddr = address.Get();
|
||||
} catch (const std::runtime_error&) {
|
||||
auto res = DecodePaymentAddress(fromaddress);
|
||||
if (!res) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
||||
}
|
||||
zaddr = *res;
|
||||
if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
|
||||
}
|
||||
@@ -3537,13 +3536,12 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||
fromTaddr = IsValidDestination(taddr);
|
||||
libzcash::PaymentAddress zaddr;
|
||||
if (!fromTaddr) {
|
||||
CZCPaymentAddress address(fromaddress);
|
||||
try {
|
||||
zaddr = address.Get();
|
||||
} catch (const std::runtime_error&) {
|
||||
auto res = DecodePaymentAddress(fromaddress);
|
||||
if (!res) {
|
||||
// invalid
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
||||
}
|
||||
zaddr = *res;
|
||||
}
|
||||
|
||||
// Check that we have the spending key
|
||||
@@ -3581,11 +3579,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||
bool isZaddr = false;
|
||||
CTxDestination taddr = DecodeDestination(address);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
try {
|
||||
CZCPaymentAddress zaddr(address);
|
||||
zaddr.Get();
|
||||
if (DecodePaymentAddress(address)) {
|
||||
isZaddr = true;
|
||||
} catch (const std::runtime_error&) {
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
|
||||
}
|
||||
}
|
||||
@@ -3777,10 +3773,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
||||
|
||||
// Validate the destination address
|
||||
auto destaddress = params[1].get_str();
|
||||
try {
|
||||
CZCPaymentAddress pa(destaddress);
|
||||
libzcash::PaymentAddress zaddr = pa.Get();
|
||||
} catch (const std::runtime_error&) {
|
||||
if (!DecodePaymentAddress(destaddress)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||
}
|
||||
|
||||
@@ -4021,13 +4014,13 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
taddrs.insert(taddr);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
CZCPaymentAddress zaddr(address);
|
||||
auto zaddr = DecodePaymentAddress(address);
|
||||
if (zaddr) {
|
||||
// Ignore listed z-addrs if we are using all of them
|
||||
if (!(useAny || useAnyNote)) {
|
||||
zaddrs.insert(zaddr.Get());
|
||||
zaddrs.insert(*zaddr);
|
||||
}
|
||||
} catch (const std::runtime_error&) {
|
||||
} else {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
string("Invalid parameter, unknown address format: ") + address);
|
||||
@@ -4045,11 +4038,9 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||
bool isToZaddr = false;
|
||||
CTxDestination taddr = DecodeDestination(destaddress);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
try {
|
||||
CZCPaymentAddress zaddr(destaddress);
|
||||
zaddr.Get();
|
||||
if (DecodePaymentAddress(destaddress)) {
|
||||
isToZaddr = true;
|
||||
} catch (const std::runtime_error&) {
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "checkpoints.h"
|
||||
#include "coincontrol.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "init.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "script/script.h"
|
||||
@@ -80,7 +80,7 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
|
||||
}
|
||||
|
||||
// Generate a new spending key and return its public payment address
|
||||
CZCPaymentAddress CWallet::GenerateNewZKey()
|
||||
libzcash::PaymentAddress CWallet::GenerateNewZKey()
|
||||
{
|
||||
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
||||
auto k = SpendingKey::random();
|
||||
@@ -94,10 +94,9 @@ CZCPaymentAddress CWallet::GenerateNewZKey()
|
||||
int64_t nCreationTime = GetTime();
|
||||
mapZKeyMetadata[addr] = CKeyMetadata(nCreationTime);
|
||||
|
||||
CZCPaymentAddress pubaddr(addr);
|
||||
if (!AddZKey(k))
|
||||
throw std::runtime_error("CWallet::GenerateNewZKey(): AddZKey failed");
|
||||
return pubaddr;
|
||||
return addr;
|
||||
}
|
||||
|
||||
// Add spending key to keystore and persist to disk
|
||||
@@ -3716,7 +3715,7 @@ void CWallet::GetFilteredNotes(std::vector<CSproutNotePlaintextEntry> & outEntri
|
||||
std::set<PaymentAddress> filterAddresses;
|
||||
|
||||
if (address.length() > 0) {
|
||||
filterAddresses.insert(CZCPaymentAddress(address).Get());
|
||||
filterAddresses.insert(*DecodePaymentAddress(address));
|
||||
}
|
||||
|
||||
GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable);
|
||||
@@ -3779,7 +3778,7 @@ void CWallet::GetFilteredNotes(
|
||||
ZCNoteDecryption decryptor;
|
||||
if (!GetNoteDecryptor(pa, decryptor)) {
|
||||
// Note decryptors are created when the wallet is loaded, so it should always exist
|
||||
throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", CZCPaymentAddress(pa).ToString()));
|
||||
throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", EncodePaymentAddress(pa)));
|
||||
}
|
||||
|
||||
// determine amount of funds in the note
|
||||
@@ -3796,10 +3795,10 @@ void CWallet::GetFilteredNotes(
|
||||
|
||||
} catch (const note_decryption_failed &err) {
|
||||
// Couldn't decrypt with this spending key
|
||||
throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", CZCPaymentAddress(pa).ToString()));
|
||||
throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", EncodePaymentAddress(pa)));
|
||||
} catch (const std::exception &exc) {
|
||||
// Unexpected failure
|
||||
throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", CZCPaymentAddress(pa).ToString(), exc.what()));
|
||||
throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3855,7 +3854,7 @@ void CWallet::GetUnspentFilteredNotes(
|
||||
ZCNoteDecryption decryptor;
|
||||
if (!GetNoteDecryptor(pa, decryptor)) {
|
||||
// Note decryptors are created when the wallet is loaded, so it should always exist
|
||||
throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", CZCPaymentAddress(pa).ToString()));
|
||||
throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", EncodePaymentAddress(pa)));
|
||||
}
|
||||
|
||||
// determine amount of funds in the note
|
||||
@@ -3872,10 +3871,10 @@ void CWallet::GetUnspentFilteredNotes(
|
||||
|
||||
} catch (const note_decryption_failed &err) {
|
||||
// Couldn't decrypt with this spending key
|
||||
throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", CZCPaymentAddress(pa).ToString()));
|
||||
throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", EncodePaymentAddress(pa)));
|
||||
} catch (const std::exception &exc) {
|
||||
// Unexpected failure
|
||||
throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", CZCPaymentAddress(pa).ToString(), exc.what()));
|
||||
throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -960,7 +960,7 @@ public:
|
||||
* ZKeys
|
||||
*/
|
||||
//! Generates a new zaddr
|
||||
CZCPaymentAddress GenerateNewZKey();
|
||||
libzcash::PaymentAddress GenerateNewZKey();
|
||||
//! Adds spending key to the store, and saves it to disk
|
||||
bool AddZKey(const libzcash::SpendingKey &key);
|
||||
//! Adds spending key to the store, without saving it to disk (used by LoadWallet)
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include "wallet/walletdb.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "key_io.h"
|
||||
#include "main.h"
|
||||
#include "protocol.h"
|
||||
#include "serialize.h"
|
||||
|
||||
Reference in New Issue
Block a user