Gav Wood
10 years ago
9 changed files with 511 additions and 207 deletions
@ -0,0 +1,128 @@ |
|||
/*
|
|||
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 AllAccounts.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "AllAccounts.h" |
|||
#include <sstream> |
|||
#include <QClipboard> |
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libevmcore/Instruction.h> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_AllAccounts.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
AllAccounts::AllAccounts(MainFace* _m): |
|||
Plugin(_m, "AllAccounts"), |
|||
m_ui(new Ui::AllAccounts) |
|||
{ |
|||
dock(Qt::RightDockWidgetArea, "All Accounts")->setWidget(new QWidget()); |
|||
m_ui->setupUi(dock()->widget()); |
|||
installWatches(); |
|||
refresh(); |
|||
|
|||
connect(m_ui->accounts, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SLOT(on_accounts_currentItemChanged())); |
|||
connect(m_ui->accounts, SIGNAL(doubleClicked(QModelIndex)), SLOT(on_accounts_doubleClicked())); |
|||
connect(m_ui->refreshAccounts, SIGNAL(clicked()), SLOT(refresh())); |
|||
connect(m_ui->accountsFilter, SIGNAL(textChanged(QString)), SLOT(onAllChange())); |
|||
connect(m_ui->showBasic, SIGNAL(toggled(bool)), SLOT(onAllChange())); |
|||
connect(m_ui->showContracts, SIGNAL(toggled(bool)), SLOT(onAllChange())); |
|||
connect(m_ui->onlyNamed, SIGNAL(toggled(bool)), SLOT(onAllChange())); |
|||
} |
|||
|
|||
AllAccounts::~AllAccounts() |
|||
{ |
|||
} |
|||
|
|||
void AllAccounts::installWatches() |
|||
{ |
|||
main()->installWatch(ChainChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); |
|||
main()->installWatch(PendingChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); |
|||
} |
|||
|
|||
void AllAccounts::refresh() |
|||
{ |
|||
DEV_TIMED_FUNCTION; |
|||
#if ETH_FATDB || !ETH_TRUE |
|||
cwatch << "refreshAccounts()"; |
|||
m_ui->accounts->clear(); |
|||
bool showContract = m_ui->showContracts->isChecked(); |
|||
bool showBasic = m_ui->showBasic->isChecked(); |
|||
bool onlyNamed = m_ui->onlyNamed->isChecked(); |
|||
for (auto const& i: ethereum()->addresses()) |
|||
{ |
|||
bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3); |
|||
if (!((showContract && isContract) || (showBasic && !isContract))) |
|||
continue; |
|||
string r = static_cast<Context*>(main())->render(i); |
|||
if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE")) |
|||
continue; |
|||
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), m_ui->accounts)) |
|||
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); |
|||
} |
|||
#endif |
|||
m_ui->refreshAccounts->setEnabled(false); |
|||
} |
|||
|
|||
void AllAccounts::onAllChange() |
|||
{ |
|||
m_ui->refreshAccounts->setEnabled(true); |
|||
} |
|||
|
|||
void AllAccounts::on_accounts_currentItemChanged() |
|||
{ |
|||
m_ui->accountInfo->clear(); |
|||
if (auto item = m_ui->accounts->currentItem()) |
|||
{ |
|||
auto hba = item->data(Qt::UserRole).toByteArray(); |
|||
assert(hba.size() == 20); |
|||
auto address = h160((byte const*)hba.data(), h160::ConstructFromPointer); |
|||
|
|||
stringstream s; |
|||
try |
|||
{ |
|||
auto storage = ethereum()->storageAt(address); |
|||
for (auto const& i: storage) |
|||
s << "@" << showbase << hex << main()->prettyU256(i.first) << " " << showbase << hex << main()->prettyU256(i.second) << "<br/>"; |
|||
s << "<h4>Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")</h4>" << disassemble(ethereum()->codeAt(address)); |
|||
s << ETH_HTML_DIV(ETH_HTML_MONO) << toHex(ethereum()->codeAt(address)) << "</div>"; |
|||
m_ui->accountInfo->appendHtml(QString::fromStdString(s.str())); |
|||
} |
|||
catch (dev::InvalidTrie) |
|||
{ |
|||
m_ui->accountInfo->appendHtml("Corrupted trie."); |
|||
} |
|||
m_ui->accountInfo->moveCursor(QTextCursor::Start); |
|||
} |
|||
} |
|||
|
|||
void AllAccounts::on_accounts_doubleClicked() |
|||
{ |
|||
if (m_ui->accounts->count()) |
|||
{ |
|||
auto hba = m_ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); |
|||
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); |
|||
qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,59 @@ |
|||
/*
|
|||
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 AllAccounts.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QListWidget> |
|||
#include <QPlainTextEdit> |
|||
#include "MainFace.h" |
|||
|
|||
namespace Ui |
|||
{ |
|||
class AllAccounts; |
|||
} |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class AllAccounts: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
AllAccounts(MainFace* _m); |
|||
~AllAccounts(); |
|||
|
|||
private slots: |
|||
void on_accounts_currentItemChanged(); |
|||
void on_accounts_doubleClicked(); |
|||
|
|||
void onAllChange(); |
|||
void refresh(); |
|||
private: |
|||
void installWatches(); |
|||
|
|||
Ui::AllAccounts* m_ui; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,134 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>AllAccounts</class> |
|||
<widget class="QWidget" name="AllAccounts"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>400</width> |
|||
<height>300</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Form</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<property name="spacing"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="leftMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="topMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="rightMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="bottomMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
<item> |
|||
<layout class="QHBoxLayout" name="horizontalLayout_12"> |
|||
<item> |
|||
<widget class="QLineEdit" name="accountsFilter"> |
|||
<property name="placeholderText"> |
|||
<string>Filter...</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="showBasic"> |
|||
<property name="text"> |
|||
<string>Basic</string> |
|||
</property> |
|||
<property name="checkable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="showContracts"> |
|||
<property name="text"> |
|||
<string>Contracts</string> |
|||
</property> |
|||
<property name="checkable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="onlyNamed"> |
|||
<property name="text"> |
|||
<string>Only Named</string> |
|||
</property> |
|||
<property name="checkable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="refreshAccounts"> |
|||
<property name="text"> |
|||
<string>Refresh</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
<item> |
|||
<widget class="QSplitter" name="splitter_3"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="orientation"> |
|||
<enum>Qt::Horizontal</enum> |
|||
</property> |
|||
<widget class="QListWidget" name="accounts"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="focusPolicy"> |
|||
<enum>Qt::NoFocus</enum> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
</widget> |
|||
<widget class="QPlainTextEdit" name="accountInfo"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>2</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="focusPolicy"> |
|||
<enum>Qt::WheelFocus</enum> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
@ -0,0 +1,71 @@ |
|||
/*
|
|||
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 MainFace.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "MainFace.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
|
|||
Plugin::Plugin(MainFace* _f, std::string const& _name): |
|||
m_main(_f), |
|||
m_name(_name) |
|||
{ |
|||
_f->adoptPlugin(this); |
|||
} |
|||
|
|||
QDockWidget* Plugin::dock(Qt::DockWidgetArea _area, QString _title) |
|||
{ |
|||
if (_title.isEmpty()) |
|||
_title = QString::fromStdString(m_name); |
|||
if (!m_dock) |
|||
{ |
|||
m_dock = new QDockWidget(_title, m_main); |
|||
m_main->addDockWidget(_area, m_dock); |
|||
m_dock->setFeatures(QDockWidget::AllDockWidgetFeatures | QDockWidget::DockWidgetVerticalTitleBar); |
|||
} |
|||
return m_dock; |
|||
} |
|||
|
|||
void Plugin::addToDock(Qt::DockWidgetArea _area, QDockWidget* _dockwidget, Qt::Orientation _orientation) |
|||
{ |
|||
m_main->addDockWidget(_area, _dockwidget, _orientation); |
|||
} |
|||
|
|||
void Plugin::addAction(QAction* _a) |
|||
{ |
|||
m_main->addAction(_a); |
|||
} |
|||
|
|||
void MainFace::adoptPlugin(Plugin* _p) |
|||
{ |
|||
m_plugins[_p->name()] = shared_ptr<Plugin>(_p); |
|||
} |
|||
|
|||
void MainFace::killPlugins() |
|||
{ |
|||
m_plugins.clear(); |
|||
} |
|||
|
|||
void MainFace::allChange() |
|||
{ |
|||
for (auto const& p: m_plugins) |
|||
p.second->onAllChange(); |
|||
} |
@ -0,0 +1,97 @@ |
|||
/*
|
|||
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 MainFace.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <map> |
|||
#include <string> |
|||
#include <functional> |
|||
#include <QtWidgets/QMainWindow> |
|||
#include <QtWidgets/QAction> |
|||
#include <QtWidgets/QDockWidget> |
|||
#include <libevm/ExtVMFace.h> |
|||
#include "Context.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
class WebThreeDirect; |
|||
namespace eth { class Client; class LogFilter; } |
|||
namespace shh { class WhisperHost; } |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
class Plugin; |
|||
|
|||
using WatchHandler = std::function<void(dev::eth::LocalisedLogEntries const&)>; |
|||
|
|||
class MainFace: public QMainWindow, public Context |
|||
{ |
|||
public: |
|||
explicit MainFace(QWidget* _parent = nullptr): QMainWindow(_parent) {} |
|||
|
|||
void adoptPlugin(Plugin* _p); |
|||
void killPlugins(); |
|||
|
|||
void allChange(); |
|||
|
|||
// TODO: tidy - all should be references that throw if module unavailable.
|
|||
// TODO: provide a set of available web3 modules.
|
|||
virtual dev::WebThreeDirect* web3() const = 0; |
|||
virtual dev::eth::Client* ethereum() const = 0; |
|||
virtual std::shared_ptr<dev::shh::WhisperHost> whisper() const = 0; |
|||
|
|||
virtual unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f) = 0; |
|||
virtual unsigned installWatch(dev::h256 const& _tf, WatchHandler const& _f) = 0; |
|||
|
|||
private: |
|||
std::unordered_map<std::string, std::shared_ptr<Plugin>> m_plugins; |
|||
}; |
|||
|
|||
class Plugin |
|||
{ |
|||
public: |
|||
Plugin(MainFace* _f, std::string const& _name); |
|||
virtual ~Plugin() {} |
|||
|
|||
std::string const& name() const { return m_name; } |
|||
|
|||
dev::WebThreeDirect* web3() const { return m_main->web3(); } |
|||
dev::eth::Client* ethereum() const { return m_main->ethereum(); } |
|||
std::shared_ptr<dev::shh::WhisperHost> whisper() const { return m_main->whisper(); } |
|||
MainFace* main() { return m_main; } |
|||
QDockWidget* dock(Qt::DockWidgetArea _area = Qt::RightDockWidgetArea, QString _title = QString()); |
|||
void addToDock(Qt::DockWidgetArea _area, QDockWidget* _dockwidget, Qt::Orientation _orientation); |
|||
void addAction(QAction* _a); |
|||
|
|||
virtual void onAllChange() {} |
|||
|
|||
private: |
|||
MainFace* m_main = nullptr; |
|||
std::string m_name; |
|||
QDockWidget* m_dock = nullptr; |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
Loading…
Reference in new issue