Bitcoin ABC  0.29.1
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>
9 #include <qt/addressbookpage.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 
68 void SignVerifyMessageDialog::setAddress_SM(const QString &address) {
69  ui->addressIn_SM->setText(address);
70  ui->messageIn_SM->setFocus();
71 }
72 
73 void 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 
93  if (model && model->getAddressTableModel()) {
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) {
150  case SigningResult::OK:
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 
261 bool 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
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:404
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:127
void setClipboard(const QString &str)
Definition: guiutil.cpp:774
QFont fixedPitchFont()
Definition: guiutil.cpp:84
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
bool error(const char *fmt, const Args &...args)
Definition: system.h:45