Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#include <common/signmessage.h>8#include <addresstype.h>9#include <hash.h>10#include <key.h>11#include <key_io.h>12#include <pubkey.h>13#include <uint256.h>14#include <util/check.h>15#include <util/strencodings.h>17#include <optional>18#include <span>19#include <string>20#include <variant>21#include <vector>23/**24* Text used to signify that a signed message follows and to prevent25* inadvertently signing a transaction.26*/27const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n";29MessageVerificationResult MessageVerify(30const std::string& address,31const std::string& signature,32const std::string& message)33{34CTxDestination destination = DecodeDestination(address);35if (!IsValidDestination(destination)) {36return MessageVerificationResult::ERR_INVALID_ADDRESS;37}39if (std::get_if<PKHash>(&destination) == nullptr) {40return MessageVerificationResult::ERR_ADDRESS_NO_KEY;41}43auto signature_bytes = DecodeBase64(signature);44if (!signature_bytes) {45return MessageVerificationResult::ERR_MALFORMED_SIGNATURE;46}48CPubKey pubkey;49if (!pubkey.RecoverCompact(MessageHash(message), *signature_bytes)) {50return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED;51}53if (!(PKHash(pubkey) == *std::get_if<PKHash>(&destination))) {54return MessageVerificationResult::ERR_NOT_SIGNED;55}57return MessageVerificationResult::OK;58}60bool MessageSign(61const CKey& privkey,62const std::string& message,63std::string& signature)64{65std::vector<unsigned char> signature_bytes;67if (!privkey.SignCompact(MessageHash(message), signature_bytes)) {68return false;69}71signature = EncodeBase64(signature_bytes);73return true;74}76uint256 MessageHash(const std::string& message)77{78HashWriter hasher{};79hasher << MESSAGE_MAGIC << message;81return hasher.GetHash();82}84std::string SigningResultString(const SigningResult res)85{86switch (res) {87case SigningResult::OK:88return "No error";89case SigningResult::PRIVATE_KEY_NOT_AVAILABLE:90return "Private key not available";91case SigningResult::SIGNING_FAILED:92return "Sign failed";93} // no default case, so the compiler can warn about missing cases94assert(false);95}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.