// Copyright (c) 2011-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include namespace wallet { RPCHelpMan signmessage() { return RPCHelpMan{"signmessage", "\nSign a message with the private key of an address" + HELP_REQUIRING_PASSPHRASE, { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."}, {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, }, RPCResult{ RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" }, RPCExamples{ "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + "\nVerify the signature\n" + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs a JSON-RPC call\n" + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { const std::shared_ptr pwallet = GetWalletForJSONRPCRequest(request); if (!pwallet) return UniValue::VNULL; LOCK(pwallet->cs_wallet); EnsureWalletIsUnlocked(*pwallet); std::string strAddress = request.params[0].get_str(); std::string strMessage = request.params[1].get_str(); CTxDestination dest = DecodeDestination(strAddress); if (!IsValidDestination(dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } const PKHash* pkhash = std::get_if(&dest); if (!pkhash) { throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); } std::string signature; SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); if (err == SigningResult::SIGNING_FAILED) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); } else if (err != SigningResult::OK) { throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); } return signature; }, }; } } // namespace wallet