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