Add blinding key import/export RPCs

This commit is contained in:
Matt Corallo 2016-03-01 16:52:32 -08:00 committed by Gregory Sanders
parent c33e8ea41e
commit eaf5ab06be
2 changed files with 96 additions and 0 deletions

View file

@ -639,3 +639,95 @@ UniValue dumpwallet(const UniValue& params, bool fHelp)
file.close();
return NullUniValue;
}
UniValue dumpblindingkey(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
if (fHelp || params.size() < 1 || params.size() > 1)
throw runtime_error(
"dumpblindingkey \"address\"\n"
"\nDumps the private blinding key for a CT address in hex."
"\nArguments:\n"
"1. \"address\" (string, required) The CT address\n"
);
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
}
if (!address.IsBlinded()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not a CT address");
}
CTxDestination dest = address.Get();
CScript script = GetScriptForDestination(dest);
CKey key;
key = pwalletMain->GetBlindingKey(&script);
if (key.IsValid()) {
CPubKey pubkey = key.GetPubKey();
if (pubkey == address.GetBlindingKey()) {
return HexStr(key.begin(), key.end());
}
}
// Just for backward compatibility
key = pwalletMain->GetBlindingKey(NULL);
if (key.IsValid()) {
CPubKey pubkey = key.GetPubKey();
if (pubkey == address.GetBlindingKey()) {
return HexStr(key.begin(), key.end());
}
}
throw JSONRPCError(RPC_WALLET_ERROR, "Blinding key for address is unknown");
}
UniValue importblindingkey(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
if (fHelp || params.size() < 2 || params.size() > 2)
throw runtime_error(
"importblindingkey \"address\" \"blindinghex\"\n"
"\nImports a private blinding key in hex for a CT address."
"\nArguments:\n"
"1. \"address\" (string, required) The CT address\n"
"2. \"hexkey\" (string, required) The blinding key in hex\n"
);
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
}
if (!address.IsBlinded()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Not a CT address");
}
if (!IsHex(params[1].get_str())) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid hexadecimal for key");
}
std::vector<unsigned char> keydata = ParseHex(params[1].get_str());
if (keydata.size() != 32) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid hexadecimal key length");
}
CKey key;
key.Set(keydata.begin(), keydata.end(), true);
if (!key.IsValid() || key.GetPubKey() != address.GetBlindingKey()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Address and key do not match");
}
uint256 keyval;
memcpy(keyval.begin(), &keydata[0], 32);
if (!pwalletMain->AddSpecificBlindingKey(CScriptID(GetScriptForDestination(address.Get())), keyval)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Failed to import blinding key");
}
pwalletMain->MarkDirty();
return NullUniValue;
}

View file

@ -2661,6 +2661,8 @@ extern UniValue dumpwallet(const UniValue& params, bool fHelp);
extern UniValue importwallet(const UniValue& params, bool fHelp);
extern UniValue importprunedfunds(const UniValue& params, bool fHelp);
extern UniValue removeprunedfunds(const UniValue& params, bool fHelp);
extern UniValue dumpblindingkey(const UniValue& params, bool fHelp);
extern UniValue importblindingkey(const UniValue& params, bool fHelp);
static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode
@ -2671,6 +2673,7 @@ static const CRPCCommand commands[] =
{ "wallet", "addmultisigaddress", &addmultisigaddress, true },
{ "wallet", "addwitnessaddress", &addwitnessaddress, true },
{ "wallet", "backupwallet", &backupwallet, true },
{ "wallet", "dumpblindingkey", &dumpblindingkey, true },
{ "wallet", "dumpprivkey", &dumpprivkey, true },
{ "wallet", "dumpwallet", &dumpwallet, true },
{ "wallet", "encryptwallet", &encryptwallet, true },
@ -2688,6 +2691,7 @@ static const CRPCCommand commands[] =
{ "wallet", "importprivkey", &importprivkey, true },
{ "wallet", "importwallet", &importwallet, true },
{ "wallet", "importaddress", &importaddress, true },
{ "wallet", "importblindingkey", &importblindingkey, true },
{ "wallet", "importprunedfunds", &importprunedfunds, true },
{ "wallet", "importpubkey", &importpubkey, true },
{ "wallet", "keypoolrefill", &keypoolrefill, true },