1 // Copyright (c) 2011-2017 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.
5 #include <qt/signverifymessagedialog.h>
6 #include <qt/forms/ui_signverifymessagedialog.h>
8 #include <qt/addressbookpage.h>
9 #include <qt/guiutil.h>
10 #include <qt/platformstyle.h>
11 #include <qt/walletmodel.h>
15 #include <validation.h> // For strMessageMagic
16 #include <wallet/wallet.h>
23 SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle
*_platformStyle
, QWidget
*parent
) :
25 ui(new Ui::SignVerifyMessageDialog
),
27 platformStyle(_platformStyle
)
31 ui
->addressBookButton_SM
->setIcon(platformStyle
->SingleColorIcon(":/icons/address-book"));
32 ui
->pasteButton_SM
->setIcon(platformStyle
->SingleColorIcon(":/icons/editpaste"));
33 ui
->copySignatureButton_SM
->setIcon(platformStyle
->SingleColorIcon(":/icons/editcopy"));
34 ui
->signMessageButton_SM
->setIcon(platformStyle
->SingleColorIcon(":/icons/edit"));
35 ui
->clearButton_SM
->setIcon(platformStyle
->SingleColorIcon(":/icons/remove"));
36 ui
->addressBookButton_VM
->setIcon(platformStyle
->SingleColorIcon(":/icons/address-book"));
37 ui
->verifyMessageButton_VM
->setIcon(platformStyle
->SingleColorIcon(":/icons/transaction_0"));
38 ui
->clearButton_VM
->setIcon(platformStyle
->SingleColorIcon(":/icons/remove"));
40 #if QT_VERSION >= 0x040700
41 ui
->signatureOut_SM
->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
44 GUIUtil::setupAddressWidget(ui
->addressIn_SM
, this);
45 GUIUtil::setupAddressWidget(ui
->addressIn_VM
, this);
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);
54 ui
->signatureOut_SM
->setFont(GUIUtil::fixedPitchFont());
55 ui
->signatureIn_VM
->setFont(GUIUtil::fixedPitchFont());
58 SignVerifyMessageDialog::~SignVerifyMessageDialog()
63 void SignVerifyMessageDialog::setModel(WalletModel
*_model
)
68 void SignVerifyMessageDialog::setAddress_SM(const QString
&address
)
70 ui
->addressIn_SM
->setText(address
);
71 ui
->messageIn_SM
->setFocus();
74 void SignVerifyMessageDialog::setAddress_VM(const QString
&address
)
76 ui
->addressIn_VM
->setText(address
);
77 ui
->messageIn_VM
->setFocus();
80 void SignVerifyMessageDialog::showTab_SM(bool fShow
)
82 ui
->tabWidget
->setCurrentIndex(0);
87 void SignVerifyMessageDialog::showTab_VM(bool fShow
)
89 ui
->tabWidget
->setCurrentIndex(1);
94 void SignVerifyMessageDialog::on_addressBookButton_SM_clicked()
96 if (model
&& model
->getAddressTableModel())
98 AddressBookPage
dlg(platformStyle
, AddressBookPage::ForSelection
, AddressBookPage::ReceivingTab
, this);
99 dlg
.setModel(model
->getAddressTableModel());
102 setAddress_SM(dlg
.getReturnValue());
107 void SignVerifyMessageDialog::on_pasteButton_SM_clicked()
109 setAddress_SM(QApplication::clipboard()->text());
112 void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
117 /* Clear old signature to ensure users don't get confused on error with an old signature displayed */
118 ui
->signatureOut_SM
->clear();
120 CTxDestination destination
= DecodeDestination(ui
->addressIn_SM
->text().toStdString());
121 if (!IsValidDestination(destination
)) {
122 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
123 ui
->statusLabel_SM
->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
126 const CKeyID
* keyID
= boost::get
<CKeyID
>(&destination
);
128 ui
->addressIn_SM
->setValid(false);
129 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
130 ui
->statusLabel_SM
->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
134 WalletModel::UnlockContext
ctx(model
->requestUnlock());
137 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
138 ui
->statusLabel_SM
->setText(tr("Wallet unlock was cancelled."));
143 if (!model
->getPrivKey(*keyID
, key
))
145 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
146 ui
->statusLabel_SM
->setText(tr("Private key for the entered address is not available."));
150 CHashWriter
ss(SER_GETHASH
, 0);
151 ss
<< strMessageMagic
;
152 ss
<< ui
->messageIn_SM
->document()->toPlainText().toStdString();
154 std::vector
<unsigned char> vchSig
;
155 if (!key
.SignCompact(ss
.GetHash(), vchSig
))
157 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
158 ui
->statusLabel_SM
->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
162 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: green; }");
163 ui
->statusLabel_SM
->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
165 ui
->signatureOut_SM
->setText(QString::fromStdString(EncodeBase64(vchSig
.data(), vchSig
.size())));
168 void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked()
170 GUIUtil::setClipboard(ui
->signatureOut_SM
->text());
173 void SignVerifyMessageDialog::on_clearButton_SM_clicked()
175 ui
->addressIn_SM
->clear();
176 ui
->messageIn_SM
->clear();
177 ui
->signatureOut_SM
->clear();
178 ui
->statusLabel_SM
->clear();
180 ui
->addressIn_SM
->setFocus();
183 void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()
185 if (model
&& model
->getAddressTableModel())
187 AddressBookPage
dlg(platformStyle
, AddressBookPage::ForSelection
, AddressBookPage::SendingTab
, this);
188 dlg
.setModel(model
->getAddressTableModel());
191 setAddress_VM(dlg
.getReturnValue());
196 void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
198 CTxDestination destination
= DecodeDestination(ui
->addressIn_VM
->text().toStdString());
199 if (!IsValidDestination(destination
)) {
200 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
201 ui
->statusLabel_VM
->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
204 if (!boost::get
<CKeyID
>(&destination
)) {
205 ui
->addressIn_VM
->setValid(false);
206 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
207 ui
->statusLabel_VM
->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
211 bool fInvalid
= false;
212 std::vector
<unsigned char> vchSig
= DecodeBase64(ui
->signatureIn_VM
->text().toStdString().c_str(), &fInvalid
);
216 ui
->signatureIn_VM
->setValid(false);
217 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
218 ui
->statusLabel_VM
->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
222 CHashWriter
ss(SER_GETHASH
, 0);
223 ss
<< strMessageMagic
;
224 ss
<< ui
->messageIn_VM
->document()->toPlainText().toStdString();
227 if (!pubkey
.RecoverCompact(ss
.GetHash(), vchSig
))
229 ui
->signatureIn_VM
->setValid(false);
230 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
231 ui
->statusLabel_VM
->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again."));
235 if (!(CTxDestination(pubkey
.GetID()) == destination
)) {
236 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
237 ui
->statusLabel_VM
->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
241 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: green; }");
242 ui
->statusLabel_VM
->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
245 void SignVerifyMessageDialog::on_clearButton_VM_clicked()
247 ui
->addressIn_VM
->clear();
248 ui
->signatureIn_VM
->clear();
249 ui
->messageIn_VM
->clear();
250 ui
->statusLabel_VM
->clear();
252 ui
->addressIn_VM
->setFocus();
255 bool SignVerifyMessageDialog::eventFilter(QObject
*object
, QEvent
*event
)
257 if (event
->type() == QEvent::MouseButtonPress
|| event
->type() == QEvent::FocusIn
)
259 if (ui
->tabWidget
->currentIndex() == 0)
261 /* Clear status message on focus change */
262 ui
->statusLabel_SM
->clear();
264 /* Select generated signature */
265 if (object
== ui
->signatureOut_SM
)
267 ui
->signatureOut_SM
->selectAll();
271 else if (ui
->tabWidget
->currentIndex() == 1)
273 /* Clear status message on focus change */
274 ui
->statusLabel_VM
->clear();
277 return QDialog::eventFilter(object
, event
);