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