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