Make evident the relationship between chainparams and key IO.
This commit is contained in:
parent
8121e874e2
commit
07ff0d19a0
|
@ -240,9 +240,11 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strIn
|
|||
if (!ParseMoney(strValue, value))
|
||||
throw std::runtime_error("invalid TX output value");
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// extract and validate ADDRESS
|
||||
std::string strAddr = strInput.substr(pos + 1, std::string::npos);
|
||||
CTxDestination destination = DecodeDestination(strAddr);
|
||||
CTxDestination destination = keyIO.DecodeDestination(strAddr);
|
||||
if (!IsValidDestination(destination)) {
|
||||
throw std::runtime_error("invalid TX output address");
|
||||
}
|
||||
|
@ -399,10 +401,12 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& strInput)
|
|||
UniValue keysObj = registers["privatekeys"];
|
||||
fGivenKeys = true;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
for (size_t kidx = 0; kidx < keysObj.size(); kidx++) {
|
||||
if (!keysObj[kidx].isStr())
|
||||
throw std::runtime_error("privatekey not a std::string");
|
||||
CKey key = DecodeSecret(keysObj[kidx].getValStr());
|
||||
CKey key = keyIO.DecodeSecret(keysObj[kidx].getValStr());
|
||||
if (!key.IsValid()) {
|
||||
throw std::runtime_error("privatekey not valid");
|
||||
}
|
||||
|
|
|
@ -127,6 +127,48 @@ public:
|
|||
|
||||
consensus.nFundingPeriodLength = consensus.nPostBlossomSubsidyHalvingInterval / 48;
|
||||
|
||||
// guarantees the first 2 characters, when base58 encoded, are "t1"
|
||||
keyInfo.base58Prefixes[PUBKEY_ADDRESS] = {0x1C,0xB8};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "t3"
|
||||
keyInfo.base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBD};
|
||||
// the first character, when base58 encoded, is "5" or "K" or "L" (as in Bitcoin)
|
||||
keyInfo.base58Prefixes[SECRET_KEY] = {0x80};
|
||||
// do not rely on these BIP32 prefixes; they are not specified and may change
|
||||
keyInfo.base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x88,0xB2,0x1E};
|
||||
keyInfo.base58Prefixes[EXT_SECRET_KEY] = {0x04,0x88,0xAD,0xE4};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "zc"
|
||||
keyInfo.base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0x9A};
|
||||
// guarantees the first 4 characters, when base58 encoded, are "ZiVK"
|
||||
keyInfo.base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAB,0xD3};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "SK"
|
||||
keyInfo.base58Prefixes[ZCSPENDING_KEY] = {0xAB,0x36};
|
||||
|
||||
keyInfo.bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zs";
|
||||
keyInfo.bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviews";
|
||||
keyInfo.bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivks";
|
||||
keyInfo.bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-main";
|
||||
keyInfo.bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviews";
|
||||
|
||||
// TODO: This `if` can be removed once canopy activation height is set.
|
||||
if (consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) {
|
||||
std::vector<std::string> addresses(48, "");
|
||||
consensus.AddZIP207FundingStream(
|
||||
keyInfo,
|
||||
Consensus::FS_ZIP214_ECC,
|
||||
consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400,
|
||||
addresses);
|
||||
consensus.AddZIP207FundingStream(
|
||||
keyInfo,
|
||||
Consensus::FS_ZIP214_ZF,
|
||||
consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400,
|
||||
addresses);
|
||||
consensus.AddZIP207FundingStream(
|
||||
keyInfo,
|
||||
Consensus::FS_ZIP214_MG,
|
||||
consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400,
|
||||
addresses);
|
||||
}
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("000000000000000000000000000000000000000000000000017e73a331fae01c");
|
||||
|
||||
|
@ -157,28 +199,6 @@ public:
|
|||
vSeeds.push_back(CDNSSeedData("zfnd.org", "mainnet.seeder.zfnd.org")); // Zcash Foundation
|
||||
vSeeds.push_back(CDNSSeedData("yolo.money", "mainnet.is.yolo.money")); // gtank
|
||||
|
||||
// guarantees the first 2 characters, when base58 encoded, are "t1"
|
||||
base58Prefixes[PUBKEY_ADDRESS] = {0x1C,0xB8};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "t3"
|
||||
base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBD};
|
||||
// the first character, when base58 encoded, is "5" or "K" or "L" (as in Bitcoin)
|
||||
base58Prefixes[SECRET_KEY] = {0x80};
|
||||
// do not rely on these BIP32 prefixes; they are not specified and may change
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x88,0xB2,0x1E};
|
||||
base58Prefixes[EXT_SECRET_KEY] = {0x04,0x88,0xAD,0xE4};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "zc"
|
||||
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0x9A};
|
||||
// guarantees the first 4 characters, when base58 encoded, are "ZiVK"
|
||||
base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAB,0xD3};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "SK"
|
||||
base58Prefixes[ZCSPENDING_KEY] = {0xAB,0x36};
|
||||
|
||||
bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zs";
|
||||
bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviews";
|
||||
bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivks";
|
||||
bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-main";
|
||||
bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviews";
|
||||
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
|
||||
|
||||
fMiningRequiresPeers = true;
|
||||
|
@ -336,20 +356,46 @@ public:
|
|||
|
||||
consensus.nFundingPeriodLength = consensus.nPostBlossomSubsidyHalvingInterval / 48;
|
||||
|
||||
// guarantees the first 2 characters, when base58 encoded, are "tm"
|
||||
keyInfo.base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "t2"
|
||||
keyInfo.base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA};
|
||||
// the first character, when base58 encoded, is "9" or "c" (as in Bitcoin)
|
||||
keyInfo.base58Prefixes[SECRET_KEY] = {0xEF};
|
||||
// do not rely on these BIP32 prefixes; they are not specified and may change
|
||||
keyInfo.base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF};
|
||||
keyInfo.base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "zt"
|
||||
keyInfo.base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xB6};
|
||||
// guarantees the first 4 characters, when base58 encoded, are "ZiVt"
|
||||
keyInfo.base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "ST"
|
||||
keyInfo.base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
||||
|
||||
keyInfo.bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "ztestsapling";
|
||||
keyInfo.bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewtestsapling";
|
||||
keyInfo.bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivktestsapling";
|
||||
keyInfo.bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-test";
|
||||
keyInfo.bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviewtestsapling";
|
||||
|
||||
// TODO: This `if` can be removed once canopy activation height is set.
|
||||
if (consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) {
|
||||
std::vector<std::string> addresses(48, "");
|
||||
consensus.AddZIP207FundingStream(
|
||||
keyInfo,
|
||||
Consensus::FS_ZIP214_ECC,
|
||||
consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400,
|
||||
{/*TODO*/});
|
||||
addresses);
|
||||
consensus.AddZIP207FundingStream(
|
||||
keyInfo,
|
||||
Consensus::FS_ZIP214_ZF,
|
||||
consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400,
|
||||
{/*TODO*/});
|
||||
addresses);
|
||||
consensus.AddZIP207FundingStream(
|
||||
keyInfo,
|
||||
Consensus::FS_ZIP214_MG,
|
||||
consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400,
|
||||
{/*TODO*/});
|
||||
addresses);
|
||||
}
|
||||
|
||||
// On testnet we activate this rule 6 blocks after Blossom activation. From block 299188 and
|
||||
|
@ -395,28 +441,6 @@ public:
|
|||
vSeeds.push_back(CDNSSeedData("zfnd.org", "testnet.seeder.zfnd.org")); // Zcash Foundation
|
||||
vSeeds.push_back(CDNSSeedData("yolo.money", "testnet.is.yolo.money")); // gtank
|
||||
|
||||
// guarantees the first 2 characters, when base58 encoded, are "tm"
|
||||
base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "t2"
|
||||
base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA};
|
||||
// the first character, when base58 encoded, is "9" or "c" (as in Bitcoin)
|
||||
base58Prefixes[SECRET_KEY] = {0xEF};
|
||||
// do not rely on these BIP32 prefixes; they are not specified and may change
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF};
|
||||
base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "zt"
|
||||
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xB6};
|
||||
// guarantees the first 4 characters, when base58 encoded, are "ZiVt"
|
||||
base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C};
|
||||
// guarantees the first 2 characters, when base58 encoded, are "ST"
|
||||
base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
||||
|
||||
bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "ztestsapling";
|
||||
bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewtestsapling";
|
||||
bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivktestsapling";
|
||||
bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-test";
|
||||
bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviewtestsapling";
|
||||
|
||||
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
|
||||
|
||||
fMiningRequiresPeers = true;
|
||||
|
@ -517,6 +541,23 @@ public:
|
|||
consensus.nFundingPeriodLength = consensus.nPostBlossomSubsidyHalvingInterval / 48;
|
||||
// Defined funding streams can be enabled with node config flags.
|
||||
|
||||
// These prefixes are the same as the testnet prefixes
|
||||
keyInfo.base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25};
|
||||
keyInfo.base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA};
|
||||
keyInfo.base58Prefixes[SECRET_KEY] = {0xEF};
|
||||
// do not rely on these BIP32 prefixes; they are not specified and may change
|
||||
keyInfo.base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF};
|
||||
keyInfo.base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94};
|
||||
keyInfo.base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xB6};
|
||||
keyInfo.base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C};
|
||||
keyInfo.base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
||||
|
||||
keyInfo.bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zregtestsapling";
|
||||
keyInfo.bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewregtestsapling";
|
||||
keyInfo.bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivkregtestsapling";
|
||||
keyInfo.bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-regtest";
|
||||
keyInfo.bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviewregtestsapling";
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x00");
|
||||
|
||||
|
@ -552,22 +593,6 @@ public:
|
|||
0,
|
||||
0
|
||||
};
|
||||
// These prefixes are the same as the testnet prefixes
|
||||
base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25};
|
||||
base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA};
|
||||
base58Prefixes[SECRET_KEY] = {0xEF};
|
||||
// do not rely on these BIP32 prefixes; they are not specified and may change
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF};
|
||||
base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94};
|
||||
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xB6};
|
||||
base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C};
|
||||
base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08};
|
||||
|
||||
bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zregtestsapling";
|
||||
bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewregtestsapling";
|
||||
bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivkregtestsapling";
|
||||
bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-regtest";
|
||||
bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviewregtestsapling";
|
||||
|
||||
// Founders reward script expects a vector of 2-of-3 multisig addresses
|
||||
vFoundersRewardAddress = { "t2FwcEhFdNXuFMv1tcYwaBJtYVtMj8b1uTg" };
|
||||
|
@ -659,7 +684,8 @@ std::string CChainParams::GetFoundersRewardAddressAtHeight(int nHeight) const {
|
|||
CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const {
|
||||
assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight(nHeight));
|
||||
|
||||
CTxDestination address = DecodeDestination(GetFoundersRewardAddressAtHeight(nHeight).c_str());
|
||||
KeyIO keyIO(*this);
|
||||
CTxDestination address = keyIO.DecodeDestination(GetFoundersRewardAddressAtHeight(nHeight).c_str());
|
||||
assert(IsValidDestination(address));
|
||||
assert(IsScriptDestination(address));
|
||||
CScriptID scriptID = boost::get<CScriptID>(address); // address is a boost variant
|
||||
|
|
|
@ -32,6 +32,15 @@ struct CCheckpointData {
|
|||
double fTransactionsPerDay;
|
||||
};
|
||||
|
||||
class CBaseKeyInfo : public Consensus::KeyInfo {
|
||||
public:
|
||||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
||||
const std::string& Bech32HRP(Bech32Type type) const { return bech32HRPs[type]; }
|
||||
|
||||
std::vector<unsigned char> base58Prefixes[Consensus::KeyInfo::MAX_BASE58_TYPES];
|
||||
std::string bech32HRPs[Consensus::KeyInfo::MAX_BECH32_TYPES];
|
||||
};
|
||||
|
||||
/**
|
||||
* CChainParams defines various tweakable parameters of a given instance of the
|
||||
* Bitcoin system. There are three: the main network on which people trade goods
|
||||
|
@ -39,33 +48,9 @@ struct CCheckpointData {
|
|||
* a regression test mode which is intended for private networks only. It has
|
||||
* minimal difficulty to ensure that blocks can be found instantly.
|
||||
*/
|
||||
class CChainParams
|
||||
class CChainParams: public Consensus::KeyInfo
|
||||
{
|
||||
public:
|
||||
enum Base58Type {
|
||||
PUBKEY_ADDRESS,
|
||||
SCRIPT_ADDRESS,
|
||||
SECRET_KEY,
|
||||
EXT_PUBLIC_KEY,
|
||||
EXT_SECRET_KEY,
|
||||
|
||||
ZCPAYMENT_ADDRRESS,
|
||||
ZCSPENDING_KEY,
|
||||
ZCVIEWING_KEY,
|
||||
|
||||
MAX_BASE58_TYPES
|
||||
};
|
||||
|
||||
enum Bech32Type {
|
||||
SAPLING_PAYMENT_ADDRESS,
|
||||
SAPLING_FULL_VIEWING_KEY,
|
||||
SAPLING_INCOMING_VIEWING_KEY,
|
||||
SAPLING_EXTENDED_SPEND_KEY,
|
||||
SAPLING_EXTENDED_FVK,
|
||||
|
||||
MAX_BECH32_TYPES
|
||||
};
|
||||
|
||||
const Consensus::Params& GetConsensus() const { return consensus; }
|
||||
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
|
||||
|
@ -93,8 +78,12 @@ public:
|
|||
/** Return the BIP70 network string (main, test or regtest) */
|
||||
std::string NetworkIDString() const { return strNetworkID; }
|
||||
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
|
||||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
|
||||
const std::string& Bech32HRP(Bech32Type type) const { return bech32HRPs[type]; }
|
||||
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const {
|
||||
return keyInfo.Base58Prefix(type);
|
||||
}
|
||||
const std::string& Bech32HRP(Bech32Type type) const {
|
||||
return keyInfo.Bech32HRP(type);
|
||||
}
|
||||
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
|
||||
const CCheckpointData& Checkpoints() const { return checkpointData; }
|
||||
/** Return the founder's reward address and script for a given block height */
|
||||
|
@ -113,8 +102,7 @@ protected:
|
|||
int nDefaultPort = 0;
|
||||
uint64_t nPruneAfterHeight = 0;
|
||||
std::vector<CDNSSeedData> vSeeds;
|
||||
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
|
||||
std::string bech32HRPs[MAX_BECH32_TYPES];
|
||||
CBaseKeyInfo keyInfo;
|
||||
std::string strNetworkID;
|
||||
std::string strCurrencyUnits;
|
||||
uint32_t bip44CoinType;
|
||||
|
|
|
@ -142,18 +142,21 @@ namespace Consensus {
|
|||
|
||||
FundingStream FundingStream::ParseFundingStream(
|
||||
const Consensus::Params& params,
|
||||
const Consensus::KeyInfo& keyInfo,
|
||||
const int startHeight,
|
||||
const int endHeight,
|
||||
const std::vector<std::string>& strAddresses)
|
||||
{
|
||||
KeyIO keyIO(keyInfo);
|
||||
|
||||
// Parse the address strings into concrete types.
|
||||
std::vector<FundingStreamAddress> addresses;
|
||||
for (auto addr : strAddresses) {
|
||||
auto taddr = DecodeDestination(addr);
|
||||
auto taddr = keyIO.DecodeDestination(addr);
|
||||
if (IsValidDestination(taddr)) {
|
||||
addresses.push_back(GetScriptForDestination(taddr));
|
||||
} else {
|
||||
auto zaddr = DecodePaymentAddress(addr);
|
||||
auto zaddr = keyIO.DecodePaymentAddress(addr);
|
||||
// If the string is not a valid transparent or Sapling address, we will
|
||||
// throw here.
|
||||
|
||||
|
@ -166,12 +169,13 @@ namespace Consensus {
|
|||
};
|
||||
|
||||
void Params::AddZIP207FundingStream(
|
||||
const Consensus::KeyInfo& keyInfo,
|
||||
FundingStreamIndex idx,
|
||||
int startHeight,
|
||||
int endHeight,
|
||||
const std::vector<std::string>& strAddresses)
|
||||
{
|
||||
vFundingStreams[idx] = FundingStream::ParseFundingStream(*this, startHeight, endHeight, strAddresses);
|
||||
vFundingStreams[idx] = FundingStream::ParseFundingStream(*this, keyInfo, startHeight, endHeight, strAddresses);
|
||||
};
|
||||
|
||||
FundingStreamAddress FundingStream::RecipientAddress(const Consensus::Params& params, int nHeight) const
|
||||
|
|
|
@ -101,6 +101,37 @@ enum FundingStreamError {
|
|||
INSUFFICIENT_ADDRESSES,
|
||||
};
|
||||
|
||||
class KeyInfo
|
||||
{
|
||||
public:
|
||||
enum Base58Type {
|
||||
PUBKEY_ADDRESS,
|
||||
SCRIPT_ADDRESS,
|
||||
SECRET_KEY,
|
||||
EXT_PUBLIC_KEY,
|
||||
EXT_SECRET_KEY,
|
||||
|
||||
ZCPAYMENT_ADDRRESS,
|
||||
ZCSPENDING_KEY,
|
||||
ZCVIEWING_KEY,
|
||||
|
||||
MAX_BASE58_TYPES
|
||||
};
|
||||
|
||||
enum Bech32Type {
|
||||
SAPLING_PAYMENT_ADDRESS,
|
||||
SAPLING_FULL_VIEWING_KEY,
|
||||
SAPLING_INCOMING_VIEWING_KEY,
|
||||
SAPLING_EXTENDED_SPEND_KEY,
|
||||
SAPLING_EXTENDED_FVK,
|
||||
|
||||
MAX_BECH32_TYPES
|
||||
};
|
||||
|
||||
virtual const std::vector<unsigned char>& Base58Prefix(Base58Type type) const =0;
|
||||
virtual const std::string& Bech32HRP(Bech32Type type) const =0;
|
||||
};
|
||||
|
||||
class FundingStream
|
||||
{
|
||||
private:
|
||||
|
@ -123,6 +154,7 @@ public:
|
|||
|
||||
static FundingStream ParseFundingStream(
|
||||
const Consensus::Params& params,
|
||||
const Consensus::KeyInfo& keyInfo,
|
||||
const int startHeight,
|
||||
const int endHeight,
|
||||
const std::vector<std::string>& strAddresses);
|
||||
|
@ -209,6 +241,7 @@ struct Params {
|
|||
int nFundingPeriodLength;
|
||||
boost::optional<FundingStream> vFundingStreams[MAX_FUNDING_STREAMS];
|
||||
void AddZIP207FundingStream(
|
||||
const Consensus::KeyInfo& keyInfo,
|
||||
FundingStreamIndex idx,
|
||||
int startHeight,
|
||||
int endHeight,
|
||||
|
|
|
@ -142,9 +142,10 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
|||
out.pushKV("reqSigs", nRequired);
|
||||
out.pushKV("type", GetTxnOutputType(type));
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue a(UniValue::VARR);
|
||||
for (const CTxDestination& addr : addresses) {
|
||||
a.push_back(EncodeDestination(addr));
|
||||
a.push_back(keyIO.EncodeDestination(addr));
|
||||
}
|
||||
out.pushKV("addresses", a);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ TEST(FoundersRewardTest, create_testnet_2of3multisig) {
|
|||
pubkeys.resize(3);
|
||||
CPubKey newKey;
|
||||
std::vector<std::string> addresses;
|
||||
KeyIO keyIO(Params());
|
||||
for (int i = 0; i < numKeys; i++) {
|
||||
ASSERT_TRUE(pWallet->GetKeyFromPool(newKey));
|
||||
pubkeys[0] = newKey;
|
||||
|
@ -61,7 +62,7 @@ TEST(FoundersRewardTest, create_testnet_2of3multisig) {
|
|||
pWallet->AddCScript(result);
|
||||
pWallet->SetAddressBook(innerID, "", "receive");
|
||||
|
||||
std::string address = EncodeDestination(innerID);
|
||||
std::string address = keyIO.EncodeDestination(innerID);
|
||||
addresses.push_back(address);
|
||||
}
|
||||
|
||||
|
@ -239,19 +240,22 @@ TEST(FundingStreamsRewardTest, Zip207Distribution) {
|
|||
|
||||
int minHeight = GetLastFoundersRewardHeight(consensus) + 1;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
auto sk = libzcash::SaplingSpendingKey(uint256());
|
||||
for (int idx = Consensus::FIRST_FUNDING_STREAM; idx < Consensus::MAX_FUNDING_STREAMS; idx++) {
|
||||
// we can just use the same addresses for all streams, all we're trying to do here
|
||||
// is validate that the streams add up to the 20% of block reward.
|
||||
auto shieldedAddr = keyIO.EncodePaymentAddress(sk.default_address());
|
||||
UpdateFundingStreamParameters(
|
||||
(Consensus::FundingStreamIndex) idx,
|
||||
Consensus::FundingStream::ParseFundingStream(
|
||||
consensus,
|
||||
Params(),
|
||||
minHeight,
|
||||
minHeight + 12,
|
||||
{
|
||||
"t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi",
|
||||
EncodePaymentAddress(sk.default_address())
|
||||
shieldedAddr,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -278,15 +282,18 @@ TEST(FundingStreamsRewardTest, ParseFundingStream) {
|
|||
|
||||
int minHeight = GetLastFoundersRewardHeight(consensus) + 1;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
auto sk = libzcash::SaplingSpendingKey(uint256());
|
||||
auto shieldedAddr = keyIO.EncodePaymentAddress(sk.default_address());
|
||||
ASSERT_THROW(
|
||||
Consensus::FundingStream::ParseFundingStream(
|
||||
consensus,
|
||||
Params(),
|
||||
minHeight,
|
||||
minHeight + 13,
|
||||
{
|
||||
"t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi",
|
||||
EncodePaymentAddress(sk.default_address())
|
||||
shieldedAddr,
|
||||
}
|
||||
),
|
||||
std::runtime_error
|
||||
|
|
|
@ -9,18 +9,19 @@
|
|||
TEST(Keys, EncodeAndDecodeSapling)
|
||||
{
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
auto m = GetTestMasterSaplingSpendingKey();
|
||||
|
||||
for (uint32_t i = 0; i < 1000; i++) {
|
||||
auto sk = m.Derive(i);
|
||||
{
|
||||
std::string sk_string = EncodeSpendingKey(sk);
|
||||
std::string sk_string = keyIO.EncodeSpendingKey(sk);
|
||||
EXPECT_EQ(
|
||||
sk_string.substr(0, 24),
|
||||
Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY));
|
||||
|
||||
auto spendingkey2 = DecodeSpendingKey(sk_string);
|
||||
auto spendingkey2 = keyIO.DecodeSpendingKey(sk_string);
|
||||
EXPECT_TRUE(IsValidSpendingKey(spendingkey2));
|
||||
|
||||
ASSERT_TRUE(boost::get<libzcash::SaplingExtendedSpendingKey>(&spendingkey2) != nullptr);
|
||||
|
@ -29,12 +30,12 @@ TEST(Keys, EncodeAndDecodeSapling)
|
|||
}
|
||||
{
|
||||
auto extfvk = sk.ToXFVK();
|
||||
std::string vk_string = EncodeViewingKey(extfvk);
|
||||
std::string vk_string = keyIO.EncodeViewingKey(extfvk);
|
||||
EXPECT_EQ(
|
||||
vk_string.substr(0, 7),
|
||||
Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_FVK));
|
||||
|
||||
auto viewingkey2 = DecodeViewingKey(vk_string);
|
||||
auto viewingkey2 = keyIO.DecodeViewingKey(vk_string);
|
||||
EXPECT_TRUE(IsValidViewingKey(viewingkey2));
|
||||
|
||||
ASSERT_TRUE(boost::get<libzcash::SaplingExtendedFullViewingKey>(&viewingkey2) != nullptr);
|
||||
|
@ -44,12 +45,12 @@ TEST(Keys, EncodeAndDecodeSapling)
|
|||
{
|
||||
auto addr = sk.DefaultAddress();
|
||||
|
||||
std::string addr_string = EncodePaymentAddress(addr);
|
||||
std::string addr_string = keyIO.EncodePaymentAddress(addr);
|
||||
EXPECT_EQ(
|
||||
addr_string.substr(0, 2),
|
||||
Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS));
|
||||
|
||||
auto paymentaddr2 = DecodePaymentAddress(addr_string);
|
||||
auto paymentaddr2 = keyIO.DecodePaymentAddress(addr_string);
|
||||
EXPECT_TRUE(IsValidPaymentAddress(paymentaddr2));
|
||||
|
||||
ASSERT_TRUE(boost::get<libzcash::SaplingPaymentAddress>(&paymentaddr2) != nullptr);
|
||||
|
|
12
src/init.cpp
12
src/init.cpp
|
@ -1039,12 +1039,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
|
||||
nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
|
||||
|
||||
KeyIO keyIO(chainparams);
|
||||
#ifdef ENABLE_MINING
|
||||
if (mapArgs.count("-mineraddress")) {
|
||||
CTxDestination addr = DecodeDestination(mapArgs["-mineraddress"]);
|
||||
CTxDestination addr = keyIO.DecodeDestination(mapArgs["-mineraddress"]);
|
||||
if (!IsValidDestination(addr)) {
|
||||
// Try a Sapling address
|
||||
auto zaddr = DecodePaymentAddress(mapArgs["-mineraddress"]);
|
||||
auto zaddr = keyIO.DecodePaymentAddress(mapArgs["-mineraddress"]);
|
||||
if (!IsValidPaymentAddress(zaddr) ||
|
||||
boost::get<libzcash::SaplingPaymentAddress>(&zaddr) == nullptr)
|
||||
{
|
||||
|
@ -1127,7 +1128,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
std::vector<std::string> vStreamAddrs;
|
||||
boost::split(vStreamAddrs, vStreamParams[3], boost::is_any_of(","));
|
||||
|
||||
auto fs = Consensus::FundingStream::ParseFundingStream(Params().GetConsensus(), nStartHeight, nEndHeight, vStreamAddrs);
|
||||
auto fs = Consensus::FundingStream::ParseFundingStream(
|
||||
Params().GetConsensus(), Params(), nStartHeight, nEndHeight, vStreamAddrs);
|
||||
|
||||
UpdateFundingStreamParameters((Consensus::FundingStreamIndex) nFundingStreamId, fs);
|
||||
}
|
||||
|
@ -1586,12 +1588,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
#ifdef ENABLE_WALLET
|
||||
bool minerAddressInLocalWallet = false;
|
||||
if (pwalletMain) {
|
||||
CTxDestination addr = DecodeDestination(mapArgs["-mineraddress"]);
|
||||
CTxDestination addr = keyIO.DecodeDestination(mapArgs["-mineraddress"]);
|
||||
if (IsValidDestination(addr)) {
|
||||
CKeyID keyID = boost::get<CKeyID>(addr);
|
||||
minerAddressInLocalWallet = pwalletMain->HaveKey(keyID);
|
||||
} else {
|
||||
auto zaddr = DecodePaymentAddress(mapArgs["-mineraddress"]);
|
||||
auto zaddr = keyIO.DecodePaymentAddress(mapArgs["-mineraddress"]);
|
||||
minerAddressInLocalWallet = boost::apply_visitor(
|
||||
HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr);
|
||||
}
|
||||
|
|
166
src/key_io.cpp
166
src/key_io.cpp
|
@ -22,21 +22,21 @@ namespace
|
|||
class DestinationEncoder : public boost::static_visitor<std::string>
|
||||
{
|
||||
private:
|
||||
const CChainParams& m_params;
|
||||
const Consensus::KeyInfo& keyInfo;
|
||||
|
||||
public:
|
||||
DestinationEncoder(const CChainParams& params) : m_params(params) {}
|
||||
DestinationEncoder(const Consensus::KeyInfo& keyInfo) : keyInfo(keyInfo) {}
|
||||
|
||||
std::string operator()(const CKeyID& id) const
|
||||
{
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::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);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::SCRIPT_ADDRESS);
|
||||
data.insert(data.end(), id.begin(), id.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
@ -44,43 +44,19 @@ public:
|
|||
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();
|
||||
}
|
||||
|
||||
class PaymentAddressEncoder : public boost::static_visitor<std::string>
|
||||
{
|
||||
private:
|
||||
const CChainParams& m_params;
|
||||
const Consensus::KeyInfo& keyInfo;
|
||||
|
||||
public:
|
||||
PaymentAddressEncoder(const CChainParams& params) : m_params(params) {}
|
||||
PaymentAddressEncoder(const Consensus::KeyInfo& keyInfo) : keyInfo(keyInfo) {}
|
||||
|
||||
std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << zaddr;
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::ZCPAYMENT_ADDRRESS);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
return EncodeBase58Check(data);
|
||||
}
|
||||
|
@ -95,7 +71,7 @@ public:
|
|||
// See calculation comment below
|
||||
data.reserve((seraddr.size() * 8 + 4) / 5);
|
||||
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, seraddr.begin(), seraddr.end());
|
||||
return bech32::Encode(m_params.Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS), data);
|
||||
return bech32::Encode(keyInfo.Bech32HRP(Consensus::KeyInfo::SAPLING_PAYMENT_ADDRESS), data);
|
||||
}
|
||||
|
||||
std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
|
||||
|
@ -104,16 +80,16 @@ public:
|
|||
class ViewingKeyEncoder : public boost::static_visitor<std::string>
|
||||
{
|
||||
private:
|
||||
const CChainParams& m_params;
|
||||
const Consensus::KeyInfo& keyInfo;
|
||||
|
||||
public:
|
||||
ViewingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
||||
ViewingKeyEncoder(const Consensus::KeyInfo& keyInfo) : keyInfo(keyInfo) {}
|
||||
|
||||
std::string operator()(const libzcash::SproutViewingKey& vk) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << vk;
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::ZCVIEWING_KEY);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
|
@ -130,7 +106,7 @@ public:
|
|||
// See calculation comment below
|
||||
data.reserve((serkey.size() * 8 + 4) / 5);
|
||||
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, serkey.begin(), serkey.end());
|
||||
std::string ret = bech32::Encode(m_params.Bech32HRP(CChainParams::SAPLING_EXTENDED_FVK), data);
|
||||
std::string ret = bech32::Encode(keyInfo.Bech32HRP(Consensus::KeyInfo::SAPLING_EXTENDED_FVK), data);
|
||||
memory_cleanse(serkey.data(), serkey.size());
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
|
@ -142,16 +118,16 @@ public:
|
|||
class SpendingKeyEncoder : public boost::static_visitor<std::string>
|
||||
{
|
||||
private:
|
||||
const CChainParams& m_params;
|
||||
const Consensus::KeyInfo& keyInfo;
|
||||
|
||||
public:
|
||||
SpendingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
||||
SpendingKeyEncoder(const Consensus::KeyInfo& keyInfo) : keyInfo(keyInfo) {}
|
||||
|
||||
std::string operator()(const libzcash::SproutSpendingKey& zkey) const
|
||||
{
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << zkey;
|
||||
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::ZCSPENDING_KEY);
|
||||
data.insert(data.end(), ss.begin(), ss.end());
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
|
@ -168,7 +144,7 @@ public:
|
|||
// See calculation comment below
|
||||
data.reserve((serkey.size() * 8 + 4) / 5);
|
||||
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, serkey.begin(), serkey.end());
|
||||
std::string ret = bech32::Encode(m_params.Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY), data);
|
||||
std::string ret = bech32::Encode(keyInfo.Bech32HRP(Consensus::KeyInfo::SAPLING_EXTENDED_SPEND_KEY), data);
|
||||
memory_cleanse(serkey.data(), serkey.size());
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
|
@ -186,12 +162,36 @@ const size_t ConvertedSaplingExtendedFullViewingKeySize = (ZIP32_XFVK_SIZE * 8 +
|
|||
const size_t ConvertedSaplingExtendedSpendingKeySize = (ZIP32_XSK_SIZE * 8 + 4) / 5;
|
||||
} // namespace
|
||||
|
||||
CKey DecodeSecret(const std::string& str)
|
||||
CTxDestination KeyIO::DecodeDestination(const std::string& str)
|
||||
{
|
||||
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 = keyInfo.Base58Prefix(Consensus::KeyInfo::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 = keyInfo.Base58Prefix(Consensus::KeyInfo::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();
|
||||
};
|
||||
|
||||
CKey KeyIO::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);
|
||||
const std::vector<unsigned char>& privkey_prefix = keyInfo.Base58Prefix(Consensus::KeyInfo::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();
|
||||
|
@ -202,10 +202,10 @@ CKey DecodeSecret(const std::string& str)
|
|||
return key;
|
||||
}
|
||||
|
||||
std::string EncodeSecret(const CKey& key)
|
||||
std::string KeyIO::EncodeSecret(const CKey& key)
|
||||
{
|
||||
assert(key.IsValid());
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::SECRET_KEY);
|
||||
data.insert(data.end(), key.begin(), key.end());
|
||||
if (key.IsCompressed()) {
|
||||
data.push_back(1);
|
||||
|
@ -215,12 +215,12 @@ std::string EncodeSecret(const CKey& key)
|
|||
return ret;
|
||||
}
|
||||
|
||||
CExtPubKey DecodeExtPubKey(const std::string& str)
|
||||
CExtPubKey KeyIO::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);
|
||||
const std::vector<unsigned char>& prefix = keyInfo.Base58Prefix(Consensus::KeyInfo::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());
|
||||
}
|
||||
|
@ -228,9 +228,9 @@ CExtPubKey DecodeExtPubKey(const std::string& str)
|
|||
return key;
|
||||
}
|
||||
|
||||
std::string EncodeExtPubKey(const CExtPubKey& key)
|
||||
std::string KeyIO::EncodeExtPubKey(const CExtPubKey& key)
|
||||
{
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::EXT_PUBLIC_KEY);
|
||||
size_t size = data.size();
|
||||
data.resize(size + BIP32_EXTKEY_SIZE);
|
||||
key.Encode(data.data() + size);
|
||||
|
@ -238,12 +238,12 @@ std::string EncodeExtPubKey(const CExtPubKey& key)
|
|||
return ret;
|
||||
}
|
||||
|
||||
CExtKey DecodeExtKey(const std::string& str)
|
||||
CExtKey KeyIO::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);
|
||||
const std::vector<unsigned char>& prefix = keyInfo.Base58Prefix(Consensus::KeyInfo::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());
|
||||
}
|
||||
|
@ -251,9 +251,9 @@ CExtKey DecodeExtKey(const std::string& str)
|
|||
return key;
|
||||
}
|
||||
|
||||
std::string EncodeExtKey(const CExtKey& key)
|
||||
std::string KeyIO::EncodeExtKey(const CExtKey& key)
|
||||
{
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
|
||||
std::vector<unsigned char> data = keyInfo.Base58Prefix(Consensus::KeyInfo::EXT_SECRET_KEY);
|
||||
size_t size = data.size();
|
||||
data.resize(size + BIP32_EXTKEY_SIZE);
|
||||
key.Encode(data.data() + size);
|
||||
|
@ -262,40 +262,31 @@ std::string EncodeExtKey(const CExtKey& key)
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string EncodeDestination(const CTxDestination& dest)
|
||||
std::string KeyIO::EncodeDestination(const CTxDestination& dest)
|
||||
{
|
||||
return boost::apply_visitor(DestinationEncoder(Params()), dest);
|
||||
return boost::apply_visitor(DestinationEncoder(keyInfo), dest);
|
||||
}
|
||||
|
||||
CTxDestination DecodeDestination(const std::string& str)
|
||||
bool KeyIO::IsValidDestinationString(const std::string& str)
|
||||
{
|
||||
return DecodeDestination(str, Params());
|
||||
return IsValidDestination(DecodeDestination(str));
|
||||
}
|
||||
|
||||
bool IsValidDestinationString(const std::string& str, const CChainParams& params)
|
||||
std::string KeyIO::EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
||||
{
|
||||
return IsValidDestination(DecodeDestination(str, params));
|
||||
}
|
||||
|
||||
bool IsValidDestinationString(const std::string& str)
|
||||
{
|
||||
return IsValidDestinationString(str, Params());
|
||||
}
|
||||
|
||||
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
||||
{
|
||||
return boost::apply_visitor(PaymentAddressEncoder(Params()), zaddr);
|
||||
return boost::apply_visitor(PaymentAddressEncoder(keyInfo), zaddr);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
T1 DecodeAny(
|
||||
const Consensus::KeyInfo& keyInfo,
|
||||
const std::string& str,
|
||||
std::pair<CChainParams::Base58Type, size_t> sprout,
|
||||
std::pair<CChainParams::Bech32Type, size_t> sapling)
|
||||
std::pair<Consensus::KeyInfo::Base58Type, size_t> sprout,
|
||||
std::pair<Consensus::KeyInfo::Bech32Type, size_t> sapling)
|
||||
{
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& prefix = Params().Base58Prefix(sprout.first);
|
||||
const std::vector<unsigned char>& prefix = keyInfo.Base58Prefix(sprout.first);
|
||||
if ((data.size() == sprout.second + prefix.size()) &&
|
||||
std::equal(prefix.begin(), prefix.end(), data.begin())) {
|
||||
CSerializeData serialized(data.begin() + prefix.size(), data.end());
|
||||
|
@ -310,7 +301,7 @@ T1 DecodeAny(
|
|||
|
||||
data.clear();
|
||||
auto bech = bech32::Decode(str);
|
||||
if (bech.first == Params().Bech32HRP(sapling.first) &&
|
||||
if (bech.first == keyInfo.Bech32HRP(sapling.first) &&
|
||||
bech.second.size() == sapling.second) {
|
||||
// Bech32 decoding
|
||||
data.reserve((bech.second.size() * 5) / 8);
|
||||
|
@ -327,50 +318,53 @@ T1 DecodeAny(
|
|||
return libzcash::InvalidEncoding();
|
||||
}
|
||||
|
||||
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
|
||||
libzcash::PaymentAddress KeyIO::DecodePaymentAddress(const std::string& str)
|
||||
{
|
||||
return DecodeAny<libzcash::PaymentAddress,
|
||||
libzcash::SproutPaymentAddress,
|
||||
libzcash::SaplingPaymentAddress>(
|
||||
keyInfo,
|
||||
str,
|
||||
std::make_pair(CChainParams::ZCPAYMENT_ADDRRESS, libzcash::SerializedSproutPaymentAddressSize),
|
||||
std::make_pair(CChainParams::SAPLING_PAYMENT_ADDRESS, ConvertedSaplingPaymentAddressSize)
|
||||
std::make_pair(Consensus::KeyInfo::ZCPAYMENT_ADDRRESS, libzcash::SerializedSproutPaymentAddressSize),
|
||||
std::make_pair(Consensus::KeyInfo::SAPLING_PAYMENT_ADDRESS, ConvertedSaplingPaymentAddressSize)
|
||||
);
|
||||
}
|
||||
|
||||
bool IsValidPaymentAddressString(const std::string& str) {
|
||||
bool KeyIO::IsValidPaymentAddressString(const std::string& str) {
|
||||
return IsValidPaymentAddress(DecodePaymentAddress(str));
|
||||
}
|
||||
|
||||
std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
|
||||
std::string KeyIO::EncodeViewingKey(const libzcash::ViewingKey& vk)
|
||||
{
|
||||
return boost::apply_visitor(ViewingKeyEncoder(Params()), vk);
|
||||
return boost::apply_visitor(ViewingKeyEncoder(keyInfo), vk);
|
||||
}
|
||||
|
||||
libzcash::ViewingKey DecodeViewingKey(const std::string& str)
|
||||
libzcash::ViewingKey KeyIO::DecodeViewingKey(const std::string& str)
|
||||
{
|
||||
return DecodeAny<libzcash::ViewingKey,
|
||||
libzcash::SproutViewingKey,
|
||||
libzcash::SaplingExtendedFullViewingKey>(
|
||||
keyInfo,
|
||||
str,
|
||||
std::make_pair(CChainParams::ZCVIEWING_KEY, libzcash::SerializedSproutViewingKeySize),
|
||||
std::make_pair(CChainParams::SAPLING_EXTENDED_FVK, ConvertedSaplingExtendedFullViewingKeySize)
|
||||
std::make_pair(Consensus::KeyInfo::ZCVIEWING_KEY, libzcash::SerializedSproutViewingKeySize),
|
||||
std::make_pair(Consensus::KeyInfo::SAPLING_EXTENDED_FVK, ConvertedSaplingExtendedFullViewingKeySize)
|
||||
);
|
||||
}
|
||||
|
||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
||||
std::string KeyIO::EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
||||
{
|
||||
return boost::apply_visitor(SpendingKeyEncoder(Params()), zkey);
|
||||
return boost::apply_visitor(SpendingKeyEncoder(keyInfo), zkey);
|
||||
}
|
||||
|
||||
libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
|
||||
libzcash::SpendingKey KeyIO::DecodeSpendingKey(const std::string& str)
|
||||
{
|
||||
|
||||
return DecodeAny<libzcash::SpendingKey,
|
||||
libzcash::SproutSpendingKey,
|
||||
libzcash::SaplingExtendedSpendingKey>(
|
||||
keyInfo,
|
||||
str,
|
||||
std::make_pair(CChainParams::ZCSPENDING_KEY, libzcash::SerializedSproutSpendingKeySize),
|
||||
std::make_pair(CChainParams::SAPLING_EXTENDED_SPEND_KEY, ConvertedSaplingExtendedSpendingKeySize)
|
||||
std::make_pair(Consensus::KeyInfo::ZCSPENDING_KEY, libzcash::SerializedSproutSpendingKeySize),
|
||||
std::make_pair(Consensus::KeyInfo::SAPLING_EXTENDED_SPEND_KEY, ConvertedSaplingExtendedSpendingKeySize)
|
||||
);
|
||||
}
|
||||
|
|
42
src/key_io.h
42
src/key_io.h
|
@ -15,27 +15,35 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
CKey DecodeSecret(const std::string& str);
|
||||
std::string EncodeSecret(const CKey& key);
|
||||
class KeyIO {
|
||||
private:
|
||||
const Consensus::KeyInfo& keyInfo;
|
||||
|
||||
CExtKey DecodeExtKey(const std::string& str);
|
||||
std::string EncodeExtKey(const CExtKey& extkey);
|
||||
CExtPubKey DecodeExtPubKey(const std::string& str);
|
||||
std::string EncodeExtPubKey(const CExtPubKey& extpubkey);
|
||||
public:
|
||||
KeyIO(const Consensus::KeyInfo& keyInfo): keyInfo(keyInfo) { }
|
||||
|
||||
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);
|
||||
CKey DecodeSecret(const std::string& str);
|
||||
std::string EncodeSecret(const CKey& key);
|
||||
|
||||
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr);
|
||||
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str);
|
||||
bool IsValidPaymentAddressString(const std::string& str);
|
||||
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 EncodeViewingKey(const libzcash::ViewingKey& vk);
|
||||
libzcash::ViewingKey DecodeViewingKey(const std::string& str);
|
||||
std::string EncodeDestination(const CTxDestination& dest);
|
||||
CTxDestination DecodeDestination(const std::string& str);
|
||||
|
||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey);
|
||||
libzcash::SpendingKey DecodeSpendingKey(const std::string& str);
|
||||
bool IsValidDestinationString(const std::string& str);
|
||||
|
||||
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr);
|
||||
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str);
|
||||
bool IsValidPaymentAddressString(const std::string& str);
|
||||
|
||||
std::string EncodeViewingKey(const libzcash::ViewingKey& vk);
|
||||
libzcash::ViewingKey DecodeViewingKey(const std::string& str);
|
||||
|
||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey);
|
||||
libzcash::SpendingKey DecodeSpendingKey(const std::string& str);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_KEYIO_H
|
||||
|
|
|
@ -645,9 +645,11 @@ class MinerAddressScript : public CReserveScript
|
|||
|
||||
void GetMinerAddress(MinerAddress &minerAddress)
|
||||
{
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// Try a transparent address first
|
||||
auto mAddrArg = GetArg("-mineraddress", "");
|
||||
CTxDestination addr = DecodeDestination(mAddrArg);
|
||||
CTxDestination addr = keyIO.DecodeDestination(mAddrArg);
|
||||
if (IsValidDestination(addr)) {
|
||||
boost::shared_ptr<MinerAddressScript> mAddr(new MinerAddressScript());
|
||||
CKeyID keyID = boost::get<CKeyID>(addr);
|
||||
|
@ -656,7 +658,7 @@ void GetMinerAddress(MinerAddress &minerAddress)
|
|||
minerAddress = mAddr;
|
||||
} else {
|
||||
// Try a Sapling address
|
||||
auto zaddr = DecodePaymentAddress(mAddrArg);
|
||||
auto zaddr = keyIO.DecodePaymentAddress(mAddrArg);
|
||||
if (IsValidPaymentAddress(zaddr)) {
|
||||
if (boost::get<libzcash::SaplingPaymentAddress>(&zaddr) != nullptr) {
|
||||
minerAddress = boost::get<libzcash::SaplingPaymentAddress>(zaddr);
|
||||
|
|
|
@ -143,6 +143,7 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex)
|
|||
result.pushKV("version", block.nVersion);
|
||||
result.pushKV("merkleroot", block.hashMerkleRoot.GetHex());
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue deltas(UniValue::VARR);
|
||||
for (unsigned int i = 0; i < block.vtx.size(); i++) {
|
||||
const CTransaction &tx = block.vtx[i];
|
||||
|
@ -165,7 +166,7 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex)
|
|||
}
|
||||
CTxDestination dest = DestFromAddressHash(spentInfo.addressType, spentInfo.addressHash);
|
||||
if (IsValidDestination(dest)) {
|
||||
delta.pushKV("address", EncodeDestination(dest));
|
||||
delta.pushKV("address", keyIO.EncodeDestination(dest));
|
||||
}
|
||||
delta.pushKV("satoshis", -1 * spentInfo.satoshis);
|
||||
delta.pushKV("index", (int)j);
|
||||
|
@ -190,9 +191,9 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex)
|
|||
dest = CKeyID(addrhash);
|
||||
}
|
||||
if (IsValidDestination(dest)) {
|
||||
delta.pushKV("address", EncodeDestination(dest));
|
||||
delta.pushKV("address", keyIO.EncodeDestination(dest));
|
||||
}
|
||||
delta.pushKV("address", EncodeDestination(dest));
|
||||
delta.pushKV("address", keyIO.EncodeDestination(dest));
|
||||
delta.pushKV("satoshis", out.nValue);
|
||||
delta.pushKV("index", (int)k);
|
||||
|
||||
|
|
|
@ -905,7 +905,7 @@ UniValue getblocksubsidy(const UniValue& params, bool fHelp)
|
|||
auto elems = Consensus::GetActiveFundingStreams(nHeight, consensus);
|
||||
for (auto elem : elems) {
|
||||
CAmount value = elem.Value(nBlockSubsidy);
|
||||
fundingstreams.pushKV(elem.recipient, value);
|
||||
fundingstreams.pushKV(elem.recipient, (double) value / COIN);
|
||||
nMinerReward -= value;
|
||||
}
|
||||
result.pushKV("fundingstreams", fundingstreams);
|
||||
|
|
|
@ -127,6 +127,7 @@ public:
|
|||
}
|
||||
|
||||
UniValue operator()(const CScriptID &scriptID) const {
|
||||
KeyIO keyIO(Params());
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CScript subscript;
|
||||
obj.pushKV("isscript", true);
|
||||
|
@ -139,7 +140,7 @@ public:
|
|||
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
|
||||
UniValue a(UniValue::VARR);
|
||||
for (const CTxDestination& addr : addresses) {
|
||||
a.push_back(EncodeDestination(addr));
|
||||
a.push_back(keyIO.EncodeDestination(addr));
|
||||
}
|
||||
obj.pushKV("addresses", a);
|
||||
if (whichType == TX_MULTISIG)
|
||||
|
@ -180,14 +181,15 @@ UniValue validateaddress(const UniValue& params, bool fHelp)
|
|||
LOCK(cs_main);
|
||||
#endif
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination dest = keyIO.DecodeDestination(params[0].get_str());
|
||||
bool isValid = IsValidDestination(dest);
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.pushKV("isvalid", isValid);
|
||||
if (isValid)
|
||||
{
|
||||
std::string currentAddress = EncodeDestination(dest);
|
||||
std::string currentAddress = keyIO.EncodeDestination(dest);
|
||||
ret.pushKV("address", currentAddress);
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
|
@ -271,8 +273,9 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp)
|
|||
LOCK(cs_main);
|
||||
#endif
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
string strAddress = params[0].get_str();
|
||||
auto address = DecodePaymentAddress(strAddress);
|
||||
auto address = keyIO.DecodePaymentAddress(strAddress);
|
||||
bool isValid = IsValidPaymentAddress(address);
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
@ -304,6 +307,9 @@ CScript _createmultisig_redeemScript(const UniValue& params)
|
|||
"(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
|
||||
if (keys.size() > 16)
|
||||
throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
std::vector<CPubKey> pubkeys;
|
||||
pubkeys.resize(keys.size());
|
||||
for (unsigned int i = 0; i < keys.size(); i++)
|
||||
|
@ -311,7 +317,7 @@ CScript _createmultisig_redeemScript(const UniValue& params)
|
|||
const std::string& ks = keys[i].get_str();
|
||||
#ifdef ENABLE_WALLET
|
||||
// Case 1: Bitcoin address and we have full public key:
|
||||
CTxDestination dest = DecodeDestination(ks);
|
||||
CTxDestination dest = keyIO.DecodeDestination(ks);
|
||||
if (pwalletMain && IsValidDestination(dest)) {
|
||||
const CKeyID *keyID = boost::get<CKeyID>(&dest);
|
||||
if (!keyID) {
|
||||
|
@ -385,8 +391,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp)
|
|||
CScript inner = _createmultisig_redeemScript(params);
|
||||
CScriptID innerID(inner);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("address", EncodeDestination(innerID));
|
||||
result.pushKV("address", keyIO.EncodeDestination(innerID));
|
||||
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
|
||||
|
||||
return result;
|
||||
|
@ -421,7 +428,8 @@ UniValue verifymessage(const UniValue& params, bool fHelp)
|
|||
string strSign = params[1].get_str();
|
||||
string strMessage = params[2].get_str();
|
||||
|
||||
CTxDestination destination = DecodeDestination(strAddress);
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination destination = keyIO.DecodeDestination(strAddress);
|
||||
if (!IsValidDestination(destination)) {
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
|
||||
}
|
||||
|
@ -506,10 +514,11 @@ UniValue getexperimentalfeatures(const UniValue& params, bool fHelp)
|
|||
static bool getAddressFromIndex(
|
||||
int type, const uint160 &hash, std::string &address)
|
||||
{
|
||||
KeyIO keyIO(Params());
|
||||
if (type == CScript::P2SH) {
|
||||
address = EncodeDestination(CScriptID(hash));
|
||||
address = keyIO.EncodeDestination(CScriptID(hash));
|
||||
} else if (type == CScript::P2PKH) {
|
||||
address = EncodeDestination(CKeyID(hash));
|
||||
address = keyIO.EncodeDestination(CKeyID(hash));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -560,8 +569,10 @@ static bool getAddressesFromParams(
|
|||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
for (const auto& it : param_addresses) {
|
||||
CTxDestination address = DecodeDestination(it);
|
||||
CTxDestination address = keyIO.DecodeDestination(it);
|
||||
uint160 hashBytes;
|
||||
int type = 0;
|
||||
if (!getIndexKey(address, hashBytes, type)) {
|
||||
|
|
|
@ -51,9 +51,10 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud
|
|||
out.pushKV("reqSigs", nRequired);
|
||||
out.pushKV("type", GetTxnOutputType(type));
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue a(UniValue::VARR);
|
||||
for (const CTxDestination& addr : addresses) {
|
||||
a.push_back(EncodeDestination(addr));
|
||||
a.push_back(keyIO.EncodeDestination(addr));
|
||||
}
|
||||
out.pushKV("addresses", a);
|
||||
}
|
||||
|
@ -161,6 +162,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
|||
if (tx.fOverwintered) {
|
||||
entry.pushKV("expiryheight", (int64_t)tx.nExpiryHeight);
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue vin(UniValue::VARR);
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
|
||||
UniValue in(UniValue::VOBJ);
|
||||
|
@ -184,7 +187,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
|||
CTxDestination dest =
|
||||
DestFromAddressHash(spentInfo.addressType, spentInfo.addressHash);
|
||||
if (IsValidDestination(dest)) {
|
||||
in.pushKV("address", EncodeDestination(dest));
|
||||
in.pushKV("address", keyIO.EncodeDestination(dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -585,10 +588,11 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
|||
rawTx.vin.push_back(in);
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
std::set<CTxDestination> destinations;
|
||||
vector<string> addrList = sendTo.getKeys();
|
||||
for (const std::string& name_ : addrList) {
|
||||
CTxDestination destination = DecodeDestination(name_);
|
||||
CTxDestination destination = keyIO.DecodeDestination(name_);
|
||||
if (!IsValidDestination(destination)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + name_);
|
||||
}
|
||||
|
@ -740,7 +744,8 @@ UniValue decodescript(const UniValue& params, bool fHelp)
|
|||
}
|
||||
ScriptPubKeyToJSON(script, r, false);
|
||||
|
||||
r.pushKV("p2sh", EncodeDestination(CScriptID(script)));
|
||||
KeyIO keyIO(Params());
|
||||
r.pushKV("p2sh", keyIO.EncodeDestination(CScriptID(script)));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -865,6 +870,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
|
|||
view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
bool fGivenKeys = false;
|
||||
CBasicKeyStore tempKeystore;
|
||||
if (params.size() > 2 && !params[2].isNull()) {
|
||||
|
@ -872,7 +879,7 @@ 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];
|
||||
CKey key = DecodeSecret(k.get_str());
|
||||
CKey key = keyIO.DecodeSecret(k.get_str());
|
||||
if (!key.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||
tempKeystore.AddKey(key);
|
||||
|
|
|
@ -100,26 +100,28 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
|||
} else {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
if (isPrivkey) {
|
||||
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
|
||||
// Must be valid private key
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
privkey = keyIO.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);
|
||||
|
||||
// Private key must be invalid public key
|
||||
destination = DecodeDestination(exp_base58string);
|
||||
destination = keyIO.DecodeDestination(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid privkey as pubkey:" + strTest);
|
||||
} else {
|
||||
// Must be valid public key
|
||||
destination = DecodeDestination(exp_base58string);
|
||||
destination = keyIO.DecodeDestination(exp_base58string);
|
||||
CScript script = GetScriptForDestination(destination);
|
||||
BOOST_CHECK_MESSAGE(IsValidDestination(destination), "!IsValid:" + strTest);
|
||||
BOOST_CHECK_EQUAL(HexStr(script), HexStr(exp_payload));
|
||||
|
||||
// Public key must be invalid private key
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
privkey = keyIO.DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid pubkey as privkey:" + strTest);
|
||||
}
|
||||
}
|
||||
|
@ -148,17 +150,19 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
|||
} else {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
if (isPrivkey) {
|
||||
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
|
||||
CKey key;
|
||||
key.Set(exp_payload.begin(), exp_payload.end(), isCompressed);
|
||||
assert(key.IsValid());
|
||||
BOOST_CHECK_MESSAGE(EncodeSecret(key) == exp_base58string, "result mismatch: " + strTest);
|
||||
BOOST_CHECK_MESSAGE(keyIO.EncodeSecret(key) == exp_base58string, "result mismatch: " + strTest);
|
||||
} else {
|
||||
CTxDestination dest;
|
||||
CScript exp_script(exp_payload.begin(), exp_payload.end());
|
||||
ExtractDestination(exp_script, dest);
|
||||
std::string address = EncodeDestination(dest);
|
||||
std::string address = keyIO.EncodeDestination(dest);
|
||||
BOOST_CHECK_EQUAL(address, exp_base58string);
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +177,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
|||
CKey privkey;
|
||||
CTxDestination destination;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
std::string strTest = test.write();
|
||||
|
@ -184,9 +189,9 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
|||
std::string exp_base58string = test[0].get_str();
|
||||
|
||||
// must be invalid as public and as private key
|
||||
destination = DecodeDestination(exp_base58string);
|
||||
destination = keyIO.DecodeDestination(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey:" + strTest);
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
privkey = keyIO.DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid privkey:" + strTest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,18 +84,19 @@ void RunTest(const TestVector &test) {
|
|||
CExtPubKey pubkey;
|
||||
key.SetMaster(&seed[0], seed.size());
|
||||
pubkey = key.Neuter();
|
||||
KeyIO keyIO(Params());
|
||||
BOOST_FOREACH(const TestDerivation &derive, test.vDerive) {
|
||||
unsigned char data[74];
|
||||
key.Encode(data);
|
||||
pubkey.Encode(data);
|
||||
|
||||
// Test private key
|
||||
BOOST_CHECK(EncodeExtKey(key) == derive.prv);
|
||||
BOOST_CHECK(DecodeExtKey(derive.prv) == key); //ensure a base58 decoded key also matches
|
||||
BOOST_CHECK(keyIO.EncodeExtKey(key) == derive.prv);
|
||||
BOOST_CHECK(keyIO.DecodeExtKey(derive.prv) == key); //ensure a base58 decoded key also matches
|
||||
|
||||
// Test public key
|
||||
BOOST_CHECK(EncodeExtPubKey(pubkey) == derive.pub);
|
||||
BOOST_CHECK(DecodeExtPubKey(derive.pub) == pubkey); //ensure a base58 decoded pubkey also matches
|
||||
BOOST_CHECK(keyIO.EncodeExtPubKey(pubkey) == derive.pub);
|
||||
BOOST_CHECK(keyIO.DecodeExtPubKey(derive.pub) == pubkey); //ensure a base58 decoded pubkey also matches
|
||||
|
||||
// Derive new keys
|
||||
CExtKey keyNew;
|
||||
|
|
|
@ -86,8 +86,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
|
||||
{
|
||||
KeyIO keyIO(Params());
|
||||
std::string strSecret = std::string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
|
||||
CKey key = DecodeSecret(strSecret);
|
||||
CKey key = keyIO.DecodeSecret(strSecret);
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end());
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ void dumpKeyInfo(uint256 privkey)
|
|||
memcpy(&sec[0], &secret[0], 32);
|
||||
printf(" * secret (hex): %s\n", HexStr(sec).c_str());
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
for (int nCompressed=0; nCompressed<2; nCompressed++)
|
||||
{
|
||||
bool fCompressed = nCompressed == 1;
|
||||
|
@ -57,7 +58,7 @@ void dumpKeyInfo(uint256 privkey)
|
|||
key.SetSecret(secret, fCompressed);
|
||||
vector<unsigned char> vchPubKey = key.GetPubKey();
|
||||
printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str());
|
||||
printf(" * address (base58): %s\n", EncodeDestination(vchPubKey).c_str());
|
||||
printf(" * address (base58): %s\n", keyIO.EncodeDestination(vchPubKey).c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -67,15 +68,16 @@ BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(key_test1)
|
||||
{
|
||||
CKey key1 = DecodeSecret(strSecret1);
|
||||
KeyIO keyIO(Params());
|
||||
CKey key1 = keyIO.DecodeSecret(strSecret1);
|
||||
BOOST_CHECK(key1.IsValid() && !key1.IsCompressed());
|
||||
CKey key2 = DecodeSecret(strSecret2);
|
||||
CKey key2 = keyIO.DecodeSecret(strSecret2);
|
||||
BOOST_CHECK(key2.IsValid() && !key2.IsCompressed());
|
||||
CKey key1C = DecodeSecret(strSecret1C);
|
||||
CKey key1C = keyIO.DecodeSecret(strSecret1C);
|
||||
BOOST_CHECK(key1C.IsValid() && key1C.IsCompressed());
|
||||
CKey key2C = DecodeSecret(strSecret2C);
|
||||
CKey key2C = keyIO.DecodeSecret(strSecret2C);
|
||||
BOOST_CHECK(key2C.IsValid() && key2C.IsCompressed());
|
||||
CKey bad_key = DecodeSecret(strAddressBad);
|
||||
CKey bad_key = keyIO.DecodeSecret(strAddressBad);
|
||||
BOOST_CHECK(!bad_key.IsValid());
|
||||
|
||||
CPubKey pubkey1 = key1. GetPubKey();
|
||||
|
@ -103,10 +105,10 @@ BOOST_AUTO_TEST_CASE(key_test1)
|
|||
BOOST_CHECK(!key2C.VerifyPubKey(pubkey2));
|
||||
BOOST_CHECK(key2C.VerifyPubKey(pubkey2C));
|
||||
|
||||
BOOST_CHECK(DecodeDestination(addr1) == CTxDestination(pubkey1.GetID()));
|
||||
BOOST_CHECK(DecodeDestination(addr2) == CTxDestination(pubkey2.GetID()));
|
||||
BOOST_CHECK(DecodeDestination(addr1C) == CTxDestination(pubkey1C.GetID()));
|
||||
BOOST_CHECK(DecodeDestination(addr2C) == CTxDestination(pubkey2C.GetID()));
|
||||
BOOST_CHECK(keyIO.DecodeDestination(addr1) == CTxDestination(pubkey1.GetID()));
|
||||
BOOST_CHECK(keyIO.DecodeDestination(addr2) == CTxDestination(pubkey2.GetID()));
|
||||
BOOST_CHECK(keyIO.DecodeDestination(addr1C) == CTxDestination(pubkey1C.GetID()));
|
||||
BOOST_CHECK(keyIO.DecodeDestination(addr2C) == CTxDestination(pubkey2C.GetID()));
|
||||
|
||||
for (int n=0; n<16; n++)
|
||||
{
|
||||
|
@ -189,15 +191,16 @@ BOOST_AUTO_TEST_CASE(key_test1)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(zc_address_test)
|
||||
{
|
||||
KeyIO keyIO(Params());
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
auto sk = SproutSpendingKey::random();
|
||||
{
|
||||
string sk_string = EncodeSpendingKey(sk);
|
||||
string sk_string = keyIO.EncodeSpendingKey(sk);
|
||||
|
||||
BOOST_CHECK(sk_string[0] == 'S');
|
||||
BOOST_CHECK(sk_string[1] == 'K');
|
||||
|
||||
auto spendingkey2 = DecodeSpendingKey(sk_string);
|
||||
auto spendingkey2 = keyIO.DecodeSpendingKey(sk_string);
|
||||
BOOST_CHECK(IsValidSpendingKey(spendingkey2));
|
||||
BOOST_ASSERT(boost::get<SproutSpendingKey>(&spendingkey2) != nullptr);
|
||||
auto sk2 = boost::get<SproutSpendingKey>(spendingkey2);
|
||||
|
@ -206,12 +209,12 @@ BOOST_AUTO_TEST_CASE(zc_address_test)
|
|||
{
|
||||
auto addr = sk.address();
|
||||
|
||||
std::string addr_string = EncodePaymentAddress(addr);
|
||||
std::string addr_string = keyIO.EncodePaymentAddress(addr);
|
||||
|
||||
BOOST_CHECK(addr_string[0] == 'z');
|
||||
BOOST_CHECK(addr_string[1] == 'c');
|
||||
|
||||
auto paymentaddr2 = DecodePaymentAddress(addr_string);
|
||||
auto paymentaddr2 = keyIO.DecodePaymentAddress(addr_string);
|
||||
BOOST_ASSERT(IsValidPaymentAddress(paymentaddr2));
|
||||
|
||||
BOOST_ASSERT(boost::get<SproutPaymentAddress>(&paymentaddr2) != nullptr);
|
||||
|
@ -228,13 +231,14 @@ BOOST_AUTO_TEST_CASE(zs_address_test)
|
|||
|
||||
auto m = GetTestMasterSaplingSpendingKey();
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
for (uint32_t i = 0; i < 1000; i++) {
|
||||
auto sk = m.Derive(i);
|
||||
{
|
||||
std::string sk_string = EncodeSpendingKey(sk);
|
||||
std::string sk_string = keyIO.EncodeSpendingKey(sk);
|
||||
BOOST_CHECK(sk_string.compare(0, 27, Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY)) == 0);
|
||||
|
||||
auto spendingkey2 = DecodeSpendingKey(sk_string);
|
||||
auto spendingkey2 = keyIO.DecodeSpendingKey(sk_string);
|
||||
BOOST_CHECK(IsValidSpendingKey(spendingkey2));
|
||||
|
||||
BOOST_ASSERT(boost::get<SaplingExtendedSpendingKey>(&spendingkey2) != nullptr);
|
||||
|
@ -244,10 +248,10 @@ BOOST_AUTO_TEST_CASE(zs_address_test)
|
|||
{
|
||||
auto addr = sk.DefaultAddress();
|
||||
|
||||
std::string addr_string = EncodePaymentAddress(addr);
|
||||
std::string addr_string = keyIO.EncodePaymentAddress(addr);
|
||||
BOOST_CHECK(addr_string.compare(0, 15, Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS)) == 0);
|
||||
|
||||
auto paymentaddr2 = DecodePaymentAddress(addr_string);
|
||||
auto paymentaddr2 = keyIO.DecodePaymentAddress(addr_string);
|
||||
BOOST_CHECK(IsValidPaymentAddress(paymentaddr2));
|
||||
|
||||
BOOST_ASSERT(boost::get<SaplingPaymentAddress>(&paymentaddr2) != nullptr);
|
||||
|
|
|
@ -286,7 +286,8 @@ libzcash::SaplingExtendedSpendingKey GetTestMasterSaplingSpendingKey() {
|
|||
}
|
||||
|
||||
CKey AddTestCKeyToKeyStore(CBasicKeyStore& keyStore) {
|
||||
CKey tsk = DecodeSecret(T_SECRET_REGTEST);
|
||||
KeyIO keyIO(Params());
|
||||
CKey tsk = keyIO.DecodeSecret(T_SECRET_REGTEST);
|
||||
keyStore.AddKey(tsk);
|
||||
return tsk;
|
||||
}
|
||||
|
|
|
@ -91,12 +91,13 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
|||
builder_ = builder.get();
|
||||
}
|
||||
|
||||
toTaddr_ = DecodeDestination(std::get<0>(recipient));
|
||||
KeyIO keyIO(Params());
|
||||
toTaddr_ = keyIO.DecodeDestination(std::get<0>(recipient));
|
||||
isToTaddr_ = IsValidDestination(toTaddr_);
|
||||
isToZaddr_ = false;
|
||||
|
||||
if (!isToTaddr_) {
|
||||
auto address = DecodePaymentAddress(std::get<0>(recipient));
|
||||
auto address = keyIO.DecodePaymentAddress(std::get<0>(recipient));
|
||||
if (IsValidPaymentAddress(address)) {
|
||||
isToZaddr_ = true;
|
||||
toPaymentAddress_ = address;
|
||||
|
@ -866,6 +867,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
arrOutputMap.push_back(static_cast<uint64_t>(outputMap[i]));
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// !!! Payment disclosure START
|
||||
unsigned char buffer[32] = {0};
|
||||
|
@ -883,7 +885,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), keyIO.EncodePaymentAddress(zaddr));
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
|
|
@ -192,9 +192,10 @@ CAmount AsyncRPCOperation_saplingmigration::chooseAmount(const CAmount& availabl
|
|||
|
||||
// Unless otherwise specified, the migration destination address is the address for Sapling account 0
|
||||
libzcash::SaplingPaymentAddress AsyncRPCOperation_saplingmigration::getMigrationDestAddress(const HDSeed& seed) {
|
||||
KeyIO keyIO(Params());
|
||||
if (mapArgs.count("-migrationdestaddress")) {
|
||||
std::string migrationDestAddress = mapArgs["-migrationdestaddress"];
|
||||
auto address = DecodePaymentAddress(migrationDestAddress);
|
||||
auto address = keyIO.DecodePaymentAddress(migrationDestAddress);
|
||||
auto saplingAddress = boost::get<libzcash::SaplingPaymentAddress>(&address);
|
||||
assert(saplingAddress != nullptr); // This is checked in init.cpp
|
||||
return *saplingAddress;
|
||||
|
|
|
@ -85,12 +85,14 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
|||
builder_ = builder.get();
|
||||
}
|
||||
|
||||
fromtaddr_ = DecodeDestination(fromAddress);
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
fromtaddr_ = keyIO.DecodeDestination(fromAddress);
|
||||
isfromtaddr_ = IsValidDestination(fromtaddr_);
|
||||
isfromzaddr_ = false;
|
||||
|
||||
if (!isfromtaddr_) {
|
||||
auto address = DecodePaymentAddress(fromAddress);
|
||||
auto address = keyIO.DecodePaymentAddress(fromAddress);
|
||||
if (IsValidPaymentAddress(address)) {
|
||||
// We don't need to lock on the wallet as spending key related methods are thread-safe
|
||||
if (!boost::apply_visitor(HaveSpendingKeyForPaymentAddress(pwalletMain), address)) {
|
||||
|
@ -343,6 +345,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(z_outputs_total));
|
||||
LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(minersFee));
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
/**
|
||||
* SCENARIO #0
|
||||
|
@ -424,7 +427,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
auto value = r.amount;
|
||||
auto hexMemo = r.memo;
|
||||
|
||||
auto addr = DecodePaymentAddress(address);
|
||||
auto addr = keyIO.DecodePaymentAddress(address);
|
||||
assert(boost::get<libzcash::SaplingPaymentAddress>(&addr) != nullptr);
|
||||
auto to = boost::get<libzcash::SaplingPaymentAddress>(addr);
|
||||
|
||||
|
@ -438,7 +441,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
auto outputAddress = r.address;
|
||||
auto amount = r.amount;
|
||||
|
||||
auto address = DecodeDestination(outputAddress);
|
||||
auto address = keyIO.DecodeDestination(outputAddress);
|
||||
builder_.AddTransparentOutput(address, amount);
|
||||
}
|
||||
|
||||
|
@ -583,7 +586,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
std::string hexMemo = smr.memo;
|
||||
zOutputsDeque.pop_front();
|
||||
|
||||
PaymentAddress pa = DecodePaymentAddress(address);
|
||||
PaymentAddress pa = keyIO.DecodePaymentAddress(address);
|
||||
JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(pa), value);
|
||||
if (hexMemo.size() > 0) {
|
||||
jso.memo = get_memo_from_hex_string(hexMemo);
|
||||
|
@ -845,7 +848,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 = DecodePaymentAddress(address);
|
||||
PaymentAddress pa = keyIO.DecodePaymentAddress(address);
|
||||
// If we are here, we know we have no Sapling outputs.
|
||||
JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(pa), value);
|
||||
if (hexMemo.size() > 0) {
|
||||
|
@ -1145,6 +1148,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
arrOutputMap.push_back(static_cast<uint64_t>(outputMap[i]));
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// !!! Payment disclosure START
|
||||
unsigned char buffer[32] = {0};
|
||||
|
@ -1162,7 +1166,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), keyIO.EncodePaymentAddress(zaddr));
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
@ -1179,11 +1183,13 @@ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() {
|
|||
|
||||
CMutableTransaction rawTx(tx_);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
for (SendManyRecipient & r : t_outputs_) {
|
||||
std::string outputAddress = r.address;
|
||||
CAmount nAmount = r.amount;
|
||||
|
||||
CTxDestination address = DecodeDestination(outputAddress);
|
||||
CTxDestination address = keyIO.DecodeDestination(outputAddress);
|
||||
if (!IsValidDestination(address)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid output address, not a valid taddr.");
|
||||
}
|
||||
|
|
|
@ -74,7 +74,8 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
|
|||
}
|
||||
|
||||
// Check the destination address is valid for this network i.e. not testnet being used on mainnet
|
||||
auto address = DecodePaymentAddress(toAddress);
|
||||
KeyIO keyIO(Params());
|
||||
auto address = keyIO.DecodePaymentAddress(toAddress);
|
||||
if (IsValidPaymentAddress(address)) {
|
||||
tozaddr_ = address;
|
||||
} else {
|
||||
|
@ -386,6 +387,8 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
arrOutputMap.push_back(static_cast<uint64_t>(outputMap[i]));
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// !!! Payment disclosure START
|
||||
unsigned char buffer[32] = {0};
|
||||
memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer
|
||||
|
@ -402,7 +405,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr));
|
||||
LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), keyIO.EncodePaymentAddress(zaddr));
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
|
||||
|
|
|
@ -8,8 +8,9 @@
|
|||
#include "util.h"
|
||||
|
||||
std::string PaymentDisclosureInfo::ToString() const {
|
||||
KeyIO keyIO(Params());
|
||||
return strprintf("PaymentDisclosureInfo(version=%d, esk=%s, joinSplitPrivKey=<omitted>, address=%s)",
|
||||
version, esk.ToString(), EncodePaymentAddress(zaddr));
|
||||
version, esk.ToString(), keyIO.EncodePaymentAddress(zaddr));
|
||||
}
|
||||
|
||||
std::string PaymentDisclosure::ToString() const {
|
||||
|
@ -18,8 +19,9 @@ std::string PaymentDisclosure::ToString() const {
|
|||
}
|
||||
|
||||
std::string PaymentDisclosurePayload::ToString() const {
|
||||
KeyIO keyIO(Params());
|
||||
return strprintf("PaymentDisclosurePayload(version=%d, esk=%s, txid=%s, js=%d, n=%d, address=%s, message=%s)",
|
||||
version, esk.ToString(), txid.ToString(), js, n, EncodePaymentAddress(zaddr), message);
|
||||
version, esk.ToString(), txid.ToString(), js, n, keyIO.EncodePaymentAddress(zaddr), message);
|
||||
}
|
||||
|
||||
PaymentDisclosure::PaymentDisclosure(const uint256 &joinSplitPubKey, const PaymentDisclosureKey &key, const PaymentDisclosureInfo &info, const std::string &message)
|
||||
|
|
|
@ -250,10 +250,12 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp)
|
|||
errs.push_back("Payment disclosure signature does not match transaction signature");
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// Check the payment address is valid
|
||||
SproutPaymentAddress zaddr = pd.payload.zaddr;
|
||||
{
|
||||
o.pushKV("paymentAddress", EncodePaymentAddress(zaddr));
|
||||
o.pushKV("paymentAddress", keyIO.EncodePaymentAddress(zaddr));
|
||||
|
||||
try {
|
||||
// Decrypt the note to get value and memo field
|
||||
|
|
|
@ -116,7 +116,9 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
|
|||
if (params.size() > 2)
|
||||
fRescan = params[2].get_bool();
|
||||
|
||||
CKey key = DecodeSecret(strSecret);
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
CKey key = keyIO.DecodeSecret(strSecret);
|
||||
if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
|
@ -128,7 +130,7 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
|
|||
|
||||
// Don't throw error in case a key is already there
|
||||
if (pwalletMain->HaveKey(vchAddress)) {
|
||||
return EncodeDestination(vchAddress);
|
||||
return keyIO.EncodeDestination(vchAddress);
|
||||
}
|
||||
|
||||
pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
|
||||
|
@ -144,7 +146,7 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
return EncodeDestination(vchAddress);
|
||||
return keyIO.EncodeDestination(vchAddress);
|
||||
}
|
||||
|
||||
void ImportAddress(const CTxDestination& dest, const string& strLabel);
|
||||
|
@ -227,7 +229,8 @@ UniValue importaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination dest = keyIO.DecodeDestination(params[0].get_str());
|
||||
if (IsValidDestination(dest)) {
|
||||
if (fP2SH) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead");
|
||||
|
@ -373,6 +376,8 @@ UniValue importwallet_impl(const UniValue& params, bool fImportZKeys)
|
|||
int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
|
||||
file.seekg(0, file.beg);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
pwalletMain->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI
|
||||
while (file.good()) {
|
||||
pwalletMain->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))));
|
||||
|
@ -388,7 +393,7 @@ UniValue importwallet_impl(const UniValue& params, bool fImportZKeys)
|
|||
|
||||
// Let's see if the address is a valid Zcash spending key
|
||||
if (fImportZKeys) {
|
||||
auto spendingkey = DecodeSpendingKey(vstr[0]);
|
||||
auto spendingkey = keyIO.DecodeSpendingKey(vstr[0]);
|
||||
int64_t nTime = DecodeDumpTime(vstr[1]);
|
||||
// Only include hdKeypath and seedFpStr if we have both
|
||||
boost::optional<std::string> hdKeypath = (vstr.size() > 3) ? boost::optional<std::string>(vstr[2]) : boost::none;
|
||||
|
@ -409,14 +414,14 @@ UniValue importwallet_impl(const UniValue& params, bool fImportZKeys)
|
|||
}
|
||||
}
|
||||
|
||||
CKey key = DecodeSecret(vstr[0]);
|
||||
CKey key = keyIO.DecodeSecret(vstr[0]);
|
||||
if (!key.IsValid())
|
||||
continue;
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
assert(key.VerifyPubKey(pubkey));
|
||||
CKeyID keyid = pubkey.GetID();
|
||||
if (pwalletMain->HaveKey(keyid)) {
|
||||
LogPrintf("Skipping import of %s (key already present)\n", EncodeDestination(keyid));
|
||||
LogPrintf("Skipping import of %s (key already present)\n", keyIO.EncodeDestination(keyid));
|
||||
continue;
|
||||
}
|
||||
int64_t nTime = DecodeDumpTime(vstr[1]);
|
||||
|
@ -434,7 +439,7 @@ UniValue importwallet_impl(const UniValue& params, bool fImportZKeys)
|
|||
fLabel = true;
|
||||
}
|
||||
}
|
||||
LogPrintf("Importing %s...\n", EncodeDestination(keyid));
|
||||
LogPrintf("Importing %s...\n", keyIO.EncodeDestination(keyid));
|
||||
if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
|
||||
fGood = false;
|
||||
continue;
|
||||
|
@ -489,8 +494,10 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp)
|
|||
|
||||
EnsureWalletIsUnlocked();
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
std::string strAddress = params[0].get_str();
|
||||
CTxDestination dest = DecodeDestination(strAddress);
|
||||
CTxDestination dest = keyIO.DecodeDestination(strAddress);
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
|
||||
}
|
||||
|
@ -502,7 +509,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 EncodeSecret(vchSecret);
|
||||
return keyIO.EncodeSecret(vchSecret);
|
||||
}
|
||||
|
||||
|
||||
|
@ -593,6 +600,8 @@ UniValue dumpwallet_impl(const UniValue& params, bool fDumpZKeys)
|
|||
mapKeyBirth.clear();
|
||||
std::sort(vKeyBirth.begin(), vKeyBirth.end());
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// produce output
|
||||
file << strprintf("# Wallet dump created by Zcash %s (%s)\n", CLIENT_BUILD, CLIENT_DATE);
|
||||
file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
|
||||
|
@ -609,15 +618,15 @@ UniValue dumpwallet_impl(const UniValue& params, bool fDumpZKeys)
|
|||
for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
|
||||
const CKeyID &keyid = it->second;
|
||||
std::string strTime = EncodeDumpTime(it->first);
|
||||
std::string strAddr = EncodeDestination(keyid);
|
||||
std::string strAddr = keyIO.EncodeDestination(keyid);
|
||||
CKey key;
|
||||
if (pwalletMain->GetKey(keyid, key)) {
|
||||
if (pwalletMain->mapAddressBook.count(keyid)) {
|
||||
file << strprintf("%s %s label=%s # addr=%s\n", EncodeSecret(key), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr);
|
||||
file << strprintf("%s %s label=%s # addr=%s\n", keyIO.EncodeSecret(key), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr);
|
||||
} else if (setKeyPool.count(keyid)) {
|
||||
file << strprintf("%s %s reserve=1 # addr=%s\n", EncodeSecret(key), strTime, strAddr);
|
||||
file << strprintf("%s %s reserve=1 # addr=%s\n", keyIO.EncodeSecret(key), strTime, strAddr);
|
||||
} else {
|
||||
file << strprintf("%s %s change=1 # addr=%s\n", EncodeSecret(key), strTime, strAddr);
|
||||
file << strprintf("%s %s change=1 # addr=%s\n", keyIO.EncodeSecret(key), strTime, strAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -633,7 +642,7 @@ UniValue dumpwallet_impl(const UniValue& params, bool fDumpZKeys)
|
|||
libzcash::SproutSpendingKey key;
|
||||
if (pwalletMain->GetSproutSpendingKey(addr, key)) {
|
||||
std::string strTime = EncodeDumpTime(pwalletMain->mapSproutZKeyMetadata[addr].nCreateTime);
|
||||
file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr));
|
||||
file << strprintf("%s %s # zaddr=%s\n", keyIO.EncodeSpendingKey(key), strTime, keyIO.EncodePaymentAddress(addr));
|
||||
}
|
||||
}
|
||||
std::set<libzcash::SaplingPaymentAddress> saplingAddresses;
|
||||
|
@ -649,9 +658,9 @@ UniValue dumpwallet_impl(const UniValue& params, bool fDumpZKeys)
|
|||
std::string strTime = EncodeDumpTime(keyMeta.nCreateTime);
|
||||
// Keys imported with z_importkey do not have zip32 metadata
|
||||
if (keyMeta.hdKeypath.empty() || keyMeta.seedFp.IsNull()) {
|
||||
file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(extsk), strTime, EncodePaymentAddress(addr));
|
||||
file << strprintf("%s %s # zaddr=%s\n", keyIO.EncodeSpendingKey(extsk), strTime, keyIO.EncodePaymentAddress(addr));
|
||||
} else {
|
||||
file << strprintf("%s %s %s %s # zaddr=%s\n", EncodeSpendingKey(extsk), strTime, keyMeta.hdKeypath, keyMeta.seedFp.GetHex(), EncodePaymentAddress(addr));
|
||||
file << strprintf("%s %s %s %s # zaddr=%s\n", keyIO.EncodeSpendingKey(extsk), strTime, keyMeta.hdKeypath, keyMeta.seedFp.GetHex(), keyIO.EncodePaymentAddress(addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -737,8 +746,9 @@ UniValue z_importkey(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
string strSecret = params[0].get_str();
|
||||
auto spendingkey = DecodeSpendingKey(strSecret);
|
||||
auto spendingkey = keyIO.DecodeSpendingKey(strSecret);
|
||||
if (!IsValidSpendingKey(spendingkey)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||
}
|
||||
|
@ -746,7 +756,7 @@ UniValue z_importkey(const UniValue& params, bool fHelp)
|
|||
auto addrInfo = boost::apply_visitor(libzcash::AddressInfoFromSpendingKey{}, spendingkey);
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("type", addrInfo.first);
|
||||
result.pushKV("address", EncodePaymentAddress(addrInfo.second));
|
||||
result.pushKV("address", keyIO.EncodePaymentAddress(addrInfo.second));
|
||||
|
||||
// Sapling support
|
||||
auto addResult = boost::apply_visitor(AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus()), spendingkey);
|
||||
|
@ -831,8 +841,9 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
string strVKey = params[0].get_str();
|
||||
auto viewingkey = DecodeViewingKey(strVKey);
|
||||
auto viewingkey = keyIO.DecodeViewingKey(strVKey);
|
||||
if (!IsValidViewingKey(viewingkey)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid viewing key");
|
||||
}
|
||||
|
@ -840,7 +851,7 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp)
|
|||
auto addrInfo = boost::apply_visitor(libzcash::AddressInfoFromViewingKey{}, viewingkey);
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("type", addrInfo.first);
|
||||
result.pushKV("address", EncodePaymentAddress(addrInfo.second));
|
||||
result.pushKV("address", keyIO.EncodePaymentAddress(addrInfo.second));
|
||||
|
||||
auto addResult = boost::apply_visitor(AddViewingKeyToWallet(pwalletMain), viewingkey);
|
||||
if (addResult == SpendingKeyExists) {
|
||||
|
@ -889,7 +900,8 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
|
|||
|
||||
string strAddress = params[0].get_str();
|
||||
|
||||
auto address = DecodePaymentAddress(strAddress);
|
||||
KeyIO keyIO(Params());
|
||||
auto address = keyIO.DecodePaymentAddress(strAddress);
|
||||
if (!IsValidPaymentAddress(address)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
||||
}
|
||||
|
@ -899,7 +911,7 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
|
|||
if (!sk) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
|
||||
}
|
||||
return EncodeSpendingKey(sk.get());
|
||||
return keyIO.EncodeSpendingKey(sk.get());
|
||||
}
|
||||
|
||||
UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
|
||||
|
@ -927,14 +939,15 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
|
|||
|
||||
string strAddress = params[0].get_str();
|
||||
|
||||
auto address = DecodePaymentAddress(strAddress);
|
||||
KeyIO keyIO(Params());
|
||||
auto address = keyIO.DecodePaymentAddress(strAddress);
|
||||
if (!IsValidPaymentAddress(address)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
||||
}
|
||||
|
||||
auto vk = boost::apply_visitor(GetViewingKeyForPaymentAddress(pwalletMain), address);
|
||||
if (vk) {
|
||||
return EncodeViewingKey(vk.get());
|
||||
return keyIO.EncodeViewingKey(vk.get());
|
||||
} else {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr");
|
||||
}
|
||||
|
|
|
@ -168,7 +168,8 @@ UniValue getnewaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
pwalletMain->SetAddressBook(keyID, strAccount, "receive");
|
||||
|
||||
return EncodeDestination(keyID);
|
||||
KeyIO keyIO(Params());
|
||||
return keyIO.EncodeDestination(keyID);
|
||||
}
|
||||
|
||||
|
||||
|
@ -236,7 +237,8 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
UniValue ret(UniValue::VSTR);
|
||||
|
||||
ret = EncodeDestination(GetAccountAddress(strAccount));
|
||||
KeyIO keyIO(Params());
|
||||
ret = keyIO.EncodeDestination(GetAccountAddress(strAccount));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -272,7 +274,8 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
CKeyID keyID = vchPubKey.GetID();
|
||||
|
||||
return EncodeDestination(keyID);
|
||||
KeyIO keyIO(Params());
|
||||
return keyIO.EncodeDestination(keyID);
|
||||
}
|
||||
|
||||
|
||||
|
@ -295,7 +298,8 @@ UniValue setaccount(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination dest = keyIO.DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
|
||||
}
|
||||
|
@ -342,7 +346,8 @@ UniValue getaccount(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination dest = keyIO.DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
|
||||
}
|
||||
|
@ -381,13 +386,14 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp)
|
|||
|
||||
string strAccount = AccountFromValue(params[0]);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// Find all addresses that have the given account
|
||||
UniValue ret(UniValue::VARR);
|
||||
for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) {
|
||||
const CTxDestination& dest = item.first;
|
||||
const std::string& strName = item.second.name;
|
||||
if (strName == strAccount) {
|
||||
ret.push_back(EncodeDestination(dest));
|
||||
ret.push_back(keyIO.EncodeDestination(dest));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -455,7 +461,8 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination dest = keyIO.DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
|
||||
}
|
||||
|
@ -513,6 +520,7 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue jsonGroupings(UniValue::VARR);
|
||||
std::map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
|
||||
for (const std::set<CTxDestination>& grouping : pwalletMain->GetAddressGroupings()) {
|
||||
|
@ -520,7 +528,7 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp)
|
|||
for (const CTxDestination& address : grouping)
|
||||
{
|
||||
UniValue addressInfo(UniValue::VARR);
|
||||
addressInfo.push_back(EncodeDestination(address));
|
||||
addressInfo.push_back(keyIO.EncodeDestination(address));
|
||||
addressInfo.push_back(ValueFromAmount(balances[address]));
|
||||
{
|
||||
if (pwalletMain->mapAddressBook.find(address) != pwalletMain->mapAddressBook.end()) {
|
||||
|
@ -567,7 +575,8 @@ UniValue signmessage(const UniValue& params, bool fHelp)
|
|||
string strAddress = params[0].get_str();
|
||||
string strMessage = params[1].get_str();
|
||||
|
||||
CTxDestination dest = DecodeDestination(strAddress);
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination dest = keyIO.DecodeDestination(strAddress);
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
|
||||
}
|
||||
|
@ -621,8 +630,9 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// Bitcoin address
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
CTxDestination dest = keyIO.DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
|
||||
}
|
||||
|
@ -960,8 +970,9 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
std::string strAccount = AccountFromValue(params[0]);
|
||||
CTxDestination dest = DecodeDestination(params[1].get_str());
|
||||
CTxDestination dest = keyIO.DecodeDestination(params[1].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Zcash address");
|
||||
}
|
||||
|
@ -1053,10 +1064,11 @@ UniValue sendmany(const UniValue& params, bool fHelp)
|
|||
std::set<CTxDestination> destinations;
|
||||
std::vector<CRecipient> vecSend;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
CAmount totalAmount = 0;
|
||||
std::vector<std::string> keys = sendTo.getKeys();
|
||||
for (const std::string& name_ : keys) {
|
||||
CTxDestination dest = DecodeDestination(name_);
|
||||
CTxDestination dest = keyIO.DecodeDestination(name_);
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + name_);
|
||||
}
|
||||
|
@ -1152,7 +1164,8 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp)
|
|||
pwalletMain->AddCScript(inner);
|
||||
|
||||
pwalletMain->SetAddressBook(innerID, strAccount, "send");
|
||||
return EncodeDestination(innerID);
|
||||
KeyIO keyIO(Params());
|
||||
return keyIO.EncodeDestination(innerID);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1218,6 +1231,8 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
|||
}
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// Reply
|
||||
UniValue ret(UniValue::VARR);
|
||||
std::map<std::string, tallyitem> mapAccountTally;
|
||||
|
@ -1250,7 +1265,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
|||
UniValue obj(UniValue::VOBJ);
|
||||
if(fIsWatchonly)
|
||||
obj.pushKV("involvesWatchonly", true);
|
||||
obj.pushKV("address", EncodeDestination(dest));
|
||||
obj.pushKV("address", keyIO.EncodeDestination(dest));
|
||||
obj.pushKV("account", strAccount);
|
||||
obj.pushKV("amount", ValueFromAmount(nAmount));
|
||||
obj.pushKV("amountZat", nAmount);
|
||||
|
@ -1366,7 +1381,8 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp)
|
|||
static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
|
||||
{
|
||||
if (IsValidDestination(dest)) {
|
||||
entry.pushKV("address", EncodeDestination(dest));
|
||||
KeyIO keyIO(Params());
|
||||
entry.pushKV("address", keyIO.EncodeDestination(dest));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2440,12 +2456,13 @@ UniValue listunspent(const UniValue& params, bool fHelp)
|
|||
if (params.size() > 1)
|
||||
nMaxDepth = params[1].get_int();
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
std::set<CTxDestination> destinations;
|
||||
if (params.size() > 2) {
|
||||
UniValue inputs = params[2].get_array();
|
||||
for (size_t idx = 0; idx < inputs.size(); idx++) {
|
||||
const UniValue& input = inputs[idx];
|
||||
CTxDestination dest = DecodeDestination(input.get_str());
|
||||
CTxDestination dest = keyIO.DecodeDestination(input.get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + input.get_str());
|
||||
}
|
||||
|
@ -2477,7 +2494,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
|
|||
entry.pushKV("generated", out.tx->IsCoinBase());
|
||||
|
||||
if (fValidAddress) {
|
||||
entry.pushKV("address", EncodeDestination(address));
|
||||
entry.pushKV("address", keyIO.EncodeDestination(address));
|
||||
|
||||
if (pwalletMain->mapAddressBook.count(address))
|
||||
entry.pushKV("account", pwalletMain->mapAddressBook[address].name);
|
||||
|
@ -2575,6 +2592,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// User has supplied zaddrs to filter on
|
||||
if (params.size() > 3) {
|
||||
UniValue addresses = params[3].get_array();
|
||||
|
@ -2590,7 +2608,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string");
|
||||
}
|
||||
string address = o.get_str();
|
||||
auto zaddr = DecodePaymentAddress(address);
|
||||
auto zaddr = keyIO.DecodePaymentAddress(address);
|
||||
if (!IsValidPaymentAddress(zaddr)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, address is not a valid zaddr: ") + address);
|
||||
}
|
||||
|
@ -2635,7 +2653,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
|||
obj.pushKV("confirmations", entry.confirmations);
|
||||
bool hasSproutSpendingKey = HaveSpendingKeyForPaymentAddress(pwalletMain)(entry.address);
|
||||
obj.pushKV("spendable", hasSproutSpendingKey);
|
||||
obj.pushKV("address", EncodePaymentAddress(entry.address));
|
||||
obj.pushKV("address", keyIO.EncodePaymentAddress(entry.address));
|
||||
obj.pushKV("amount", ValueFromAmount(CAmount(entry.note.value())));
|
||||
std::string data(entry.memo.begin(), entry.memo.end());
|
||||
obj.pushKV("memo", HexStr(data));
|
||||
|
@ -2652,7 +2670,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
|||
obj.pushKV("confirmations", entry.confirmations);
|
||||
bool hasSaplingSpendingKey = HaveSpendingKeyForPaymentAddress(pwalletMain)(entry.address);
|
||||
obj.pushKV("spendable", hasSaplingSpendingKey);
|
||||
obj.pushKV("address", EncodePaymentAddress(entry.address));
|
||||
obj.pushKV("address", keyIO.EncodePaymentAddress(entry.address));
|
||||
obj.pushKV("amount", ValueFromAmount(CAmount(entry.note.value()))); // note.value() is equivalent to plaintext.value()
|
||||
obj.pushKV("memo", HexStr(entry.memo));
|
||||
if (hasSaplingSpendingKey) {
|
||||
|
@ -2914,7 +2932,8 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
auto spendingkey = DecodeSpendingKey(params[0].get_str());
|
||||
KeyIO keyIO(Params());
|
||||
auto spendingkey = keyIO.DecodeSpendingKey(params[0].get_str());
|
||||
if (!IsValidSpendingKey(spendingkey)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||
}
|
||||
|
@ -3037,8 +3056,9 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
|||
std::vector<SproutSpendingKey> keys;
|
||||
std::vector<uint256> commitments;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
for (const string& name_ : inputs.getKeys()) {
|
||||
auto spendingkey = DecodeSpendingKey(inputs[name_].get_str());
|
||||
auto spendingkey = keyIO.DecodeSpendingKey(inputs[name_].get_str());
|
||||
if (!IsValidSpendingKey(spendingkey)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||
}
|
||||
|
@ -3086,7 +3106,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
|||
}
|
||||
|
||||
for (const string& name_ : outputs.getKeys()) {
|
||||
auto addrTo = DecodePaymentAddress(name_);
|
||||
auto addrTo = keyIO.DecodePaymentAddress(name_);
|
||||
if (!IsValidPaymentAddress(addrTo)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address.");
|
||||
}
|
||||
|
@ -3206,10 +3226,11 @@ UniValue zc_raw_keygen(const UniValue& params, bool fHelp)
|
|||
auto addr = k.address();
|
||||
auto viewing_key = k.viewing_key();
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("zcaddress", EncodePaymentAddress(addr));
|
||||
result.pushKV("zcsecretkey", EncodeSpendingKey(k));
|
||||
result.pushKV("zcviewingkey", EncodeViewingKey(viewing_key));
|
||||
result.pushKV("zcaddress", keyIO.EncodePaymentAddress(addr));
|
||||
result.pushKV("zcsecretkey", keyIO.EncodeSpendingKey(k));
|
||||
result.pushKV("zcviewingkey", keyIO.EncodeViewingKey(viewing_key));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3246,10 +3267,11 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp)
|
|||
addrType = params[0].get_str();
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
if (addrType == ADDR_TYPE_SPROUT) {
|
||||
return EncodePaymentAddress(pwalletMain->GenerateNewSproutZKey());
|
||||
return keyIO.EncodePaymentAddress(pwalletMain->GenerateNewSproutZKey());
|
||||
} else if (addrType == ADDR_TYPE_SAPLING) {
|
||||
return EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey());
|
||||
return keyIO.EncodePaymentAddress(pwalletMain->GenerateNewSaplingZKey());
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid address type");
|
||||
}
|
||||
|
@ -3284,13 +3306,14 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp)
|
|||
fIncludeWatchonly = params[0].get_bool();
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue ret(UniValue::VARR);
|
||||
{
|
||||
std::set<libzcash::SproutPaymentAddress> addresses;
|
||||
pwalletMain->GetSproutPaymentAddresses(addresses);
|
||||
for (auto addr : addresses) {
|
||||
if (fIncludeWatchonly || HaveSpendingKeyForPaymentAddress(pwalletMain)(addr)) {
|
||||
ret.push_back(EncodePaymentAddress(addr));
|
||||
ret.push_back(keyIO.EncodePaymentAddress(addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3299,7 +3322,7 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp)
|
|||
pwalletMain->GetSaplingPaymentAddresses(addresses);
|
||||
for (auto addr : addresses) {
|
||||
if (fIncludeWatchonly || HaveSpendingKeyForPaymentAddress(pwalletMain)(addr)) {
|
||||
ret.push_back(EncodePaymentAddress(addr));
|
||||
ret.push_back(keyIO.EncodePaymentAddress(addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3311,8 +3334,9 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ign
|
|||
vector<COutput> vecOutputs;
|
||||
CAmount balance = 0;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
if (transparentAddress.length() > 0) {
|
||||
CTxDestination taddr = DecodeDestination(transparentAddress);
|
||||
CTxDestination taddr = keyIO.DecodeDestination(transparentAddress);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
throw std::runtime_error("invalid transparent address");
|
||||
}
|
||||
|
@ -3427,7 +3451,8 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
|||
// Check that the from address is valid.
|
||||
auto fromaddress = params[0].get_str();
|
||||
|
||||
auto zaddr = DecodePaymentAddress(fromaddress);
|
||||
KeyIO keyIO(Params());
|
||||
auto zaddr = keyIO.DecodePaymentAddress(fromaddress);
|
||||
if (!IsValidPaymentAddress(zaddr)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr.");
|
||||
}
|
||||
|
@ -3530,13 +3555,14 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0");
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// Check that the from address is valid.
|
||||
auto fromaddress = params[0].get_str();
|
||||
bool fromTaddr = false;
|
||||
CTxDestination taddr = DecodeDestination(fromaddress);
|
||||
CTxDestination taddr = keyIO.DecodeDestination(fromaddress);
|
||||
fromTaddr = IsValidDestination(taddr);
|
||||
if (!fromTaddr) {
|
||||
auto res = DecodePaymentAddress(fromaddress);
|
||||
auto res = keyIO.DecodePaymentAddress(fromaddress);
|
||||
if (!IsValidPaymentAddress(res)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
||||
}
|
||||
|
@ -3705,6 +3731,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
|
|||
}
|
||||
};
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// Sprout spends
|
||||
for (size_t i = 0; i < wtx.vJoinSplit.size(); ++i) {
|
||||
for (size_t j = 0; j < wtx.vJoinSplit[i].nullifiers.size(); ++j) {
|
||||
|
@ -3729,7 +3756,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
|
|||
entry.pushKV("txidPrev", jsop.hash.GetHex());
|
||||
entry.pushKV("jsPrev", (int)jsop.js);
|
||||
entry.pushKV("jsOutputPrev", (int)jsop.n);
|
||||
entry.pushKV("address", EncodePaymentAddress(pa));
|
||||
entry.pushKV("address", keyIO.EncodePaymentAddress(pa));
|
||||
entry.pushKV("value", ValueFromAmount(notePt.value()));
|
||||
entry.pushKV("valueZat", notePt.value());
|
||||
spends.push_back(entry);
|
||||
|
@ -3749,7 +3776,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
|
|||
entry.pushKV("type", ADDR_TYPE_SPROUT);
|
||||
entry.pushKV("js", (int)jsop.js);
|
||||
entry.pushKV("jsOutput", (int)jsop.n);
|
||||
entry.pushKV("address", EncodePaymentAddress(pa));
|
||||
entry.pushKV("address", keyIO.EncodePaymentAddress(pa));
|
||||
entry.pushKV("value", ValueFromAmount(notePt.value()));
|
||||
entry.pushKV("valueZat", notePt.value());
|
||||
addMemo(entry, memo);
|
||||
|
@ -3792,7 +3819,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
|
|||
entry.pushKV("spend", (int)i);
|
||||
entry.pushKV("txidPrev", op.hash.GetHex());
|
||||
entry.pushKV("outputPrev", (int)op.n);
|
||||
entry.pushKV("address", EncodePaymentAddress(pa));
|
||||
entry.pushKV("address", keyIO.EncodePaymentAddress(pa));
|
||||
entry.pushKV("value", ValueFromAmount(notePt.value()));
|
||||
entry.pushKV("valueZat", notePt.value());
|
||||
spends.push_back(entry);
|
||||
|
@ -3831,7 +3858,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
|
|||
entry.pushKV("type", ADDR_TYPE_SAPLING);
|
||||
entry.pushKV("output", (int)op.n);
|
||||
entry.pushKV("outgoing", isOutgoing);
|
||||
entry.pushKV("address", EncodePaymentAddress(pa));
|
||||
entry.pushKV("address", keyIO.EncodePaymentAddress(pa));
|
||||
entry.pushKV("value", ValueFromAmount(notePt.value()));
|
||||
entry.pushKV("valueZat", notePt.value());
|
||||
addMemo(entry, memo);
|
||||
|
@ -3997,10 +4024,11 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
auto fromaddress = params[0].get_str();
|
||||
bool fromTaddr = false;
|
||||
bool fromSapling = false;
|
||||
CTxDestination taddr = DecodeDestination(fromaddress);
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination taddr = keyIO.DecodeDestination(fromaddress);
|
||||
fromTaddr = IsValidDestination(taddr);
|
||||
if (!fromTaddr) {
|
||||
auto res = DecodePaymentAddress(fromaddress);
|
||||
auto res = keyIO.DecodePaymentAddress(fromaddress);
|
||||
if (!IsValidPaymentAddress(res)) {
|
||||
// invalid
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
||||
|
@ -4049,9 +4077,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
|
||||
string address = find_value(o, "address").get_str();
|
||||
bool isZaddr = false;
|
||||
CTxDestination taddr = DecodeDestination(address);
|
||||
CTxDestination taddr = keyIO.DecodeDestination(address);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
auto res = DecodePaymentAddress(address);
|
||||
auto res = keyIO.DecodePaymentAddress(address);
|
||||
if (IsValidPaymentAddress(res)) {
|
||||
isZaddr = true;
|
||||
|
||||
|
@ -4153,7 +4181,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
size_t txsize = 0;
|
||||
for (int i = 0; i < zaddrRecipients.size(); i++) {
|
||||
auto address = zaddrRecipients[i].address;
|
||||
auto res = DecodePaymentAddress(address);
|
||||
auto res = keyIO.DecodePaymentAddress(address);
|
||||
bool toSapling = boost::get<libzcash::SaplingPaymentAddress>(&res) != nullptr;
|
||||
if (toSapling) {
|
||||
mtx.vShieldedOutput.push_back(OutputDescription());
|
||||
|
@ -4302,7 +4330,8 @@ UniValue z_getmigrationstatus(const UniValue& params, bool fHelp) {
|
|||
// parameter is not set and no default address has yet been generated.
|
||||
// Note: The following function may return the default address even if it has not been added to the wallet
|
||||
auto destinationAddress = AsyncRPCOperation_saplingmigration::getMigrationDestAddress(pwalletMain->GetHDSeedForRPC());
|
||||
migrationStatus.pushKV("destination_address", EncodePaymentAddress(destinationAddress));
|
||||
KeyIO keyIO(Params());
|
||||
migrationStatus.pushKV("destination_address", keyIO.EncodePaymentAddress(destinationAddress));
|
||||
// The values of "unmigrated_amount" and "migrated_amount" MUST take into
|
||||
// account failed transactions, that were not mined within their expiration
|
||||
// height.
|
||||
|
@ -4431,9 +4460,10 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
|||
// Validate the from address
|
||||
auto fromaddress = params[0].get_str();
|
||||
bool isFromWildcard = fromaddress == "*";
|
||||
KeyIO keyIO(Params());
|
||||
CTxDestination taddr;
|
||||
if (!isFromWildcard) {
|
||||
taddr = DecodeDestination(fromaddress);
|
||||
taddr = keyIO.DecodeDestination(fromaddress);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or \"*\".");
|
||||
}
|
||||
|
@ -4441,7 +4471,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
|||
|
||||
// Validate the destination address
|
||||
auto destaddress = params[1].get_str();
|
||||
if (!IsValidPaymentAddressString(destaddress)) {
|
||||
if (!keyIO.IsValidPaymentAddressString(destaddress)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||
}
|
||||
|
||||
|
@ -4449,7 +4479,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
|||
const bool canopyActive = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_CANOPY);
|
||||
|
||||
if (canopyActive) {
|
||||
auto decodeAddr = DecodePaymentAddress(destaddress);
|
||||
auto decodeAddr = keyIO.DecodePaymentAddress(destaddress);
|
||||
bool isToSproutZaddr = (boost::get<libzcash::SproutPaymentAddress>(&decodeAddr) != nullptr);
|
||||
|
||||
if (isToSproutZaddr) {
|
||||
|
@ -4678,6 +4708,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
bool isFromNonSprout = false;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// Sources
|
||||
for (const UniValue& o : addresses.getValues()) {
|
||||
if (!o.isStr())
|
||||
|
@ -4694,12 +4725,12 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
useAnySapling = true;
|
||||
isFromNonSprout = true;
|
||||
} else {
|
||||
CTxDestination taddr = DecodeDestination(address);
|
||||
CTxDestination taddr = keyIO.DecodeDestination(address);
|
||||
if (IsValidDestination(taddr)) {
|
||||
taddrs.insert(taddr);
|
||||
isFromNonSprout = true;
|
||||
} else {
|
||||
auto zaddr = DecodePaymentAddress(address);
|
||||
auto zaddr = keyIO.DecodePaymentAddress(address);
|
||||
if (IsValidPaymentAddress(zaddr)) {
|
||||
zaddrs.insert(zaddr);
|
||||
if (boost::get<libzcash::SaplingPaymentAddress>(&zaddr) != nullptr) {
|
||||
|
@ -4732,9 +4763,9 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
auto destaddress = params[1].get_str();
|
||||
bool isToSproutZaddr = false;
|
||||
bool isToSaplingZaddr = false;
|
||||
CTxDestination taddr = DecodeDestination(destaddress);
|
||||
CTxDestination taddr = keyIO.DecodeDestination(destaddress);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
auto decodeAddr = DecodePaymentAddress(destaddress);
|
||||
auto decodeAddr = keyIO.DecodePaymentAddress(destaddress);
|
||||
if (IsValidPaymentAddress(decodeAddr)) {
|
||||
if (boost::get<libzcash::SaplingPaymentAddress>(&decodeAddr) != nullptr) {
|
||||
isToSaplingZaddr = true;
|
||||
|
|
|
@ -68,18 +68,19 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig)
|
|||
// new, compressed:
|
||||
const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4";
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
UniValue v;
|
||||
CTxDestination address;
|
||||
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false));
|
||||
address = DecodeDestination(v.get_str());
|
||||
address = keyIO.DecodeDestination(v.get_str());
|
||||
BOOST_CHECK(IsValidDestination(address) && IsScriptDestination(address));
|
||||
|
||||
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false));
|
||||
address = DecodeDestination(v.get_str());
|
||||
address = keyIO.DecodeDestination(v.get_str());
|
||||
BOOST_CHECK(IsValidDestination(address) && IsScriptDestination(address));
|
||||
|
||||
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false));
|
||||
address = DecodeDestination(v.get_str());
|
||||
address = keyIO.DecodeDestination(v.get_str());
|
||||
BOOST_CHECK(IsValidDestination(address) && IsScriptDestination(address));
|
||||
|
||||
BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error);
|
||||
|
@ -122,9 +123,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
/*********************************
|
||||
* setaccount
|
||||
*********************************/
|
||||
BOOST_CHECK_NO_THROW(CallRPC("setaccount " + EncodeDestination(setaccountDemoAddress) + " \"\""));
|
||||
KeyIO keyIO(Params());
|
||||
BOOST_CHECK_NO_THROW(CallRPC("setaccount " + keyIO.EncodeDestination(setaccountDemoAddress) + " \"\""));
|
||||
/* Accounts are disabled */
|
||||
BOOST_CHECK_THROW(CallRPC("setaccount " + EncodeDestination(setaccountDemoAddress) + " nullaccount"), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("setaccount " + keyIO.EncodeDestination(setaccountDemoAddress) + " nullaccount"), runtime_error);
|
||||
/* t1VtArtnn1dGPiD2WFfMXYXW5mHM3q1GpgV is not owned by the test wallet. */
|
||||
BOOST_CHECK_THROW(CallRPC("setaccount t1VtArtnn1dGPiD2WFfMXYXW5mHM3q1GpgV nullaccount"), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error);
|
||||
|
@ -136,7 +138,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
* getbalance
|
||||
*********************************/
|
||||
BOOST_CHECK_NO_THROW(CallRPC("getbalance"));
|
||||
BOOST_CHECK_THROW(CallRPC("getbalance " + EncodeDestination(demoAddress)), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("getbalance " + keyIO.EncodeDestination(demoAddress)), runtime_error);
|
||||
|
||||
/*********************************
|
||||
* listunspent
|
||||
|
@ -178,10 +180,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
* listtransactions
|
||||
*********************************/
|
||||
BOOST_CHECK_NO_THROW(CallRPC("listtransactions"));
|
||||
BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + EncodeDestination(demoAddress)));
|
||||
BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + EncodeDestination(demoAddress) + " 20"));
|
||||
BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + EncodeDestination(demoAddress) + " 20 0"));
|
||||
BOOST_CHECK_THROW(CallRPC("listtransactions " + EncodeDestination(demoAddress) + " not_int"), runtime_error);
|
||||
BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + keyIO.EncodeDestination(demoAddress)));
|
||||
BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + keyIO.EncodeDestination(demoAddress) + " 20"));
|
||||
BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + keyIO.EncodeDestination(demoAddress) + " 20 0"));
|
||||
BOOST_CHECK_THROW(CallRPC("listtransactions " + keyIO.EncodeDestination(demoAddress) + " not_int"), runtime_error);
|
||||
|
||||
/*********************************
|
||||
* listlockunspent
|
||||
|
@ -218,33 +220,33 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
/* Accounts are deprecated */
|
||||
BOOST_CHECK_THROW(CallRPC("getaccountaddress accountThatDoesntExists"), runtime_error);
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount));
|
||||
BOOST_CHECK(DecodeDestination(retValue.get_str()) == demoAddress);
|
||||
BOOST_CHECK(keyIO.DecodeDestination(retValue.get_str()) == demoAddress);
|
||||
|
||||
/*********************************
|
||||
* getaccount
|
||||
*********************************/
|
||||
BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error);
|
||||
BOOST_CHECK_NO_THROW(CallRPC("getaccount " + EncodeDestination(demoAddress)));
|
||||
BOOST_CHECK_NO_THROW(CallRPC("getaccount " + keyIO.EncodeDestination(demoAddress)));
|
||||
|
||||
/*********************************
|
||||
* signmessage + verifymessage
|
||||
*********************************/
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + EncodeDestination(demoAddress) + " mymessage"));
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + keyIO.EncodeDestination(demoAddress) + " mymessage"));
|
||||
BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error);
|
||||
/* Should throw error because this address is not loaded in the wallet */
|
||||
BOOST_CHECK_THROW(CallRPC("signmessage t1h8SqgtM3QM5e2M8EzhhT1yL2PXXtA6oqe mymessage"), runtime_error);
|
||||
|
||||
/* missing arguments */
|
||||
BOOST_CHECK_THROW(CallRPC("verifymessage " + EncodeDestination(demoAddress)), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("verifymessage " + EncodeDestination(demoAddress) + " " + retValue.get_str()), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("verifymessage " + keyIO.EncodeDestination(demoAddress)), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("verifymessage " + keyIO.EncodeDestination(demoAddress) + " " + retValue.get_str()), runtime_error);
|
||||
/* Illegal address */
|
||||
BOOST_CHECK_THROW(CallRPC("verifymessage t1VtArtnn1dGPiD2WFfMXYXW5mHM3q1Gpg " + retValue.get_str() + " mymessage"), runtime_error);
|
||||
/* wrong address */
|
||||
BOOST_CHECK(CallRPC("verifymessage t1VtArtnn1dGPiD2WFfMXYXW5mHM3q1GpgV " + retValue.get_str() + " mymessage").get_bool() == false);
|
||||
/* Correct address and signature but wrong message */
|
||||
BOOST_CHECK(CallRPC("verifymessage " + EncodeDestination(demoAddress) + " " + retValue.get_str() + " wrongmessage").get_bool() == false);
|
||||
BOOST_CHECK(CallRPC("verifymessage " + keyIO.EncodeDestination(demoAddress) + " " + retValue.get_str() + " wrongmessage").get_bool() == false);
|
||||
/* Correct address, message and signature*/
|
||||
BOOST_CHECK(CallRPC("verifymessage " + EncodeDestination(demoAddress) + " " + retValue.get_str() + " mymessage").get_bool() == true);
|
||||
BOOST_CHECK(CallRPC("verifymessage " + keyIO.EncodeDestination(demoAddress) + " " + retValue.get_str() + " mymessage").get_bool() == true);
|
||||
|
||||
/*********************************
|
||||
* getaddressesbyaccount
|
||||
|
@ -255,7 +257,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
BOOST_CHECK_EQUAL(4, arr.size());
|
||||
bool notFound = true;
|
||||
for (auto a : arr.getValues()) {
|
||||
notFound &= DecodeDestination(a.get_str()) != demoAddress;
|
||||
notFound &= keyIO.DecodeDestination(a.get_str()) != demoAddress;
|
||||
}
|
||||
BOOST_CHECK(!notFound);
|
||||
|
||||
|
@ -516,8 +518,9 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
|
|||
libzcash::SproutSpendingKey key;
|
||||
BOOST_CHECK(pwalletMain->GetSproutSpendingKey(addr, key));
|
||||
|
||||
std::string s1 = EncodePaymentAddress(addr);
|
||||
std::string s2 = EncodeSpendingKey(key);
|
||||
KeyIO keyIO(Params());
|
||||
std::string s1 = keyIO.EncodePaymentAddress(addr);
|
||||
std::string s2 = keyIO.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.
|
||||
|
@ -557,11 +560,12 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
|||
// error if too many args
|
||||
BOOST_CHECK_THROW(CallRPC("z_importwallet toomany args"), runtime_error);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// create a random key locally
|
||||
auto testSpendingKey = libzcash::SproutSpendingKey::random();
|
||||
auto testPaymentAddress = testSpendingKey.address();
|
||||
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
||||
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
||||
std::string testAddr = keyIO.EncodePaymentAddress(testPaymentAddress);
|
||||
std::string testKey = keyIO.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"
|
||||
|
@ -599,7 +603,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
|||
BOOST_CHECK(addrs.size()==1);
|
||||
|
||||
// check that we have the spending key for the address
|
||||
auto address = DecodePaymentAddress(testAddr);
|
||||
auto address = keyIO.DecodePaymentAddress(testAddr);
|
||||
BOOST_CHECK(IsValidPaymentAddress(address));
|
||||
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||
auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||
|
@ -608,7 +612,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
|||
// Verify the spending key is the same as the test data
|
||||
libzcash::SproutSpendingKey k;
|
||||
BOOST_CHECK(pwalletMain->GetSproutSpendingKey(addr, k));
|
||||
BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k));
|
||||
BOOST_CHECK_EQUAL(testKey, keyIO.EncodeSpendingKey(k));
|
||||
}
|
||||
|
||||
|
||||
|
@ -631,8 +635,9 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
|||
BOOST_CHECK_THROW(CallRPC("z_exportkey toomany args"), runtime_error);
|
||||
|
||||
// error if invalid args
|
||||
KeyIO keyIO(Params());
|
||||
auto sk = libzcash::SproutSpendingKey::random();
|
||||
std::string prefix = std::string("z_importkey ") + EncodeSpendingKey(sk) + " yes ";
|
||||
std::string prefix = std::string("z_importkey ") + keyIO.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
|
||||
|
@ -653,8 +658,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
|||
// create a random Sprout key locally
|
||||
auto testSpendingKey = libzcash::SproutSpendingKey::random();
|
||||
auto testPaymentAddress = testSpendingKey.address();
|
||||
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
||||
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
||||
std::string testAddr = keyIO.EncodePaymentAddress(testPaymentAddress);
|
||||
std::string testKey = keyIO.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);
|
||||
|
@ -662,8 +667,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
|||
// create a random Sapling key locally
|
||||
auto testSaplingSpendingKey = m.Derive(i);
|
||||
auto testSaplingPaymentAddress = testSaplingSpendingKey.DefaultAddress();
|
||||
std::string testSaplingAddr = EncodePaymentAddress(testSaplingPaymentAddress);
|
||||
std::string testSaplingKey = EncodeSpendingKey(testSaplingSpendingKey);
|
||||
std::string testSaplingAddr = keyIO.EncodePaymentAddress(testSaplingPaymentAddress);
|
||||
std::string testSaplingKey = keyIO.EncodeSpendingKey(testSaplingSpendingKey);
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("z_importkey ") + testSaplingKey));
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC(string("z_exportkey ") + testSaplingAddr));
|
||||
BOOST_CHECK_EQUAL(retValue.get_str(), testSaplingKey);
|
||||
|
@ -682,7 +687,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
|||
|
||||
// Make new addresses for the set
|
||||
for (int i=0; i<n2; i++) {
|
||||
myaddrs.insert(EncodePaymentAddress(pwalletMain->GenerateNewSproutZKey()));
|
||||
myaddrs.insert(keyIO.EncodePaymentAddress(pwalletMain->GenerateNewSproutZKey()));
|
||||
}
|
||||
|
||||
// Verify number of addresses stored in wallet is n1+n2
|
||||
|
@ -729,17 +734,18 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_getnewaddress) {
|
|||
pwalletMain->GenerateNewSeed();
|
||||
}
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// No parameter defaults to sapling address
|
||||
addr = CallRPC("z_getnewaddress");
|
||||
CheckHaveAddr<SaplingPaymentAddress>(DecodePaymentAddress(addr.get_str()));
|
||||
CheckHaveAddr<SaplingPaymentAddress>(keyIO.DecodePaymentAddress(addr.get_str()));
|
||||
|
||||
// Passing 'sapling' should also work
|
||||
addr = CallRPC("z_getnewaddress sapling");
|
||||
CheckHaveAddr<SaplingPaymentAddress>(DecodePaymentAddress(addr.get_str()));
|
||||
CheckHaveAddr<SaplingPaymentAddress>(keyIO.DecodePaymentAddress(addr.get_str()));
|
||||
|
||||
// Should also support sprout
|
||||
addr = CallRPC("z_getnewaddress sprout");
|
||||
CheckHaveAddr<SproutPaymentAddress>(DecodePaymentAddress(addr.get_str()));
|
||||
CheckHaveAddr<SproutPaymentAddress>(keyIO.DecodePaymentAddress(addr.get_str()));
|
||||
|
||||
// Should throw on invalid argument
|
||||
CheckRPCThrows("z_getnewaddress garbage", "Invalid address type");
|
||||
|
@ -1062,7 +1068,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
|
|||
std::fill(v.begin(),v.end(), 'A');
|
||||
std::string badmemo(v.begin(), v.end());
|
||||
auto pa = pwalletMain->GenerateNewSproutZKey();
|
||||
std::string zaddr1 = EncodePaymentAddress(pa);
|
||||
KeyIO keyIO(Params());
|
||||
std::string zaddr1 = keyIO.EncodePaymentAddress(pa);
|
||||
BOOST_CHECK_THROW(CallRPC(string("z_sendmany tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ ")
|
||||
+ "[{\"address\":\"" + zaddr1 + "\", \"amount\":123.456}]"), runtime_error);
|
||||
|
||||
|
@ -1153,7 +1160,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress"));
|
||||
std::string taddr1 = retValue.get_str();
|
||||
auto pa = pwalletMain->GenerateNewSproutZKey();
|
||||
std::string zaddr1 = EncodePaymentAddress(pa);
|
||||
KeyIO keyIO(Params());
|
||||
std::string zaddr1 = keyIO.EncodePaymentAddress(pa);
|
||||
|
||||
// there are no utxos to spend
|
||||
{
|
||||
|
@ -1351,11 +1359,12 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_taddr_to_sapling)
|
|||
|
||||
UniValue retValue;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// add keys manually
|
||||
auto taddr = pwalletMain->GenerateNewKey().GetID();
|
||||
std::string taddr1 = EncodeDestination(taddr);
|
||||
std::string taddr1 = keyIO.EncodeDestination(taddr);
|
||||
auto pa = pwalletMain->GenerateNewSaplingZKey();
|
||||
std::string zaddr1 = EncodePaymentAddress(pa);
|
||||
std::string zaddr1 = keyIO.EncodePaymentAddress(pa);
|
||||
|
||||
auto consensusParams = Params().GetConsensus();
|
||||
retValue = CallRPC("getblockcount");
|
||||
|
@ -1700,8 +1709,9 @@ BOOST_AUTO_TEST_CASE(rpc_z_shieldcoinbase_internals)
|
|||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(consensusParams, nHeight + 1);
|
||||
|
||||
// Add keys manually
|
||||
KeyIO keyIO(Params());
|
||||
auto pa = pwalletMain->GenerateNewSproutZKey();
|
||||
std::string zaddr = EncodePaymentAddress(pa);
|
||||
std::string zaddr = keyIO.EncodePaymentAddress(pa);
|
||||
|
||||
// Insufficient funds
|
||||
{
|
||||
|
@ -1908,7 +1918,8 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals)
|
|||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress"));
|
||||
MergeToAddressRecipient taddr1(retValue.get_str(), "");
|
||||
auto pa = pwalletMain->GenerateNewSproutZKey();
|
||||
MergeToAddressRecipient zaddr1(EncodePaymentAddress(pa), "DEADBEEF");
|
||||
KeyIO keyIO(Params());
|
||||
MergeToAddressRecipient zaddr1(keyIO.EncodePaymentAddress(pa), "DEADBEEF");
|
||||
|
||||
// Insufficient funds
|
||||
{
|
||||
|
|
|
@ -465,9 +465,10 @@ bool CWallet::LoadCScript(const CScript& redeemScript)
|
|||
/* A sanity check was added in pull #3843 to avoid adding redeemScripts
|
||||
* that never can be redeemed. However, old wallets may still contain
|
||||
* these. Do not add them to the wallet and warn. */
|
||||
KeyIO keyIO(Params());
|
||||
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
|
||||
{
|
||||
std::string strAddr = EncodeDestination(CScriptID(redeemScript));
|
||||
std::string strAddr = keyIO.EncodeDestination(CScriptID(redeemScript));
|
||||
LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
|
||||
__func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
|
||||
return true;
|
||||
|
@ -2271,13 +2272,14 @@ std::pair<SproutNotePlaintext, SproutPaymentAddress> CWalletTx::DecryptSproutNot
|
|||
auto nd = this->mapSproutNoteData.at(jsop);
|
||||
SproutPaymentAddress pa = nd.address;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// Get cached decryptor
|
||||
ZCNoteDecryption decryptor;
|
||||
if (!pwallet->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",
|
||||
EncodePaymentAddress(pa)));
|
||||
keyIO.EncodePaymentAddress(pa)));
|
||||
}
|
||||
|
||||
auto hSig = this->vJoinSplit[jsop.js].h_sig(this->joinSplitPubKey);
|
||||
|
@ -2294,12 +2296,12 @@ std::pair<SproutNotePlaintext, SproutPaymentAddress> CWalletTx::DecryptSproutNot
|
|||
// Couldn't decrypt with this spending key
|
||||
throw std::runtime_error(strprintf(
|
||||
"Could not decrypt note for payment address %s",
|
||||
EncodePaymentAddress(pa)));
|
||||
keyIO.EncodePaymentAddress(pa)));
|
||||
} catch (const std::exception &exc) {
|
||||
// Unexpected failure
|
||||
throw std::runtime_error(strprintf(
|
||||
"Error while decrypting note for payment address %s: %s",
|
||||
EncodePaymentAddress(pa), exc.what()));
|
||||
keyIO.EncodePaymentAddress(pa), exc.what()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3955,22 +3957,24 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
|
|||
}
|
||||
NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
|
||||
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
|
||||
KeyIO keyIO(Params());
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(EncodeDestination(address), strPurpose))
|
||||
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(keyIO.EncodeDestination(address), strPurpose))
|
||||
return false;
|
||||
return CWalletDB(strWalletFile).WriteName(EncodeDestination(address), strName);
|
||||
return CWalletDB(strWalletFile).WriteName(keyIO.EncodeDestination(address), strName);
|
||||
}
|
||||
|
||||
bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||
{
|
||||
KeyIO keyIO(Params());
|
||||
{
|
||||
LOCK(cs_wallet); // mapAddressBook
|
||||
|
||||
if(fFileBacked)
|
||||
{
|
||||
// Delete destdata tuples associated with address
|
||||
std::string strAddress = EncodeDestination(address);
|
||||
std::string strAddress = keyIO.EncodeDestination(address);
|
||||
BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
|
||||
{
|
||||
CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
|
||||
|
@ -3983,8 +3987,8 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
|
|||
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
CWalletDB(strWalletFile).ErasePurpose(EncodeDestination(address));
|
||||
return CWalletDB(strWalletFile).EraseName(EncodeDestination(address));
|
||||
CWalletDB(strWalletFile).ErasePurpose(keyIO.EncodeDestination(address));
|
||||
return CWalletDB(strWalletFile).EraseName(keyIO.EncodeDestination(address));
|
||||
}
|
||||
|
||||
bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
|
||||
|
@ -4558,7 +4562,8 @@ bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, co
|
|||
mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
return CWalletDB(strWalletFile).WriteDestData(EncodeDestination(dest), key, value);
|
||||
KeyIO keyIO(Params());
|
||||
return CWalletDB(strWalletFile).WriteDestData(keyIO.EncodeDestination(dest), key, value);
|
||||
}
|
||||
|
||||
bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
|
||||
|
@ -4567,7 +4572,8 @@ bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
|
|||
return false;
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
return CWalletDB(strWalletFile).EraseDestData(EncodeDestination(dest), key);
|
||||
KeyIO keyIO(Params());
|
||||
return CWalletDB(strWalletFile).EraseDestData(keyIO.EncodeDestination(dest), key);
|
||||
}
|
||||
|
||||
bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
|
||||
|
@ -4842,10 +4848,11 @@ bool CWallet::ParameterInteraction()
|
|||
bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
|
||||
fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
// Check Sapling migration address if set and is a valid Sapling address
|
||||
if (mapArgs.count("-migrationdestaddress")) {
|
||||
std::string migrationDestAddress = mapArgs["-migrationdestaddress"];
|
||||
libzcash::PaymentAddress address = DecodePaymentAddress(migrationDestAddress);
|
||||
libzcash::PaymentAddress address = keyIO.DecodePaymentAddress(migrationDestAddress);
|
||||
if (boost::get<libzcash::SaplingPaymentAddress>(&address) == nullptr) {
|
||||
return UIError(_("-migrationdestaddress must be a valid Sapling address."));
|
||||
}
|
||||
|
@ -4957,8 +4964,9 @@ void CWallet::GetFilteredNotes(
|
|||
{
|
||||
std::set<PaymentAddress> filterAddresses;
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
if (address.length() > 0) {
|
||||
filterAddresses.insert(DecodePaymentAddress(address));
|
||||
filterAddresses.insert(keyIO.DecodePaymentAddress(address));
|
||||
}
|
||||
|
||||
GetFilteredNotes(sproutEntries, saplingEntries, filterAddresses, minDepth, INT_MAX, ignoreSpent, requireSpendingKey);
|
||||
|
@ -4981,6 +4989,7 @@ void CWallet::GetFilteredNotes(
|
|||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
|
||||
KeyIO keyIO(Params());
|
||||
for (auto & p : mapWallet) {
|
||||
CWalletTx wtx = p.second;
|
||||
|
||||
|
@ -5028,7 +5037,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", EncodePaymentAddress(pa)));
|
||||
throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", keyIO.EncodePaymentAddress(pa)));
|
||||
}
|
||||
|
||||
// determine amount of funds in the note
|
||||
|
@ -5046,10 +5055,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", EncodePaymentAddress(pa)));
|
||||
throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", keyIO.EncodePaymentAddress(pa)));
|
||||
} catch (const std::exception &exc) {
|
||||
// Unexpected failure
|
||||
throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what()));
|
||||
throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", keyIO.EncodePaymentAddress(pa), exc.what()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5236,8 +5245,9 @@ KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::InvalidEncoding&
|
|||
|
||||
KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const {
|
||||
auto addr = sk.address();
|
||||
KeyIO keyIO(Params());
|
||||
if (log){
|
||||
LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
|
||||
LogPrint("zrpc", "Importing zaddr %s...\n", keyIO.EncodePaymentAddress(addr));
|
||||
}
|
||||
if (m_wallet->HaveSproutSpendingKey(addr)) {
|
||||
return KeyAlreadyExists;
|
||||
|
@ -5252,9 +5262,10 @@ KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKe
|
|||
KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedSpendingKey &sk) const {
|
||||
auto extfvk = sk.ToXFVK();
|
||||
auto ivk = extfvk.fvk.in_viewing_key();
|
||||
KeyIO keyIO(Params());
|
||||
{
|
||||
if (log){
|
||||
LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(sk.DefaultAddress()));
|
||||
LogPrint("zrpc", "Importing zaddr %s...\n", keyIO.EncodePaymentAddress(sk.DefaultAddress()));
|
||||
}
|
||||
// Don't throw error in case a key is already there
|
||||
if (m_wallet->HaveSaplingSpendingKey(extfvk)) {
|
||||
|
|
|
@ -458,6 +458,8 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
CWalletScanState &wss, string& strType, string& strErr)
|
||||
{
|
||||
try {
|
||||
KeyIO keyIO(Params());
|
||||
|
||||
// Unserialize
|
||||
// Taking advantage of the fact that pair serialization
|
||||
// is just the two items serialized one after the other
|
||||
|
@ -466,13 +468,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
{
|
||||
string strAddress;
|
||||
ssKey >> strAddress;
|
||||
ssValue >> pwallet->mapAddressBook[DecodeDestination(strAddress)].name;
|
||||
ssValue >> pwallet->mapAddressBook[keyIO.DecodeDestination(strAddress)].name;
|
||||
}
|
||||
else if (strType == "purpose")
|
||||
{
|
||||
string strAddress;
|
||||
ssKey >> strAddress;
|
||||
ssValue >> pwallet->mapAddressBook[DecodeDestination(strAddress)].purpose;
|
||||
ssValue >> pwallet->mapAddressBook[keyIO.DecodeDestination(strAddress)].purpose;
|
||||
}
|
||||
else if (strType == "tx")
|
||||
{
|
||||
|
@ -829,7 +831,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
ssKey >> strAddress;
|
||||
ssKey >> strKey;
|
||||
ssValue >> strValue;
|
||||
if (!pwallet->LoadDestData(DecodeDestination(strAddress), strKey, strValue))
|
||||
if (!pwallet->LoadDestData(keyIO.DecodeDestination(strAddress), strKey, strValue))
|
||||
{
|
||||
strErr = "Error reading wallet database: LoadDestData failed";
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue