]> Git Repo - VerusCoin.git/blob - src/qt/signverifymessagedialog.cpp
Merge pull request #169 from jl777/dev
[VerusCoin.git] / src / qt / signverifymessagedialog.cpp
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.
4
5 #include "signverifymessagedialog.h"
6 #include "ui_signverifymessagedialog.h"
7
8 #include "addressbookpage.h"
9 #include "guiutil.h"
10 #include "scicon.h"
11 #include "walletmodel.h"
12
13 #include "base58.h"
14 #include "init.h"
15 #include "main.h" // For strMessageMagic
16 #include "wallet/wallet.h"
17
18 #include <string>
19 #include <vector>
20
21 #include <QClipboard>
22
23 SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) :
24     QDialog(parent),
25     ui(new Ui::SignVerifyMessageDialog),
26     model(0)
27 {
28     ui->setupUi(this);
29
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"));
38
39 #if QT_VERSION >= 0x040700
40     ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
41 #endif
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::bitcoinAddressFont());
54     ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont());
55 }
56
57 SignVerifyMessageDialog::~SignVerifyMessageDialog()
58 {
59     delete ui;
60 }
61
62 void SignVerifyMessageDialog::setModel(WalletModel *model)
63 {
64     this->model = model;
65 }
66
67 void SignVerifyMessageDialog::setAddress_SM(const QString &address)
68 {
69     ui->addressIn_SM->setText(address);
70     ui->messageIn_SM->setFocus();
71 }
72
73 void SignVerifyMessageDialog::setAddress_VM(const QString &address)
74 {
75     ui->addressIn_VM->setText(address);
76     ui->messageIn_VM->setFocus();
77 }
78
79 void SignVerifyMessageDialog::showTab_SM(bool fShow)
80 {
81     ui->tabWidget->setCurrentIndex(0);
82     if (fShow)
83         this->show();
84 }
85
86 void SignVerifyMessageDialog::showTab_VM(bool fShow)
87 {
88     ui->tabWidget->setCurrentIndex(1);
89     if (fShow)
90         this->show();
91 }
92
93 void SignVerifyMessageDialog::on_addressBookButton_SM_clicked()
94 {
95     if (model && model->getAddressTableModel())
96     {
97         AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
98         dlg.setModel(model->getAddressTableModel());
99         if (dlg.exec())
100         {
101             setAddress_SM(dlg.getReturnValue());
102         }
103     }
104 }
105
106 void SignVerifyMessageDialog::on_pasteButton_SM_clicked()
107 {
108     setAddress_SM(QApplication::clipboard()->text());
109 }
110
111 void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
112 {
113     if (!model)
114         return;
115
116     /* Clear old signature to ensure users don't get confused on error with an old signature displayed */
117     ui->signatureOut_SM->clear();
118
119     CBitcoinAddress addr(ui->addressIn_SM->text().toStdString());
120     if (!addr.IsValid())
121     {
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."));
124         return;
125     }
126     CKeyID keyID;
127     if (!addr.GetKeyID(keyID))
128     {
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."));
132         return;
133     }
134
135     WalletModel::UnlockContext ctx(model->requestUnlock());
136     if (!ctx.isValid())
137     {
138         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
139         ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
140         return;
141     }
142
143     CKey key;
144     if (!pwalletMain->GetKey(keyID, key))
145     {
146         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
147         ui->statusLabel_SM->setText(tr("Private key for the entered address is not available."));
148         return;
149     }
150
151     CDataStream ss(SER_GETHASH, 0);
152     ss << strMessageMagic;
153     ss << ui->messageIn_SM->document()->toPlainText().toStdString();
154
155     std::vector<unsigned char> vchSig;
156     if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
157     {
158         ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
159         ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
160         return;
161     }
162
163     ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
164     ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
165
166     ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
167 }
168
169 void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked()
170 {
171     GUIUtil::setClipboard(ui->signatureOut_SM->text());
172 }
173
174 void SignVerifyMessageDialog::on_clearButton_SM_clicked()
175 {
176     ui->addressIn_SM->clear();
177     ui->messageIn_SM->clear();
178     ui->signatureOut_SM->clear();
179     ui->statusLabel_SM->clear();
180
181     ui->addressIn_SM->setFocus();
182 }
183
184 void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()
185 {
186     if (model && model->getAddressTableModel())
187     {
188         AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
189         dlg.setModel(model->getAddressTableModel());
190         if (dlg.exec())
191         {
192             setAddress_VM(dlg.getReturnValue());
193         }
194     }
195 }
196
197 void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
198 {
199     CBitcoinAddress addr(ui->addressIn_VM->text().toStdString());
200     if (!addr.IsValid())
201     {
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."));
204         return;
205     }
206     CKeyID keyID;
207     if (!addr.GetKeyID(keyID))
208     {
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."));
212         return;
213     }
214
215     bool fInvalid = false;
216     std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid);
217
218     if (fInvalid)
219     {
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."));
223         return;
224     }
225
226     CDataStream ss(SER_GETHASH, 0);
227     ss << strMessageMagic;
228     ss << ui->messageIn_VM->document()->toPlainText().toStdString();
229
230     CPubKey pubkey;
231     if (!pubkey.RecoverCompact(Hash(ss.begin(), ss.end()), vchSig))
232     {
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."));
236         return;
237     }
238
239     if (!(CBitcoinAddress(pubkey.GetID()) == addr))
240     {
241         ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
242         ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
243         return;
244     }
245
246     ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
247     ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
248 }
249
250 void SignVerifyMessageDialog::on_clearButton_VM_clicked()
251 {
252     ui->addressIn_VM->clear();
253     ui->signatureIn_VM->clear();
254     ui->messageIn_VM->clear();
255     ui->statusLabel_VM->clear();
256
257     ui->addressIn_VM->setFocus();
258 }
259
260 bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
261 {
262     if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn)
263     {
264         if (ui->tabWidget->currentIndex() == 0)
265         {
266             /* Clear status message on focus change */
267             ui->statusLabel_SM->clear();
268
269             /* Select generated signature */
270             if (object == ui->signatureOut_SM)
271             {
272                 ui->signatureOut_SM->selectAll();
273                 return true;
274             }
275         }
276         else if (ui->tabWidget->currentIndex() == 1)
277         {
278             /* Clear status message on focus change */
279             ui->statusLabel_VM->clear();
280         }
281     }
282     return QDialog::eventFilter(object, event);
283 }
This page took 0.03971 seconds and 4 git commands to generate.