Bitcoin Core 32.99.0
P2P Digital Currency
signmessage.cpp
Go to the documentation of this file.
1// Copyright (c) 2010 Satoshi Nakamoto
2// Copyright (c) 2009-present The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
7#include <rpc/register.h> // IWYU pragma: associated
8
9#include <key.h>
10#include <key_io.h>
11#include <rpc/protocol.h>
12#include <rpc/request.h>
13#include <rpc/server.h>
14#include <rpc/util.h>
15#include <univalue.h>
16
17#include <string>
18#include <string_view>
19#include <vector>
20
22{
23 return RPCMethod{"verifymessage",
24 "Verify a signed message.",
25 {
26 {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the signature."},
27 {"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "The signature provided by the signer in base 64 encoding (see signmessage)."},
28 {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."},
29 },
31 RPCResult::Type::BOOL, "", "If the signature is verified or not."
32 },
34 "\nUnlock the wallet for 30 seconds\n"
35 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
36 "\nCreate the signature\n"
37 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
38 "\nVerify the signature\n"
39 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
40 "\nAs a JSON-RPC call\n"
41 + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"signature\", \"my message\"")
42 },
43 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
44 {
45 switch (MessageVerify(std::string{self.Arg<std::string_view>("address")},
46 std::string{self.Arg<std::string_view>("signature")},
47 std::string{self.Arg<std::string_view>("message")})) {
49 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
51 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
53 throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding");
56 return false;
58 return true;
59 }
60
61 return false;
62 },
63 };
64}
65
67{
68 return RPCMethod{
69 "signmessagewithprivkey",
70 "Sign a message with the private key of an address\n",
71 {
72 {"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."},
73 {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
74 },
76 RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
77 },
79 "\nCreate the signature\n"
80 + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
81 "\nVerify the signature\n"
82 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
83 "\nAs a JSON-RPC call\n"
84 + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
85 },
86 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
87 {
88 std::string strPrivkey = request.params[0].get_str();
89 std::string strMessage = request.params[1].get_str();
90
91 CKey key = DecodeSecret(strPrivkey);
92 if (!key.IsValid()) {
93 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
94 }
95
96 std::string signature;
97
98 if (!MessageSign(key, strMessage, signature)) {
99 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
100 }
101
102 return signature;
103 },
104 };
105}
106
108{
109 static const CRPCCommand commands[]{
110 {"util", &verifymessage},
111 {"util", &signmessagewithprivkey},
112 };
113 for (const auto& c : commands) {
114 t.appendCommand(c.name, &c);
115 }
116}
An encapsulated private key.
Definition: key.h:40
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:128
RPC command dispatcher.
Definition: server.h:89
auto Arg(std::string_view key) const
Helper to get a required or default-valued request argument.
Definition: util.h:470
const std::string & get_str() const
bool MessageSign(const CKey &privkey, const std::string &message, std::string &signature)
Sign a message.
Definition: signmessage.cpp:60
MessageVerificationResult MessageVerify(const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: signmessage.cpp:29
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:214
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:75
@ RPC_TYPE_ERROR
Unexpected type was passed as parameter.
Definition: protocol.h:66
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:67
static RPCMethod signmessagewithprivkey()
Definition: signmessage.cpp:66
static RPCMethod verifymessage()
Definition: signmessage.cpp:21
void RegisterSignMessageRPCCommands(CRPCTable &t)
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:189
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:207
@ ERR_MALFORMED_SIGNATURE
The provided signature couldn't be parsed (maybe invalid base64).
@ ERR_INVALID_ADDRESS
The provided address is invalid.
@ ERR_ADDRESS_NO_KEY
The provided address is valid but does not refer to a public key.
@ ERR_NOT_SIGNED
The message was not signed with the private key of the provided address.
@ OK
The message verification was successful.
@ ERR_PUBKEY_NOT_RECOVERED
A public key could not be recovered from the provided signature and message.
@ NO
Required arg.