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.
5 #include "signverifymessagedialog.h"
6 #include "ui_signverifymessagedialog.h"
8 #include "addressbookpage.h"
10 #include "platformstyle.h"
11 #include "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 CBitcoinAddress
addr(ui
->addressIn_SM
->text().toStdString());
123 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
124 ui
->statusLabel_SM
->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
128 if (!addr
.GetKeyID(keyID
))
130 ui
->addressIn_SM
->setValid(false);
131 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
132 ui
->statusLabel_SM
->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
136 WalletModel::UnlockContext
ctx(model
->requestUnlock());
139 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
140 ui
->statusLabel_SM
->setText(tr("Wallet unlock was cancelled."));
145 if (!model
->getPrivKey(keyID
, key
))
147 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
148 ui
->statusLabel_SM
->setText(tr("Private key for the entered address is not available."));
152 CHashWriter
ss(SER_GETHASH
, 0);
153 ss
<< strMessageMagic
;
154 ss
<< ui
->messageIn_SM
->document()->toPlainText().toStdString();
156 std::vector
<unsigned char> vchSig
;
157 if (!key
.SignCompact(ss
.GetHash(), vchSig
))
159 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: red; }");
160 ui
->statusLabel_SM
->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
164 ui
->statusLabel_SM
->setStyleSheet("QLabel { color: green; }");
165 ui
->statusLabel_SM
->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
167 ui
->signatureOut_SM
->setText(QString::fromStdString(EncodeBase64(&vchSig
[0], vchSig
.size())));
170 void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked()
172 GUIUtil::setClipboard(ui
->signatureOut_SM
->text());
175 void SignVerifyMessageDialog::on_clearButton_SM_clicked()
177 ui
->addressIn_SM
->clear();
178 ui
->messageIn_SM
->clear();
179 ui
->signatureOut_SM
->clear();
180 ui
->statusLabel_SM
->clear();
182 ui
->addressIn_SM
->setFocus();
185 void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()
187 if (model
&& model
->getAddressTableModel())
189 AddressBookPage
dlg(platformStyle
, AddressBookPage::ForSelection
, AddressBookPage::SendingTab
, this);
190 dlg
.setModel(model
->getAddressTableModel());
193 setAddress_VM(dlg
.getReturnValue());
198 void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
200 CBitcoinAddress
addr(ui
->addressIn_VM
->text().toStdString());
203 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
204 ui
->statusLabel_VM
->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
208 if (!addr
.GetKeyID(keyID
))
210 ui
->addressIn_VM
->setValid(false);
211 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
212 ui
->statusLabel_VM
->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
216 bool fInvalid
= false;
217 std::vector
<unsigned char> vchSig
= DecodeBase64(ui
->signatureIn_VM
->text().toStdString().c_str(), &fInvalid
);
221 ui
->signatureIn_VM
->setValid(false);
222 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
223 ui
->statusLabel_VM
->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
227 CHashWriter
ss(SER_GETHASH
, 0);
228 ss
<< strMessageMagic
;
229 ss
<< ui
->messageIn_VM
->document()->toPlainText().toStdString();
232 if (!pubkey
.RecoverCompact(ss
.GetHash(), vchSig
))
234 ui
->signatureIn_VM
->setValid(false);
235 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
236 ui
->statusLabel_VM
->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again."));
240 if (!(CBitcoinAddress(pubkey
.GetID()) == addr
))
242 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: red; }");
243 ui
->statusLabel_VM
->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
247 ui
->statusLabel_VM
->setStyleSheet("QLabel { color: green; }");
248 ui
->statusLabel_VM
->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
251 void SignVerifyMessageDialog::on_clearButton_VM_clicked()
253 ui
->addressIn_VM
->clear();
254 ui
->signatureIn_VM
->clear();
255 ui
->messageIn_VM
->clear();
256 ui
->statusLabel_VM
->clear();
258 ui
->addressIn_VM
->setFocus();
261 bool SignVerifyMessageDialog::eventFilter(QObject
*object
, QEvent
*event
)
263 if (event
->type() == QEvent::MouseButtonPress
|| event
->type() == QEvent::FocusIn
)
265 if (ui
->tabWidget
->currentIndex() == 0)
267 /* Clear status message on focus change */
268 ui
->statusLabel_SM
->clear();
270 /* Select generated signature */
271 if (object
== ui
->signatureOut_SM
)
273 ui
->signatureOut_SM
->selectAll();
277 else if (ui
->tabWidget
->currentIndex() == 1)
279 /* Clear status message on focus change */
280 ui
->statusLabel_VM
->clear();
283 return QDialog::eventFilter(object
, event
);