diff --git a/alethzero/Main.ui b/alethzero/Main.ui
index b987636e0..7d9d032b7 100644
--- a/alethzero/Main.ui
+++ b/alethzero/Main.ui
@@ -132,7 +132,7 @@
0
0
1617
- 22
+ 24
diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index 1f3b3ffc9..5d5250ac1 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -667,9 +667,10 @@ std::string Main::render(dev::Address const& _a) const
if (p.size() == 9 && p.find_first_not_of("QWERYUOPASDFGHJKLZXCVBNM1234567890") == string::npos)
p = ICAP(p, "XREG").encoded();
else
- DEV_IGNORE_EXCEPTIONS(n = ICAP(_a).encoded());
- if (n.empty())
- n = _a.abridged();
+ DEV_IGNORE_EXCEPTIONS(n = ICAP(_a).encoded().substr(0, 8));
+ if (!n.empty())
+ n += " ";
+ n += _a.abridged();
return p.empty() ? n : (p + " " + n);
}
@@ -1586,25 +1587,6 @@ void Main::on_transactionQueue_currentItemChanged()
ui->pendingInfo->moveCursor(QTextCursor::Start);
}
-void Main::on_inject_triggered()
-{
- QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex");
- try
- {
- bytes b = fromHex(s.toStdString(), WhenError::Throw);
- ethereum()->injectTransaction(b);
- }
- catch (BadHexCharacter& _e)
- {
- cwarn << "invalid hex character, transaction rejected";
- cwarn << boost::diagnostic_information(_e);
- }
- catch (...)
- {
- cwarn << "transaction rejected";
- }
-}
-
void Main::on_injectBlock_triggered()
{
QString s = QInputDialog::getText(this, "Inject Block", "Enter block dump in hex");
diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h
index e528d0fee..69b4d920a 100644
--- a/alethzero/MainWin.h
+++ b/alethzero/MainWin.h
@@ -179,7 +179,6 @@ private slots:
void on_paranoia_triggered();
void on_killBlockchain_triggered();
void on_clearPending_triggered();
- void on_inject_triggered();
void on_injectBlock_triggered();
void on_forceMining_triggered();
void on_usePrivate_triggered();
diff --git a/alethzero/plugins/namers/OtherAccounts.cpp b/alethzero/plugins/namers/OtherAccounts.cpp
index fc2d518bc..19b602b91 100644
--- a/alethzero/plugins/namers/OtherAccounts.cpp
+++ b/alethzero/plugins/namers/OtherAccounts.cpp
@@ -21,6 +21,7 @@
#include "OtherAccounts.h"
#include
+#include
#include
#include
#include
@@ -46,12 +47,22 @@ void OtherAccounts::import()
if (d.exec() == QDialog::Accepted)
{
QStringList sl = u.accounts->toPlainText().split("\n");
+ unsigned line = 1;
for (QString const& s: sl)
{
- Address addr = dev::eth::toAddress(s.section(QRegExp("[ \\0\\t]+"), 0, 0).toStdString());
- string name = s.section(QRegExp("[ \\0\\t]+"), 1).toStdString();
- m_toName[addr] = name;
- m_toAddress[name] = addr;
+ try
+ {
+ Address addr = dev::eth::toAddress(s.section(QRegExp("[ \\0\\t]+"), 0, 0).trimmed().toStdString());
+ string name = s.section(QRegExp("[ \\0\\t]+"), 1).trimmed().toStdString();
+ m_toName[addr] = name;
+ m_toAddress[name] = addr;
+ }
+ catch (...)
+ {
+ if (QMessageBox::warning(&d, "Invalid Line Format", "Line format or address given on line " + QString::number(line) + " is invalid:\n" + s, QMessageBox::Abort, QMessageBox::Ignore) == QMessageBox::Abort)
+ break;
+ }
+ line++;
}
main()->noteSettingsChanged();
noteKnownChanged();
diff --git a/alethzero/plugins/special/InjectTransactions.cpp b/alethzero/plugins/special/InjectTransactions.cpp
new file mode 100644
index 000000000..f1535f56e
--- /dev/null
+++ b/alethzero/plugins/special/InjectTransactions.cpp
@@ -0,0 +1,87 @@
+/*
+ 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 .
+*/
+/** @file InjectTransactions.h
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#include "InjectTransactions.h"
+#include
+#include
+#include
+#include
+#include "ui_InjectTransactions.h"
+using namespace std;
+using namespace dev;
+using namespace az;
+using namespace eth;
+
+DEV_AZ_NOTE_PLUGIN(InjectTransactions);
+
+InjectTransactions::InjectTransactions(MainFace* _m):
+ Plugin(_m, "InjectTransactions")
+{
+ connect(addMenuItem("Inject Transaction...", "menuSpecial", true), SIGNAL(triggered()), SLOT(injectOne()));
+ connect(addMenuItem("Bulk Inject Transactions...", "menuSpecial", false), SIGNAL(triggered()), SLOT(injectBulk()));
+}
+
+InjectTransactions::~InjectTransactions()
+{
+}
+
+void InjectTransactions::injectOne()
+{
+ bool ok;
+ QString s = QInputDialog::getText(main(), "Inject Transaction", "Enter transaction dump in hex", QLineEdit::Normal, QString(), &ok);
+ if (ok)
+ doInject(s);
+}
+
+void InjectTransactions::injectBulk()
+{
+ QDialog d;
+ Ui_InjectTransactions u;
+ u.setupUi(&d);
+ d.setWindowTitle("Bulk Inject Transactions");
+ if (d.exec() == QDialog::Accepted)
+ for (QString const& s: u.transactions->toPlainText().split("\n"))
+ doInject(s);
+}
+
+void InjectTransactions::doInject(QString _txHex)
+{
+ try
+ {
+ bytes b = fromHex(_txHex.toStdString(), WhenError::Throw);
+ main()->ethereum()->injectTransaction(b);
+ }
+ catch (BadHexCharacter& _e)
+ {
+ if (QMessageBox::warning(main(), "Invalid Transaction Hex", "Invalid hex character in:\n" + _txHex + "\nTransaction rejected.", QMessageBox::Ignore, QMessageBox::Abort) == QMessageBox::Abort)
+ return;
+ }
+ catch (Exception& _e)
+ {
+ if (QMessageBox::warning(main(), "Transaction Rejected", "Invalid transaction; due to" + QString::fromStdString(_e.what()) + "\n" + _txHex + "\nTransaction rejected.", QMessageBox::Ignore, QMessageBox::Abort) == QMessageBox::Abort)
+ return;
+ }
+ catch (...)
+ {
+ // Should not happen under normal circumstances.
+ return;
+ }
+}
diff --git a/alethzero/plugins/special/InjectTransactions.h b/alethzero/plugins/special/InjectTransactions.h
new file mode 100644
index 000000000..76941027d
--- /dev/null
+++ b/alethzero/plugins/special/InjectTransactions.h
@@ -0,0 +1,48 @@
+/*
+ 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 .
+*/
+/** @file InjectTransactions.h
+ * @author Gav Wood
+ * @date 2015
+ */
+
+#pragma once
+
+#include "MainFace.h"
+
+namespace dev
+{
+namespace az
+{
+
+class InjectTransactions: public QObject, public Plugin
+{
+ Q_OBJECT
+
+public:
+ InjectTransactions(MainFace* _m);
+ ~InjectTransactions();
+
+private slots:
+ void injectOne();
+ void injectBulk();
+
+private:
+ void doInject(QString _txHex);
+};
+
+}
+}
diff --git a/alethzero/plugins/special/InjectTransactions.ui b/alethzero/plugins/special/InjectTransactions.ui
new file mode 100644
index 000000000..e135130eb
--- /dev/null
+++ b/alethzero/plugins/special/InjectTransactions.ui
@@ -0,0 +1,95 @@
+
+
+ InjectTransactions
+
+
+
+ 0
+ 0
+ 511
+ 508
+
+
+
+ Dialog
+
+
+ -
+
+
+ Write the transactions you wish to inject here, in hex, one per line.
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Cancel
+
+
+
+ -
+
+
+ &Import
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ inject
+ clicked()
+ InjectTransactions
+ accept()
+
+
+ 462
+ 484
+
+
+ 449
+ 504
+
+
+
+
+ cancel
+ clicked()
+ InjectTransactions
+ reject()
+
+
+ 381
+ 483
+
+
+ 351
+ 506
+
+
+
+
+
diff --git a/ethkey/KeyAux.h b/ethkey/KeyAux.h
index 74f89ad4a..d69b801bb 100644
--- a/ethkey/KeyAux.h
+++ b/ethkey/KeyAux.h
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include "BuildInfo.h"
using namespace std;
using namespace dev;
@@ -108,6 +109,9 @@ public:
Export,
Recode,
Kill,
+ NewBrain,
+ ImportBrain,
+ InspectBrain,
SignTx,
DecodeTx,
};
@@ -175,6 +179,18 @@ public:
m_inputs = strings(1, argv[++i]);
m_name = argv[++i];
}
+ else if (arg == "--new-brain" && i + 1 < argc)
+ {
+ m_mode = OperationMode::NewBrain;
+ m_name = argv[++i];
+ }
+ else if (arg == "--import-brain" && i + 1 < argc)
+ {
+ m_mode = OperationMode::ImportBrain;
+ m_name = argv[++i];
+ }
+ else if (arg == "--inspect-brain")
+ m_mode = OperationMode::InspectBrain;
else if (arg == "--import-with-address" && i + 3 < argc)
{
m_mode = OperationMode::ImportWithAddress;
@@ -203,9 +219,34 @@ public:
return k;
}
+ Secret getSecret(std::string const& _signKey)
+ {
+ string json = contentsString(_signKey);
+ if (!json.empty())
+ return Secret(secretStore().secret(secretStore().readKeyContent(json), [&](){ return getPassword("Enter password for key: "); }));
+ else
+ {
+ if (h128 u = fromUUID(_signKey))
+ return Secret(secretStore().secret(u, [&](){ return getPassword("Enter password for key: "); }));
+ else if (Address a = Address(_signKey))
+ return keyManager().secret(a, [&](){ return getPassword("Enter password for key (hint:" + keyManager().passwordHint(a) + "): "); });
+ else if (_signKey.substr(0, 6) == "brain:")
+ return KeyManager::brain(_signKey.substr(6));
+ else if (_signKey == "brain")
+ return KeyManager::brain(getPassword("Enter brain wallet phrase: "));
+ else
+ {
+ cerr << "Bad file, UUID and address: " << _signKey << endl;
+ exit(-1);
+ }
+ }
+ }
+
void execute()
{
- if (m_mode == OperationMode::CreateWallet)
+ switch (m_mode)
+ {
+ case OperationMode::CreateWallet:
{
KeyManager wallet(m_walletPath, m_secretsPath);
if (m_masterPassword.empty())
@@ -223,8 +264,9 @@ public:
cerr << "unable to create wallet" << endl << boost::diagnostic_information(_e);
}
}
+ break;
}
- else if (m_mode == OperationMode::DecodeTx)
+ case OperationMode::DecodeTx:
{
bytes b = inputData(m_inputs[0]);
if (b.empty())
@@ -269,50 +311,11 @@ public:
{
cerr << "Invalid transaction: " << ex.what() << endl;
}
+ break;
}
- else if (m_mode == OperationMode::SignTx)
+ case OperationMode::SignTx:
{
- Secret s;
-
- string json = contentsString(m_signKey);
- if (!json.empty())
- {
- SecretStore store(m_secretsPath);
- s = Secret(store.secret(store.readKeyContent(json), [&](){ return getPassword("Enter password for key: "); }));
- }
- else
- {
- if (h128 u = fromUUID(m_signKey))
- {
- SecretStore store(m_secretsPath);
- s = Secret(store.secret(u, [&](){ return getPassword("Enter password for key: "); }));
- }
- else if (Address a = Address(m_signKey))
- {
- KeyManager wallet(m_walletPath, m_secretsPath);
- if (wallet.exists())
- {
- openWallet(wallet);
- s = wallet.secret(a, [&](){ return getPassword("Enter password for key: "); });
- }
- else
- {
- cerr << "Wallet doesn't exist." << endl;
- exit(-1);
- }
- }
- else
- {
- cerr << "Bad file, UUID and address: " << m_signKey << endl;
- exit(-1);
- }
- }
- if (!s)
- {
- cerr << "UUID/address not found: " << m_signKey << endl;
- exit(-1);
- }
-
+ Secret s = getSecret(m_signKey);
for (string const& i: m_inputs)
{
bool isFile;
@@ -338,182 +341,208 @@ public:
cerr << "Invalid transaction: " << ex.what() << endl;
}
}
+ break;
}
- else if (m_mode < OperationMode::CreateWallet)
+ case OperationMode::NewBrain:
{
- SecretStore store(m_secretsPath);
- switch (m_mode)
- {
- case OperationMode::ListBare:
- for (h128 const& u: std::set() + store.keys())
- cout << toUUID(u) << endl;
- break;
- case OperationMode::NewBare:
+ if (m_name != "--")
+ keyManager();
+ boost::random_device d;
+ boost::random::uniform_int_distribution pickWord(0, WordList.size() - 1);
+ string seed;
+ for (int i = 0; i < 13; ++i)
+ seed += (seed.size() ? " " : "") + WordList[pickWord(d)];
+ cout << "Your brain key phrase: <<" << seed << ">>" << endl;
+ if (m_name != "--")
{
- if (m_lock.empty())
- m_lock = createPassword("Enter a password with which to secure this account: ");
- auto k = makeKey();
- h128 u = store.importSecret(k.secret().ref(), m_lock);
- cout << "Created key " << toUUID(u) << endl;
- cout << " Address: " << k.address().hex() << endl;
- cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
- break;
- }
- case OperationMode::ImportBare:
- for (string const& input: m_inputs)
- {
- h128 u;
- bytesSec b;
- b.writable() = fromHex(input);
- if (b.size() != 32)
- {
- std::string s = contentsString(input);
- b.writable() = fromHex(s);
- if (b.size() != 32)
- u = store.importKey(input);
- }
- if (!u && b.size() == 32)
- u = store.importSecret(b, lockPassword(toAddress(Secret(b)).abridged()));
- if (!u)
- {
- cerr << "Cannot import " << input << " not a file or secret." << endl;
- continue;
- }
- cout << "Successfully imported " << input << " as " << toUUID(u);
- }
- break;
- case OperationMode::InspectBare:
- for (auto const& i: m_inputs)
- if (!contents(i).empty())
- {
- h128 u = store.readKey(i, false);
- bytesSec s = store.secret(u, [&](){ return getPassword("Enter password for key " + i + ": "); });
- cout << "Key " << i << ":" << endl;
- cout << " UUID: " << toUUID(u) << ":" << endl;
- cout << " Address: " << toAddress(Secret(s)).hex() << endl;
- cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
- }
- else if (h128 u = fromUUID(i))
- {
- bytesSec s = store.secret(u, [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); });
- cout << "Key " << i << ":" << endl;
- cout << " Address: " << toAddress(Secret(s)).hex() << endl;
- cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
- }
- else
- cerr << "Couldn't inspect " << i << "; not found." << endl;
- break;
- case OperationMode::ExportBare: break;
- case OperationMode::RecodeBare:
- for (auto const& i: m_inputs)
- if (h128 u = fromUUID(i))
- if (store.recode(u, lockPassword(toUUID(u)), [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); }, kdf()))
- cerr << "Re-encoded " << toUUID(u) << endl;
- else
- cerr << "Couldn't re-encode " << toUUID(u) << "; key corrupt or incorrect password supplied." << endl;
- else
- cerr << "Couldn't re-encode " << i << "; not found." << endl;
- break;
- case OperationMode::KillBare:
- for (auto const& i: m_inputs)
- if (h128 u = fromUUID(i))
- store.kill(u);
- else
- cerr << "Couldn't kill " << i << "; not found." << endl;
- break;
- default: break;
+ std::string hint;
+ cout << "Enter a hint for the phrase if you want: " << flush;
+ getline(cin, hint);
+ Address a = keyManager().importBrain(seed, m_name, hint);
+ cout << a.abridged() << endl;
+ cout << " ICAP: " << ICAP(a).encoded() << endl;
+ cout << " Address: " << a.hex() << endl;
}
+ break;
}
- else
+ case OperationMode::InspectBrain:
{
- KeyManager wallet(m_walletPath, m_secretsPath);
- if (wallet.exists())
- openWallet(wallet);
- else
- {
- cerr << "Couldn't open wallet. Does it exist?" << endl;
- exit(-1);
- }
- switch (m_mode)
- {
- case OperationMode::New:
- {
- tie(m_lock, m_lockHint) = createPassword(wallet, "Enter a password with which to secure this account (or nothing to use the master password): ", m_lock, m_lockHint);
- auto k = makeKey();
- bool usesMaster = m_lock.empty();
- h128 u = usesMaster ? wallet.import(k.secret(), m_name) : wallet.import(k.secret(), m_name, m_lock, m_lockHint);
- cout << "Created key " << toUUID(u) << endl;
- cout << " Name: " << m_name << endl;
- if (usesMaster)
- cout << " Uses master password." << endl;
- else
- cout << " Password hint: " << m_lockHint << endl;
- cout << " Address: " << k.address().hex() << endl;
- cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
- break;
- }
- case OperationMode::ImportWithAddress:
+ Address a = toAddress(KeyManager::brain(getPassword("Enter brain wallet key phrase: ")));
+ cout << a.abridged() << endl;
+ cout << " ICAP: " << ICAP(a).encoded() << endl;
+ cout << " Address: " << a.hex() << endl;
+ break;
+ }
+ case OperationMode::ListBare:
+ for (h128 const& u: std::set() + secretStore().keys())
+ cout << toUUID(u) << endl;
+ break;
+ case OperationMode::NewBare:
+ {
+ if (m_lock.empty())
+ m_lock = createPassword("Enter a password with which to secure this account: ");
+ auto k = makeKey();
+ h128 u = secretStore().importSecret(k.secret().ref(), m_lock);
+ cout << "Created key " << toUUID(u) << endl;
+ cout << " Address: " << k.address().hex() << endl;
+ cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
+ break;
+ }
+ case OperationMode::ImportBare:
+ for (string const& input: m_inputs)
{
- string const& i = m_inputs[0];
h128 u;
bytesSec b;
- b.writable() = fromHex(i);
+ b.writable() = fromHex(input);
if (b.size() != 32)
{
- std::string s = contentsString(i);
+ std::string s = contentsString(input);
b.writable() = fromHex(s);
if (b.size() != 32)
- u = wallet.store().importKey(i);
+ u = secretStore().importKey(input);
}
if (!u && b.size() == 32)
- u = wallet.store().importSecret(b, lockPassword(toAddress(Secret(b)).abridged()));
+ u = secretStore().importSecret(b, lockPassword(toAddress(Secret(b)).abridged()));
if (!u)
{
- cerr << "Cannot import " << i << " not a file or secret." << endl;
- break;
+ cerr << "Cannot import " << input << " not a file or secret." << endl;
+ continue;
}
- wallet.importExisting(u, m_name, m_address);
- cout << "Successfully imported " << i << ":" << endl;
- cout << " Name: " << m_name << endl;
- cout << " Address: " << m_address << endl;
- cout << " UUID: " << toUUID(u) << endl;
- break;
+ cout << "Successfully imported " << input << " as " << toUUID(u);
}
- case OperationMode::ImportPresale:
+ break;
+ case OperationMode::InspectBare:
+ for (auto const& i: m_inputs)
+ if (!contents(i).empty())
+ {
+ h128 u = secretStore().readKey(i, false);
+ bytesSec s = secretStore().secret(u, [&](){ return getPassword("Enter password for key " + i + ": "); });
+ cout << "Key " << i << ":" << endl;
+ cout << " UUID: " << toUUID(u) << ":" << endl;
+ cout << " Address: " << toAddress(Secret(s)).hex() << endl;
+ cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
+ }
+ else if (h128 u = fromUUID(i))
+ {
+ bytesSec s = secretStore().secret(u, [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); });
+ cout << "Key " << i << ":" << endl;
+ cout << " Address: " << toAddress(Secret(s)).hex() << endl;
+ cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
+ }
+ else
+ cerr << "Couldn't inspect " << i << "; not found." << endl;
+ break;
+ case OperationMode::ExportBare: break;
+ case OperationMode::RecodeBare:
+ for (auto const& i: m_inputs)
+ if (h128 u = fromUUID(i))
+ if (secretStore().recode(u, lockPassword(toUUID(u)), [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); }, kdf()))
+ cerr << "Re-encoded " << toUUID(u) << endl;
+ else
+ cerr << "Couldn't re-encode " << toUUID(u) << "; key corrupt or incorrect password supplied." << endl;
+ else
+ cerr << "Couldn't re-encode " << i << "; not found." << endl;
+ break;
+ case OperationMode::KillBare:
+ for (auto const& i: m_inputs)
+ if (h128 u = fromUUID(i))
+ secretStore().kill(u);
+ else
+ cerr << "Couldn't kill " << i << "; not found." << endl;
+ break;
+ case OperationMode::New:
+ {
+ keyManager();
+ tie(m_lock, m_lockHint) = createPassword(keyManager(), "Enter a password with which to secure this account (or nothing to use the master password): ", m_lock, m_lockHint);
+ auto k = makeKey();
+ bool usesMaster = m_lock.empty();
+ h128 u = usesMaster ? keyManager().import(k.secret(), m_name) : keyManager().import(k.secret(), m_name, m_lock, m_lockHint);
+ cout << "Created key " << toUUID(u) << endl;
+ cout << " Name: " << m_name << endl;
+ if (usesMaster)
+ cout << " Uses master password." << endl;
+ else
+ cout << " Password hint: " << m_lockHint << endl;
+ cout << " Address: " << k.address().hex() << endl;
+ cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
+ break;
+ }
+ case OperationMode::ImportWithAddress:
+ {
+ keyManager();
+ string const& i = m_inputs[0];
+ h128 u;
+ bytesSec b;
+ b.writable() = fromHex(i);
+ if (b.size() != 32)
{
- std::string pw;
- KeyPair k = wallet.presaleSecret(contentsString(m_inputs[0]), [&](bool){ return (pw = getPassword("Enter the password for the presale key: ")); });
- wallet.import(k.secret(), m_name, pw, "Same password as used for presale key");
- break;
+ std::string s = contentsString(i);
+ b.writable() = fromHex(s);
+ if (b.size() != 32)
+ u = keyManager().store().importKey(i);
}
- case OperationMode::List:
+ if (!u && b.size() == 32)
+ u = keyManager().store().importSecret(b, lockPassword(toAddress(Secret(b)).abridged()));
+ if (!u)
{
- vector bare;
- vector nonIcap;
- for (auto const& u: wallet.store().keys())
- if (Address a = wallet.address(u))
- if (a[0])
- nonIcap.push_back(u);
- else
- {
- cout << toUUID(u) << " " << a.abridged();
- cout << " " << ICAP(a).encoded();
- cout << " " << wallet.accountName(a) << endl;
- }
- else
- bare.push_back(u);
- for (auto const& u: nonIcap)
- if (Address a = wallet.address(u))
- {
- cout << toUUID(u) << " " << a.abridged();
- cout << " " << ICAP(a).encoded();
- cout << " " << wallet.accountName(a) << endl;
- }
- for (auto const& u: bare)
- cout << toUUID(u) << " (Bare)" << endl;
- }
- default: break;
+ cerr << "Cannot import " << i << " not a file or secret." << endl;
+ break;
}
+ keyManager().importExisting(u, m_name, m_address);
+ cout << "Successfully imported " << i << ":" << endl;
+ cout << " Name: " << m_name << endl;
+ cout << " Address: " << m_address << endl;
+ cout << " UUID: " << toUUID(u) << endl;
+ break;
+ }
+ case OperationMode::ImportBrain:
+ {
+ keyManager();
+ std::string seed = getPassword("Enter brain wallet key phrase: ");
+ std::string hint;
+ cout << "Enter a hint for the phrase if you want: " << flush;
+ getline(cin, hint);
+ Address a = keyManager().importBrain(seed, m_name, hint);
+ cout << a << endl;
+ cout << " ICAP: " << ICAP(a).encoded() << endl;
+ cout << " Address: " << a.hex() << endl;
+ break;
+ }
+ case OperationMode::ImportPresale:
+ {
+ keyManager();
+ std::string pw;
+ KeyPair k = keyManager().presaleSecret(contentsString(m_inputs[0]), [&](bool){ return (pw = getPassword("Enter the password for the presale key: ")); });
+ keyManager().import(k.secret(), m_name, pw, "Same password as used for presale key");
+ break;
+ }
+ case OperationMode::List:
+ {
+ vector bare;
+ AddressHash got;
+
+ for (auto const& u: keyManager().store().keys())
+ if (Address a = keyManager().address(u))
+ {
+ got.insert(a);
+ cout << toUUID(u) << " " << a.abridged();
+ string s = ICAP(a).encoded();
+ cout << " " << s << string(35 - s.size(), ' ');
+ cout << " " << keyManager().accountName(a) << endl;
+ }
+ else
+ bare.push_back(u);
+ for (auto const& a: keyManager().accounts())
+ if (!got.count(a))
+ {
+ cout << " (Brain) " << a.abridged();
+ cout << " " << ICAP(a).encoded() << " ";
+ cout << " " << keyManager().accountName(a) << endl;
+ }
+ for (auto const& u: bare)
+ cout << toUUID(u) << " (Bare)" << endl;
+ }
+ default: break;
}
}
@@ -544,6 +573,12 @@ public:
<< " --import-with-address [||] Import keys from given source with given address and place in wallet." << endl
<< " -e,--export [ | , ... ] Export given keys." << endl
<< " -r,--recode [ || , ... ] Decrypt and re-encrypt given keys." << endl
+ << "Brain wallet operating modes:" << endl
+ << "WARNING: Brain wallets with human-generated passphrasses are highly susceptible to attack. Don't use such a thing for" << endl
+ << "anything important." << endl
+ << " --new-brain [ |-- ] Create a new 13-word brain wallet; argument is the name or if --, do not add to wallet."<< endl
+ << " --import-brain Import your own brain wallet." << endl
+ << " --inspect-brain Check the address of a particular brain wallet." << endl
<< "Wallet configuration:" << endl
<< " --create-wallet Create an Ethereum master wallet." << endl
<< " --wallet-path Specify Ethereum wallet path (default: " << KeyManager::defaultPath() << ")" << endl
@@ -551,7 +586,7 @@ public:
<< endl
<< "Transaction operating modes:" << endl
<< " -d,--decode-tx [|] Decode given transaction." << endl
- << " -s,--sign-tx [ || ] [ | , ... ] (Re-)Sign given transaction." << endl
+ << " -s,--sign-tx [ |||brain(:) ] [ | , ... ] (Re-)Sign given transaction." << endl
<< endl
<< "Encryption configuration:" << endl
<< " --kdf Specify KDF to use when encrypting (default: sc rypt)" << endl
@@ -613,6 +648,35 @@ private:
KDF kdf() const { return m_kdf == "pbkdf2" ? KDF::PBKDF2_SHA256 : KDF::Scrypt; }
+ KeyManager& keyManager()
+ {
+ if (!m_keyManager)
+ {
+ m_keyManager.reset(new KeyManager(m_walletPath, m_secretsPath));
+ if (m_keyManager->exists())
+ openWallet(*m_keyManager);
+ else
+ {
+ cerr << "Couldn't open wallet. Does it exist?" << endl;
+ exit(-1);
+ }
+ }
+ return *m_keyManager;
+ }
+
+ SecretStore& secretStore()
+ {
+ if (m_keyManager)
+ return m_keyManager->store();
+ if (!m_secretStore)
+ m_secretStore.reset(new SecretStore(m_secretsPath));
+ return *m_secretStore;
+ }
+
+ /// Where the keys are.
+ unique_ptr m_secretStore;
+ unique_ptr m_keyManager;
+
/// Operating mode.
OperationMode m_mode;