signmessage.cpp
1 // Copyright (c) 2011-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <common/signmessage.h> 6 #include <key_io.h> 7 #include <rpc/util.h> 8 #include <wallet/rpc/util.h> 9 #include <wallet/wallet.h> 10 11 #include <univalue.h> 12 13 namespace wallet { 14 RPCHelpMan signmessage() 15 { 16 return RPCHelpMan{ 17 "signmessage", 18 "Sign a message with the private key of an address" + 19 HELP_REQUIRING_PASSPHRASE, 20 { 21 {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."}, 22 {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, 23 }, 24 RPCResult{ 25 RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" 26 }, 27 RPCExamples{ 28 "\nUnlock the wallet for 30 seconds\n" 29 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + 30 "\nCreate the signature\n" 31 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + 32 "\nVerify the signature\n" 33 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + 34 "\nAs a JSON-RPC call\n" 35 + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") 36 }, 37 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 38 { 39 const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); 40 if (!pwallet) return UniValue::VNULL; 41 42 LOCK(pwallet->cs_wallet); 43 44 EnsureWalletIsUnlocked(*pwallet); 45 46 std::string strAddress = request.params[0].get_str(); 47 std::string strMessage = request.params[1].get_str(); 48 49 CTxDestination dest = DecodeDestination(strAddress); 50 if (!IsValidDestination(dest)) { 51 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); 52 } 53 54 const PKHash* pkhash = std::get_if<PKHash>(&dest); 55 if (!pkhash) { 56 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); 57 } 58 59 std::string signature; 60 SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); 61 if (err == SigningResult::SIGNING_FAILED) { 62 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); 63 } else if (err != SigningResult::OK) { 64 throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); 65 } 66 67 return signature; 68 }, 69 }; 70 } 71 } // namespace wallet