void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() { /* Clear old signature to ensure users don't get confused on error with an old signature displayed */ ui->signatureOut_SM->clear(); CBitcoinAddress addr(ui->addressIn_SM->text().toStdString()); if (!addr.IsValid()) { ui->addressIn_SM->setValid(false); ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); return; } CKeyID keyID; if (!addr.GetKeyID(keyID)) { ui->addressIn_SM->setValid(false); ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); return; } WalletModel::UnlockContext ctx(model->requestUnlock()); if (!ctx.isValid()) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled.")); return; } CKey key; if (!pwalletMain->GetKey(keyID, key)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("Private key for the entered address is not available.")); return; } CDataStream ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->messageIn_SM->document()->toPlainText().toStdString(); std::vector<unsigned char> vchSig; if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>")); return; } ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }"); ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>")); ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size()))); }
void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() { if (!model) return; /* Clear old signature to ensure users don't get confused on error with an old signature displayed */ ui->signatureOut_SM->clear(); CTxDestination destination = DecodeDestination(ui->addressIn_SM->text().toStdString()); if (!IsValidDestination(destination)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); return; } const CKeyID* keyID = boost::get<CKeyID>(&destination); if (!keyID) { ui->addressIn_SM->setValid(false); ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); return; } WalletModel::UnlockContext ctx(model->requestUnlock()); if (!ctx.isValid()) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled.")); return; } CKey key; if (!model->wallet().getPrivKey(*keyID, key)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("Private key for the entered address is not available.")); return; } CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->messageIn_SM->document()->toPlainText().toStdString(); std::vector<unsigned char> vchSig; if (!key.SignCompact(ss.GetHash(), vchSig)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>")); return; } ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }"); ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>")); ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(vchSig.data(), vchSig.size()))); }
Value signmessage(const Array& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( "signmessage \"Dacrsaddress\" \"message\"\n" "\nSign a message with the private key of an address" + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"Dacrsaddress\" (string, required) The Honghuo address to use for the private key.\n" "2. \"message\" (string, required) The message to create a signature of.\n" "\nResult:\n" "\"signature\" (string) The signature of the message encoded in base 64\n" "\nExamples:\n" "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") + "\nVerify the signature\n" + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + "\nAs json rpc\n" + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"") ); EnsureWalletIsUnlocked(); string strAddress = params[0].get_str(); string strMessage = params[1].get_str(); CKeyID keyID(strAddress); if (keyID.IsEmpty()) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); CKey key; if (!pwalletMain->GetKey(keyID, key)) throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available"); CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << strMessage; vector<unsigned char> vchSig; if (!key.SignCompact(ss.GetHash(), vchSig)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); return EncodeBase64(&vchSig[0], vchSig.size()); }
void MessagePage::on_signMessage_clicked() { QString address = ui->signFrom->text(); CBitcoinAddress addr(address.toStdString()); if (!addr.IsValid()) { QMessageBox::critical(this, tr("Error signing"), tr("%1 is not a valid address.").arg(address), QMessageBox::Abort, QMessageBox::Abort); return; } WalletModel::UnlockContext ctx(model->requestUnlock()); if(!ctx.isValid()) { // Unlock wallet was cancelled return; } CKey key; if (!pwalletMain->GetKey(addr, key)) { QMessageBox::critical(this, tr("Error signing"), tr("Private key for %1 is not available.").arg(address), QMessageBox::Abort, QMessageBox::Abort); return; } CDataStream ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->message->document()->toPlainText().toStdString(); std::vector<unsigned char> vchSig; if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) { QMessageBox::critical(this, tr("Error signing"), tr("Sign failed"), QMessageBox::Abort, QMessageBox::Abort); } ui->signature->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size()))); ui->signature->setFont(GUIUtil::bitcoinAddressFont()); }
UniValue signmessagewithprivkey(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "signmessagewithprivkey \"privkey\" \"message\"\n" "\nSign a message with the private key of an address\n" "\nArguments:\n" "1. \"privkey\" (string, required) The private key to sign the message with.\n" "2. \"message\" (string, required) The message to create a signature of.\n" "\nResult:\n" "\"signature\" (string) The signature of the message encoded in base 64\n" "\nExamples:\n" "\nCreate the signature\n" + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") + "\nVerify the signature\n" + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs json rpc\n" + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") ); std::string strPrivkey = request.params[0].get_str(); std::string strMessage = request.params[1].get_str(); CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(strPrivkey); if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); CKey key = vchSecret.GetKey(); if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << strMessage; std::vector<unsigned char> vchSig; if (!key.SignCompact(ss.GetHash(), vchSig)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); return EncodeBase64(&vchSig[0], vchSig.size()); }
static UniValue signmessagewithprivkey(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 2) throw std::runtime_error( RPCHelpMan{"signmessagewithprivkey", "\nSign a message with the private key of an address\n", { {"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."}, {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, }, RPCResult{ "\"signature\" (string) The signature of the message encoded in base 64\n" }, RPCExamples{ "\nCreate the signature\n" + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") + "\nVerify the signature\n" + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + "\nAs a JSON-RPC call\n" + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") }, }.ToString()); std::string strPrivkey = request.params[0].get_str(); std::string strMessage = request.params[1].get_str(); CKey key = DecodeSecret(strPrivkey); if (!key.IsValid()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); } CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << strMessage; std::vector<unsigned char> vchSig; if (!key.SignCompact(ss.GetHash(), vchSig)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); return EncodeBase64(vchSig.data(), vchSig.size()); }
bool CHashSigner::SignHash(const uint256& hash, const CKey key, std::vector<unsigned char>& vchSigRet) { return key.SignCompact(hash, vchSigRet); }