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