Skip to content

Commit f90efbf

Browse files
committed
Create signmessagewithprivkey rpc
New rpc 'signmessagewithprivkey' which takes a private key to sign a message without using the wallet.
1 parent e26b620 commit f90efbf

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/rpc/misc.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,48 @@ UniValue verifymessage(const UniValue& params, bool fHelp)
366366
return (pubkey.GetID() == keyID);
367367
}
368368

369+
UniValue signmessagewithprivkey(const UniValue& params, bool fHelp)
370+
{
371+
if (fHelp || params.size() != 2)
372+
throw runtime_error(
373+
"signmessagewithprivkey \"privkey\" \"message\"\n"
374+
"\nSign a message with the private key of an address\n"
375+
"\nArguments:\n"
376+
"1. \"privkey\" (string, required) The private key to sign the message with.\n"
377+
"2. \"message\" (string, required) The message to create a signature of.\n"
378+
"\nResult:\n"
379+
"\"signature\" (string) The signature of the message encoded in base 64\n"
380+
"\nExamples:\n"
381+
"\nCreate the signature\n"
382+
+ HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
383+
"\nVerify the signature\n"
384+
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
385+
"\nAs json rpc\n"
386+
+ HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
387+
);
388+
389+
string strPrivkey = params[0].get_str();
390+
string strMessage = params[1].get_str();
391+
392+
CBitcoinSecret vchSecret;
393+
bool fGood = vchSecret.SetString(strPrivkey);
394+
if (!fGood)
395+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
396+
CKey key = vchSecret.GetKey();
397+
if (!key.IsValid())
398+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
399+
400+
CHashWriter ss(SER_GETHASH, 0);
401+
ss << strMessageMagic;
402+
ss << strMessage;
403+
404+
vector<unsigned char> vchSig;
405+
if (!key.SignCompact(ss.GetHash(), vchSig))
406+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
407+
408+
return EncodeBase64(&vchSig[0], vchSig.size());
409+
}
410+
369411
UniValue setmocktime(const UniValue& params, bool fHelp)
370412
{
371413
if (fHelp || params.size() != 1)
@@ -404,6 +446,7 @@ static const CRPCCommand commands[] =
404446
{ "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
405447
{ "util", "createmultisig", &createmultisig, true },
406448
{ "util", "verifymessage", &verifymessage, true },
449+
{ "util", "signmessagewithprivkey", &signmessagewithprivkey, true },
407450

408451
/* Not shown in help */
409452
{ "hidden", "setmocktime", &setmocktime, true },

0 commit comments

Comments
 (0)