Browse Source

Merge pull request #1767 from arkpar/mix_state_io

State export/import
cl-refactor
Gav Wood 10 years ago
parent
commit
938a70c725
  1. 3
      alethzero/CMakeLists.txt
  2. 183
      alethzero/ExportState.cpp
  3. 57
      alethzero/ExportState.h
  4. 183
      alethzero/ExportState.ui
  5. 7
      alethzero/Main.ui
  6. 7
      alethzero/MainWin.cpp
  7. 1
      alethzero/MainWin.h
  8. 45
      mix/ClientModel.cpp
  9. 5
      mix/ClientModel.h
  10. 18
      mix/MixClient.cpp
  11. 4
      mix/MixClient.h
  12. 425
      mix/qml/StateDialog.qml
  13. 15
      mix/qml/StateListModel.qml
  14. 30
      test/libweb3jsonrpc/webthreestubclient.h
  15. 626
      test/webthreestubclient.h

3
alethzero/CMakeLists.txt

@ -22,6 +22,7 @@ qt5_wrap_ui(ui_Main.h Main.ui)
qt5_wrap_ui(ui_Connect.h Connect.ui) qt5_wrap_ui(ui_Connect.h Connect.ui)
qt5_wrap_ui(ui_Debugger.h Debugger.ui) qt5_wrap_ui(ui_Debugger.h Debugger.ui)
qt5_wrap_ui(ui_Transact.h Transact.ui) qt5_wrap_ui(ui_Transact.h Transact.ui)
qt5_wrap_ui(ui_ExportState.h ExportState.ui)
file(GLOB HEADERS "*.h") file(GLOB HEADERS "*.h")
@ -34,7 +35,7 @@ endif ()
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake # eth_add_executable is defined in cmake/EthExecutableHelper.cmake
eth_add_executable(${EXECUTABLE} eth_add_executable(${EXECUTABLE}
ICON alethzero ICON alethzero
UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui
WIN_RESOURCES alethzero.rc WIN_RESOURCES alethzero.rc
) )

183
alethzero/ExportState.cpp

@ -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();
}

57
alethzero/ExportState.h

@ -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;
};

183
alethzero/ExportState.ui

@ -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>&amp;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>&amp;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>&amp;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>&amp;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>&amp;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>&amp;Close</string>
</property>
<property name="shortcut">
<string>Esc</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

7
alethzero/Main.ui

@ -160,6 +160,8 @@
<addaction name="killAccount"/> <addaction name="killAccount"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="loadJS"/> <addaction name="loadJS"/>
<addaction name="separator"/>
<addaction name="exportState"/>
</widget> </widget>
<widget class="QMenu" name="menu_Help"> <widget class="QMenu" name="menu_Help">
<property name="title"> <property name="title">
@ -1478,6 +1480,11 @@ font-size: 14pt</string>
<string>&amp;Load Javascript...</string> <string>&amp;Load Javascript...</string>
</property> </property>
</action> </action>
<action name="exportState">
<property name="text">
<string>&amp;Export State...</string>
</property>
</action>
<action name="debugStepBack"> <action name="debugStepBack">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>

7
alethzero/MainWin.cpp

@ -72,6 +72,7 @@
#include "DappLoader.h" #include "DappLoader.h"
#include "DappHost.h" #include "DappHost.h"
#include "WebPage.h" #include "WebPage.h"
#include "ExportState.h"
#include "ui_Main.h" #include "ui_Main.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -820,6 +821,12 @@ void Main::on_exportKey_triggered()
} }
} }
void Main::on_exportState_triggered()
{
ExportStateDialog dialog(this);
dialog.exec();
}
void Main::on_usePrivate_triggered() void Main::on_usePrivate_triggered()
{ {
if (ui->usePrivate->isChecked()) if (ui->usePrivate->isChecked())

1
alethzero/MainWin.h

@ -134,6 +134,7 @@ private slots:
// Tools // Tools
void on_newTransaction_triggered(); void on_newTransaction_triggered();
void on_loadJS_triggered(); void on_loadJS_triggered();
void on_exportState_triggered();
// Stuff concerning the blocks/transactions/accounts panels // Stuff concerning the blocks/transactions/accounts panels
void ourAccountsRowsMoved(); void ourAccountsRowsMoved();

45
mix/ClientModel.cpp

@ -85,7 +85,7 @@ ClientModel::ClientModel():
connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection); connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection);
m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString())); m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString()));
m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), m_client->userAccounts(), m_client.get())); m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector<KeyPair>(), m_client.get()));
connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection); connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection);
} }
@ -169,14 +169,41 @@ QVariantMap ClientModel::gasCosts() const
void ClientModel::setupState(QVariantMap _state) void ClientModel::setupState(QVariantMap _state)
{ {
QVariantList balances = _state.value("accounts").toList(); QVariantList stateAccounts = _state.value("accounts").toList();
QVariantList stateContracts = _state.value("contracts").toList();
QVariantList transactions = _state.value("transactions").toList(); QVariantList transactions = _state.value("transactions").toList();
map<Secret, u256> accounts; map<Address, Account> accounts;
for (auto const& b: balances) std::vector<KeyPair> userAccounts;
for (auto const& b: stateAccounts)
{
QVariantMap account = b.toMap();
Address address = {};
if (account.contains("secret"))
{
KeyPair key(Secret(account.value("secret").toString().toStdString()));
userAccounts.push_back(key);
address = key.address();
}
else if (account.contains("address"))
address = Address(fromHex(account.value("address").toString().toStdString()));
if (!address)
continue;
accounts[address] = Account(qvariant_cast<QEther*>(account.value("balance"))->toU256Wei(), Account::NormalCreation);
}
for (auto const& c: stateContracts)
{ {
QVariantMap address = b.toMap(); QVariantMap contract = c.toMap();
accounts.insert(make_pair(Secret(address.value("secret").toString().toStdString()), (qvariant_cast<QEther*>(address.value("balance")))->toU256Wei())); Address address = Address(fromHex(contract.value("address").toString().toStdString()));
Account account(qvariant_cast<QEther*>(contract.value("balance"))->toU256Wei(), Account::ContractConception);
bytes code = fromHex(contract.value("code").toString().toStdString());
account.setCode(code);
QVariantMap storageMap = contract.value("storage").toMap();
for(auto s = storageMap.cbegin(); s != storageMap.cend(); ++s)
account.setStorage(fromBigEndian<u256>(fromHex(s.key().toStdString())), fromBigEndian<u256>(fromHex(s.value().toString().toStdString())));
accounts[address] = account;
} }
vector<TransactionSettings> transactionSequence; vector<TransactionSettings> transactionSequence;
@ -215,10 +242,11 @@ void ClientModel::setupState(QVariantMap _state)
transactionSequence.push_back(transactionSettings); transactionSequence.push_back(transactionSettings);
} }
} }
m_web3Server->setAccounts(userAccounts);
executeSequence(transactionSequence, accounts, Secret(_state.value("miner").toMap().value("secret").toString().toStdString())); executeSequence(transactionSequence, accounts, Secret(_state.value("miner").toMap().value("secret").toString().toStdString()));
} }
void ClientModel::executeSequence(vector<TransactionSettings> const& _sequence, map<Secret, u256> const& _balances, Secret const& _miner) void ClientModel::executeSequence(vector<TransactionSettings> const& _sequence, std::map<Address, Account> const& _accounts, Secret const& _miner)
{ {
if (m_running) if (m_running)
{ {
@ -230,8 +258,7 @@ void ClientModel::executeSequence(vector<TransactionSettings> const& _sequence,
emit runStarted(); emit runStarted();
emit runStateChanged(); emit runStateChanged();
m_client->resetState(_balances, _miner); m_client->resetState(_accounts, _miner);
m_web3Server->setAccounts(m_client->userAccounts());
//run sequence //run sequence
m_runFuture = QtConcurrent::run([=]() m_runFuture = QtConcurrent::run([=]()
{ {

5
mix/ClientModel.h

@ -32,6 +32,9 @@
namespace dev namespace dev
{ {
namespace eth { class Account; }
namespace mix namespace mix
{ {
@ -209,7 +212,7 @@ private:
RecordLogEntry* lastBlock() const; RecordLogEntry* lastBlock() const;
QVariantMap contractAddresses() const; QVariantMap contractAddresses() const;
QVariantMap gasCosts() const; QVariantMap gasCosts() const;
void executeSequence(std::vector<TransactionSettings> const& _sequence, std::map<Secret, u256> const& _balances, Secret const& _miner); void executeSequence(std::vector<TransactionSettings> const& _sequence, std::map<Address, dev::eth::Account> const& _accounts, Secret const& _miner);
dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings());
void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr);
void onNewTransaction(); void onNewTransaction();

18
mix/MixClient.cpp

@ -39,7 +39,6 @@ namespace dev
namespace mix namespace mix
{ {
Secret const c_defaultUserAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074");
u256 const c_mixGenesisDifficulty = 131072; //TODO: make it lower for Mix somehow u256 const c_mixGenesisDifficulty = 131072; //TODO: make it lower for Mix somehow
namespace namespace
@ -69,16 +68,14 @@ bytes MixBlockChain::createGenesisBlock(h256 _stateRoot)
MixClient::MixClient(std::string const& _dbPath): MixClient::MixClient(std::string const& _dbPath):
m_dbPath(_dbPath) m_dbPath(_dbPath)
{ {
std::map<Secret, u256> account; resetState(std::map<Address, Account>());
account.insert(std::make_pair(c_defaultUserAccountSecret, 1000000 * ether));
resetState(account);
} }
MixClient::~MixClient() MixClient::~MixClient()
{ {
} }
void MixClient::resetState(std::map<Secret, u256> _accounts, Secret _miner) void MixClient::resetState(std::map<Address, Account> const& _accounts, Secret const& _miner)
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
Guard fl(x_filtersWatches); Guard fl(x_filtersWatches);
@ -89,16 +86,7 @@ void MixClient::resetState(std::map<Secret, u256> _accounts, Secret _miner)
SecureTrieDB<Address, MemoryDB> accountState(&m_stateDB); SecureTrieDB<Address, MemoryDB> accountState(&m_stateDB);
accountState.init(); accountState.init();
m_userAccounts.clear(); dev::eth::commit(_accounts, static_cast<MemoryDB&>(m_stateDB), accountState);
std::map<Address, Account> genesisState;
for (auto account: _accounts)
{
KeyPair a = KeyPair(account.first);
m_userAccounts.push_back(a);
genesisState.insert(std::make_pair(a.address(), Account(account.second, Account::NormalCreation)));
}
dev::eth::commit(genesisState, static_cast<MemoryDB&>(m_stateDB), accountState);
h256 stateRoot = accountState.root(); h256 stateRoot = accountState.root();
m_bc.reset(); m_bc.reset();
m_bc.reset(new MixBlockChain(m_dbPath, stateRoot)); m_bc.reset(new MixBlockChain(m_dbPath, stateRoot));

4
mix/MixClient.h

@ -48,7 +48,7 @@ public:
MixClient(std::string const& _dbPath); MixClient(std::string const& _dbPath);
virtual ~MixClient(); virtual ~MixClient();
/// Reset state to the empty state with given balance. /// Reset state to the empty state with given balance.
void resetState(std::map<Secret, u256> _accounts, Secret _miner = Secret()); void resetState(std::map<dev::Address, dev::eth::Account> const& _accounts, Secret const& _miner = Secret());
void mine(); void mine();
ExecutionResult lastExecution() const; ExecutionResult lastExecution() const;
ExecutionResult execution(unsigned _index) const; ExecutionResult execution(unsigned _index) const;
@ -75,7 +75,6 @@ public:
/// @returns the last mined block information /// @returns the last mined block information
using Interface::blockInfo; // to remove warning about hiding virtual function using Interface::blockInfo; // to remove warning about hiding virtual function
eth::BlockInfo blockInfo() const; eth::BlockInfo blockInfo() const;
std::vector<KeyPair> userAccounts() { return m_userAccounts; }
protected: protected:
/// ClientBase methods /// ClientBase methods
@ -92,7 +91,6 @@ private:
void noteChanged(h256Set const& _filters); void noteChanged(h256Set const& _filters);
dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::Secret const& _secret, dev::u256 const& _gas); dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::Secret const& _secret, dev::u256 const& _gas);
std::vector<KeyPair> m_userAccounts;
eth::State m_state; eth::State m_state;
eth::State m_startState; eth::State m_startState;
OverlayDB m_stateDB; OverlayDB m_stateDB;

425
mix/qml/StateDialog.qml

@ -14,7 +14,7 @@ Dialog {
modality: Qt.ApplicationModal modality: Qt.ApplicationModal
width: 630 width: 630
height: 500 height: 660
title: qsTr("Edit State") title: qsTr("Edit State")
visible: false visible: false
@ -27,6 +27,7 @@ Dialog {
property int stateIndex property int stateIndex
property var stateTransactions: [] property var stateTransactions: []
property var stateAccounts: [] property var stateAccounts: []
property var stateContracts: []
signal accepted signal accepted
StateDialogStyle { StateDialogStyle {
@ -34,63 +35,67 @@ Dialog {
} }
function open(index, item, setDefault) { function open(index, item, setDefault) {
stateIndex = index; stateIndex = index
stateTitle = item.title; stateTitle = item.title
transactionsModel.clear(); transactionsModel.clear()
stateTransactions = []; stateTransactions = []
var transactions = item.transactions; var transactions = item.transactions
for (var t = 0; t < transactions.length; t++) { for (var t = 0; t < transactions.length; t++) {
transactionsModel.append(item.transactions[t]); transactionsModel.append(item.transactions[t])
stateTransactions.push(item.transactions[t]); stateTransactions.push(item.transactions[t])
} }
accountsModel.clear(); accountsModel.clear()
stateAccounts = []; stateAccounts = []
var miner = 0; var miner = 0
for (var k = 0; k < item.accounts.length; k++) for (var k = 0; k < item.accounts.length; k++) {
{ accountsModel.append(item.accounts[k])
accountsModel.append(item.accounts[k]); stateAccounts.push(item.accounts[k])
stateAccounts.push(item.accounts[k]);
if (item.miner && item.accounts[k].name === item.miner.name) if (item.miner && item.accounts[k].name === item.miner.name)
miner = k; miner = k
} }
visible = true; stateContracts = []
isDefault = setDefault; if (item.contracts) {
titleField.focus = true; for (k = 0; k < item.contracts.length; k++) {
defaultCheckBox.enabled = !isDefault; contractsModel.append(item.contracts[k])
comboMiner.model = stateAccounts; stateContracts.push(item.contracts[k])
comboMiner.currentIndex = miner; }
forceActiveFocus(); }
visible = true
isDefault = setDefault
titleField.focus = true
defaultCheckBox.enabled = !isDefault
comboMiner.model = stateAccounts
comboMiner.currentIndex = miner
forceActiveFocus()
} }
function acceptAndClose() { function acceptAndClose() {
close(); close()
accepted(); accepted()
} }
function close() { function close() {
visible = false; visible = false
} }
function getItem() { function getItem() {
var item = { var item = {
title: stateDialog.stateTitle, title: stateDialog.stateTitle,
transactions: [], transactions: stateTransactions,
accounts: [] accounts: stateAccounts,
contracts: stateContracts
} }
item.transactions = stateTransactions; for (var k = 0; k < stateAccounts.length; k++) {
item.accounts = stateAccounts; if (stateAccounts[k].name === comboMiner.currentText) {
for (var k = 0; k < stateAccounts.length; k++) item.miner = stateAccounts[k]
{ break
if (stateAccounts[k].name === comboMiner.currentText)
{
item.miner = stateAccounts[k];
break;
} }
} }
return item; return item
} }
contentItem: Rectangle { contentItem: Rectangle {
@ -106,31 +111,147 @@ Dialog {
ColumnLayout { ColumnLayout {
id: dialogContent id: dialogContent
anchors.top: parent.top anchors.top: parent.top
RowLayout RowLayout {
{
Layout.fillWidth: true Layout.fillWidth: true
DefaultLabel { DefaultLabel {
Layout.preferredWidth: 85 Layout.preferredWidth: 85
text: qsTr("Title") text: qsTr("Title")
} }
DefaultTextField DefaultTextField {
{
id: titleField id: titleField
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
CommonSeparator CommonSeparator {
{
Layout.fillWidth: true Layout.fillWidth: true
} }
RowLayout RowLayout {
{
Layout.fillWidth: true Layout.fillWidth: true
Rectangle Rectangle {
{ Layout.preferredWidth: 85
DefaultLabel {
id: contractsLabel
Layout.preferredWidth: 85
wrapMode: Text.WrapAnywhere
text: qsTr("Genesis\nContracts")
}
Button {
id: importStateButton
anchors.top: contractsLabel.bottom
anchors.topMargin: 10
action: importStateAction
}
Action {
id: importStateAction
tooltip: qsTr("Import genesis state from JSON file")
text: qsTr("Import...")
onTriggered: {
importJsonFileDialog.open()
}
}
FileDialog {
id: importJsonFileDialog
visible: false
title: qsTr("Select State File")
nameFilters: [qsTr("JSON files (*.json)", "All files (*)")]
onAccepted: {
var path = importJsonFileDialog.fileUrl.toString()
var jsonData = fileIo.readFile(path)
if (jsonData) {
var json = JSON.parse(jsonData)
for (var address in json) {
var account = {
address: address,
name: (json[address].name ? json[address].name : address),
balance: QEtherHelper.createEther(json[address].wei, QEther.Wei),
code: json[address].code,
storage: json[address].storage
}
if (account.code) {
contractsModel.append(account)
stateContracts.push(account)
} else {
accountsModel.append(account)
stateAccounts.push(account)
}
}
}
}
}
}
TableView {
id: genesisContractsView
Layout.fillWidth: true
model: contractsModel
headerVisible: false
TableViewColumn {
role: "name"
title: qsTr("Name")
width: 230
delegate: Item {
RowLayout {
height: 25
width: parent.width
anchors.verticalCenter: parent.verticalCenter
Button {
iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteContractAction
}
Action {
id: deleteContractAction
tooltip: qsTr("Delete Contract")
onTriggered: {
stateContracts.splice(styleData.row, 1)
contractsModel.remove(styleData.row)
}
}
DefaultTextField {
anchors.verticalCenter: parent.verticalCenter
onTextChanged: {
if (styleData.row > -1)
stateContracts[styleData.row].name = text
}
text: styleData.value
}
}
}
}
TableViewColumn {
role: "balance"
title: qsTr("Balance")
width: 200
delegate: Item {
Ether {
edit: true
displayFormattedValue: false
value: styleData.value
}
}
}
rowDelegate: Rectangle {
color: styleData.alternate ? "transparent" : "#f0f0f0"
height: 30
}
}
}
CommonSeparator {
Layout.fillWidth: true
}
RowLayout {
Layout.fillWidth: true
Rectangle {
Layout.preferredWidth: 85 Layout.preferredWidth: 85
DefaultLabel { DefaultLabel {
id: accountsLabel id: accountsLabel
@ -138,8 +259,7 @@ Dialog {
text: qsTr("Accounts") text: qsTr("Accounts")
} }
Button Button {
{
id: newAccountButton id: newAccountButton
anchors.top: accountsLabel.bottom anchors.top: accountsLabel.bottom
anchors.topMargin: 10 anchors.topMargin: 10
@ -150,31 +270,28 @@ Dialog {
Action { Action {
id: newAccountAction id: newAccountAction
tooltip: qsTr("Add new Account") tooltip: qsTr("Add new Account")
onTriggered: onTriggered: {
{ add()
add();
} }
function add() function add() {
{ var account = stateListModel.newAccount(
var account = stateListModel.newAccount("1000000", QEther.Ether); "1000000", QEther.Ether)
stateAccounts.push(account); stateAccounts.push(account)
accountsModel.append(account); accountsModel.append(account)
return account; return account
} }
} }
} }
MessageDialog MessageDialog {
{
id: alertAlreadyUsed id: alertAlreadyUsed
text: qsTr("This account is in use. You cannot remove it. The first account is used to deploy config contract and cannot be removed.") text: qsTr("This account is in use. You cannot remove it. The first account is used to deploy config contract and cannot be removed.")
icon: StandardIcon.Warning icon: StandardIcon.Warning
standardButtons: StandardButton.Ok standardButtons: StandardButton.Ok
} }
TableView TableView {
{
id: accountsView id: accountsView
Layout.fillWidth: true Layout.fillWidth: true
model: accountsModel model: accountsModel
@ -184,12 +301,10 @@ Dialog {
title: qsTr("Name") title: qsTr("Name")
width: 230 width: 230
delegate: Item { delegate: Item {
RowLayout RowLayout {
{
height: 25 height: 25
width: parent.width width: parent.width
Button Button {
{
iconSource: "qrc:/qml/img/delete_sign.png" iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteAccountAction action: deleteAccountAction
} }
@ -197,18 +312,21 @@ Dialog {
Action { Action {
id: deleteAccountAction id: deleteAccountAction
tooltip: qsTr("Delete Account") tooltip: qsTr("Delete Account")
onTriggered: onTriggered: {
{ if (transactionsModel.isUsed(
if (transactionsModel.isUsed(stateAccounts[styleData.row].secret)) stateAccounts[styleData.row].secret))
alertAlreadyUsed.open(); alertAlreadyUsed.open()
else else {
{ if (stateAccounts[styleData.row].name
if (stateAccounts[styleData.row].name === comboMiner.currentText) === comboMiner.currentText)
comboMiner.currentIndex = 0; comboMiner.currentIndex = 0
stateAccounts.splice(styleData.row, 1); stateAccounts.splice(
accountsModel.remove(styleData.row); styleData.row,
comboMiner.model = stateAccounts; 1)
comboMiner.update(); accountsModel.remove(
styleData.row)
comboMiner.model = stateAccounts //TODO: filter accounts wo private keys
comboMiner.update()
} }
} }
} }
@ -216,12 +334,11 @@ Dialog {
DefaultTextField { DefaultTextField {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
onTextChanged: { onTextChanged: {
if (styleData.row > -1) if (styleData.row > -1) {
{
stateAccounts[styleData.row].name = text stateAccounts[styleData.row].name = text
var index = comboMiner.currentIndex; var index = comboMiner.currentIndex
comboMiner.model = stateAccounts; comboMiner.model = stateAccounts
comboMiner.currentIndex = index; comboMiner.currentIndex = index
} }
} }
text: { text: {
@ -238,28 +355,24 @@ Dialog {
width: 200 width: 200
delegate: Item { delegate: Item {
Ether { Ether {
id: balanceField
edit: true edit: true
displayFormattedValue: false displayFormattedValue: false
value: styleData.value value: styleData.value
} }
} }
} }
rowDelegate: rowDelegate: Rectangle {
Rectangle {
color: styleData.alternate ? "transparent" : "#f0f0f0" color: styleData.alternate ? "transparent" : "#f0f0f0"
height: 30; height: 30
} }
} }
} }
CommonSeparator CommonSeparator {
{
Layout.fillWidth: true Layout.fillWidth: true
} }
RowLayout RowLayout {
{
Layout.fillWidth: true Layout.fillWidth: true
DefaultLabel { DefaultLabel {
Layout.preferredWidth: 85 Layout.preferredWidth: 85
@ -272,13 +385,11 @@ Dialog {
} }
} }
CommonSeparator CommonSeparator {
{
Layout.fillWidth: true Layout.fillWidth: true
} }
RowLayout RowLayout {
{
Layout.fillWidth: true Layout.fillWidth: true
DefaultLabel { DefaultLabel {
Layout.preferredWidth: 85 Layout.preferredWidth: 85
@ -290,17 +401,14 @@ Dialog {
} }
} }
CommonSeparator CommonSeparator {
{
Layout.fillWidth: true Layout.fillWidth: true
} }
RowLayout RowLayout {
{
Layout.fillWidth: true Layout.fillWidth: true
Rectangle Rectangle {
{
Layout.preferredWidth: 85 Layout.preferredWidth: 85
DefaultLabel { DefaultLabel {
id: transactionsLabel id: transactionsLabel
@ -308,8 +416,7 @@ Dialog {
text: qsTr("Transactions") text: qsTr("Transactions")
} }
Button Button {
{
anchors.top: transactionsLabel.bottom anchors.top: transactionsLabel.bottom
anchors.topMargin: 10 anchors.topMargin: 10
iconSource: "qrc:/qml/img/plus.png" iconSource: "qrc:/qml/img/plus.png"
@ -323,8 +430,7 @@ Dialog {
} }
} }
TableView TableView {
{
id: transactionsView id: transactionsView
Layout.fillWidth: true Layout.fillWidth: true
model: transactionsModel model: transactionsModel
@ -334,12 +440,10 @@ Dialog {
title: qsTr("Name") title: qsTr("Name")
width: 150 width: 150
delegate: Item { delegate: Item {
RowLayout RowLayout {
{
height: 30 height: 30
width: parent.width width: parent.width
Button Button {
{
iconSource: "qrc:/qml/img/delete_sign.png" iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteTransactionAction action: deleteTransactionAction
} }
@ -347,20 +451,23 @@ Dialog {
Action { Action {
id: deleteTransactionAction id: deleteTransactionAction
tooltip: qsTr("Delete") tooltip: qsTr("Delete")
onTriggered: transactionsModel.deleteTransaction(styleData.row) onTriggered: transactionsModel.deleteTransaction(
styleData.row)
} }
Button Button {
{
iconSource: "qrc:/qml/img/edit.png" iconSource: "qrc:/qml/img/edit.png"
action: editAction action: editAction
visible: styleData.row >= 0 ? !transactionsModel.get(styleData.row).stdContract : false visible: styleData.row
>= 0 ? !transactionsModel.get(
styleData.row).stdContract : false
width: 10 width: 10
height: 10 height: 10
Action { Action {
id: editAction id: editAction
tooltip: qsTr("Edit") tooltip: qsTr("Edit")
onTriggered: transactionsModel.editTransaction(styleData.row) onTriggered: transactionsModel.editTransaction(
styleData.row)
} }
} }
@ -368,56 +475,63 @@ Dialog {
Layout.preferredWidth: 150 Layout.preferredWidth: 150
text: { text: {
if (styleData.row >= 0) if (styleData.row >= 0)
return transactionsModel.get(styleData.row).functionId; return transactionsModel.get(
styleData.row).functionId
else else
return ""; return ""
} }
} }
} }
} }
} }
rowDelegate: rowDelegate: Rectangle {
Rectangle {
color: styleData.alternate ? "transparent" : "#f0f0f0" color: styleData.alternate ? "transparent" : "#f0f0f0"
height: 30; height: 30
} }
} }
} }
} }
RowLayout RowLayout {
{
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right; anchors.right: parent.right
Button { Button {
text: qsTr("Delete"); text: qsTr("Delete")
enabled: !modalStateDialog.isDefault enabled: !modalStateDialog.isDefault
onClicked: { onClicked: {
projectModel.stateListModel.deleteState(stateIndex); projectModel.stateListModel.deleteState(stateIndex)
close(); close()
} }
} }
Button { Button {
text: qsTr("OK"); text: qsTr("OK")
onClicked: { onClicked: {
close(); close()
accepted(); accepted()
} }
} }
Button { Button {
text: qsTr("Cancel"); text: qsTr("Cancel")
onClicked: close(); onClicked: close()
} }
} }
ListModel { ListModel {
id: accountsModel id: accountsModel
function removeAccount(_i) function removeAccount(_i) {
{ accountsModel.remove(_i)
accountsModel.remove(_i); stateAccounts.splice(_i, 1)
stateAccounts.splice(_i, 1); }
}
ListModel {
id: contractsModel
function removeContract(_i) {
contractsModel.remove(_i)
stateContracts.splice(_i, 1)
} }
} }
@ -425,47 +539,46 @@ Dialog {
id: transactionsModel id: transactionsModel
function editTransaction(index) { function editTransaction(index) {
transactionDialog.stateAccounts = stateAccounts; transactionDialog.stateAccounts = stateAccounts
transactionDialog.open(index, transactionsModel.get(index)); transactionDialog.open(index,
transactionsModel.get(index))
} }
function addTransaction() { function addTransaction() {
// Set next id here to work around Qt bug // Set next id here to work around Qt bug
// https://bugreports.qt-project.org/browse/QTBUG-41327 // https://bugreports.qt-project.org/browse/QTBUG-41327
// Second call to signal handler would just edit the item that was just created, no harm done // Second call to signal handler would just edit the item that was just created, no harm done
var item = TransactionHelper.defaultTransaction(); var item = TransactionHelper.defaultTransaction()
transactionDialog.stateAccounts = stateAccounts; transactionDialog.stateAccounts = stateAccounts
transactionDialog.open(transactionsModel.count, item); transactionDialog.open(transactionsModel.count, item)
} }
function deleteTransaction(index) { function deleteTransaction(index) {
stateTransactions.splice(index, 1); stateTransactions.splice(index, 1)
transactionsModel.remove(index); transactionsModel.remove(index)
} }
function isUsed(secret) function isUsed(secret) {
{ for (var i in stateTransactions) {
for (var i in stateTransactions)
{
if (stateTransactions[i].sender === secret) if (stateTransactions[i].sender === secret)
return true; return true
} }
return false; return false
} }
} }
TransactionDialog TransactionDialog {
{
id: transactionDialog id: transactionDialog
onAccepted: onAccepted: {
{ var item = transactionDialog.getItem()
var item = transactionDialog.getItem();
if (transactionDialog.transactionIndex < transactionsModel.count) { if (transactionDialog.transactionIndex < transactionsModel.count) {
transactionsModel.set(transactionDialog.transactionIndex, item); transactionsModel.set(
stateTransactions[transactionDialog.transactionIndex] = item; transactionDialog.transactionIndex,
item)
stateTransactions[transactionDialog.transactionIndex] = item
} else { } else {
transactionsModel.append(item); transactionsModel.append(item)
stateTransactions.push(item); stateTransactions.push(item)
} }
} }
} }

15
mix/qml/StateListModel.qml

@ -18,10 +18,13 @@ Item {
function fromPlainStateItem(s) { function fromPlainStateItem(s) {
if (!s.accounts) if (!s.accounts)
s.accounts = [stateListModel.newAccount("1000000", QEther.Ether, defaultAccount)]; //support for old project s.accounts = [stateListModel.newAccount("1000000", QEther.Ether, defaultAccount)]; //support for old project
if (!s.contracts)
s.contracts = [];
return { return {
title: s.title, title: s.title,
transactions: s.transactions.map(fromPlainTransactionItem), transactions: s.transactions.map(fromPlainTransactionItem),
accounts: s.accounts.map(fromPlainAccountItem), accounts: s.accounts.map(fromPlainAccountItem),
contracts: s.contracts.map(fromPlainAccountItem),
miner: s.miner miner: s.miner
}; };
} }
@ -30,8 +33,11 @@ Item {
{ {
return { return {
name: t.name, name: t.name,
address: t.address,
secret: t.secret, secret: t.secret,
balance: QEtherHelper.createEther(t.balance.value, t.balance.unit) balance: QEtherHelper.createEther(t.balance.value, t.balance.unit),
storage: t.storage,
code: t.code,
}; };
} }
@ -62,6 +68,7 @@ Item {
title: s.title, title: s.title,
transactions: s.transactions.map(toPlainTransactionItem), transactions: s.transactions.map(toPlainTransactionItem),
accounts: s.accounts.map(toPlainAccountItem), accounts: s.accounts.map(toPlainAccountItem),
contracts: s.contracts.map(toPlainAccountItem),
miner: s.miner miner: s.miner
}; };
} }
@ -85,6 +92,9 @@ Item {
value: t.balance.value, value: t.balance.value,
unit: t.balance.unit unit: t.balance.unit
}, },
address: t.address,
storage: t.storage,
code: t.code,
}; };
} }
@ -190,7 +200,8 @@ Item {
var item = { var item = {
title: "", title: "",
transactions: [], transactions: [],
accounts: [] accounts: [],
contracts: []
}; };
var account = newAccount("1000000", QEther.Ether, defaultAccount) var account = newAccount("1000000", QEther.Ether, defaultAccount)

30
test/libweb3jsonrpc/webthreestubclient.h

@ -476,6 +476,36 @@ class WebThreeStubClient : public jsonrpc::Client
else else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
} }
std::string eth_signTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_signTransaction",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_inspectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_inspectTransaction",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_injectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_injectTransaction",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
{ {
Json::Value p; Json::Value p;

626
test/webthreestubclient.h

@ -1,626 +0,0 @@
/**
* This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY!
*/
#ifndef JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_
#define JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_
#include <jsonrpccpp/client.h>
class WebThreeStubClient : public jsonrpc::Client
{
public:
WebThreeStubClient(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {}
std::string web3_sha3(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("web3_sha3",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string web3_clientVersion() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("web3_clientVersion",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string net_version() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("net_version",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string net_peerCount() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("net_peerCount",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool net_listening() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("net_listening",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_protocolVersion() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_protocolVersion",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_hashrate() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_hashrate",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_coinbase() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_coinbase",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_mining() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_mining",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_gasPrice() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_gasPrice",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_accounts() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_accounts",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_blockNumber() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_blockNumber",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getBalance(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getBalance",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
p.append(param3);
Json::Value result = this->CallMethod("eth_getStorageAt",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getTransactionCount(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getTransactionCount",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getBlockTransactionCountByHash(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getBlockTransactionCountByHash",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getBlockTransactionCountByNumber(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getBlockTransactionCountByNumber",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getUncleCountByBlockHash(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getUncleCountByBlockHash",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getUncleCountByBlockNumber(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getUncleCountByBlockNumber",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_getCode(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getCode",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_sendTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_sendTransaction",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_call(const Json::Value& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_call",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_flush() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_flush",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getBlockByHash(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getBlockByHash",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getBlockByNumber(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getBlockByNumber",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getTransactionByHash(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getTransactionByHash",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getTransactionByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getTransactionByBlockHashAndIndex",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getTransactionByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getTransactionByBlockNumberAndIndex",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getUncleByBlockHashAndIndex",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getUncleByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("eth_getUncleByBlockNumberAndIndex",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getCompilers() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_getCompilers",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_compileLLL(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_compileLLL",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_compileSerpent(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_compileSerpent",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_compileSolidity(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_compileSolidity",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_newFilter",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_newBlockFilter(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_newBlockFilter",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_uninstallFilter",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getFilterChanges",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getFilterLogs(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getFilterLogs",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getLogs(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getLogs",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getWork() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("eth_getWork",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
p.append(param3);
Json::Value result = this->CallMethod("eth_submitWork",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_register(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_register",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_unregister(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_unregister",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_fetchQueuedTransactions(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_fetchQueuedTransactions",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string eth_signTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_signTransaction",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_inspectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_inspectTransaction",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool eth_injectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_injectTransaction",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
p.append(param3);
Json::Value result = this->CallMethod("db_put",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string db_get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("db_get",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool shh_post(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("shh_post",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string shh_newIdentity() throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p = Json::nullValue;
Json::Value result = this->CallMethod("shh_newIdentity",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool shh_hasIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("shh_hasIdentity",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string shh_newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("shh_newGroup",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string shh_addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
p.append(param2);
Json::Value result = this->CallMethod("shh_addToGroup",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
std::string shh_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("shh_newFilter",p);
if (result.isString())
return result.asString();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
bool shh_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("shh_uninstallFilter",p);
if (result.isBool())
return result.asBool();
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value shh_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("shh_getFilterChanges",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value shh_getMessages(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("shh_getMessages",p);
if (result.isArray())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
};
#endif //JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_
Loading…
Cancel
Save