Browse Source

Compiles and tested basically ok.

cl-refactor
Gav Wood 10 years ago
parent
commit
69328f1dbf
  1. 2
      alethzero/Context.h
  2. 166
      alethzero/MainWin.cpp
  3. 13
      alethzero/MainWin.h
  4. 2
      alethzero/OurWebThreeStubServer.cpp
  5. 23
      alethzero/Transact.cpp
  6. 4
      alethzero/Transact.h

2
alethzero/Context.h

@ -64,5 +64,7 @@ public:
virtual std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const = 0; virtual std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const = 0;
virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0; virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0;
virtual std::string render(dev::Address const& _a) const = 0; virtual std::string render(dev::Address const& _a) const = 0;
virtual dev::Secret retrieveSecret(dev::Address const& _a) const = 0;
}; };

166
alethzero/MainWin.cpp

@ -31,6 +31,7 @@
#include <QtWidgets/QDialog> #include <QtWidgets/QDialog>
#include <QtWidgets/QMessageBox> #include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog> #include <QtWidgets/QInputDialog>
#include <QtWidgets/QListWidgetItem>
#include <QtWebEngine/QtWebEngine> #include <QtWebEngine/QtWebEngine>
#include <QtWebEngineWidgets/QWebEngineView> #include <QtWebEngineWidgets/QWebEngineView>
#include <QtWebEngineWidgets/QWebEngineCallback> #include <QtWebEngineWidgets/QWebEngineCallback>
@ -200,8 +201,6 @@ Main::Main(QWidget *parent) :
ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version));
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
QSettings s("ethereum", "alethzero"); QSettings s("ethereum", "alethzero");
m_networkConfig = s.value("peers").toByteArray(); m_networkConfig = s.value("peers").toByteArray();
bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size());
@ -230,6 +229,7 @@ Main::Main(QWidget *parent) :
// ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true); // ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true);
// QWebEngineInspector* inspector = new QWebEngineInspector(); // QWebEngineInspector* inspector = new QWebEngineInspector();
// inspector->setPage(page); // inspector->setPage(page);
setBeneficiary(*m_keyManager.accounts().begin());
readSettings(); readSettings();
#if !ETH_FATDB #if !ETH_FATDB
removeDockWidget(ui->dockWidget_accounts); removeDockWidget(ui->dockWidget_accounts);
@ -390,9 +390,9 @@ void Main::installBalancesWatch()
// TODO: Update for new currencies reg. // TODO: Update for new currencies reg.
for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, PendingBlock); ++i) for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, PendingBlock); ++i)
altCoins.push_back(right160(ethereum()->stateAt(coinsAddr, i + 1))); altCoins.push_back(right160(ethereum()->stateAt(coinsAddr, i + 1)));
for (auto i: m_myKeys) for (auto const& i: m_keyManager.accounts())
for (auto c: altCoins) for (auto c: altCoins)
tf.address(c).topic(0, h256(i.address(), h256::AlignRight)); tf.address(c).topic(0, h256(i, h256::AlignRight));
uninstallWatch(m_balancesFilter); uninstallWatch(m_balancesFilter);
m_balancesFilter = installWatch(tf, [=](LocalisedLogEntries const&){ onBalancesChange(); }); m_balancesFilter = installWatch(tf, [=](LocalisedLogEntries const&){ onBalancesChange(); });
@ -461,7 +461,7 @@ void Main::load(QString _s)
void Main::on_newTransaction_triggered() void Main::on_newTransaction_triggered()
{ {
m_transact.setEnvironment(m_myKeys, ethereum(), &m_natSpecDB); m_transact.setEnvironment(m_keyManager.accounts(), ethereum(), &m_natSpecDB);
m_transact.exec(); m_transact.exec();
} }
@ -648,17 +648,7 @@ void Main::on_paranoia_triggered()
void Main::writeSettings() void Main::writeSettings()
{ {
QSettings s("ethereum", "alethzero"); QSettings s("ethereum", "alethzero");
{ s.remove("address");
QByteArray b;
b.resize(sizeof(Secret) * m_myKeys.size());
auto p = b.data();
for (auto i: m_myKeys)
{
memcpy(p, &(i.secret()), sizeof(Secret));
p += sizeof(Secret);
}
s.setValue("address", b);
}
{ {
QByteArray b; QByteArray b;
b.resize(sizeof(Secret) * m_myIdentities.size()); b.resize(sizeof(Secret) * m_myIdentities.size());
@ -698,6 +688,20 @@ void Main::writeSettings()
s.setValue("windowState", saveState()); s.setValue("windowState", saveState());
} }
Secret Main::retrieveSecret(Address const& _a) const
{
auto info = m_keyManager.accountDetails()[_a];
while (true)
{
if (Secret s = m_keyManager.secret(_a, [&](){
return QInputDialog::getText(const_cast<Main*>(this), "Import Account Key", QString("Enter the password for the account %2 (%1). The hint is:\n%3").arg(QString::fromStdString(_a.abridged())).arg(QString::fromStdString(info.first)).arg(QString::fromStdString(info.second)), QLineEdit::Password).toStdString();
}))
return s;
else if (QMessageBox::warning(const_cast<Main*>(this), "Incorrect Password", "The password you gave is incorrect for this key.", QMessageBox::Retry, QMessageBox::Cancel) == QMessageBox::Cancel)
return Secret();
}
}
void Main::readSettings(bool _skipGeometry) void Main::readSettings(bool _skipGeometry)
{ {
QSettings s("ethereum", "alethzero"); QSettings s("ethereum", "alethzero");
@ -707,21 +711,17 @@ void Main::readSettings(bool _skipGeometry)
restoreState(s.value("windowState").toByteArray()); restoreState(s.value("windowState").toByteArray());
{ {
m_myKeys.clear();
QByteArray b = s.value("address").toByteArray(); QByteArray b = s.value("address").toByteArray();
if (b.isEmpty()) if (!b.isEmpty())
m_myKeys.append(KeyPair::create());
else
{ {
h256 k; h256 k;
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
{ {
memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret)); memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret));
if (!count(m_myKeys.begin(), m_myKeys.end(), KeyPair(k))) if (!m_keyManager.accounts().count(KeyPair(k).address()))
m_myKeys.append(KeyPair(k)); m_keyManager.import(k, "Imported (UNSAFE) key.");
} }
} }
ethereum()->setAddress(m_myKeys.back().address());
} }
{ {
@ -766,16 +766,38 @@ void Main::readSettings(bool _skipGeometry)
on_urlEdit_returnPressed(); on_urlEdit_returnPressed();
} }
std::string Main::getPassword(std::string const& _title, std::string const& _for)
{
QString password;
while (true)
{
password = QInputDialog::getText(nullptr, QString::fromStdString(_title), QString::fromStdString(_for), QLineEdit::Password, QString());
QString confirm = QInputDialog::getText(nullptr, QString::fromStdString(_title), "Confirm this password by typing it again", QLineEdit::Password, QString());
if (password == confirm)
break;
QMessageBox::warning(nullptr, QString::fromStdString(_title), "You entered two different passwords - please enter the same password twice.", QMessageBox::Ok);
}
return password.toStdString();
}
void Main::on_importKey_triggered() void Main::on_importKey_triggered()
{ {
QString s = QInputDialog::getText(this, "Import Account Key", "Enter account's secret key"); QString s = QInputDialog::getText(this, "Import Account Key", "Enter account's secret key", QLineEdit::Password);
bytes b = fromHex(s.toStdString()); bytes b = fromHex(s.toStdString());
if (b.size() == 32) if (b.size() == 32)
{ {
auto k = KeyPair(h256(b)); auto k = KeyPair(h256(b));
if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) if (!m_keyManager.accounts().count(k.address()))
{ {
m_myKeys.append(k); QString s = QInputDialog::getText(this, "Import Account Key", "Enter this account's name");
if (QMessageBox::question(this, "Additional Security?", "Would you like to use additional security for this key? This lets you protect it with a different password to other keys, but also means you must re-enter the key's password every time you wish to use the account.", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
{
std::string password = getPassword("Import Account Key", "Enter the password you would like to use for this key. Don't forget it!");
std::string hint = QInputDialog::getText(this, "Import Account Key", "Enter a hint to help you remember this password.").toStdString();
m_keyManager.import(k.secret(), s.toStdString(), password, hint);
}
else
m_keyManager.import(k.secret(), s.toStdString());
keysChanged(); keysChanged();
} }
else else
@ -816,15 +838,8 @@ void Main::on_importKeyFile_triggered()
} }
cnote << k.address(); cnote << k.address();
if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) if (!m_keyManager.accounts().count(k.address()))
{ ethereum()->submitTransaction(k.sec(), ethereum()->balanceAt(k.address()) - gasPrice() * c_txGas, m_beneficiary, {}, c_txGas, gasPrice());
if (m_myKeys.empty())
{
m_myKeys.push_back(KeyPair::create());
keysChanged();
}
ethereum()->submitTransaction(k.sec(), ethereum()->balanceAt(k.address()) - gasPrice() * c_txGas, m_myKeys.back().address(), {}, c_txGas, gasPrice());
}
else else
QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account."); QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account.");
} }
@ -843,10 +858,12 @@ void Main::on_importKeyFile_triggered()
void Main::on_exportKey_triggered() void Main::on_exportKey_triggered()
{ {
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) if (ui->ourAccounts->currentRow() >= 0)
{ {
auto k = m_myKeys[ui->ourAccounts->currentRow()]; auto hba = ui->ourAccounts->currentItem()->data(Qt::UserRole).toByteArray();
QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(k.address()) + " is:\n" + toHex(k.sec().ref()))); Address h((byte const*)hba.data(), Address::ConstructFromPointer);
Secret s = retrieveSecret(h);
QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(h) + " is:\n" + s.hex()));
} }
} }
@ -944,6 +961,24 @@ void Main::refreshMining()
*/ */
} }
void Main::setBeneficiary(Address const& _b)
{
for (int i = 0; i < ui->ourAccounts->count(); ++i)
{
auto hba = ui->ourAccounts->item(i)->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
ui->ourAccounts->item(i)->setCheckState(h == _b ? Qt::Checked : Qt::Unchecked);
}
m_beneficiary = _b;
ethereum()->setAddress(_b);
}
void Main::on_ourAccounts_itemClicked(QListWidgetItem* _i)
{
auto hba = _i->data(Qt::UserRole).toByteArray();
setBeneficiary(Address((byte const*)hba.data(), Address::ConstructFromPointer));
}
void Main::refreshBalances() void Main::refreshBalances()
{ {
cwatch << "refreshBalances()"; cwatch << "refreshBalances()";
@ -962,11 +997,13 @@ void Main::refreshBalances()
// cdebug << n << addr << denom << sha3(h256(n).asBytes()); // cdebug << n << addr << denom << sha3(h256(n).asBytes());
altCoins[addr] = make_tuple(fromRaw(n), 0, denom); altCoins[addr] = make_tuple(fromRaw(n), 0, denom);
}*/ }*/
for (auto i: m_myKeys) for (pair<Address, std::pair<std::string, std::string>> const& i: m_keyManager.accountDetails())
{ {
u256 b = ethereum()->balanceAt(i.address()); u256 b = ethereum()->balanceAt(i.first);
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.address()))).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts)) QListWidgetItem* li = new QListWidgetItem(QString("%4 %2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.first))).arg((unsigned)ethereum()->countAt(i.first)).arg(QString::fromStdString(i.second.first)), ui->ourAccounts);
->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size)); li->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size));
li->setFlags(Qt::ItemIsUserCheckable);
li->setCheckState(m_beneficiary == i.first ? Qt::Checked : Qt::Unchecked);
totalBalance += b; totalBalance += b;
// for (auto& c: altCoins) // for (auto& c: altCoins)
@ -1416,20 +1453,6 @@ void Main::on_transactionQueue_currentItemChanged()
ui->pendingInfo->moveCursor(QTextCursor::Start); ui->pendingInfo->moveCursor(QTextCursor::Start);
} }
void Main::ourAccountsRowsMoved()
{
QList<KeyPair> myKeys;
for (int i = 0; i < ui->ourAccounts->count(); ++i)
{
auto hba = ui->ourAccounts->item(i)->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
for (auto i: m_myKeys)
if (i.address() == h)
myKeys.push_back(i);
}
m_myKeys = myKeys;
}
void Main::on_inject_triggered() void Main::on_inject_triggered()
{ {
QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex"); QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex");
@ -1855,7 +1878,7 @@ void Main::on_mine_triggered()
{ {
if (ui->mine->isChecked()) if (ui->mine->isChecked())
{ {
ethereum()->setAddress(m_myKeys.last().address()); ethereum()->setAddress(m_beneficiary);
ethereum()->startMining(); ethereum()->startMining();
} }
else else
@ -1928,24 +1951,39 @@ void Main::on_newAccount_triggered()
t->join(); t->join();
delete t; delete t;
} }
m_myKeys.append(p);
QString s = QInputDialog::getText(this, "Create Account", "Enter this account's name");
if (QMessageBox::question(this, "Create Account", "Would you like to use additional security for this key? This lets you protect it with a different password to other keys, but also means you must re-enter the key's password every time you wish to use the account.", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
{
std::string password = getPassword("Create Account", "Enter the password you would like to use for this key. Don't forget it!");
std::string hint = QInputDialog::getText(this, "Create Account", "Enter a hint to help you remember this password.").toStdString();
m_keyManager.import(p.secret(), s.toStdString(), password, hint);
}
else
m_keyManager.import(p.secret(), s.toStdString());
keysChanged(); keysChanged();
} }
void Main::on_killAccount_triggered() void Main::on_killAccount_triggered()
{ {
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) if (ui->ourAccounts->currentRow() >= 0)
{ {
auto k = m_myKeys[ui->ourAccounts->currentRow()]; auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray();
Address h((byte const*)hba.data(), Address::ConstructFromPointer);
auto k = m_keyManager.accountDetails()[h];
if ( if (
ethereum()->balanceAt(k.address()) != 0 && ethereum()->balanceAt(h) != 0 &&
QMessageBox::critical(this, "Kill Account?!", QMessageBox::critical(this, QString::fromStdString("Kill Account " + k.first + "?!"),
QString::fromStdString("Account " + render(k.address()) + " has " + formatBalance(ethereum()->balanceAt(k.address())) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\n" QString::fromStdString("Account " + k.first + " (" + render(h) + ") has " + formatBalance(ethereum()->balanceAt(h)) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\n"
"Are you sure you want to continue?"), "Are you sure you want to continue?"),
QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
return; return;
m_myKeys.erase(m_myKeys.begin() + ui->ourAccounts->currentRow()); m_keyManager.kill(h);
if (m_keyManager.accounts().empty())
m_keyManager.import(Secret::random(), "Default account");
keysChanged(); keysChanged();
if (m_beneficiary == h)
setBeneficiary(*m_keyManager.accounts().begin());
} }
} }

13
alethzero/MainWin.h

@ -43,6 +43,8 @@
#include "NatspecHandler.h" #include "NatspecHandler.h"
#include "Connect.h" #include "Connect.h"
class QListWidgetItem;
namespace Ui { namespace Ui {
class Main; class Main;
} }
@ -87,12 +89,14 @@ public:
std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const override; std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const override;
std::string renderDiff(dev::eth::StateDiff const& _d) const override; std::string renderDiff(dev::eth::StateDiff const& _d) const override;
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; } QList<dev::KeyPair> owned() const { return m_myIdentities; }
dev::u256 gasPrice() const { return 10 * dev::eth::szabo; } dev::u256 gasPrice() const { return 10 * dev::eth::szabo; }
dev::eth::KeyManager& keyManager() { return m_keyManager; } dev::eth::KeyManager& keyManager() { return m_keyManager; }
dev::Secret retrieveSecret(dev::Address const& _a) const override;
public slots: public slots:
void load(QString _file); void load(QString _file);
void note(QString _entry); void note(QString _entry);
@ -147,7 +151,7 @@ private slots:
void on_exportState_triggered(); void on_exportState_triggered();
// Stuff concerning the blocks/transactions/accounts panels // Stuff concerning the blocks/transactions/accounts panels
void ourAccountsRowsMoved(); void on_ourAccounts_itemClicked(QListWidgetItem* _i);
void on_ourAccounts_doubleClicked(); void on_ourAccounts_doubleClicked();
void on_accounts_doubleClicked(); void on_accounts_doubleClicked();
void on_accounts_currentItemChanged(); void on_accounts_currentItemChanged();
@ -239,6 +243,9 @@ private:
void refreshBlockCount(); void refreshBlockCount();
void refreshBalances(); void refreshBalances();
void setBeneficiary(dev::Address const& _b);
std::string getPassword(std::string const& _title, std::string const& _for);
std::unique_ptr<Ui::Main> ui; std::unique_ptr<Ui::Main> ui;
std::unique_ptr<dev::WebThreeDirect> m_webThree; std::unique_ptr<dev::WebThreeDirect> m_webThree;
@ -250,11 +257,11 @@ private:
QByteArray m_networkConfig; QByteArray m_networkConfig;
QStringList m_servers; QStringList m_servers;
QList<dev::KeyPair> m_myKeys;
QList<dev::KeyPair> m_myIdentities; QList<dev::KeyPair> m_myIdentities;
dev::eth::KeyManager m_keyManager; dev::eth::KeyManager m_keyManager;
QString m_privateChain; QString m_privateChain;
dev::Address m_nameReg; dev::Address m_nameReg;
dev::Address m_beneficiary;
QList<QPair<QString, QString>> m_consoleHistory; QList<QPair<QString, QString>> m_consoleHistory;
QMutex m_logLock; QMutex m_logLock;

2
alethzero/OurWebThreeStubServer.cpp

@ -134,7 +134,7 @@ void OurAccountHolder::doValidations()
queueTransaction(t); queueTransaction(t);
else else
// sign and submit. // sign and submit.
if (Secret s = m_main->keyManager().secret(t.from)) if (Secret s = m_main->retrieveSecret(t.from))
m_web3->ethereum()->submitTransaction(s, t); m_web3->ethereum()->submitTransaction(s, t);
} }
} }

23
alethzero/Transact.cpp

@ -69,9 +69,9 @@ Transact::~Transact()
delete ui; delete ui;
} }
void Transact::setEnvironment(QList<dev::KeyPair> _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB) void Transact::setEnvironment(AddressHash const& _accounts, dev::eth::Client* _eth, NatSpecFace* _natSpecDB)
{ {
m_myKeys = _myKeys; m_accounts = _accounts;
m_ethereum = _eth; m_ethereum = _eth;
m_natSpecDB = _natSpecDB; m_natSpecDB = _natSpecDB;
} }
@ -126,8 +126,8 @@ void Transact::updateFee()
ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str())); ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str()));
bool ok = false; bool ok = false;
for (auto i: m_myKeys) for (auto const& i: m_accounts)
if (ethereum()->balanceAt(i.address()) >= totalReq) if (ethereum()->balanceAt(i) >= totalReq)
{ {
ok = true; ok = true;
break; break;
@ -388,17 +388,20 @@ Secret Transact::findSecret(u256 _totalReq) const
if (!ethereum()) if (!ethereum())
return Secret(); return Secret();
Secret best; Address best;
u256 bestBalance = 0; u256 bestBalance = 0;
for (auto const& i: m_myKeys) for (auto const& i: m_accounts)
{ {
auto b = ethereum()->balanceAt(i.address(), PendingBlock); auto b = ethereum()->balanceAt(i, PendingBlock);
if (b >= _totalReq) if (b >= _totalReq)
return i.secret(); {
best = i;
break;
}
if (b > bestBalance) if (b > bestBalance)
bestBalance = b, best = i.secret(); bestBalance = b, best = i;
} }
return best; return m_context->retrieveSecret(best);
} }
void Transact::on_send_clicked() void Transact::on_send_clicked()

4
alethzero/Transact.h

@ -41,7 +41,7 @@ public:
explicit Transact(Context* _context, QWidget* _parent = 0); explicit Transact(Context* _context, QWidget* _parent = 0);
~Transact(); ~Transact();
void setEnvironment(QList<dev::KeyPair> _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB); void setEnvironment(dev::AddressHash const& _accounts, dev::eth::Client* _eth, NatSpecFace* _natSpecDB);
private slots: private slots:
void on_destination_currentTextChanged(QString); void on_destination_currentTextChanged(QString);
@ -76,7 +76,7 @@ private:
unsigned m_backupGas = 0; unsigned m_backupGas = 0;
dev::bytes m_data; dev::bytes m_data;
QList<dev::KeyPair> m_myKeys; dev::AddressHash m_accounts;
dev::eth::Client* m_ethereum = nullptr; dev::eth::Client* m_ethereum = nullptr;
Context* m_context = nullptr; Context* m_context = nullptr;
NatSpecFace* m_natSpecDB = nullptr; NatSpecFace* m_natSpecDB = nullptr;

Loading…
Cancel
Save