mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Merge pull request #906 from sje397/ValidateMessage
Add a menu option and dialog to verify a signed message
This commit is contained in:
commit
bb361cc644
@ -160,7 +160,8 @@ HEADERS += src/qt/bitcoingui.h \
|
||||
src/qt/qtipcserver.h \
|
||||
src/allocators.h \
|
||||
src/ui_interface.h \
|
||||
src/qt/rpcconsole.h
|
||||
src/qt/rpcconsole.h \
|
||||
src/qt/verifymessagedialog.h
|
||||
|
||||
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
||||
src/qt/transactiontablemodel.cpp \
|
||||
@ -216,7 +217,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
|
||||
src/protocol.cpp \
|
||||
src/qt/notificator.cpp \
|
||||
src/qt/qtipcserver.cpp \
|
||||
src/qt/rpcconsole.cpp
|
||||
src/qt/rpcconsole.cpp \
|
||||
src/qt/verifymessagedialog.cpp
|
||||
|
||||
RESOURCES += \
|
||||
src/qt/bitcoin.qrc
|
||||
@ -231,7 +233,8 @@ FORMS += \
|
||||
src/qt/forms/overviewpage.ui \
|
||||
src/qt/forms/sendcoinsentry.ui \
|
||||
src/qt/forms/askpassphrasedialog.ui \
|
||||
src/qt/forms/rpcconsole.ui
|
||||
src/qt/forms/rpcconsole.ui \
|
||||
src/qt/forms/verifymessagedialog.ui
|
||||
|
||||
contains(USE_QRCODE, 1) {
|
||||
HEADERS += src/qt/qrcodedialog.h
|
||||
|
@ -324,6 +324,7 @@ void AddressBookPage::on_showQRCode_clicked()
|
||||
QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString();
|
||||
|
||||
QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "addressbookpage.h"
|
||||
#include "sendcoinsdialog.h"
|
||||
#include "messagepage.h"
|
||||
#include "verifymessagedialog.h"
|
||||
#include "optionsdialog.h"
|
||||
#include "aboutdialog.h"
|
||||
#include "clientmodel.h"
|
||||
@ -257,6 +258,8 @@ void BitcoinGUI::createActions()
|
||||
changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
|
||||
openRPCConsoleAction = new QAction(tr("&Debug window"), this);
|
||||
openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console"));
|
||||
verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
|
||||
verifyMessageAction->setToolTip(tr("Verify a message signature"));
|
||||
|
||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
|
||||
@ -266,6 +269,7 @@ void BitcoinGUI::createActions()
|
||||
connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
|
||||
connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
|
||||
connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
|
||||
connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(verifyMessage()));
|
||||
}
|
||||
|
||||
void BitcoinGUI::createMenuBar()
|
||||
@ -285,6 +289,7 @@ void BitcoinGUI::createMenuBar()
|
||||
#ifndef FIRST_CLASS_MESSAGING
|
||||
file->addAction(messageAction);
|
||||
#endif
|
||||
file->addAction(verifyMessageAction);
|
||||
file->addSeparator();
|
||||
file->addAction(quitAction);
|
||||
|
||||
@ -408,6 +413,7 @@ void BitcoinGUI::createTrayIcon()
|
||||
trayIconMenu->addAction(openRPCConsoleAction);
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(messageAction);
|
||||
trayIconMenu->addAction(verifyMessageAction);
|
||||
#ifndef FIRST_CLASS_MESSAGING
|
||||
trayIconMenu->addSeparator();
|
||||
#endif
|
||||
@ -839,6 +845,13 @@ void BitcoinGUI::changePassphrase()
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void BitcoinGUI::verifyMessage()
|
||||
{
|
||||
VerifyMessageDialog *dlg = new VerifyMessageDialog(walletModel->getAddressTableModel(), this);
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dlg->show();
|
||||
}
|
||||
|
||||
void BitcoinGUI::unlockWallet()
|
||||
{
|
||||
if(!walletModel)
|
||||
|
@ -79,6 +79,7 @@ private:
|
||||
QAction *sendCoinsAction;
|
||||
QAction *addressBookAction;
|
||||
QAction *messageAction;
|
||||
QAction *verifyMessageAction;
|
||||
QAction *aboutAction;
|
||||
QAction *receiveCoinsAction;
|
||||
QAction *optionsAction;
|
||||
@ -163,6 +164,8 @@ private slots:
|
||||
void backupWallet();
|
||||
/** Change encrypted wallet passphrase */
|
||||
void changePassphrase();
|
||||
/** Verify a message signature */
|
||||
void verifyMessage();
|
||||
/** Ask for pass phrase to unlock wallet temporarily */
|
||||
void unlockWallet();
|
||||
|
||||
|
149
src/qt/forms/verifymessagedialog.ui
Normal file
149
src/qt/forms/verifymessagedialog.ui
Normal file
@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>VerifyMessageDialog</class>
|
||||
<widget class="QDialog" name="VerifyMessageDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>494</width>
|
||||
<height>342</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Verify Signed Message</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Enter the message and signature below (be careful to correctly copy newlines, spaces, tabs, and other invisible characters), and press apply to obtain the bitcoin address used to sign the message.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="edMessage"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lnSig">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Signature</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lnAddress">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStatus">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="copyToClipboard">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Copy the currently selected address to the system clipboard</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Copy Address</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>VerifyMessageDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>VerifyMessageDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -15,7 +15,6 @@ QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enabl
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(QString("%1").arg(address));
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
ui->chkReqPayment->setVisible(enableReq);
|
||||
ui->lnReqAmount->setVisible(enableReq);
|
||||
|
75
src/qt/verifymessagedialog.cpp
Normal file
75
src/qt/verifymessagedialog.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "verifymessagedialog.h"
|
||||
#include "ui_verifymessagedialog.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QAbstractButton>
|
||||
#include <QClipboard>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "main.h"
|
||||
#include "wallet.h"
|
||||
#include "walletmodel.h"
|
||||
#include "addresstablemodel.h"
|
||||
#include "guiutil.h"
|
||||
|
||||
VerifyMessageDialog::VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::VerifyMessageDialog),
|
||||
model(addressModel)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
GUIUtil::setupAddressWidget(ui->lnAddress, this);
|
||||
}
|
||||
|
||||
VerifyMessageDialog::~VerifyMessageDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool VerifyMessageDialog::checkAddress()
|
||||
{
|
||||
CDataStream ss(SER_GETHASH, 0);
|
||||
ss << strMessageMagic;
|
||||
ss << ui->edMessage->document()->toPlainText().toStdString();
|
||||
uint256 hash = Hash(ss.begin(), ss.end());
|
||||
|
||||
bool invalid = true;
|
||||
std::vector<unsigned char> vchSig = DecodeBase64(ui->lnSig->text().toStdString().c_str(), &invalid);
|
||||
|
||||
if(invalid)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature could not be decoded. Please check the signature and try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
CKey key;
|
||||
if(!key.SetCompactSignature(hash, vchSig))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature did not match the message digest. Please check the signature and try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
CBitcoinAddress address(key.GetPubKey());
|
||||
QString qStringAddress = QString::fromStdString(address.ToString());
|
||||
ui->lnAddress->setText(qStringAddress);
|
||||
ui->copyToClipboard->setEnabled(true);
|
||||
|
||||
QString label = model->labelForAddress(qStringAddress);
|
||||
ui->lblStatus->setText(label.isEmpty() ? tr("Address not found in address book.") : tr("Address found in address book: %1").arg(label));
|
||||
return true;
|
||||
}
|
||||
|
||||
void VerifyMessageDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
if(ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole)
|
||||
checkAddress();
|
||||
}
|
||||
|
||||
void VerifyMessageDialog::on_copyToClipboard_clicked()
|
||||
{
|
||||
QApplication::clipboard()->setText(ui->lnAddress->text());
|
||||
}
|
36
src/qt/verifymessagedialog.h
Normal file
36
src/qt/verifymessagedialog.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef VERIFYMESSAGEDIALOG_H
|
||||
#define VERIFYMESSAGEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class AddressTableModel;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAbstractButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Ui {
|
||||
class VerifyMessageDialog;
|
||||
}
|
||||
|
||||
class VerifyMessageDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent = 0);
|
||||
~VerifyMessageDialog();
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_clicked(QAbstractButton *button);
|
||||
|
||||
void on_copyToClipboard_clicked();
|
||||
|
||||
private:
|
||||
bool checkAddress();
|
||||
|
||||
Ui::VerifyMessageDialog *ui;
|
||||
AddressTableModel *model;
|
||||
};
|
||||
|
||||
#endif // VERIFYMESSAGEDIALOG_H
|
Loading…
Reference in New Issue
Block a user