Replace CBitcoinSecret with {Encode,Decode}Secret
This commit is contained in:
parent
ffc6e48b29
commit
32e69fa0df
9 changed files with 62 additions and 118 deletions
|
@ -323,39 +323,35 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par
|
|||
}
|
||||
} // namespace
|
||||
|
||||
void CBitcoinSecret::SetKey(const CKey& vchSecret)
|
||||
CKey DecodeSecret(const std::string& str)
|
||||
{
|
||||
assert(vchSecret.IsValid());
|
||||
SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
|
||||
if (vchSecret.IsCompressed())
|
||||
vchData.push_back(1);
|
||||
CKey key;
|
||||
std::vector<unsigned char> data;
|
||||
if (DecodeBase58Check(str, data)) {
|
||||
const std::vector<unsigned char>& privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
if ((data.size() == 32 + privkey_prefix.size() || (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
|
||||
std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
|
||||
bool compressed = data.size() == 33 + privkey_prefix.size();
|
||||
key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
|
||||
}
|
||||
}
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return key;
|
||||
}
|
||||
|
||||
CKey CBitcoinSecret::GetKey()
|
||||
std::string EncodeSecret(const CKey& key)
|
||||
{
|
||||
CKey ret;
|
||||
assert(vchData.size() >= 32);
|
||||
ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
|
||||
assert(key.IsValid());
|
||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
data.insert(data.end(), key.begin(), key.end());
|
||||
if (key.IsCompressed()) {
|
||||
data.push_back(1);
|
||||
}
|
||||
std::string ret = EncodeBase58Check(data);
|
||||
memory_cleanse(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::IsValid() const
|
||||
{
|
||||
bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
|
||||
bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
|
||||
return fExpectedFormat && fCorrectVersion;
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::SetString(const char* pszSecret)
|
||||
{
|
||||
return CBase58Data::SetString(pszSecret) && IsValid();
|
||||
}
|
||||
|
||||
bool CBitcoinSecret::SetString(const std::string& strSecret)
|
||||
{
|
||||
return SetString(strSecret.c_str());
|
||||
}
|
||||
|
||||
std::string EncodeDestination(const CTxDestination& dest)
|
||||
{
|
||||
return boost::apply_visitor(DestinationEncoder(Params()), dest);
|
||||
|
|
17
src/base58.h
17
src/base58.h
|
@ -94,21 +94,8 @@ public:
|
|||
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
* A base58-encoded secret key
|
||||
*/
|
||||
class CBitcoinSecret : public CBase58Data
|
||||
{
|
||||
public:
|
||||
void SetKey(const CKey& vchSecret);
|
||||
CKey GetKey();
|
||||
bool IsValid() const;
|
||||
bool SetString(const char* pszSecret);
|
||||
bool SetString(const std::string& strSecret);
|
||||
|
||||
CBitcoinSecret(const CKey& vchSecret) { SetKey(vchSecret); }
|
||||
CBitcoinSecret() {}
|
||||
};
|
||||
CKey DecodeSecret(const std::string& str);
|
||||
std::string EncodeSecret(const CKey& key);
|
||||
|
||||
template<typename K, int Size, CChainParams::Base58Type Type> class CBitcoinExtKeyBase : public CBase58Data
|
||||
{
|
||||
|
|
|
@ -563,12 +563,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
|
|||
for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) {
|
||||
if (!keysObj[kidx].isStr())
|
||||
throw std::runtime_error("privatekey not a std::string");
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(keysObj[kidx].getValStr());
|
||||
if (!fGood)
|
||||
CKey key = DecodeSecret(keysObj[kidx].getValStr());
|
||||
if (!key.IsValid()) {
|
||||
throw std::runtime_error("privatekey not valid");
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
}
|
||||
tempKeystore.AddKey(key);
|
||||
}
|
||||
|
||||
|
|
|
@ -224,13 +224,10 @@ UniValue signmessagewithprivkey(const JSONRPCRequest& request)
|
|||
std::string strPrivkey = request.params[0].get_str();
|
||||
std::string strMessage = request.params[1].get_str();
|
||||
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(strPrivkey);
|
||||
if (!fGood)
|
||||
CKey key = DecodeSecret(strPrivkey);
|
||||
if (!key.IsValid()) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||
CKey key = vchSecret.GetKey();
|
||||
if (!key.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
|
||||
}
|
||||
|
||||
CHashWriter ss(SER_GETHASH, 0);
|
||||
ss << strMessageMagic;
|
||||
|
|
|
@ -896,13 +896,9 @@ UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
|
|||
const UniValue& keys = request.params[1].get_array();
|
||||
for (unsigned int idx = 0; idx < keys.size(); ++idx) {
|
||||
UniValue k = keys[idx];
|
||||
CBitcoinSecret vchSecret;
|
||||
if (!vchSecret.SetString(k.get_str())) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||
}
|
||||
CKey key = vchSecret.GetKey();
|
||||
CKey key = DecodeSecret(k.get_str());
|
||||
if (!key.IsValid()) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||
}
|
||||
keystore.AddKey(key);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
|
|||
BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
||||
{
|
||||
UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
|
||||
CBitcoinSecret secret;
|
||||
CKey privkey;
|
||||
CTxDestination destination;
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
|
||||
|
@ -97,9 +97,8 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
|||
if (isPrivkey) {
|
||||
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
|
||||
// Must be valid private key
|
||||
BOOST_CHECK_MESSAGE(secret.SetString(exp_base58string), "!SetString:"+ strTest);
|
||||
BOOST_CHECK_MESSAGE(secret.IsValid(), "!IsValid:" + strTest);
|
||||
CKey privkey = secret.GetKey();
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest);
|
||||
BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
|
||||
BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest);
|
||||
|
||||
|
@ -129,8 +128,8 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
|||
}
|
||||
|
||||
// Public key must be invalid private key
|
||||
secret.SetString(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid pubkey as privkey:" + strTest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,9 +157,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
|||
CKey key;
|
||||
key.Set(exp_payload.begin(), exp_payload.end(), isCompressed);
|
||||
assert(key.IsValid());
|
||||
CBitcoinSecret secret;
|
||||
secret.SetKey(key);
|
||||
BOOST_CHECK_MESSAGE(secret.ToString() == exp_base58string, "result mismatch: " + strTest);
|
||||
BOOST_CHECK_MESSAGE(EncodeSecret(key) == exp_base58string, "result mismatch: " + strTest);
|
||||
} else {
|
||||
CTxDestination dest;
|
||||
CScript exp_script(exp_payload.begin(), exp_payload.end());
|
||||
|
@ -179,7 +176,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
|||
BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
||||
{
|
||||
UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases
|
||||
CBitcoinSecret secret;
|
||||
CKey privkey;
|
||||
CTxDestination destination;
|
||||
|
||||
for (unsigned int idx = 0; idx < tests.size(); idx++) {
|
||||
|
@ -197,8 +194,8 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
|||
SelectParams(chain);
|
||||
destination = DecodeDestination(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!IsValidDestination(destination), "IsValid pubkey in mainnet:" + strTest);
|
||||
secret.SetString(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid privkey in mainnet:" + strTest);
|
||||
privkey = DecodeSecret(exp_base58string);
|
||||
BOOST_CHECK_MESSAGE(!privkey.IsValid(), "IsValid privkey in mainnet:" + strTest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,10 +85,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
|
|||
BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
|
||||
{
|
||||
std::string strSecret = std::string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
|
||||
CBitcoinSecret vchSecret;
|
||||
BOOST_CHECK(vchSecret.SetString(strSecret));
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
CKey key = DecodeSecret(strSecret);
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
std::vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end());
|
||||
|
||||
|
|
|
@ -32,21 +32,16 @@ BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(key_test1)
|
||||
{
|
||||
CBitcoinSecret bsecret1, bsecret2, bsecret1C, bsecret2C, baddress1;
|
||||
BOOST_CHECK( bsecret1.SetString (strSecret1));
|
||||
BOOST_CHECK( bsecret2.SetString (strSecret2));
|
||||
BOOST_CHECK( bsecret1C.SetString(strSecret1C));
|
||||
BOOST_CHECK( bsecret2C.SetString(strSecret2C));
|
||||
BOOST_CHECK(!baddress1.SetString(strAddressBad));
|
||||
|
||||
CKey key1 = bsecret1.GetKey();
|
||||
BOOST_CHECK(key1.IsCompressed() == false);
|
||||
CKey key2 = bsecret2.GetKey();
|
||||
BOOST_CHECK(key2.IsCompressed() == false);
|
||||
CKey key1C = bsecret1C.GetKey();
|
||||
BOOST_CHECK(key1C.IsCompressed() == true);
|
||||
CKey key2C = bsecret2C.GetKey();
|
||||
BOOST_CHECK(key2C.IsCompressed() == true);
|
||||
CKey key1 = DecodeSecret(strSecret1);
|
||||
BOOST_CHECK(key1.IsValid() && !key1.IsCompressed());
|
||||
CKey key2 = DecodeSecret(strSecret2);
|
||||
BOOST_CHECK(key2.IsValid() && !key2.IsCompressed());
|
||||
CKey key1C = DecodeSecret(strSecret1C);
|
||||
BOOST_CHECK(key1C.IsValid() && key1C.IsCompressed());
|
||||
CKey key2C = DecodeSecret(strSecret2C);
|
||||
BOOST_CHECK(key2C.IsValid() && key2C.IsCompressed());
|
||||
CKey bad_key = DecodeSecret(strAddressBad);
|
||||
BOOST_CHECK(!bad_key.IsValid());
|
||||
|
||||
CPubKey pubkey1 = key1. GetPubKey();
|
||||
CPubKey pubkey2 = key2. GetPubKey();
|
||||
|
|
|
@ -147,13 +147,8 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
|||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
|
||||
}
|
||||
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(strSecret);
|
||||
|
||||
if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
|
||||
CKey key = DecodeSecret(strSecret);
|
||||
if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
assert(key.VerifyPubKey(pubkey));
|
||||
|
@ -554,9 +549,8 @@ UniValue importwallet(const JSONRPCRequest& request)
|
|||
boost::split(vstr, line, boost::is_any_of(" "));
|
||||
if (vstr.size() < 2)
|
||||
continue;
|
||||
CBitcoinSecret vchSecret;
|
||||
if (vchSecret.SetString(vstr[0])) {
|
||||
CKey key = vchSecret.GetKey();
|
||||
CKey key = DecodeSecret(vstr[0]);
|
||||
if (key.IsValid()) {
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
assert(key.VerifyPubKey(pubkey));
|
||||
CKeyID keyid = pubkey.GetID();
|
||||
|
@ -659,7 +653,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
|
|||
if (!pwallet->GetKey(keyid, vchSecret)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
|
||||
}
|
||||
return CBitcoinSecret(vchSecret).ToString();
|
||||
return EncodeSecret(vchSecret);
|
||||
}
|
||||
|
||||
|
||||
|
@ -755,7 +749,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
|
|||
std::string strLabel;
|
||||
CKey key;
|
||||
if (pwallet->GetKey(keyid, key)) {
|
||||
file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime);
|
||||
file << strprintf("%s %s ", EncodeSecret(key), strTime);
|
||||
if (GetWalletAddressesForKey(pwallet, keyid, strAddr, strLabel)) {
|
||||
file << strprintf("label=%s", strLabel);
|
||||
} else if (keyid == masterKeyID) {
|
||||
|
@ -911,17 +905,10 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
|
|||
for (size_t i = 0; i < keys.size(); i++) {
|
||||
const std::string& privkey = keys[i].get_str();
|
||||
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(privkey);
|
||||
|
||||
if (!fGood) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
}
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
CKey key = DecodeSecret(privkey);
|
||||
|
||||
if (!key.IsValid()) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
}
|
||||
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
|
@ -1018,16 +1005,10 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6
|
|||
const std::string& strPrivkey = keys[0].get_str();
|
||||
|
||||
// Checks.
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(strPrivkey);
|
||||
CKey key = DecodeSecret(strPrivkey);
|
||||
|
||||
if (!fGood) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
}
|
||||
|
||||
CKey key = vchSecret.GetKey();
|
||||
if (!key.IsValid()) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
|
||||
}
|
||||
|
||||
CPubKey pubKey = key.GetPubKey();
|
||||
|
|
Loading…
Reference in a new issue