Bitcoin ABC 0.30.5
P2P Digital Currency
signverifymessagedialog.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2016 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 <qt/forms/ui_signverifymessagedialog.h>
7
8#include <key_io.h>
10#include <qt/guiutil.h>
11#include <qt/platformstyle.h>
12#include <qt/walletmodel.h>
13#include <util/message.h> // For MessageSign(), MessageVerify()
14#include <wallet/wallet.h>
15
16#include <QClipboard>
17
18#include <variant>
19#include <vector>
20
22 const PlatformStyle *_platformStyle, QWidget *parent)
23 : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), model(nullptr),
24 platformStyle(_platformStyle) {
25 ui->setupUi(this);
26
27 ui->addressBookButton_SM->setIcon(
28 platformStyle->SingleColorIcon(":/icons/address-book"));
29 ui->pasteButton_SM->setIcon(
30 platformStyle->SingleColorIcon(":/icons/editpaste"));
31 ui->copySignatureButton_SM->setIcon(
32 platformStyle->SingleColorIcon(":/icons/editcopy"));
33 ui->signMessageButton_SM->setIcon(
34 platformStyle->SingleColorIcon(":/icons/edit"));
35 ui->clearButton_SM->setIcon(
36 platformStyle->SingleColorIcon(":/icons/remove"));
37 ui->addressBookButton_VM->setIcon(
38 platformStyle->SingleColorIcon(":/icons/address-book"));
39 ui->verifyMessageButton_VM->setIcon(
40 platformStyle->SingleColorIcon(":/icons/transaction_0"));
41 ui->clearButton_VM->setIcon(
42 platformStyle->SingleColorIcon(":/icons/remove"));
43
44 GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
45 GUIUtil::setupAddressWidget(ui->addressIn_VM, this);
46
47 ui->addressIn_SM->installEventFilter(this);
48 ui->messageIn_SM->installEventFilter(this);
49 ui->signatureOut_SM->installEventFilter(this);
50 ui->addressIn_VM->installEventFilter(this);
51 ui->messageIn_VM->installEventFilter(this);
52 ui->signatureIn_VM->installEventFilter(this);
53
54 ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont());
55 ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont());
56
58}
59
61 delete ui;
62}
63
65 this->model = _model;
66}
67
68void SignVerifyMessageDialog::setAddress_SM(const QString &address) {
69 ui->addressIn_SM->setText(address);
70 ui->messageIn_SM->setFocus();
71}
72
73void SignVerifyMessageDialog::setAddress_VM(const QString &address) {
74 ui->addressIn_VM->setText(address);
75 ui->messageIn_VM->setFocus();
76}
77
79 ui->tabWidget->setCurrentIndex(0);
80 if (fShow) {
81 this->show();
82 }
83}
84
86 ui->tabWidget->setCurrentIndex(1);
87 if (fShow) {
88 this->show();
89 }
90}
91
97 if (dlg.exec()) {
99 }
100 }
101}
102
104 setAddress_SM(QApplication::clipboard()->text());
105}
106
108 if (!model) {
109 return;
110 }
111
112 /* Clear old signature to ensure users don't get confused on error with an
113 * old signature displayed */
114 ui->signatureOut_SM->clear();
115
116 CTxDestination destination = DecodeDestination(
117 ui->addressIn_SM->text().toStdString(), model->getChainParams());
118 if (!IsValidDestination(destination)) {
119 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
120 ui->statusLabel_SM->setText(
121 tr("The entered address is invalid.") + QString(" ") +
122 tr("Please check the address and try again."));
123 return;
124 }
125 const PKHash *pkhash = std::get_if<PKHash>(&destination);
126 if (!pkhash) {
127 ui->addressIn_SM->setValid(false);
128 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
129 ui->statusLabel_SM->setText(
130 tr("The entered address does not refer to a key.") + QString(" ") +
131 tr("Please check the address and try again."));
132 return;
133 }
134
136 if (!ctx.isValid()) {
137 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
138 ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
139 return;
140 }
141
142 const std::string &message =
143 ui->messageIn_SM->document()->toPlainText().toStdString();
144 std::string signature;
145 SigningResult res =
146 model->wallet().signMessage(message, *pkhash, signature);
147
148 QString error;
149 switch (res) {
151 error = tr("No error");
152 break;
154 error = tr("Private key for the entered address is not available.");
155 break;
157 error = tr("Message signing failed.");
158 break;
159 // no default case, so the compiler can warn about missing cases
160 }
161
162 if (res != SigningResult::OK) {
163 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
164 ui->statusLabel_SM->setText(QString("<nobr>") + error +
165 QString("</nobr>"));
166 return;
167 }
168
169 ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
170 ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") +
171 QString("</nobr>"));
172
173 ui->signatureOut_SM->setText(QString::fromStdString(signature));
174}
175
177 GUIUtil::setClipboard(ui->signatureOut_SM->text());
178}
179
181 ui->addressIn_SM->clear();
182 ui->messageIn_SM->clear();
183 ui->signatureOut_SM->clear();
184 ui->statusLabel_SM->clear();
185
186 ui->addressIn_SM->setFocus();
187}
188
190 if (model && model->getAddressTableModel()) {
194 if (dlg.exec()) {
196 }
197 }
198}
199
201 const std::string &address = ui->addressIn_VM->text().toStdString();
202 const std::string &signature = ui->signatureIn_VM->text().toStdString();
203 const std::string &message =
204 ui->messageIn_VM->document()->toPlainText().toStdString();
205
206 const auto result =
207 MessageVerify(model->getChainParams(), address, signature, message);
208
209 if (result == MessageVerificationResult::OK) {
210 ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
211 } else {
212 ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
213 }
214
215 switch (result) {
217 ui->statusLabel_VM->setText(QString("<nobr>") +
218 tr("Message verified.") +
219 QString("</nobr>"));
220 return;
222 ui->statusLabel_VM->setText(
223 tr("The entered address is invalid.") + QString(" ") +
224 tr("Please check the address and try again."));
225 return;
227 ui->addressIn_VM->setValid(false);
228 ui->statusLabel_VM->setText(
229 tr("The entered address does not refer to a key.") +
230 QString(" ") + tr("Please check the address and try again."));
231 return;
233 ui->signatureIn_VM->setValid(false);
234 ui->statusLabel_VM->setText(
235 tr("The signature could not be decoded.") + QString(" ") +
236 tr("Please check the signature and try again."));
237 return;
239 ui->signatureIn_VM->setValid(false);
240 ui->statusLabel_VM->setText(
241 tr("The signature did not match the message digest.") +
242 QString(" ") + tr("Please check the signature and try again."));
243 return;
245 ui->statusLabel_VM->setText(QString("<nobr>") +
246 tr("Message verification failed.") +
247 QString("</nobr>"));
248 return;
249 }
250}
251
253 ui->addressIn_VM->clear();
254 ui->signatureIn_VM->clear();
255 ui->messageIn_VM->clear();
256 ui->statusLabel_VM->clear();
257
258 ui->addressIn_VM->setFocus();
259}
260
261bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) {
262 if (event->type() == QEvent::MouseButtonPress ||
263 event->type() == QEvent::FocusIn) {
264 if (ui->tabWidget->currentIndex() == 0) {
265 /* Clear status message on focus change */
266 ui->statusLabel_SM->clear();
267
268 /* Select generated signature */
269 if (object == ui->signatureOut_SM) {
270 ui->signatureOut_SM->selectAll();
271 return true;
272 }
273 } else if (ui->tabWidget->currentIndex() == 1) {
274 /* Clear status message on focus change */
275 ui->statusLabel_VM->clear();
276 }
277 }
278 return QDialog::eventFilter(object, event);
279}
secp256k1_context * ctx
Widget that shows a list of sending or receiving addresses.
@ ForSelection
Open address book to pick address.
void setModel(AddressTableModel *model)
const QString & getReturnValue() const
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
bool eventFilter(QObject *object, QEvent *event) override
void setAddress_SM(const QString &address)
SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent)
const PlatformStyle * platformStyle
void setModel(WalletModel *model)
Ui::SignVerifyMessageDialog * ui
void setAddress_VM(const QString &address)
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:47
const CChainParams & getChainParams() const
AddressTableModel * getAddressTableModel()
interfaces::Wallet & wallet() const
Definition: walletmodel.h:150
UnlockContext requestUnlock()
virtual SigningResult signMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig)=0
Sign message.
CTxDestination DecodeDestination(const std::string &addr, const CChainParams &params)
Definition: key_io.cpp:174
bool error(const char *fmt, const Args &...args)
Definition: logging.h:226
MessageVerificationResult MessageVerify(const CChainParams &params, const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: message.cpp:24
SigningResult
Definition: message.h:47
@ PRIVATE_KEY_NOT_AVAILABLE
@ OK
No error.
@ ERR_MALFORMED_SIGNATURE
The provided signature couldn't be parsed (maybe invalid base64).
@ ERR_INVALID_ADDRESS
The provided address is invalid.
@ ERR_ADDRESS_NO_KEY
The provided address is valid but does not refer to a public key.
@ ERR_NOT_SIGNED
The message was not signed with the private key of the provided address.
@ OK
The message verification was successful.
@ ERR_PUBKEY_NOT_RECOVERED
A public key could not be recovered from the provided signature and message.
void handleCloseWindowShortcut(QWidget *w)
Definition: guiutil.cpp:407
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:130
void setClipboard(const QString &str)
Definition: guiutil.cpp:776
QFont fixedPitchFont()
Definition: guiutil.cpp:87
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:260
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:85