1 // Copyright (c) 2011-2013 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"
11 #include "walletmodel.h"
15 #include "main.h" // For strMessageMagic
16 #include "wallet/wallet.h"
23 SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) :
25 ui(new Ui::SignVerifyMessageDialog),
30 ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book"));
31 ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste"));
32 ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy"));
33 ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit"));
34 ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove"));
35 ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book"));
36 ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0"));
37 ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove"));
39 #if QT_VERSION >= 0x040700
40 ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
43 GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
44 GUIUtil::setupAddressWidget(ui->addressIn_VM, this);
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);
53 ui->signatureOut_SM->setFont(GUIUtil::bitcoinAddressFont());
54 ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont());
57 SignVerifyMessageDialog::~SignVerifyMessageDialog()
62 void SignVerifyMessageDialog::setModel(WalletModel *model)
67 void SignVerifyMessageDialog::setAddress_SM(const QString &address)
69 ui->addressIn_SM->setText(address);
70 ui->messageIn_SM->setFocus();
73 void SignVerifyMessageDialog::setAddress_VM(const QString &address)
75 ui->addressIn_VM->setText(address);
76 ui->messageIn_VM->setFocus();
79 void SignVerifyMessageDialog::showTab_SM(bool fShow)
81 ui->tabWidget->setCurrentIndex(0);
86 void SignVerifyMessageDialog::showTab_VM(bool fShow)
88 ui->tabWidget->setCurrentIndex(1);
93 void SignVerifyMessageDialog::on_addressBookButton_SM_clicked()
95 if (model && model->getAddressTableModel())
97 AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
98 dlg.setModel(model->getAddressTableModel());
101 setAddress_SM(dlg.getReturnValue());
106 void SignVerifyMessageDialog::on_pasteButton_SM_clicked()
108 setAddress_SM(QApplication::clipboard()->text());
111 void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
116 /* Clear old signature to ensure users don't get confused on error with an old signature displayed */
117 ui->signatureOut_SM->clear();
119 CBitcoinAddress addr(ui->addressIn_SM->text().toStdString());
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."));
127 if (!addr.GetKeyID(keyID))
129 ui->addressIn_SM->setValid(false);
130 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
131 ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
135 WalletModel::UnlockContext ctx(model->requestUnlock());
138 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
139 ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
144 if (!pwalletMain->GetKey(keyID, key))
146 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
147 ui->statusLabel_SM->setText(tr("Private key for the entered address is not available."));
151 CDataStream ss(SER_GETHASH, 0);
152 ss << strMessageMagic;
153 ss << ui->messageIn_SM->document()->toPlainText().toStdString();
155 std::vector<unsigned char> vchSig;
156 if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
158 ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
159 ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
163 ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
164 ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
166 ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
169 void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked()
171 GUIUtil::setClipboard(ui->signatureOut_SM->text());
174 void SignVerifyMessageDialog::on_clearButton_SM_clicked()
176 ui->addressIn_SM->clear();
177 ui->messageIn_SM->clear();
178 ui->signatureOut_SM->clear();
179 ui->statusLabel_SM->clear();
181 ui->addressIn_SM->setFocus();
184 void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()
186 if (model && model->getAddressTableModel())
188 AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
189 dlg.setModel(model->getAddressTableModel());
192 setAddress_VM(dlg.getReturnValue());
197 void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
199 CBitcoinAddress addr(ui->addressIn_VM->text().toStdString());
202 ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
203 ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
207 if (!addr.GetKeyID(keyID))
209 ui->addressIn_VM->setValid(false);
210 ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
211 ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
215 bool fInvalid = false;
216 std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid);
220 ui->signatureIn_VM->setValid(false);
221 ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
222 ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
226 CDataStream ss(SER_GETHASH, 0);
227 ss << strMessageMagic;
228 ss << ui->messageIn_VM->document()->toPlainText().toStdString();
231 if (!pubkey.RecoverCompact(Hash(ss.begin(), ss.end()), vchSig))
233 ui->signatureIn_VM->setValid(false);
234 ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
235 ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again."));
239 if (!(CBitcoinAddress(pubkey.GetID()) == addr))
241 ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
242 ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
246 ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
247 ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
250 void SignVerifyMessageDialog::on_clearButton_VM_clicked()
252 ui->addressIn_VM->clear();
253 ui->signatureIn_VM->clear();
254 ui->messageIn_VM->clear();
255 ui->statusLabel_VM->clear();
257 ui->addressIn_VM->setFocus();
260 bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
262 if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn)
264 if (ui->tabWidget->currentIndex() == 0)
266 /* Clear status message on focus change */
267 ui->statusLabel_SM->clear();
269 /* Select generated signature */
270 if (object == ui->signatureOut_SM)
272 ui->signatureOut_SM->selectAll();
276 else if (ui->tabWidget->currentIndex() == 1)
278 /* Clear status message on focus change */
279 ui->statusLabel_VM->clear();
282 return QDialog::eventFilter(object, event);