6 changed files with 488 additions and 80 deletions
@ -0,0 +1,171 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file NewAccount.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "NewAccount.h" |
|||
#include <QMenu> |
|||
#include <QDialog> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_NewAccount.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
bool beginsWith(Address _a, bytes const& _b) |
|||
{ |
|||
for (unsigned i = 0; i < min<unsigned>(20, _b.size()); ++i) |
|||
if (_a[i] != _b[i]) |
|||
return false; |
|||
return true; |
|||
} |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(NewAccount); |
|||
|
|||
NewAccount::NewAccount(MainFace* _m): |
|||
Plugin(_m, "NewAccount") |
|||
{ |
|||
connect(addMenuItem("New Account...", "menuTools", true), SIGNAL(triggered()), SLOT(create())); |
|||
} |
|||
|
|||
NewAccount::~NewAccount() |
|||
{ |
|||
} |
|||
|
|||
void NewAccount::create() |
|||
{ |
|||
QDialog d; |
|||
Ui::NewAccount u; |
|||
u.setupUi(&d); |
|||
d.setWindowTitle("New Account Wallet"); |
|||
u.hexText->setEnabled(false); |
|||
u.passwordText->setEnabled(false); |
|||
u.passwordAgainText->setEnabled(false); |
|||
u.hintText->setEnabled(false); |
|||
|
|||
QStringList items = |
|||
{ |
|||
"No vanity (instant)", |
|||
"Direct ICAP address", |
|||
"Two pairs first (a few seconds)", |
|||
"Two pairs first and second (a few minutes)", |
|||
"Three pairs first (a few minutes)", |
|||
"Four pairs first (several hours)", |
|||
"Specific hex string" |
|||
}; |
|||
u.typeComboBox->addItems(items); |
|||
|
|||
void (QComboBox:: *indexChangedSignal)(int) = &QComboBox::currentIndexChanged; |
|||
connect(u.typeComboBox, indexChangedSignal, [&](int index) |
|||
{ |
|||
u.hexText->setEnabled(index == StringMatch); |
|||
}); |
|||
|
|||
connect(u.additionalCheckBox, &QCheckBox::clicked, [&]() |
|||
{ |
|||
bool checked = u.additionalCheckBox->checkState() == Qt::CheckState::Checked; |
|||
u.passwordText->setEnabled(checked); |
|||
u.passwordAgainText->setEnabled(checked); |
|||
u.hintText->setEnabled(checked); |
|||
}); |
|||
|
|||
connect(u.create, &QPushButton::clicked, [&]() |
|||
{ |
|||
if (u.additionalCheckBox->checkState() == Qt::CheckState::Checked && !validatePassword(u)) |
|||
{ |
|||
u.passwordAgainLabel->setStyleSheet("QLabel { color : red }"); |
|||
u.passwordAgainLabel->setText("Invalid! Please re-enter password correctly:"); |
|||
return; |
|||
} |
|||
|
|||
d.accept(); |
|||
}); |
|||
|
|||
if (d.exec() == QDialog::Accepted) |
|||
onDialogAccepted(u); |
|||
|
|||
} |
|||
|
|||
bool NewAccount::validatePassword(Ui::NewAccount const& _u) |
|||
{ |
|||
return QString::compare(_u.passwordText->toPlainText(), _u.passwordAgainText->toPlainText()) == 0; |
|||
} |
|||
|
|||
void NewAccount::onDialogAccepted(Ui::NewAccount const& _u) |
|||
{ |
|||
Type v = (Type)_u.typeComboBox->currentIndex(); |
|||
bytes bs = fromHex(_u.hexText->toPlainText().toStdString()); |
|||
KeyPair p = newKeyPair(v, bs); |
|||
QString s = _u.nameText->toPlainText(); |
|||
if (_u.additionalCheckBox->checkState() == Qt::CheckState::Checked) |
|||
{ |
|||
std::string hint = _u.hintText->toPlainText().toStdString(); |
|||
std::string password = _u.passwordText->toPlainText().toStdString(); |
|||
main()->keyManager().import(p.secret(), s.toStdString(), password, hint); |
|||
} |
|||
else |
|||
main()->keyManager().import(p.secret(), s.toStdString()); |
|||
|
|||
main()->noteKeysChanged(); |
|||
} |
|||
|
|||
KeyPair NewAccount::newKeyPair(Type _type, bytes const& _prefix) |
|||
{ |
|||
KeyPair p; |
|||
bool keepGoing = true; |
|||
unsigned done = 0; |
|||
function<void()> f = [&]() { |
|||
KeyPair lp; |
|||
while (keepGoing) |
|||
{ |
|||
done++; |
|||
if (done % 1000 == 0) |
|||
cnote << "Tried" << done << "keys"; |
|||
lp = KeyPair::create(); |
|||
auto a = lp.address(); |
|||
if (_type == NoVanity || |
|||
(_type == DirectICAP && !a[0]) || |
|||
(_type == FirstTwo && a[0] == a[1]) || |
|||
(_type == FirstTwoNextTwo && a[0] == a[1] && a[2] == a[3]) || |
|||
(_type == FirstThree && a[0] == a[1] && a[1] == a[2]) || |
|||
(_type == FirstFour && a[0] == a[1] && a[1] == a[2] && a[2] == a[3]) || |
|||
(_type == StringMatch && beginsWith(lp.address(), _prefix)) |
|||
) |
|||
break; |
|||
} |
|||
if (keepGoing) |
|||
p = lp; |
|||
keepGoing = false; |
|||
}; |
|||
|
|||
vector<std::thread*> ts; |
|||
for (unsigned t = 0; t < std::thread::hardware_concurrency() - 1; ++t) |
|||
ts.push_back(new std::thread(f)); |
|||
f(); |
|||
|
|||
for (std::thread* t: ts) |
|||
{ |
|||
t->join(); |
|||
delete t; |
|||
} |
|||
return p; |
|||
} |
@ -0,0 +1,56 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file NewAccount.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
|
|||
namespace Ui |
|||
{ |
|||
class NewAccount; |
|||
} |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class NewAccount: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
NewAccount(MainFace* _m); |
|||
~NewAccount(); |
|||
|
|||
private slots: |
|||
void create(); |
|||
|
|||
private: |
|||
enum Type { NoVanity = 0, DirectICAP, FirstTwo, FirstTwoNextTwo, FirstThree, FirstFour, StringMatch }; |
|||
bool validatePassword(Ui::NewAccount const& _u); |
|||
void onDialogAccepted(Ui::NewAccount const& _u); |
|||
KeyPair newKeyPair(Type _type, bytes const& _prefix); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,260 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>NewAccount</class> |
|||
<widget class="QDialog" name="NewAccount"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>511</width> |
|||
<height>600</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Dialog</string> |
|||
</property> |
|||
<property name="styleSheet"> |
|||
<string notr="true"/> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<widget class="QLabel" name="typeLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Select new account type:</span></p></body></html></string> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QComboBox" name="typeComboBox"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>16777215</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="hexLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p>Enter some hex digits it should begin with.<br/>NOTE: The more you enter, the longer generation will take.</p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="hexText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="nameLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter this account name:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="nameText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="additionalLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>100</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Would you like to add additional security for this key? This lets you protect it with a different password to other keys, but also means that you need to re-enter the key's password every time you wish to use the account.</span></p></body></html></string> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QCheckBox" name="additionalCheckBox"> |
|||
<property name="text"> |
|||
<string>Yes</string> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="passwordLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter password:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="passwordText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="passwordAgainLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter password again:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="passwordAgainText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="hintLabel"> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter hint:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="hintText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<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="QPushButton" name="cancel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>83</width> |
|||
<height>16777215</height> |
|||
</size> |
|||
</property> |
|||
<property name="layoutDirection"> |
|||
<enum>Qt::LeftToRight</enum> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Cancel</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="create"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>83</width> |
|||
<height>16777215</height> |
|||
</size> |
|||
</property> |
|||
<property name="layoutDirection"> |
|||
<enum>Qt::LeftToRight</enum> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&Create</string> |
|||
</property> |
|||
<property name="default"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>cancel</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>NewAccount</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>381</x> |
|||
<y>483</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>351</x> |
|||
<y>506</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
Loading…
Reference in new issue