arkpar
10 years ago
14 changed files with 797 additions and 188 deletions
@ -0,0 +1,183 @@ |
|||
/*
|
|||
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 ExportState.cpp
|
|||
* @author Arkadiy Paronyan <arkadiy@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "ExportState.h" |
|||
#include <QFileDialog> |
|||
#include <QTextStream> |
|||
#include <libethereum/Client.h> |
|||
#include "MainWin.h" |
|||
#include "ui_ExportState.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
ExportStateDialog::ExportStateDialog(Main* _parent): |
|||
QDialog(_parent), |
|||
ui(new Ui::ExportState), |
|||
m_main(_parent) |
|||
{ |
|||
ui->setupUi(this); |
|||
connect(ui->close, &QPushButton::clicked, this, &ExportStateDialog::close); |
|||
connect(ui->accounts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); |
|||
connect(ui->contracts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); |
|||
fillBlocks(); |
|||
} |
|||
|
|||
ExportStateDialog::~ExportStateDialog() |
|||
{ |
|||
} |
|||
|
|||
dev::eth::Client* ExportStateDialog::ethereum() const |
|||
{ |
|||
return m_main->ethereum(); |
|||
} |
|||
|
|||
void ExportStateDialog::on_block_editTextChanged() |
|||
{ |
|||
QString text = ui->block->currentText(); |
|||
int i = ui->block->count(); |
|||
while (i-- >= 0) |
|||
if (ui->block->itemText(i) == text) |
|||
return; |
|||
fillBlocks(); |
|||
} |
|||
|
|||
void ExportStateDialog::on_block_currentIndexChanged(int _index) |
|||
{ |
|||
m_block = ui->block->itemData(_index).toUInt(); |
|||
fillContracts(); |
|||
} |
|||
|
|||
void ExportStateDialog::fillBlocks() |
|||
{ |
|||
BlockChain const& bc = ethereum()->blockChain(); |
|||
QStringList filters = ui->block->currentText().toLower().split(QRegExp("\\s+"), QString::SkipEmptyParts); |
|||
const unsigned numLastBlocks = 10; |
|||
if (ui->block->count() == 0) |
|||
{ |
|||
unsigned i = numLastBlocks; |
|||
for (auto h = bc.currentHash(); bc.details(h) && i; h = bc.details(h).parent, --i) |
|||
{ |
|||
auto d = bc.details(h); |
|||
ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); |
|||
if (h == bc.genesisHash()) |
|||
break; |
|||
} |
|||
if (ui->block->currentIndex() < 0) |
|||
ui->block->setCurrentIndex(0); |
|||
m_recentBlocks = numLastBlocks - i; |
|||
} |
|||
|
|||
int i = ui->block->count(); |
|||
while (i > 0 && i >= m_recentBlocks) |
|||
ui->block->removeItem(i--); |
|||
|
|||
h256Set blocks; |
|||
for (QString f: filters) |
|||
{ |
|||
if (f.startsWith("#")) |
|||
f = f.remove(0, 1); |
|||
if (f.size() == 64) |
|||
{ |
|||
h256 h(f.toStdString()); |
|||
if (bc.isKnown(h)) |
|||
blocks.insert(h); |
|||
for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3>(sha3(h)), 0, -1)) |
|||
blocks.insert(bc.numberHash(b)); |
|||
} |
|||
else if (f.toLongLong() <= bc.number()) |
|||
blocks.insert(bc.numberHash((unsigned)f.toLongLong())); |
|||
else if (f.size() == 40) |
|||
{ |
|||
Address h(f.toStdString()); |
|||
for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3>(sha3(h)), 0, -1)) |
|||
blocks.insert(bc.numberHash(b)); |
|||
} |
|||
} |
|||
|
|||
for (auto const& h: blocks) |
|||
{ |
|||
auto d = bc.details(h); |
|||
ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); |
|||
} |
|||
} |
|||
|
|||
void ExportStateDialog::fillContracts() |
|||
{ |
|||
ui->accounts->clear(); |
|||
ui->contracts->clear(); |
|||
ui->accounts->setEnabled(true); |
|||
ui->contracts->setEnabled(true); |
|||
for (auto i: ethereum()->addresses(m_block)) |
|||
{ |
|||
QString r = m_main->render(i); |
|||
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts)) |
|||
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); |
|||
} |
|||
} |
|||
|
|||
void ExportStateDialog::generateJSON() |
|||
{ |
|||
std::stringstream json; |
|||
json << "{\n"; |
|||
std::string prefix; |
|||
for(QListWidgetItem* item: ui->accounts->selectedItems()) |
|||
{ |
|||
auto hba = item->data(Qt::UserRole).toByteArray(); |
|||
auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer); |
|||
json << prefix << "\t\"" << toHex(address.ref()) << "\": { \"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\" }"; |
|||
prefix = ",\n"; |
|||
} |
|||
for(QListWidgetItem* item: ui->contracts->selectedItems()) |
|||
{ |
|||
auto hba = item->data(Qt::UserRole).toByteArray(); |
|||
auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer); |
|||
json << prefix << "\t\"" << toHex(address.ref()) << "\":\n\t{\n\t\t\"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\",\n"; |
|||
json << "\t\t\"code\": \"" << toHex(ethereum()->codeAt(address, m_block)) << "\",\n"; |
|||
std::map<u256, u256> storage = ethereum()->storageAt(address, m_block); |
|||
if (!storage.empty()) |
|||
{ |
|||
json << "\t\t\"storage\":\n\t\t{\n"; |
|||
for (auto s: storage) |
|||
json << "\t\t\t\"" << toHex(s.first) << "\": \"" << toHex(s.second) << "\"" << (s.first == storage.rbegin()->first ? "" : ",") <<"\n"; |
|||
json << "\t\t}\n"; |
|||
} |
|||
json << "\t}"; |
|||
prefix = ",\n"; |
|||
} |
|||
json << "\n}"; |
|||
json.flush(); |
|||
|
|||
ui->json->setEnabled(true); |
|||
ui->json->setText(QString::fromStdString(json.str())); |
|||
ui->saveButton->setEnabled(true); |
|||
} |
|||
|
|||
void ExportStateDialog::on_saveButton_clicked() |
|||
{ |
|||
QString fn = QFileDialog::getSaveFileName(this, "Save state", QString(), "JSON Files (*.json)"); |
|||
if (!fn.endsWith(".json")) |
|||
fn = fn.append(".json"); |
|||
ofstream file(fn.toStdString()); |
|||
if (file.is_open()) |
|||
file << ui->json->toPlainText().toStdString(); |
|||
} |
@ -0,0 +1,57 @@ |
|||
/*
|
|||
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 ExportState.h
|
|||
* @author Arkadiy Paronyan <arkadiy@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <QDialog> |
|||
#include <libethcore/Common.h> |
|||
|
|||
namespace Ui { class ExportState; } |
|||
namespace dev { namespace eth { class Client; } } |
|||
|
|||
class Main; |
|||
|
|||
class ExportStateDialog: public QDialog |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit ExportStateDialog(Main* _parent = 0); |
|||
virtual ~ExportStateDialog(); |
|||
|
|||
private slots: |
|||
void on_block_editTextChanged(); |
|||
void on_block_currentIndexChanged(int _index); |
|||
void on_saveButton_clicked(); |
|||
|
|||
private: |
|||
dev::eth::Client* ethereum() const; |
|||
void fillBlocks(); |
|||
void fillContracts(); |
|||
void generateJSON(); |
|||
|
|||
private: |
|||
std::unique_ptr<Ui::ExportState> ui; |
|||
Main* m_main; |
|||
int m_recentBlocks = 0; |
|||
dev::eth::BlockNumber m_block = dev::eth::LatestBlock; |
|||
}; |
@ -0,0 +1,183 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>ExportState</class> |
|||
<widget class="QDialog" name="ExportState"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>490</width> |
|||
<height>522</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Export State</string> |
|||
</property> |
|||
<property name="modal"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<layout class="QGridLayout" name="gridLayout"> |
|||
<item row="0" column="0"> |
|||
<widget class="QLabel" name="label5"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&Block</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>block</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="0" column="1"> |
|||
<widget class="QComboBox" name="block"> |
|||
<property name="editable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="currentText"> |
|||
<string/> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" column="0"> |
|||
<widget class="QLabel" name="label_7"> |
|||
<property name="text"> |
|||
<string>&Accounts</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>accounts</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" column="1"> |
|||
<widget class="QListWidget" name="accounts"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>1</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="selectionMode"> |
|||
<enum>QAbstractItemView::MultiSelection</enum> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="0"> |
|||
<widget class="QLabel" name="label_6"> |
|||
<property name="text"> |
|||
<string>&Contracts</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>contracts</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="1"> |
|||
<widget class="QListWidget" name="contracts"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>1</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="selectionMode"> |
|||
<enum>QAbstractItemView::MultiSelection</enum> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="0"> |
|||
<widget class="QLabel" name="label_2"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&JSON</string> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>json</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="1"> |
|||
<widget class="QTextEdit" name="json"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>2</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="4" column="1"> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<item> |
|||
<widget class="QPushButton" name="saveButton"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&Save...</string> |
|||
</property> |
|||
<property name="shortcut"> |
|||
<string>Esc</string> |
|||
</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="QPushButton" name="close"> |
|||
<property name="text"> |
|||
<string>&Close</string> |
|||
</property> |
|||
<property name="shortcut"> |
|||
<string>Esc</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
Loading…
Reference in new issue