Arkadiy Paronyan
9 years ago
100 changed files with 289 additions and 12854 deletions
@ -1,98 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
# let cmake autolink dependencies on windows |
|||
cmake_policy(SET CMP0020 NEW) |
|||
# this policy was introduced in cmake 3.0 |
|||
# remove if, once 3.0 will be used on unix |
|||
if (${CMAKE_MAJOR_VERSION} GREATER 2) |
|||
cmake_policy(SET CMP0043 OLD) |
|||
endif() |
|||
|
|||
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.6") AND NOT APPLE) |
|||
# Supress warnings for qt headers for clang+ccache |
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override") |
|||
endif () |
|||
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON) |
|||
aux_source_directory(. SRC_LIST) |
|||
file(GLOB_RECURSE SRC_LIST "./plugins/*.cpp") |
|||
file(GLOB_RECURSE HEADERS "./plugins/*.h") |
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
file(GLOB_RECURSE PLUGIN_UI RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/plugins/*.ui") |
|||
foreach(ITEM ${PLUGIN_UI}) |
|||
get_filename_component(UI_NAME ${ITEM} NAME_WE) |
|||
qt5_wrap_ui(ui_${UI_NAME}.h ./${ITEM}) |
|||
endforeach() |
|||
|
|||
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) |
|||
include_directories(BEFORE ..) |
|||
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) |
|||
include_directories(${Boost_INCLUDE_DIRS}) |
|||
|
|||
find_package (Qt5WebEngine) |
|||
find_package (Qt5WebEngineWidgets) |
|||
if (APPLE AND (NOT "${Qt5Core_VERSION_STRING}" VERSION_LESS "5.5")) |
|||
# TODO: remove indirect dependencies once macdeployqt is fixed |
|||
find_package (Qt5WebEngineCore) |
|||
find_package (Qt5DBus) |
|||
find_package (Qt5PrintSupport) |
|||
endif() |
|||
|
|||
qt5_wrap_ui(ui_Main.h Main.ui) |
|||
qt5_wrap_ui(ui_Connect.h Connect.ui) |
|||
qt5_wrap_ui(ui_Debugger.h Debugger.ui) |
|||
qt5_wrap_ui(ui_Transact.h Transact.ui) |
|||
qt5_wrap_ui(ui_GetPassword.h GetPassword.ui) |
|||
qt5_wrap_ui(ui_GasPricing.h GasPricing.ui) |
|||
|
|||
# Extensions |
|||
qt5_wrap_ui(ui_AllAccounts.h AllAccounts.ui) |
|||
|
|||
file(GLOB HEADERS "*.h") |
|||
|
|||
if (APPLE) |
|||
set(EXECUTABLE AlethZero) |
|||
else () |
|||
set(EXECUTABLE alethzero) |
|||
endif () |
|||
|
|||
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake |
|||
eth_add_executable(${EXECUTABLE} |
|||
ICON alethzero |
|||
UI_RESOURCES ${PLUGIN_UI} alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui GetPassword.ui GasPricing.ui |
|||
WIN_RESOURCES alethzero.rc |
|||
) |
|||
|
|||
add_dependencies(${EXECUTABLE} BuildInfo.h) |
|||
|
|||
target_link_libraries(${EXECUTABLE} Qt5::Core) |
|||
target_link_libraries(${EXECUTABLE} Qt5::Widgets) |
|||
target_link_libraries(${EXECUTABLE} Qt5::WebEngine) |
|||
target_link_libraries(${EXECUTABLE} Qt5::WebEngineWidgets) |
|||
if (APPLE AND (NOT "${Qt5Core_VERSION_STRING}" VERSION_LESS "5.5")) |
|||
target_link_libraries(${EXECUTABLE} Qt5::WebEngineCore) |
|||
target_link_libraries(${EXECUTABLE} Qt5::DBus) |
|||
target_link_libraries(${EXECUTABLE} Qt5::PrintSupport) |
|||
endif() |
|||
target_link_libraries(${EXECUTABLE} webthree) |
|||
target_link_libraries(${EXECUTABLE} ethereum) |
|||
target_link_libraries(${EXECUTABLE} evm) |
|||
target_link_libraries(${EXECUTABLE} ethcore) |
|||
target_link_libraries(${EXECUTABLE} devcrypto) |
|||
target_link_libraries(${EXECUTABLE} lll) |
|||
if (SOLIDITY) |
|||
target_link_libraries(${EXECUTABLE} solidity) |
|||
endif () |
|||
target_link_libraries(${EXECUTABLE} evmasm) |
|||
target_link_libraries(${EXECUTABLE} web3jsonrpc) |
|||
target_link_libraries(${EXECUTABLE} jsqrc) |
|||
target_link_libraries(${EXECUTABLE} natspec) |
|||
target_link_libraries(${EXECUTABLE} ${MHD_LIBRARIES}) |
|||
|
|||
if (SERPENT) |
|||
target_link_libraries(${EXECUTABLE} serpent) |
|||
endif() |
|||
|
|||
# eth_install_executable is defined in cmake/EthExecutableHelper.cmake |
|||
eth_install_executable(${EXECUTABLE} DLLS MHD_DLLS EVMJIT_DLLS OpenCL_DLLS) |
|||
|
@ -1,65 +0,0 @@ |
|||
/*
|
|||
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 Connect.cpp
|
|||
* @author Alex Leverington <nessence@gmail.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "Connect.h" |
|||
#include <libp2p/Host.h> |
|||
#include "ui_Connect.h" |
|||
using namespace dev; |
|||
using namespace az; |
|||
|
|||
Connect::Connect(QWidget *parent) : |
|||
QDialog(parent), |
|||
ui(new Ui::Connect) |
|||
{ |
|||
ui->setupUi(this); |
|||
} |
|||
|
|||
Connect::~Connect() |
|||
{ |
|||
delete ui; |
|||
} |
|||
|
|||
void Connect::setEnvironment(QStringList const& _nodes) |
|||
{ |
|||
if (ui->host->count() == 0) |
|||
ui->host->addItems(_nodes); |
|||
} |
|||
|
|||
void Connect::reset() |
|||
{ |
|||
ui->nodeId->clear(); |
|||
ui->required->setChecked(true); |
|||
} |
|||
|
|||
QString Connect::host() |
|||
{ |
|||
return ui->host->currentText(); |
|||
} |
|||
|
|||
QString Connect::nodeId() |
|||
{ |
|||
return ui->nodeId->text(); |
|||
} |
|||
|
|||
bool Connect::required() |
|||
{ |
|||
return ui->required->isChecked(); |
|||
} |
@ -1,65 +0,0 @@ |
|||
/*
|
|||
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 Connect.h
|
|||
* @author Alex Leverington <nessence@gmail.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QDialog> |
|||
#include <QList> |
|||
|
|||
namespace Ui { class Connect; } |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace p2p { class Host; } |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
class Connect: public QDialog |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit Connect(QWidget* _parent = 0); |
|||
~Connect(); |
|||
|
|||
/// Populate host chooser with default host entries.
|
|||
void setEnvironment(QStringList const& _nodes); |
|||
|
|||
/// Clear dialogue inputs.
|
|||
void reset(); |
|||
|
|||
/// @returns the host string, as chosen or entered by the user. Assumed to be "hostOrIP:port" (:port is optional).
|
|||
QString host(); |
|||
|
|||
/// @returns the identity of the node, as entered by the user. Assumed to be a 64-character hex string.
|
|||
QString nodeId(); |
|||
|
|||
/// @returns true if Required is checked by the user, indicating that the host is a required Peer.
|
|||
bool required(); |
|||
|
|||
private: |
|||
Ui::Connect* ui; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,126 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>Connect</class> |
|||
<widget class="QDialog" name="Connect"> |
|||
<property name="windowModality"> |
|||
<enum>Qt::WindowModal</enum> |
|||
</property> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>343</width> |
|||
<height>178</height> |
|||
</rect> |
|||
</property> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>343</width> |
|||
<height>178</height> |
|||
</size> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Connect to Peer</string> |
|||
</property> |
|||
<property name="modal"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<layout class="QFormLayout" name="formLayout_2"> |
|||
<item row="1" column="0"> |
|||
<layout class="QFormLayout" name="formLayout"> |
|||
<item row="1" column="0" colspan="2"> |
|||
<widget class="QComboBox" name="host"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>311</width> |
|||
<height>0</height> |
|||
</size> |
|||
</property> |
|||
<property name="editable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="0" colspan="2"> |
|||
<widget class="QLineEdit" name="nodeId"> |
|||
<property name="placeholderText"> |
|||
<string>Node Id</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="0" colspan="2"> |
|||
<widget class="QCheckBox" name="required"> |
|||
<property name="text"> |
|||
<string>Required (Always Connect to this Peer)</string> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="tristate"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="4" column="0" colspan="2"> |
|||
<widget class="QDialogButtonBox" name="buttonBox"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Horizontal</enum> |
|||
</property> |
|||
<property name="standardButtons"> |
|||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
<item row="0" column="0"> |
|||
<widget class="QLabel" name="formLabel"> |
|||
<property name="text"> |
|||
<string>Enter a peer to which a connection may be made:</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>buttonBox</sender> |
|||
<signal>accepted()</signal> |
|||
<receiver>Connect</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>248</x> |
|||
<y>254</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>157</x> |
|||
<y>274</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>buttonBox</sender> |
|||
<signal>rejected()</signal> |
|||
<receiver>Connect</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>316</x> |
|||
<y>260</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>286</x> |
|||
<y>274</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,83 +0,0 @@ |
|||
/*
|
|||
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 Debugger.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "Context.h" |
|||
#include <QComboBox> |
|||
#include <QSpinBox> |
|||
#include <libethcore/Common.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace eth; |
|||
using namespace az; |
|||
|
|||
NatSpecFace::~NatSpecFace() |
|||
{ |
|||
} |
|||
|
|||
Context::~Context() |
|||
{ |
|||
} |
|||
|
|||
void dev::az::setValueUnits(QComboBox* _units, QSpinBox* _value, u256 _v) |
|||
{ |
|||
initUnits(_units); |
|||
if (_v > 0) |
|||
{ |
|||
_units->setCurrentIndex(0); |
|||
while (_v > 50000 && _units->currentIndex() < (int)(units().size() - 2)) |
|||
{ |
|||
_v /= 1000; |
|||
_units->setCurrentIndex(_units->currentIndex() + 1); |
|||
} |
|||
} |
|||
else |
|||
_units->setCurrentIndex(6); |
|||
_value->setValue((unsigned)_v); |
|||
} |
|||
|
|||
u256 dev::az::fromValueUnits(QComboBox* _units, QSpinBox* _value) |
|||
{ |
|||
return _value->value() * units()[units().size() - 1 - _units->currentIndex()].first; |
|||
} |
|||
|
|||
void dev::az::initUnits(QComboBox* _b) |
|||
{ |
|||
for (auto n = (unsigned)units().size(); n-- != 0; ) |
|||
_b->addItem(QString::fromStdString(units()[n].second), n); |
|||
} |
|||
|
|||
vector<KeyPair> dev::az::keysAsVector(QList<KeyPair> const& keys) |
|||
{ |
|||
auto list = keys.toStdList(); |
|||
return {begin(list), end(list)}; |
|||
} |
|||
|
|||
bool dev::az::sourceIsSolidity(string const& _source) |
|||
{ |
|||
// TODO: Improve this heuristic
|
|||
return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol"); |
|||
} |
|||
|
|||
bool dev::az::sourceIsSerpent(string const& _source) |
|||
{ |
|||
// TODO: Improve this heuristic
|
|||
return (_source.substr(0, 5) == "//ser"); |
|||
} |
@ -1,84 +0,0 @@ |
|||
/*
|
|||
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 Debugger.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <vector> |
|||
#include <QString> |
|||
#include <QList> |
|||
#include <libethcore/Common.h> |
|||
|
|||
class QComboBox; |
|||
class QSpinBox; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth { struct StateDiff; class KeyManager; } |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
#define ETH_HTML_SMALL "font-size: small; " |
|||
#define ETH_HTML_MONO "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; " |
|||
#define ETH_HTML_DIV(S) "<div style=\"" S "\">" |
|||
#define ETH_HTML_SPAN(S) "<span style=\"" S "\">" |
|||
|
|||
void initUnits(QComboBox* _b); |
|||
void setValueUnits(QComboBox* _units, QSpinBox* _value, dev::u256 _v); |
|||
dev::u256 fromValueUnits(QComboBox* _units, QSpinBox* _value); |
|||
|
|||
std::vector<dev::KeyPair> keysAsVector(QList<dev::KeyPair> const& _keys); |
|||
|
|||
bool sourceIsSolidity(std::string const& _source); |
|||
bool sourceIsSerpent(std::string const& _source); |
|||
|
|||
class NatSpecFace |
|||
{ |
|||
public: |
|||
virtual ~NatSpecFace(); |
|||
|
|||
virtual void add(dev::h256 const& _contractHash, std::string const& _doc) = 0; |
|||
virtual std::string retrieve(dev::h256 const& _contractHash) const = 0; |
|||
virtual std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData) = 0; |
|||
virtual std::string getUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionDacta) = 0; |
|||
}; |
|||
|
|||
class Context |
|||
{ |
|||
public: |
|||
virtual ~Context(); |
|||
|
|||
virtual std::string pretty(dev::Address const& _a) const = 0; |
|||
virtual std::string prettyU256(dev::u256 const& _n) const = 0; |
|||
virtual std::pair<dev::Address, dev::bytes> fromString(std::string const& _a) const = 0; |
|||
virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0; |
|||
virtual std::string render(dev::Address const& _a) const = 0; |
|||
virtual dev::Secret retrieveSecret(dev::Address const& _a) const = 0; |
|||
virtual dev::eth::KeyManager& keyManager() = 0; |
|||
virtual void noteKeysChanged() = 0; |
|||
|
|||
virtual dev::u256 gasPrice() const = 0; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,148 +0,0 @@ |
|||
/*
|
|||
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 DappHost.cpp
|
|||
* @author Arkadiy Paronyan <arkadiy@ethdev.org> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "DappHost.h" |
|||
#include <QUrl> |
|||
#include <microhttpd.h> |
|||
#include <boost/algorithm/string.hpp> |
|||
#include <libdevcore/Common.h> |
|||
using namespace dev; |
|||
using namespace az; |
|||
|
|||
DappHost::DappHost(int _port, int _threads): |
|||
m_port(_port), |
|||
m_url(QString("http://localhost:%1/").arg(m_port)), |
|||
m_threads(_threads), |
|||
m_running(false), |
|||
m_daemon(nullptr) |
|||
{ |
|||
startListening(); |
|||
} |
|||
|
|||
DappHost::~DappHost() |
|||
{ |
|||
stopListening(); |
|||
} |
|||
|
|||
void DappHost::startListening() |
|||
{ |
|||
if(!this->m_running) |
|||
{ |
|||
this->m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, this->m_port, nullptr, nullptr, &DappHost::callback, this, MHD_OPTION_THREAD_POOL_SIZE, this->m_threads, MHD_OPTION_END); |
|||
if (this->m_daemon != nullptr) |
|||
this->m_running = true; |
|||
} |
|||
} |
|||
|
|||
void DappHost::stopListening() |
|||
{ |
|||
if(this->m_running) |
|||
{ |
|||
MHD_stop_daemon(this->m_daemon); |
|||
this->m_running = false; |
|||
} |
|||
} |
|||
|
|||
void DappHost::sendOptionsResponse(MHD_Connection* _connection) |
|||
{ |
|||
MHD_Response *result = MHD_create_response_from_data(0, NULL, 0, 1); |
|||
MHD_add_response_header(result, "Allow", "GET, OPTIONS"); |
|||
MHD_add_response_header(result, "Access-Control-Allow-Headers", "origin, content-type, accept"); |
|||
MHD_add_response_header(result, "DAV", "1"); |
|||
MHD_queue_response(_connection, MHD_HTTP_OK, result); |
|||
MHD_destroy_response(result); |
|||
} |
|||
|
|||
void DappHost::sendNotAllowedResponse(MHD_Connection* _connection) |
|||
{ |
|||
MHD_Response *result = MHD_create_response_from_data(0, NULL, 0, 1); |
|||
MHD_add_response_header(result, "Allow", "GET, OPTIONS"); |
|||
MHD_queue_response(_connection, MHD_HTTP_METHOD_NOT_ALLOWED, result); |
|||
MHD_destroy_response(result); |
|||
} |
|||
|
|||
void DappHost::sendResponse(std::string const& _url, MHD_Connection* _connection) |
|||
{ |
|||
QUrl requestUrl(QString::fromStdString(_url)); |
|||
QString path = requestUrl.path().toLower(); |
|||
if (path.isEmpty()) |
|||
path = "/"; |
|||
|
|||
bytesConstRef response; |
|||
unsigned code = MHD_HTTP_NOT_FOUND; |
|||
std::string contentType; |
|||
|
|||
while (!path.isEmpty()) |
|||
{ |
|||
auto iter = m_entriesByPath.find(path); |
|||
if (iter != m_entriesByPath.end()) |
|||
{ |
|||
ManifestEntry const* entry = iter->second; |
|||
auto contentIter = m_dapp.content.find(entry->hash); |
|||
if (contentIter == m_dapp.content.end()) |
|||
break; |
|||
|
|||
response = bytesConstRef(contentIter->second.data(), contentIter->second.size()); |
|||
code = entry->httpStatus != 0 ? entry->httpStatus : MHD_HTTP_OK; |
|||
contentType = entry->contentType; |
|||
break; |
|||
} |
|||
path.truncate(path.length() - 1); |
|||
path = path.mid(0, path.lastIndexOf('/')); |
|||
} |
|||
|
|||
MHD_Response *result = MHD_create_response_from_data(response.size(), const_cast<byte*>(response.data()), 0, 1); |
|||
if (!contentType.empty()) |
|||
MHD_add_response_header(result, "Content-Type", contentType.c_str()); |
|||
MHD_queue_response(_connection, code, result); |
|||
MHD_destroy_response(result); |
|||
} |
|||
|
|||
int DappHost::callback(void* _cls, MHD_Connection* _connection, char const* _url, char const* _method, char const* _version, char const* _uploadData, size_t* _uploadDataSize, void** _conCls) |
|||
{ |
|||
(void)_version; |
|||
(void)_uploadData; |
|||
(void)_uploadDataSize; |
|||
(void)_conCls; |
|||
DappHost* host = static_cast<DappHost*>(_cls); |
|||
if (std::string("GET") == _method) |
|||
host->sendResponse(std::string(_url), _connection); |
|||
else if (std::string("OPTIONS") == _method) |
|||
host->sendOptionsResponse(_connection); |
|||
else |
|||
host->sendNotAllowedResponse(_connection); |
|||
return MHD_YES; |
|||
} |
|||
|
|||
QUrl DappHost::hostDapp(Dapp&& _dapp) |
|||
{ |
|||
m_dapp = std::move(_dapp); |
|||
m_entriesByPath.clear(); |
|||
for (ManifestEntry const& entry: m_dapp.manifest.entries) |
|||
m_entriesByPath[QString::fromStdString(entry.path)] = &entry; |
|||
|
|||
return m_url; |
|||
} |
|||
|
|||
bool DappHost::servesUrl(QUrl const& _url) const |
|||
{ |
|||
return m_url == _url || m_url.isParentOf(_url); |
|||
} |
@ -1,70 +0,0 @@ |
|||
/*
|
|||
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 DappHost.h
|
|||
* @author Arkadiy Paronyan <arkadiy@ethdev.org> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <map> |
|||
#include <QUrl> |
|||
#include <QString> |
|||
#include "DappLoader.h" |
|||
|
|||
struct MHD_Daemon; |
|||
struct MHD_Connection; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
/// DApp web server. Servers web content, resolves paths by hashes
|
|||
class DappHost |
|||
{ |
|||
public: |
|||
/// @param _port Network pork to listen for incoming connections
|
|||
/// @param _threads Max number of threads to process requests
|
|||
DappHost(int _port, int _threads = 10); |
|||
virtual ~DappHost(); |
|||
/// Load and host a dapp. Previsous dapp in discarded. Synchronous
|
|||
QUrl hostDapp(Dapp&& _dapp); |
|||
|
|||
/// @returns true if the given url is served from this DappHost.
|
|||
bool servesUrl(QUrl const& _url) const; |
|||
|
|||
private: |
|||
void startListening(); |
|||
void stopListening(); |
|||
void sendOptionsResponse(MHD_Connection* _connection); |
|||
void sendNotAllowedResponse(MHD_Connection* _connection); |
|||
void sendResponse(std::string const& _url, MHD_Connection* _connection); |
|||
static int callback(void* _cls, MHD_Connection* _connection, char const* _url, char const* _method, char const* _version, char const* _uploadData, size_t* _uploadDataSize, void** _conCls); |
|||
|
|||
int const m_port; |
|||
QUrl const m_url; |
|||
int m_threads; |
|||
bool m_running; |
|||
MHD_Daemon* m_daemon; |
|||
Dapp m_dapp; |
|||
std::map<QString, ManifestEntry const*> m_entriesByPath; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,263 +0,0 @@ |
|||
/*
|
|||
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 DappLoader.cpp
|
|||
* @author Arkadiy Paronyan <arkadiy@ethdev.org> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <algorithm> |
|||
#include <json/json.h> |
|||
#include <QUrl> |
|||
#include <QStringList> |
|||
#include <QNetworkAccessManager> |
|||
#include <QNetworkReply> |
|||
#include <QMimeDatabase> |
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/RLP.h> |
|||
#include <libdevcrypto/CryptoPP.h> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libethcore/CommonJS.h> |
|||
#include <libethereum/Client.h> |
|||
#include <libwebthree/WebThree.h> |
|||
#include "DappLoader.h" |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
using namespace crypto; |
|||
|
|||
namespace dev { namespace az { QString contentsOfQResource(std::string const& res); } } |
|||
|
|||
DappLoader::DappLoader(QObject* _parent, WebThreeDirect* _web3, Address _nameReg): |
|||
QObject(_parent), m_web3(_web3), m_nameReg(_nameReg) |
|||
{ |
|||
connect(&m_net, &QNetworkAccessManager::finished, this, &DappLoader::downloadComplete); |
|||
} |
|||
|
|||
DappLocation DappLoader::resolveAppUri(QString const& _uri) |
|||
{ |
|||
QUrl url(_uri); |
|||
if (!url.scheme().isEmpty() && url.scheme() != "eth") |
|||
throw dev::Exception(); //TODO:
|
|||
|
|||
QStringList parts = url.host().split('.', QString::SkipEmptyParts); |
|||
QStringList domainParts; |
|||
std::reverse(parts.begin(), parts.end()); |
|||
parts.append(url.path().split('/', QString::SkipEmptyParts)); |
|||
|
|||
Address address = m_nameReg; |
|||
Address lastAddress; |
|||
int partIndex = 0; |
|||
|
|||
h256 contentHash; |
|||
while (address && partIndex < parts.length()) |
|||
{ |
|||
lastAddress = address; |
|||
string32 name = ZeroString32; |
|||
QByteArray utf8 = parts[partIndex].toUtf8(); |
|||
std::copy(utf8.data(), utf8.data() + utf8.size(), name.data()); |
|||
if (address != m_nameReg) |
|||
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("subRegistrar(bytes32)", name)).output); |
|||
else |
|||
address = abiOut<Address>(web3()->ethereum()->call(address, abiIn("register(bytes32)", name)).output); |
|||
|
|||
domainParts.append(parts[partIndex]); |
|||
if (!address) |
|||
{ |
|||
//we have the address of the last part, try to get content hash
|
|||
contentHash = abiOut<h256>(web3()->ethereum()->call(lastAddress, abiIn("content(bytes32)", name)).output); |
|||
if (!contentHash) |
|||
throw dev::Exception() << errinfo_comment("Can't resolve address"); |
|||
} |
|||
++partIndex; |
|||
} |
|||
|
|||
string32 urlHintName = ZeroString32; |
|||
QByteArray utf8 = QString("urlhint").toUtf8(); |
|||
std::copy(utf8.data(), utf8.data() + utf8.size(), urlHintName.data()); |
|||
|
|||
Address urlHint = abiOut<Address>(web3()->ethereum()->call(m_nameReg, abiIn("addr(bytes32)", urlHintName)).output); |
|||
string32 contentUrl = abiOut<string32>(web3()->ethereum()->call(urlHint, abiIn("url(bytes32)", contentHash)).output); |
|||
QString domain = domainParts.join('/'); |
|||
parts.erase(parts.begin(), parts.begin() + partIndex); |
|||
QString path = parts.join('/'); |
|||
QString contentUrlString = QString::fromUtf8(std::string(contentUrl.data(), contentUrl.size()).c_str()); |
|||
if (!contentUrlString.startsWith("http://") || !contentUrlString.startsWith("https://")) |
|||
contentUrlString = "http://" + contentUrlString; |
|||
return DappLocation { domain, path, contentUrlString, contentHash }; |
|||
} |
|||
|
|||
void DappLoader::downloadComplete(QNetworkReply* _reply) |
|||
{ |
|||
QUrl requestUrl = _reply->request().url(); |
|||
if (m_pageUrls.count(requestUrl) != 0) |
|||
{ |
|||
//inject web3 js
|
|||
QByteArray content = "<script>\n"; |
|||
content.append(web3Content()); |
|||
content.append(("web3.admin.setSessionKey('" + m_sessionKey + "');").c_str()); |
|||
content.append("</script>\n"); |
|||
content.append(_reply->readAll()); |
|||
QString contentType = _reply->header(QNetworkRequest::ContentTypeHeader).toString(); |
|||
if (contentType.isEmpty()) |
|||
{ |
|||
QMimeDatabase db; |
|||
contentType = db.mimeTypeForUrl(requestUrl).name(); |
|||
} |
|||
pageReady(content, contentType, requestUrl); |
|||
return; |
|||
} |
|||
|
|||
try |
|||
{ |
|||
//try to interpret as rlp
|
|||
QByteArray data = _reply->readAll(); |
|||
_reply->deleteLater(); |
|||
|
|||
h256 expected = m_uriHashes[requestUrl]; |
|||
bytes package(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size())); |
|||
Secp256k1PP dec; |
|||
dec.decrypt(Secret(expected), package); |
|||
h256 got = sha3(package); |
|||
if (got != expected) |
|||
{ |
|||
//try base64
|
|||
data = QByteArray::fromBase64(data); |
|||
package = bytes(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size())); |
|||
dec.decrypt(Secret(expected), package); |
|||
got = sha3(package); |
|||
if (got != expected) |
|||
throw dev::Exception() << errinfo_comment("Dapp content hash does not match"); |
|||
} |
|||
|
|||
RLP rlp(package); |
|||
loadDapp(rlp); |
|||
bytesRef(&package).cleanse(); // TODO: replace with bytesSec once the crypto API is up to it.
|
|||
} |
|||
catch (...) |
|||
{ |
|||
qWarning() << tr("Error downloading DApp: ") << boost::current_exception_diagnostic_information().c_str(); |
|||
emit dappError(); |
|||
} |
|||
|
|||
} |
|||
|
|||
void DappLoader::loadDapp(RLP const& _rlp) |
|||
{ |
|||
Dapp dapp; |
|||
unsigned len = _rlp.itemCountStrict(); |
|||
dapp.manifest = loadManifest(_rlp[0].toString()); |
|||
for (unsigned c = 1; c < len; ++c) |
|||
{ |
|||
bytesConstRef content = _rlp[c].toBytesConstRef(); |
|||
h256 hash = sha3(content); |
|||
auto entry = std::find_if(dapp.manifest.entries.cbegin(), dapp.manifest.entries.cend(), [=](ManifestEntry const& _e) { return _e.hash == hash; }); |
|||
if (entry != dapp.manifest.entries.cend()) |
|||
{ |
|||
if (entry->path == "/deployment.js") |
|||
{ |
|||
//inject web3 code
|
|||
bytes b(web3Content().data(), web3Content().data() + web3Content().size()); |
|||
b.insert(b.end(), content.begin(), content.end()); |
|||
dapp.content[hash] = b; |
|||
} |
|||
else |
|||
dapp.content[hash] = content.toBytes(); |
|||
} |
|||
else |
|||
throw dev::Exception() << errinfo_comment("Dapp content hash does not match"); |
|||
} |
|||
emit dappReady(dapp); |
|||
} |
|||
|
|||
QByteArray const& DappLoader::web3Content() |
|||
{ |
|||
if (m_web3Js.isEmpty()) |
|||
{ |
|||
QString code; |
|||
code += contentsOfQResource(":/js/bignumber.min.js"); |
|||
code += "\n"; |
|||
code += contentsOfQResource(":/js/webthree.js"); |
|||
code += "\n"; |
|||
code += contentsOfQResource(":/js/setup.js"); |
|||
code += "\n"; |
|||
code += contentsOfQResource(":/js/admin.js"); |
|||
code += "\n"; |
|||
m_web3Js = code.toLatin1(); |
|||
} |
|||
return m_web3Js; |
|||
} |
|||
|
|||
Manifest DappLoader::loadManifest(std::string const& _manifest) |
|||
{ |
|||
/// https://github.com/ethereum/go-ethereum/wiki/URL-Scheme
|
|||
Manifest manifest; |
|||
Json::Reader jsonReader; |
|||
Json::Value root; |
|||
jsonReader.parse(_manifest, root, false); |
|||
|
|||
Json::Value entries = root["entries"]; |
|||
for (Json::ValueIterator it = entries.begin(); it != entries.end(); ++it) |
|||
{ |
|||
Json::Value const& entryValue = *it; |
|||
std::string path = entryValue["path"].asString(); |
|||
if (path.size() == 0 || path[0] != '/') |
|||
path = "/" + path; |
|||
std::string contentType = entryValue["contentType"].asString(); |
|||
std::string strHash = entryValue["hash"].asString(); |
|||
if (strHash.length() == 64) |
|||
strHash = "0x" + strHash; |
|||
h256 hash = jsToFixed<32>(strHash); |
|||
unsigned httpStatus = entryValue["status"].asInt(); |
|||
manifest.entries.push_back(ManifestEntry{ path, hash, contentType, httpStatus }); |
|||
} |
|||
return manifest; |
|||
} |
|||
|
|||
void DappLoader::loadDapp(QString const& _uri) |
|||
{ |
|||
QUrl uri(_uri); |
|||
QUrl contentUri; |
|||
h256 hash; |
|||
if (uri.path().endsWith(".dapp") && uri.query().startsWith("hash=")) |
|||
{ |
|||
contentUri = uri; |
|||
QString query = uri.query(); |
|||
query.remove("hash="); |
|||
if (!query.startsWith("0x")) |
|||
query.insert(0, "0x"); |
|||
hash = jsToFixed<32>(query.toStdString()); |
|||
} |
|||
else |
|||
{ |
|||
DappLocation location = resolveAppUri(_uri); |
|||
contentUri = location.contentUri; |
|||
hash = location.contentHash; |
|||
uri = contentUri; |
|||
} |
|||
QNetworkRequest request(contentUri); |
|||
m_uriHashes[uri] = hash; |
|||
m_net.get(request); |
|||
} |
|||
|
|||
void DappLoader::loadPage(QString const& _uri) |
|||
{ |
|||
QUrl uri(_uri); |
|||
QNetworkRequest request(uri); |
|||
m_pageUrls.insert(uri); |
|||
m_net.get(request); |
|||
} |
|||
|
@ -1,111 +0,0 @@ |
|||
/*
|
|||
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 DappLoader.h
|
|||
* @author Arkadiy Paronyan <arkadiy@ethdev.org> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <map> |
|||
#include <string> |
|||
#include <vector> |
|||
#include <QObject> |
|||
#include <QString> |
|||
#include <QUrl> |
|||
#include <QNetworkAccessManager> |
|||
#include <libdevcore/FixedHash.h> |
|||
#include <libdevcrypto/Common.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
class WebThreeDirect; |
|||
class RLP; |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
struct ManifestEntry |
|||
{ |
|||
std::string path; |
|||
dev::h256 hash; |
|||
std::string contentType; |
|||
unsigned httpStatus; |
|||
}; |
|||
|
|||
struct Manifest |
|||
{ |
|||
std::vector<ManifestEntry> entries; |
|||
}; |
|||
|
|||
struct Dapp |
|||
{ |
|||
Manifest manifest; |
|||
std::map<dev::h256, dev::bytes> content; |
|||
}; |
|||
|
|||
|
|||
struct DappLocation |
|||
{ |
|||
QString canonDomain; |
|||
QString path; |
|||
QString contentUri; |
|||
dev::h256 contentHash; |
|||
}; |
|||
|
|||
///Downloads, unpacks and prepares DApps for hosting
|
|||
class DappLoader: public QObject |
|||
{ |
|||
Q_OBJECT |
|||
public: |
|||
DappLoader(QObject* _parent, dev::WebThreeDirect* _web3, dev::Address _nameReg); |
|||
///Load a new DApp. Resolves a name with a name reg contract. Asynchronous. dappReady is emitted once everything is read, dappError othervise
|
|||
///@param _uri Eth name path
|
|||
void loadDapp(QString const& _uri); |
|||
///Load a regular html page
|
|||
///@param _uri Page Uri
|
|||
void loadPage(QString const& _uri); |
|||
|
|||
void setSessionKey(std::string const& _s) { m_sessionKey = _s; } |
|||
|
|||
signals: |
|||
void dappReady(Dapp& _dapp); |
|||
void pageReady(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri); |
|||
void dappError(); |
|||
|
|||
private slots: |
|||
void downloadComplete(QNetworkReply* _reply); |
|||
|
|||
private: |
|||
dev::WebThreeDirect* web3() const { return m_web3; } |
|||
DappLocation resolveAppUri(QString const& _uri); |
|||
void loadDapp(dev::RLP const& _rlp); |
|||
Manifest loadManifest(std::string const& _manifest); |
|||
QByteArray const& web3Content(); |
|||
|
|||
dev::WebThreeDirect* m_web3; |
|||
QNetworkAccessManager m_net; |
|||
std::map<QUrl, dev::h256> m_uriHashes; |
|||
std::set<QUrl> m_pageUrls; |
|||
QByteArray m_web3Js; |
|||
dev::Address m_nameReg; |
|||
std::string m_sessionKey; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,384 +0,0 @@ |
|||
/*
|
|||
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 Debugger.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "Debugger.h" |
|||
|
|||
#include <fstream> |
|||
#include <QFileDialog> |
|||
#include <libevm/VM.h> |
|||
#include <libethereum/ExtVM.h> |
|||
#include <libethereum/Executive.h> |
|||
#include "ui_Debugger.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
Debugger::Debugger(Context* _c, QWidget* _parent): |
|||
QDialog(_parent), |
|||
ui(new Ui::Debugger), |
|||
m_context(_c) |
|||
{ |
|||
ui->setupUi(this); |
|||
} |
|||
|
|||
Debugger::~Debugger() |
|||
{ |
|||
delete ui; |
|||
} |
|||
|
|||
void Debugger::init() |
|||
{ |
|||
if (m_session.history.size()) |
|||
{ |
|||
alterDebugStateGroup(true); |
|||
ui->debugCode->setEnabled(false); |
|||
ui->debugTimeline->setMinimum(0); |
|||
ui->debugTimeline->setMaximum(m_session.history.size()); |
|||
ui->debugTimeline->setValue(0); |
|||
} |
|||
} |
|||
|
|||
void Debugger::populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction) |
|||
{ |
|||
finished(); |
|||
if (m_session.populate(_executive, _transaction)) |
|||
init(); |
|||
update(); |
|||
} |
|||
|
|||
bool DebugSession::populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction) |
|||
{ |
|||
try { |
|||
_executive.initialize(_transaction); |
|||
if (_executive.execute()) |
|||
return false; |
|||
} |
|||
catch (...) |
|||
{ |
|||
// Invalid transaction
|
|||
return false; |
|||
} |
|||
|
|||
vector<WorldState const*> levels; |
|||
bytes lastExtCode; |
|||
bytesConstRef lastData; |
|||
h256 lastHash; |
|||
h256 lastDataHash; |
|||
auto onOp = [&](uint64_t steps, Instruction inst, bigint newMemSize, bigint gasCost, bigint gas, VM* voidVM, ExtVMFace const* voidExt) |
|||
{ |
|||
VM& vm = *voidVM; |
|||
ExtVM const& ext = *static_cast<ExtVM const*>(voidExt); |
|||
if (ext.code != lastExtCode) |
|||
{ |
|||
lastExtCode = ext.code; |
|||
lastHash = sha3(lastExtCode); |
|||
if (!codes.count(lastHash)) |
|||
codes[lastHash] = ext.code; |
|||
} |
|||
if (ext.data != lastData) |
|||
{ |
|||
lastData = ext.data; |
|||
lastDataHash = sha3(lastData); |
|||
if (!codes.count(lastDataHash)) |
|||
codes[lastDataHash] = ext.data.toBytes(); |
|||
} |
|||
if (levels.size() < ext.depth) |
|||
levels.push_back(&history.back()); |
|||
else |
|||
levels.resize(ext.depth); |
|||
history.append(WorldState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, static_cast<u256>(gas), lastHash, lastDataHash, vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); |
|||
}; |
|||
_executive.go(onOp); |
|||
_executive.finalize(); |
|||
return true; |
|||
} |
|||
|
|||
void Debugger::finished() |
|||
{ |
|||
m_session = DebugSession(); |
|||
ui->callStack->clear(); |
|||
ui->debugCode->clear(); |
|||
ui->debugStack->clear(); |
|||
ui->debugMemory->setHtml(""); |
|||
ui->debugStorage->setHtml(""); |
|||
ui->debugStateInfo->setText(""); |
|||
alterDebugStateGroup(false); |
|||
} |
|||
|
|||
void Debugger::update() |
|||
{ |
|||
if (m_session.history.size()) |
|||
{ |
|||
WorldState const& nws = m_session.history[min((int)m_session.history.size() - 1, ui->debugTimeline->value())]; |
|||
WorldState const& ws = ui->callStack->currentRow() > 0 ? *nws.levels[nws.levels.size() - ui->callStack->currentRow()] : nws; |
|||
|
|||
if (ui->debugTimeline->value() >= m_session.history.size()) |
|||
{ |
|||
if (ws.gasCost > ws.gas) |
|||
ui->debugMemory->setHtml("<h3>OUT-OF-GAS</h3>"); |
|||
else if (ws.inst == Instruction::RETURN && ws.stack.size() >= 2) |
|||
{ |
|||
unsigned from = (unsigned)ws.stack.back(); |
|||
unsigned size = (unsigned)ws.stack[ws.stack.size() - 2]; |
|||
unsigned o = 0; |
|||
bytes out(size, 0); |
|||
for (; o < size && from + o < ws.memory.size(); ++o) |
|||
out[o] = ws.memory[from + o]; |
|||
ui->debugMemory->setHtml("<h3>RETURN</h3>" + QString::fromStdString(dev::memDump(out, 16, true))); |
|||
} |
|||
else if (ws.inst == Instruction::STOP) |
|||
ui->debugMemory->setHtml("<h3>STOP</h3>"); |
|||
else if (ws.inst == Instruction::SUICIDE && ws.stack.size() >= 1) |
|||
ui->debugMemory->setHtml("<h3>SUICIDE</h3>0x" + QString::fromStdString(toString(right160(ws.stack.back())))); |
|||
else |
|||
ui->debugMemory->setHtml("<h3>EXCEPTION</h3>"); |
|||
|
|||
ostringstream ss; |
|||
ss << dec << "EXIT | GAS: " << dec << max<dev::bigint>(0, (dev::bigint)ws.gas - ws.gasCost); |
|||
ui->debugStateInfo->setText(QString::fromStdString(ss.str())); |
|||
ui->debugStorage->setHtml(""); |
|||
ui->debugCallData->setHtml(""); |
|||
m_session.currentData = h256(); |
|||
ui->callStack->clear(); |
|||
m_session.currentLevels.clear(); |
|||
ui->debugCode->clear(); |
|||
m_session.currentCode = h256(); |
|||
ui->debugStack->setHtml(""); |
|||
} |
|||
else |
|||
{ |
|||
if (m_session.currentLevels != nws.levels || !ui->callStack->count()) |
|||
{ |
|||
m_session.currentLevels = nws.levels; |
|||
ui->callStack->clear(); |
|||
for (unsigned i = 0; i <= nws.levels.size(); ++i) |
|||
{ |
|||
WorldState const& s = i ? *nws.levels[nws.levels.size() - i] : nws; |
|||
ostringstream out; |
|||
out << s.cur.abridged(); |
|||
if (i) |
|||
out << " " << instructionInfo(s.inst).name << " @0x" << hex << s.curPC; |
|||
ui->callStack->addItem(QString::fromStdString(out.str())); |
|||
} |
|||
} |
|||
|
|||
if (ws.code != m_session.currentCode) |
|||
{ |
|||
m_session.currentCode = ws.code; |
|||
bytes const& code = m_session.codes[ws.code]; |
|||
QListWidget* dc = ui->debugCode; |
|||
dc->clear(); |
|||
m_session.pcWarp.clear(); |
|||
for (unsigned i = 0; i <= code.size(); ++i) |
|||
{ |
|||
byte b = i < code.size() ? code[i] : 0; |
|||
try |
|||
{ |
|||
QString s = QString::fromStdString(instructionInfo((Instruction)b).name); |
|||
ostringstream out; |
|||
out << hex << setw(4) << setfill('0') << i; |
|||
m_session.pcWarp[i] = dc->count(); |
|||
if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32) |
|||
{ |
|||
unsigned bc = b - (byte)Instruction::PUSH1 + 1; |
|||
s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&code[i + 1], bc))); |
|||
i += bc; |
|||
} |
|||
dc->addItem(QString::fromStdString(out.str()) + " " + s); |
|||
} |
|||
catch (...) |
|||
{ |
|||
cerr << "Unhandled exception!" << endl << boost::current_exception_diagnostic_information(); |
|||
break; // probably hit data segment
|
|||
} |
|||
} |
|||
} |
|||
|
|||
if (ws.callData != m_session.currentData) |
|||
{ |
|||
m_session.currentData = ws.callData; |
|||
if (ws.callData) |
|||
{ |
|||
assert(m_session.codes.count(ws.callData)); |
|||
ui->debugCallData->setHtml(QString::fromStdString(dev::memDump(m_session.codes[ws.callData], 16, true))); |
|||
} |
|||
else |
|||
ui->debugCallData->setHtml(""); |
|||
} |
|||
|
|||
QString stack; |
|||
for (auto i: ws.stack) |
|||
stack.prepend("<div>" + QString::fromStdString(m_context->prettyU256(i)) + "</div>"); |
|||
ui->debugStack->setHtml(stack); |
|||
ui->debugMemory->setHtml(QString::fromStdString(dev::memDump(ws.memory, 16, true))); |
|||
assert(m_session.codes.count(ws.code)); |
|||
|
|||
if (m_session.codes[ws.code].size() >= (unsigned)ws.curPC) |
|||
{ |
|||
int l = m_session.pcWarp[(unsigned)ws.curPC]; |
|||
ui->debugCode->setCurrentRow(max(0, l - 5)); |
|||
ui->debugCode->setCurrentRow(min(ui->debugCode->count() - 1, l + 5)); |
|||
ui->debugCode->setCurrentRow(l); |
|||
} |
|||
else |
|||
cwarn << "PC (" << (unsigned)ws.curPC << ") is after code range (" << m_session.codes[ws.code].size() << ")"; |
|||
|
|||
ostringstream ss; |
|||
ss << dec << "STEP: " << ws.steps << " | PC: 0x" << hex << ws.curPC << " : " << instructionInfo(ws.inst).name << " | ADDMEM: " << dec << ws.newMemSize << " words | COST: " << dec << ws.gasCost << " | GAS: " << dec << ws.gas; |
|||
ui->debugStateInfo->setText(QString::fromStdString(ss.str())); |
|||
stringstream s; |
|||
auto keys = dev::keysOf(ws.storage); |
|||
sort(keys.begin(), keys.end()); |
|||
for (auto const& key: keys) |
|||
s << "@" << m_context->prettyU256(key) << " " << m_context->prettyU256(ws.storage.at(key)) << "<br/>"; |
|||
ui->debugStorage->setHtml(QString::fromStdString(s.str())); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void Debugger::on_callStack_currentItemChanged() |
|||
{ |
|||
update(); |
|||
} |
|||
|
|||
void Debugger::alterDebugStateGroup(bool _enable) const |
|||
{ |
|||
ui->stepOver->setEnabled(_enable); |
|||
ui->stepInto->setEnabled(_enable); |
|||
ui->stepOut->setEnabled(_enable); |
|||
ui->backOver->setEnabled(_enable); |
|||
ui->backInto->setEnabled(_enable); |
|||
ui->backOut->setEnabled(_enable); |
|||
ui->dump->setEnabled(_enable); |
|||
ui->dumpStorage->setEnabled(_enable); |
|||
ui->dumpPretty->setEnabled(_enable); |
|||
} |
|||
|
|||
void Debugger::on_debugTimeline_valueChanged() |
|||
{ |
|||
update(); |
|||
} |
|||
|
|||
void Debugger::on_stepOver_clicked() |
|||
{ |
|||
if (ui->debugTimeline->value() < m_session.history.size()) { |
|||
auto l = m_session.history[ui->debugTimeline->value()].levels.size(); |
|||
if ((ui->debugTimeline->value() + 1) < m_session.history.size() && m_session.history[ui->debugTimeline->value() + 1].levels.size() > l) |
|||
{ |
|||
on_stepInto_clicked(); |
|||
if (m_session.history[ui->debugTimeline->value()].levels.size() > l) |
|||
on_stepOut_clicked(); |
|||
} |
|||
else |
|||
on_stepInto_clicked(); |
|||
} |
|||
} |
|||
|
|||
void Debugger::on_stepInto_clicked() |
|||
{ |
|||
ui->debugTimeline->setValue(ui->debugTimeline->value() + 1); |
|||
ui->callStack->setCurrentRow(0); |
|||
} |
|||
|
|||
void Debugger::on_stepOut_clicked() |
|||
{ |
|||
if (ui->debugTimeline->value() < m_session.history.size()) |
|||
{ |
|||
auto ls = m_session.history[ui->debugTimeline->value()].levels.size(); |
|||
auto l = ui->debugTimeline->value(); |
|||
for (; l < m_session.history.size() && m_session.history[l].levels.size() >= ls; ++l) {} |
|||
ui->debugTimeline->setValue(l); |
|||
ui->callStack->setCurrentRow(0); |
|||
} |
|||
} |
|||
|
|||
void Debugger::on_backInto_clicked() |
|||
{ |
|||
ui->debugTimeline->setValue(ui->debugTimeline->value() - 1); |
|||
ui->callStack->setCurrentRow(0); |
|||
} |
|||
|
|||
void Debugger::on_backOver_clicked() |
|||
{ |
|||
auto l = m_session.history[ui->debugTimeline->value()].levels.size(); |
|||
if (ui->debugTimeline->value() > 0 && m_session.history[ui->debugTimeline->value() - 1].levels.size() > l) |
|||
{ |
|||
on_backInto_clicked(); |
|||
if (m_session.history[ui->debugTimeline->value()].levels.size() > l) |
|||
on_backOut_clicked(); |
|||
} |
|||
else |
|||
on_backInto_clicked(); |
|||
} |
|||
|
|||
void Debugger::on_backOut_clicked() |
|||
{ |
|||
if (ui->debugTimeline->value() > 0 && m_session.history.size() > 0) |
|||
{ |
|||
auto ls = m_session.history[min(ui->debugTimeline->value(), m_session.history.size() - 1)].levels.size(); |
|||
int l = ui->debugTimeline->value(); |
|||
for (; l > 0 && m_session.history[l].levels.size() >= ls; --l) {} |
|||
ui->debugTimeline->setValue(l); |
|||
ui->callStack->setCurrentRow(0); |
|||
} |
|||
} |
|||
|
|||
void Debugger::on_dump_clicked() |
|||
{ |
|||
QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); |
|||
ofstream f(fn.toStdString()); |
|||
if (f.is_open()) |
|||
for (WorldState const& ws: m_session.history) |
|||
f << ws.cur << " " << hex << toHex(dev::toCompactBigEndian(ws.curPC, 1)) << " " << hex << toHex(dev::toCompactBigEndian((unsigned)(byte)ws.inst, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)ws.gas, 1)) << endl; |
|||
} |
|||
|
|||
void Debugger::on_dumpPretty_clicked() |
|||
{ |
|||
QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); |
|||
ofstream f(fn.toStdString()); |
|||
if (f.is_open()) |
|||
for (WorldState const& ws: m_session.history) |
|||
{ |
|||
f << endl << " STACK" << endl; |
|||
for (auto i: ws.stack) |
|||
f << (h256)i << endl; |
|||
f << " MEMORY" << endl << dev::memDump(ws.memory); |
|||
f << " STORAGE" << endl; |
|||
for (auto const& i: ws.storage) |
|||
f << showbase << hex << i.first << ": " << i.second << endl; |
|||
f << dec << ws.levels.size() << " | " << ws.cur << " | #" << ws.steps << " | " << hex << setw(4) << setfill('0') << ws.curPC << " : " << instructionInfo(ws.inst).name << " | " << dec << ws.gas << " | -" << dec << ws.gasCost << " | " << ws.newMemSize << "x32"; |
|||
} |
|||
} |
|||
|
|||
void Debugger::on_dumpStorage_clicked() |
|||
{ |
|||
QString fn = QFileDialog::getSaveFileName(this, "Select file to output EVM trace"); |
|||
ofstream f(fn.toStdString()); |
|||
if (f.is_open()) |
|||
for (WorldState const& ws: m_session.history) |
|||
{ |
|||
if (ws.inst == Instruction::STOP || ws.inst == Instruction::RETURN || ws.inst == Instruction::SUICIDE) |
|||
for (auto i: ws.storage) |
|||
f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl; |
|||
f << ws.cur << " " << hex << toHex(dev::toCompactBigEndian(ws.curPC, 1)) << " " << hex << toHex(dev::toCompactBigEndian((unsigned)(byte)ws.inst, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)ws.gas, 1)) << endl; |
|||
} |
|||
} |
@ -1,112 +0,0 @@ |
|||
/*
|
|||
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 Debugger.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libdevcore/RLP.h> |
|||
#include <libethcore/Common.h> |
|||
#include <libethereum/State.h> |
|||
#include <libethereum/Executive.h> |
|||
#include <QDialog> |
|||
#include <QMap> |
|||
#include <QList> |
|||
#include "Context.h" |
|||
|
|||
namespace Ui { class Debugger; } |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
struct WorldState |
|||
{ |
|||
uint64_t steps; |
|||
dev::Address cur; |
|||
dev::u256 curPC; |
|||
dev::eth::Instruction inst; |
|||
dev::bigint newMemSize; |
|||
dev::u256 gas; |
|||
dev::h256 code; |
|||
dev::h256 callData; |
|||
dev::u256s stack; |
|||
dev::bytes memory; |
|||
dev::bigint gasCost; |
|||
std::unordered_map<dev::u256, dev::u256> storage; |
|||
std::vector<WorldState const*> levels; |
|||
}; |
|||
|
|||
struct DebugSession |
|||
{ |
|||
DebugSession() {} |
|||
|
|||
bool populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction); |
|||
|
|||
dev::h256 currentCode; |
|||
dev::h256 currentData; |
|||
std::vector<WorldState const*> currentLevels; |
|||
|
|||
QMap<unsigned, unsigned> pcWarp; |
|||
QList<WorldState> history; |
|||
|
|||
std::map<dev::u256, dev::bytes> codes; |
|||
}; |
|||
|
|||
class Debugger: public QDialog |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit Debugger(Context* _context, QWidget* _parent = 0); |
|||
~Debugger(); |
|||
|
|||
void populate(dev::eth::Executive& _executive, dev::eth::Transaction const& _transaction); |
|||
|
|||
protected slots: |
|||
void on_callStack_currentItemChanged(); |
|||
void on_debugTimeline_valueChanged(); |
|||
void on_stepOver_clicked(); |
|||
void on_stepInto_clicked(); |
|||
void on_stepOut_clicked(); |
|||
void on_backOver_clicked(); |
|||
void on_backInto_clicked(); |
|||
void on_backOut_clicked(); |
|||
void on_dump_clicked(); |
|||
void on_dumpPretty_clicked(); |
|||
void on_dumpStorage_clicked(); |
|||
void on_close_clicked() { close(); } |
|||
|
|||
private: |
|||
void init(); |
|||
void update(); |
|||
void finished(); |
|||
|
|||
void alterDebugStateGroup(bool _enable) const; |
|||
|
|||
Ui::Debugger* ui; |
|||
|
|||
DebugSession m_session; |
|||
Context* m_context; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,300 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>Debugger</class> |
|||
<widget class="QDialog" name="Debugger"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>989</width> |
|||
<height>690</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Dialog</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<widget class="QFrame" name="frame"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="frameShadow"> |
|||
<enum>QFrame::Raised</enum> |
|||
</property> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<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> |
|||
<widget class="QToolButton" name="stepOver"> |
|||
<property name="text"> |
|||
<string>Step Over</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="stepInto"> |
|||
<property name="text"> |
|||
<string>Step Into</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="stepOut"> |
|||
<property name="text"> |
|||
<string>Step Out</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="backOver"> |
|||
<property name="text"> |
|||
<string>Back Over</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="backInto"> |
|||
<property name="text"> |
|||
<string>Back Into</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="backOut"> |
|||
<property name="text"> |
|||
<string>Back Out</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> |
|||
</layout> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QSplitter" name="splitter_6"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="orientation"> |
|||
<enum>Qt::Horizontal</enum> |
|||
</property> |
|||
<widget class="QSplitter" name="splitter_42"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding"> |
|||
<horstretch>1</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<widget class="QListWidget" name="debugCode"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
<widget class="QListWidget" name="callStack"> |
|||
<property name="font"> |
|||
<font> |
|||
<family>Ubuntu Mono</family> |
|||
</font> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
</widget> |
|||
<widget class="QSplitter" name="splitter_4"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding"> |
|||
<horstretch>1</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<widget class="QTextEdit" name="debugStack"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="textInteractionFlags"> |
|||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> |
|||
</property> |
|||
</widget> |
|||
<widget class="QTextEdit" name="debugMemory"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="textInteractionFlags"> |
|||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> |
|||
</property> |
|||
</widget> |
|||
<widget class="QTextEdit" name="debugStorage"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="textInteractionFlags"> |
|||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> |
|||
</property> |
|||
</widget> |
|||
<widget class="QTextEdit" name="debugCallData"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</widget> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="debugStateInfo"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string/> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QSlider" name="debugTimeline"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Horizontal</enum> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QFrame" name="frame_2"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="frameShadow"> |
|||
<enum>QFrame::Raised</enum> |
|||
</property> |
|||
<layout class="QHBoxLayout" name="horizontalLayout_2"> |
|||
<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> |
|||
<widget class="QToolButton" name="dump"> |
|||
<property name="text"> |
|||
<string>Dump</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="dumpStorage"> |
|||
<property name="text"> |
|||
<string>Dump Storage</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="dumpPretty"> |
|||
<property name="text"> |
|||
<string>Dump Pretty</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<spacer name="horizontalSpacer_2"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Horizontal</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>577</width> |
|||
<height>20</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<widget class="QToolButton" name="close"> |
|||
<property name="text"> |
|||
<string>Close</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
@ -1,201 +0,0 @@ |
|||
/*
|
|||
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 DownloadView.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "DownloadView.h" |
|||
#include <QtWidgets> |
|||
#include <QtCore> |
|||
#include <libethereum/DownloadMan.h> |
|||
#include "Grapher.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
SyncView::SyncView(QWidget* _p): QWidget(_p) |
|||
{ |
|||
} |
|||
|
|||
void SyncView::paintEvent(QPaintEvent*) |
|||
{ |
|||
QPainter painter(this); |
|||
painter.fillRect(rect(), Qt::white); |
|||
painter.setRenderHint(QPainter::Antialiasing, true); |
|||
painter.setRenderHint(QPainter::HighQualityAntialiasing, true); |
|||
|
|||
if (!m_client || !isVisible() || !rect().width() || !rect().height()) |
|||
return; |
|||
|
|||
DownloadMan const* man = m_client->downloadMan(); |
|||
BlockQueueStatus bqs = m_client->blockQueueStatus(); |
|||
SyncStatus sync = m_client->syncStatus(); |
|||
|
|||
unsigned syncFrom = m_client->numberFromHash(PendingBlockHash); |
|||
unsigned syncImported = syncFrom; |
|||
unsigned syncImporting = syncImported + bqs.importing; |
|||
unsigned syncVerified = syncImporting + bqs.verified; |
|||
unsigned syncVerifying = syncVerified + bqs.verifying; |
|||
unsigned syncUnverified = syncVerifying + bqs.unverified; |
|||
unsigned syncCount = syncUnverified + bqs.unknown - syncFrom; |
|||
|
|||
// best effort guess. assumes there's no forks.
|
|||
unsigned downloadFrom = sync.state == SyncState::Idle ? m_lastSyncFrom : m_client->numberFromHash(m_client->isKnown(man->firstBlock()) ? man->firstBlock() : PendingBlockHash); |
|||
unsigned downloadCount = sync.state == SyncState::Idle ? m_lastSyncCount : sync.blocksTotal; |
|||
unsigned downloadDone = downloadFrom + (sync.state == SyncState::Idle ? m_lastSyncCount : sync.blocksReceived); |
|||
unsigned downloadPoint = downloadFrom + (sync.state == SyncState::Idle ? m_lastSyncCount : man->overview().lastComplete); |
|||
|
|||
unsigned hashFrom = sync.state == SyncState::Hashes ? m_client->numberFromHash(PendingBlockHash) : downloadFrom; |
|||
unsigned hashCount = sync.state == SyncState::Hashes ? sync.hashesTotal : downloadCount; |
|||
unsigned hashDone = hashFrom + (sync.state == SyncState::Hashes ? sync.hashesReceived : hashCount); |
|||
|
|||
QString labelText = QString("PV%1").arg(sync.protocolVersion); |
|||
QColor labelBack = QColor::fromHsv(sync.protocolVersion == 60 ? 30 : sync.protocolVersion == 61 ? 120 : 240, 25, 200); |
|||
QColor labelFore = labelBack.darker(); |
|||
switch (sync.state) |
|||
{ |
|||
case SyncState::Hashes: |
|||
if (!syncCount || !sync.hashesEstimated) |
|||
{ |
|||
m_lastSyncFrom = min(hashFrom, m_lastSyncFrom); |
|||
m_lastSyncCount = max(hashFrom + hashCount, m_lastSyncFrom + m_lastSyncCount) - m_lastSyncFrom; |
|||
m_wasEstimate = sync.hashesEstimated; |
|||
} |
|||
break; |
|||
case SyncState::Blocks: |
|||
if (m_wasEstimate) |
|||
{ |
|||
m_lastSyncFrom = downloadFrom; |
|||
m_lastSyncCount = downloadCount; |
|||
m_wasEstimate = false; |
|||
} |
|||
break; |
|||
case SyncState::Idle: |
|||
if (!syncCount) |
|||
{ |
|||
m_lastSyncFrom = (unsigned)-1; |
|||
m_lastSyncCount = 0; |
|||
labelBack = QColor::fromHsv(0, 0, 200); |
|||
labelFore = Qt::white; |
|||
labelText = "Idle"; |
|||
} |
|||
default: break; |
|||
} |
|||
|
|||
unsigned from = min(min(hashFrom, downloadFrom), min(syncFrom, m_lastSyncFrom)); |
|||
unsigned count = max(max(hashFrom + hashCount, downloadFrom + downloadCount), max(syncFrom + syncCount, m_lastSyncFrom + m_lastSyncCount)) - from; |
|||
|
|||
/* cnote << "Range " << from << "-" << (from + count) << "(" << hashFrom << "+" << hashCount << "," << downloadFrom << "+" << downloadCount << "," << syncFrom << "+" << syncCount << ")";
|
|||
auto r = [&](unsigned u) { |
|||
return toString((u - from) * 100 / count) + "%"; |
|||
}; |
|||
|
|||
if (count) |
|||
{ |
|||
cnote << "Hashes:" << r(hashDone) << " Blocks:" << r(downloadFlank) << r(downloadDone) << r(downloadPoint); |
|||
cnote << "Importing:" << r(syncFrom) << r(syncImported) << r(syncImporting) << r(syncVerified) << r(syncVerifying) << r(syncUnverified); |
|||
} |
|||
*/ |
|||
float const squareSize = min(rect().width(), rect().height()); |
|||
auto middleRect = [&](float w, float h) { |
|||
return QRectF(rect().width() / 2 - w / 2, rect().height() / 2 - h / 2, w, h); |
|||
}; |
|||
auto middle = [&](float x) { |
|||
return middleRect(squareSize * x, squareSize * x); |
|||
}; |
|||
auto pieProgress = [&](unsigned h, unsigned s, unsigned v, float row, float thickness, unsigned nfrom, unsigned ncount) { |
|||
auto arcLen = [&](unsigned x) { |
|||
return x * -5760.f / count; |
|||
}; |
|||
auto arcPos = [&](unsigned x) { |
|||
return int(90 * 16.f + arcLen(x - from)) % 5760; |
|||
}; |
|||
painter.setPen(QPen(QColor::fromHsv(h, s, v), squareSize * thickness, Qt::SolidLine, Qt::FlatCap)); |
|||
painter.setBrush(Qt::NoBrush); |
|||
painter.drawArc(middle(0.5 + row / 2), arcPos(nfrom), arcLen(ncount)); |
|||
}; |
|||
auto pieProgress2 = [&](unsigned h, unsigned s, unsigned v, float row, float orbit, float thickness, unsigned nfrom, unsigned ncount) { |
|||
pieProgress(h, s, v, row - orbit, thickness, nfrom, ncount); |
|||
pieProgress(h, s, v, row + orbit, thickness, nfrom, ncount); |
|||
}; |
|||
auto pieLabel = [&](QString text, float points, QColor fore, QColor back) { |
|||
painter.setBrush(QBrush(back)); |
|||
painter.setFont(QFont("Helvetica", points, QFont::Bold)); |
|||
QRectF r = painter.boundingRect(middle(1.f), Qt::AlignCenter, text); |
|||
r.adjust(-r.width() / 4, -r.height() / 8, r.width() / 4, r.height() / 8); |
|||
painter.setPen(QPen(fore, r.height() / 20)); |
|||
painter.drawRoundedRect(r, r.height() / 4, r.height() / 4); |
|||
painter.drawText(r, Qt::AlignCenter, text); |
|||
}; |
|||
|
|||
float lineHeight = painter.boundingRect(rect(), Qt::AlignTop | Qt::AlignHCenter, "Ay").height(); |
|||
auto hProgress = [&](unsigned h, unsigned s, unsigned v, float row, float thickness, unsigned nfrom, unsigned ncount) { |
|||
QRectF r = rect(); |
|||
painter.setPen(QPen(QColor::fromHsv(h, s, v), r.height() * thickness * 3, Qt::SolidLine, Qt::FlatCap)); |
|||
painter.setBrush(Qt::NoBrush); |
|||
auto y = row * (r.height() - lineHeight) + lineHeight; |
|||
painter.drawLine(QPointF((nfrom - from) * r.width() / count, y), QPointF((nfrom + ncount - from) * r.width() / count, y)); |
|||
}; |
|||
auto hProgress2 = [&](unsigned h, unsigned s, unsigned v, float row, float orbit, float thickness, unsigned nfrom, unsigned ncount) { |
|||
hProgress(h, s, v, row - orbit * 3, thickness, nfrom, ncount); |
|||
hProgress(h, s, v, row + orbit * 3, thickness, nfrom, ncount); |
|||
}; |
|||
auto hLabel = [&](QString text, float points, QColor fore, QColor back) { |
|||
painter.setBrush(QBrush(back)); |
|||
painter.setFont(QFont("Helvetica", points, QFont::Bold)); |
|||
QRectF r = painter.boundingRect(rect(), Qt::AlignTop | Qt::AlignHCenter, text); |
|||
r.adjust(-r.width() / 4, r.height() / 8, r.width() / 4, 3 * r.height() / 8); |
|||
painter.setPen(QPen(fore, r.height() / 20)); |
|||
painter.drawRoundedRect(r, r.height() / 4, r.height() / 4); |
|||
painter.drawText(r, Qt::AlignCenter, text); |
|||
}; |
|||
|
|||
function<void(unsigned h, unsigned s, unsigned v, float row, float thickness, unsigned nfrom, unsigned ncount)> progress; |
|||
function<void(unsigned h, unsigned s, unsigned v, float row, float orbit, float thickness, unsigned nfrom, unsigned ncount)> progress2; |
|||
function<void(QString text, float points, QColor fore, QColor back)> label; |
|||
if (rect().width() / rect().height() > 5) |
|||
{ |
|||
progress = hProgress; |
|||
progress2 = hProgress2; |
|||
label = hLabel; |
|||
} |
|||
else |
|||
{ |
|||
progress = pieProgress; |
|||
progress2 = pieProgress2; |
|||
label = pieLabel; |
|||
} |
|||
|
|||
if (sync.state != SyncState::Idle) |
|||
{ |
|||
progress(0, 0, 220, 0.4f, 0.02f, from, hashDone - from); // Download rail
|
|||
progress(240, 25, 170, 0.4f, 0.02f, downloadDone, downloadPoint - downloadDone); // Latest download point
|
|||
progress(240, 50, 120, 0.4f, 0.04f, from, downloadDone - from); // Downloaded
|
|||
} |
|||
|
|||
progress(0, 0, 220, 0.8f, 0.01f, from, count); // Sync rail
|
|||
progress(0, 0, 170, 0.8f, 0.02f, from, syncUnverified - from); // Verification rail
|
|||
progress2(60, 25, 170, 0.8f, 0.06f, 0.005f, from, syncVerifying - from); // Verifying.
|
|||
progress2(120, 25, 170, 0.8f, 0.06f, 0.005f, from, syncVerified - from); // Verified.
|
|||
progress(120, 50, 120, 0.8f, 0.05f, from, syncFrom - from); // Imported.
|
|||
progress(0, 0, 120, 0.8f, 0.02f, syncFrom, syncImporting - syncFrom); // Importing.
|
|||
|
|||
if (sync.state != SyncState::Idle || (sync.state == SyncState::Idle && !syncCount)) |
|||
label(labelText, 11, labelFore, labelBack); |
|||
} |
@ -1,63 +0,0 @@ |
|||
/*
|
|||
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 DownloadView.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#ifdef Q_MOC_RUN |
|||
#define BOOST_MPL_IF_HPP_INCLUDED |
|||
#endif |
|||
|
|||
#include <list> |
|||
#include <QtWidgets/QWidget> |
|||
#ifndef Q_MOC_RUN |
|||
#include <libethereum/Client.h> |
|||
#endif |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth { class Client; } |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
class SyncView: public QWidget |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
SyncView(QWidget* _p = nullptr); |
|||
|
|||
void setEthereum(dev::eth::Client const* _c) { m_client = _c; } |
|||
|
|||
protected: |
|||
virtual void paintEvent(QPaintEvent*); |
|||
|
|||
private: |
|||
dev::eth::Client const* m_client = nullptr; |
|||
|
|||
unsigned m_lastSyncFrom = (unsigned)-1; |
|||
unsigned m_lastSyncCount = 0; |
|||
bool m_wasEstimate = false; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,181 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>GasPricing</class> |
|||
<widget class="QDialog" name="GasPricing"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>416</width> |
|||
<height>286</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Gas Pricing</string> |
|||
</property> |
|||
<layout class="QGridLayout" name="gridLayout"> |
|||
<item row="3" column="0" colspan="2"> |
|||
<spacer name="verticalSpacer"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>398</width> |
|||
<height>45</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item row="4" column="0" colspan="2"> |
|||
<widget class="QLabel" name="label5_3"> |
|||
<property name="text"> |
|||
<string>&Bid: The minimum grice of gas that is accepting into a block which we mine.</string> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>bidValue</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" column="0"> |
|||
<widget class="QSpinBox" name="askValue"> |
|||
<property name="suffix"> |
|||
<string/> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>430000000</number> |
|||
</property> |
|||
<property name="value"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="10" column="0" colspan="2"> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<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="default"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
<item row="0" column="0" colspan="2"> |
|||
<widget class="QLabel" name="label5_2"> |
|||
<property name="text"> |
|||
<string>&Ask: The minimum grice of gas that is accepting into a block which we mine.</string> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>askValue</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" column="1"> |
|||
<widget class="QComboBox" name="askUnits"/> |
|||
</item> |
|||
<item row="5" column="0"> |
|||
<widget class="QSpinBox" name="bidValue"> |
|||
<property name="suffix"> |
|||
<string/> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>430000000</number> |
|||
</property> |
|||
<property name="value"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="5" column="1"> |
|||
<widget class="QComboBox" name="bidUnits"/> |
|||
</item> |
|||
<item row="7" column="0" colspan="2"> |
|||
<spacer name="verticalSpacer_2"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item row="9" column="0" colspan="2"> |
|||
<spacer name="verticalSpacer_3"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item row="8" column="0" colspan="2"> |
|||
<spacer name="verticalSpacer_4"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>close</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>GasPricing</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>387</x> |
|||
<y>264</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>240</x> |
|||
<y>262</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,123 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>GetPassword</class> |
|||
<widget class="QDialog" name="GetPassword"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>400</width> |
|||
<height>187</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Enter Password</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<spacer name="verticalSpacer_3"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="label"> |
|||
<property name="text"> |
|||
<string/> |
|||
</property> |
|||
<property name="textFormat"> |
|||
<enum>Qt::RichText</enum> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<spacer name="verticalSpacer_2"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<widget class="QLineEdit" name="entry"> |
|||
<property name="echoMode"> |
|||
<enum>QLineEdit::Password</enum> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<spacer name="verticalSpacer"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<widget class="QDialogButtonBox" name="buttonBox"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Horizontal</enum> |
|||
</property> |
|||
<property name="standardButtons"> |
|||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>buttonBox</sender> |
|||
<signal>accepted()</signal> |
|||
<receiver>GetPassword</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>248</x> |
|||
<y>254</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>157</x> |
|||
<y>274</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>buttonBox</sender> |
|||
<signal>rejected()</signal> |
|||
<receiver>GetPassword</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>316</x> |
|||
<y>260</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>286</x> |
|||
<y>274</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,106 +0,0 @@ |
|||
/* BEGIN COPYRIGHT
|
|||
* |
|||
* This file is part of Noted. |
|||
* |
|||
* Copyright ©2011, 2012, Lancaster Logic Response Limited. |
|||
* |
|||
* Noted 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 2 of the License, or |
|||
* (at your option) any later version. |
|||
* |
|||
* Noted 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 Noted. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <algorithm> |
|||
#include <type_traits> |
|||
#include <cmath> |
|||
|
|||
#undef foreach |
|||
#define foreach BOOST_FOREACH |
|||
|
|||
namespace lb |
|||
{ |
|||
|
|||
template <class T> |
|||
static T graphParameters(T _min, T _max, unsigned _divisions, T* o_from = 0, T* o_delta = 0, bool _forceMinor = false, T _divisor = 1) |
|||
{ |
|||
T uMin = _min / _divisor; |
|||
T uMax = _max / _divisor; |
|||
if (uMax == uMin || !_divisions) |
|||
{ |
|||
if (o_delta && o_from) |
|||
{ |
|||
*o_from = 0; |
|||
*o_delta = 1; |
|||
} |
|||
return 1; |
|||
} |
|||
long double l10 = std::log10((uMax - uMin) / T(_divisions) * 5.5f); |
|||
long double mt = std::pow(10.f, l10 - std::floor(l10)); |
|||
long double ep = std::pow(10.f, std::floor(l10)); |
|||
T inc = _forceMinor |
|||
? ((mt > 6.f) ? ep / 2.f : (mt > 3.f) ? ep / 5.f : (mt > 1.2f) ? ep / 10.f : ep / 20.f) |
|||
: ((mt > 6.f) ? ep * 2.f : (mt > 3.f) ? ep : (mt > 1.2f) ? ep / 2.f : ep / 5.f); |
|||
if (inc == 0) |
|||
inc = 1; |
|||
if (o_delta && o_from) |
|||
{ |
|||
(*o_from) = std::floor(uMin / inc) * inc * _divisor; |
|||
(*o_delta) = (std::ceil(uMax / inc) - std::floor(uMin / inc)) * inc * _divisor; |
|||
} |
|||
else if (o_from) |
|||
{ |
|||
(*o_from) = std::ceil(uMin / inc) * inc * _divisor; |
|||
} |
|||
return inc * _divisor; |
|||
} |
|||
|
|||
struct GraphParametersForceMinor { GraphParametersForceMinor() {} }; |
|||
static const GraphParametersForceMinor ForceMinor; |
|||
|
|||
template <class T> |
|||
struct GraphParameters |
|||
{ |
|||
inline GraphParameters(std::pair<T, T> _range, unsigned _divisions) |
|||
{ |
|||
incr = graphParameters(_range.first, _range.second, _divisions, &from, &delta, false); |
|||
to = from + delta; |
|||
} |
|||
|
|||
inline GraphParameters(std::pair<T, T> _range, unsigned _divisions, GraphParametersForceMinor) |
|||
{ |
|||
incr = graphParameters(_range.first, _range.second, _divisions, &from, &delta, true); |
|||
to = from + delta; |
|||
} |
|||
|
|||
inline GraphParameters(std::pair<T, T> _range, unsigned _divisions, T _divisor) |
|||
{ |
|||
major = graphParameters(_range.first, _range.second, _divisions, &from, &delta, false, _divisor); |
|||
incr = graphParameters(_range.first, _range.second, _divisions, &from, &delta, true, _divisor); |
|||
to = from + delta; |
|||
} |
|||
|
|||
template <class S, class Enable = void> |
|||
struct MajorDeterminor { static bool go(S _s, S _j) { S ip; S fp = std::modf(_s / _j + S(0.5), &ip); return fabs(fabs(fp) - 0.5) < 0.05; } }; |
|||
template <class S> |
|||
struct MajorDeterminor<S, typename std::enable_if<std::is_integral<S>::value>::type> { static S go(S _s, S _j) { return _s % _j == 0; } }; |
|||
|
|||
bool isMajor(T _t) const { return MajorDeterminor<T>::go(_t, major); } |
|||
|
|||
T from; |
|||
T delta; |
|||
T major; |
|||
T to; |
|||
T incr; |
|||
}; |
|||
|
|||
} |
@ -1,195 +0,0 @@ |
|||
/* BEGIN COPYRIGHT
|
|||
* |
|||
* This file is part of Noted. |
|||
* |
|||
* Copyright ©2011, 2012, Lancaster Logic Response Limited. |
|||
* |
|||
* Noted 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 2 of the License, or |
|||
* (at your option) any later version. |
|||
* |
|||
* Noted 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 Noted. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <QtGui/QPainter> |
|||
|
|||
#include "GraphParameters.h" |
|||
#include "Grapher.h" |
|||
|
|||
using namespace std; |
|||
using namespace lb; |
|||
|
|||
void Grapher::init(QPainter* _p, std::pair<float, float> _xRange, std::pair<float, float> _yRange, std::function<std::string(float)> _xLabel, std::function<std::string(float)> _yLabel, std::function<std::string(float, float)> _pLabel, int _leftGutter, int _bottomGutter) |
|||
{ |
|||
fontPixelSize = QFontInfo(QFont("Ubuntu", 10)).pixelSize(); |
|||
|
|||
if (_leftGutter) |
|||
_leftGutter = max<int>(_leftGutter, fontPixelSize * 2); |
|||
if (_bottomGutter) |
|||
_bottomGutter = max<int>(_bottomGutter, fontPixelSize * 1.25); |
|||
|
|||
QRect a(_leftGutter, 0, _p->viewport().width() - _leftGutter, _p->viewport().height() - _bottomGutter); |
|||
init(_p, _xRange, _yRange, _xLabel, _yLabel, _pLabel, a); |
|||
} |
|||
|
|||
bool Grapher::drawAxes(bool _x, bool _y) const |
|||
{ |
|||
int w = active.width(); |
|||
int h = active.height(); |
|||
int l = active.left(); |
|||
int r = active.right(); |
|||
int t = active.top(); |
|||
int b = active.bottom(); |
|||
|
|||
p->setFont(QFont("Ubuntu", 10)); |
|||
p->fillRect(p->viewport(), qRgb(255, 255, 255)); |
|||
|
|||
static const int c_markLength = 2; |
|||
static const int c_markSpacing = 2; |
|||
static const int c_xSpacing = fontPixelSize * 3; |
|||
static const int c_ySpacing = fontPixelSize * 1.25; |
|||
|
|||
if (w < c_xSpacing || h < c_ySpacing || !p->viewport().contains(active)) |
|||
return false; |
|||
|
|||
if (_y) |
|||
{ |
|||
GraphParameters<float> yParams(yRange, h / c_ySpacing, 1.f); |
|||
float dy = fabs(yRange.second - yRange.first); |
|||
if (dy > .001) |
|||
for (float f = yParams.from; f < yParams.to; f += yParams.incr) |
|||
{ |
|||
int y = b - h * (f - yParams.from) / dy; |
|||
if (yParams.isMajor(f)) |
|||
{ |
|||
p->setPen(QColor(208, 208, 208)); |
|||
p->drawLine(l - c_markLength, y, r, y); |
|||
if (l > p->viewport().left()) |
|||
{ |
|||
p->setPen(QColor(144, 144, 144)); |
|||
p->drawText(QRect(0, y - c_ySpacing / 2, l - c_markLength - c_markSpacing, c_ySpacing), Qt::AlignRight|Qt::AlignVCenter, QString::fromStdString(yLabel(round(f * 100000) / 100000))); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
p->setPen(QColor(236, 236, 236)); |
|||
p->drawLine(l, y, r, y); |
|||
} |
|||
} |
|||
p->setPen(QColor(192,192,192)); |
|||
p->drawLine(l - c_markSpacing, b, r, b); |
|||
} |
|||
|
|||
if (_x) |
|||
{ |
|||
GraphParameters<float> xParams(xRange, w / c_xSpacing, 1.f); |
|||
float dx = fabs(xRange.second - xRange.first); |
|||
for (float f = xParams.from; f < xParams.to; f += xParams.incr) |
|||
{ |
|||
int x = l + w * (f - xParams.from) / dx; |
|||
if (xParams.isMajor(f)) |
|||
{ |
|||
p->setPen(QColor(208, 208, 208)); |
|||
p->drawLine(x, t, x, b + c_markLength); |
|||
if (b < p->viewport().bottom()) |
|||
{ |
|||
p->setPen(QColor(144, 144, 144)); |
|||
p->drawText(QRect(x - c_xSpacing / 2, b + c_markLength + c_markSpacing, c_xSpacing, p->viewport().height() - (b + c_markLength + c_markSpacing)), Qt::AlignHCenter|Qt::AlignTop, QString::fromStdString(xLabel(f))); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
p->setPen(QColor(236, 236, 236)); |
|||
p->drawLine(x, t, x, b); |
|||
} |
|||
} |
|||
} |
|||
|
|||
p->setClipRect(active); |
|||
return true; |
|||
} |
|||
|
|||
void Grapher::drawLineGraph(vector<float> const& _data, QColor _color, QBrush const& _fillToZero, float _width) const |
|||
{ |
|||
int s = _data.size(); |
|||
QPoint l; |
|||
for (int i = 0; i < s; ++i) |
|||
{ |
|||
int zy = yP(0.f); |
|||
QPoint h(xTP(i), yTP(_data[i])); |
|||
if (i) |
|||
{ |
|||
if (_fillToZero != Qt::NoBrush) |
|||
{ |
|||
p->setPen(Qt::NoPen); |
|||
p->setBrush(_fillToZero); |
|||
p->drawPolygon(QPolygon(QVector<QPoint>() << QPoint(h.x(), zy) << h << l << QPoint(l.x(), zy))); |
|||
} |
|||
p->setPen(QPen(_color, _width)); |
|||
p->drawLine(QLine(l, h)); |
|||
} |
|||
l = h; |
|||
} |
|||
} |
|||
|
|||
void Grapher::ruleY(float _x, QColor _color, float _width) const |
|||
{ |
|||
p->setPen(QPen(_color, _width)); |
|||
p->drawLine(xTP(_x), active.top(), xTP(_x), active.bottom()); |
|||
} |
|||
|
|||
void Grapher::drawLineGraph(std::function<float(float)> const& _f, QColor _color, QBrush const& _fillToZero, float _width) const |
|||
{ |
|||
QPoint l; |
|||
for (int x = active.left(); x < active.right(); x += 2) |
|||
{ |
|||
int zy = yP(0.f); |
|||
QPoint h(x, yTP(_f(xRU(x)))); |
|||
if (x != active.left()) |
|||
{ |
|||
if (_fillToZero != Qt::NoBrush) |
|||
{ |
|||
p->setPen(Qt::NoPen); |
|||
p->setBrush(_fillToZero); |
|||
p->drawPolygon(QPolygon(QVector<QPoint>() << QPoint(h.x(), zy) << h << l << QPoint(l.x(), zy))); |
|||
} |
|||
p->setPen(QPen(_color, _width)); |
|||
p->drawLine(QLine(l, h)); |
|||
} |
|||
l = h; |
|||
} |
|||
} |
|||
|
|||
void Grapher::labelYOrderedPoints(map<float, float> const& _data, int _maxCount, float _minFactor) const |
|||
{ |
|||
int ly = active.top() + 6; |
|||
int pc = 0; |
|||
if (_data.empty()) |
|||
return; |
|||
float smallestAllowed = prev(_data.end())->first * _minFactor; |
|||
for (auto peaki = _data.rbegin(); peaki != _data.rend(); ++peaki) |
|||
if ((peaki->first > smallestAllowed || _minFactor == 0) && pc < _maxCount) |
|||
{ |
|||
auto peak = *peaki; |
|||
int x = xTP(peak.second); |
|||
int y = yTP(peak.first); |
|||
p->setPen(QColor::fromHsvF(float(pc) / _maxCount, 1.f, 0.5f, 0.5f)); |
|||
p->drawEllipse(QPoint(x, y), 4, 4); |
|||
p->drawLine(x, y - 4, x, ly + 6); |
|||
QString f = QString::fromStdString(pLabel(xT(peak.second), yT(peak.first))); |
|||
int fw = p->fontMetrics().width(f); |
|||
p->drawLine(x + 16 + fw + 2, ly + 6, x, ly + 6); |
|||
p->setPen(QColor::fromHsvF(0, 0.f, .35f)); |
|||
p->fillRect(QRect(x+12, ly-6, fw + 8, 12), QBrush(QColor(255, 255, 255, 160))); |
|||
p->drawText(QRect(x+16, ly-6, 160, 12), Qt::AlignVCenter, f); |
|||
ly += 14; |
|||
++pc; |
|||
} |
|||
} |
@ -1,116 +0,0 @@ |
|||
/* BEGIN COPYRIGHT
|
|||
* |
|||
* This file is part of Noted. |
|||
* |
|||
* Copyright ©2011, 2012, Lancaster Logic Response Limited. |
|||
* |
|||
* Noted 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 2 of the License, or |
|||
* (at your option) any later version. |
|||
* |
|||
* Noted 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 Noted. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <map> |
|||
#include <vector> |
|||
#include <string> |
|||
#include <utility> |
|||
#include <functional> |
|||
|
|||
#include <QtGui/QBrush> |
|||
#include <QtCore/QRect> |
|||
|
|||
class QPainter; |
|||
|
|||
namespace lb |
|||
{ |
|||
|
|||
class Grapher |
|||
{ |
|||
public: |
|||
Grapher(): p(0) {} |
|||
void init(QPainter* _p, std::pair<float, float> _xRange, std::pair<float, float> _yRange, std::function<std::string(float _f)> _xLabel, std::function<std::string(float _f)> _yLabel, std::function<std::string(float, float)> _pLabel, int _leftGutter = 30, int _bottomGutter = 16); |
|||
void init(QPainter* _p, std::pair<float, float> _xRange, std::pair<float, float> _yRange, std::function<std::string(float _f)> _xLabel, std::function<std::string(float _f)> _yLabel, std::function<std::string(float, float)> _pLabel, QRect _active) |
|||
{ |
|||
p = _p; |
|||
active = _active; |
|||
xRange = _xRange; |
|||
yRange = _yRange; |
|||
dx = xRange.second - xRange.first; |
|||
dy = yRange.second - yRange.first; |
|||
xLabel = _xLabel; |
|||
yLabel = _yLabel; |
|||
pLabel = _pLabel; |
|||
} |
|||
|
|||
void setDataTransform(float _xM, float _xC, float _yM, float _yC) |
|||
{ |
|||
xM = _xM; |
|||
xC = _xC; |
|||
yM = _yM; |
|||
yC = _yC; |
|||
} |
|||
void setDataTransform(float _xM, float _xC) |
|||
{ |
|||
xM = _xM; |
|||
xC = _xC; |
|||
yM = 1.f; |
|||
yC = 0.f; |
|||
} |
|||
void resetDataTransform() { xM = yM = 1.f; xC = yC = 0.f; } |
|||
|
|||
bool drawAxes(bool _x = true, bool _y = true) const; |
|||
void drawLineGraph(std::vector<float> const& _data, QColor _color = QColor(128, 128, 128), QBrush const& _fillToZero = Qt::NoBrush, float _width = 0.f) const; |
|||
void drawLineGraph(std::function<float(float)> const& _f, QColor _color = QColor(128, 128, 128), QBrush const& _fillToZero = Qt::NoBrush, float _width = 0.f) const; |
|||
void ruleX(float _y, QColor _color = QColor(128, 128, 128), float _width = 0.f) const; |
|||
void ruleY(float _x, QColor _color = QColor(128, 128, 128), float _width = 0.f) const; |
|||
void labelYOrderedPoints(std::map<float, float> const& _translatedData, int _maxCount = 20, float _minFactor = .01f) const; |
|||
|
|||
protected: |
|||
QPainter* p = nullptr; |
|||
QRect active; |
|||
std::pair<float, float> xRange; |
|||
std::pair<float, float> yRange; |
|||
|
|||
float xM = 0; |
|||
float xC = 0; |
|||
float yM = 0; |
|||
float yC = 0; |
|||
|
|||
float dx = 0; |
|||
float dy = 0; |
|||
|
|||
std::function<std::string(float _f)> xLabel; |
|||
std::function<std::string(float _f)> yLabel; |
|||
std::function<std::string(float _x, float _y)> pLabel; |
|||
|
|||
float fontPixelSize = 0; |
|||
|
|||
// Translate from raw indexed data into x/y graph units. Only relevant for indexed data.
|
|||
float xT(float _dataIndex) const { return _dataIndex * xM + xC; } |
|||
float yT(float _dataValue) const { return _dataValue * yM + yC; } |
|||
// Translate from x/y graph units to widget pixels.
|
|||
int xP(float _xUnits) const { return active.left() + (_xUnits - xRange.first) / dx * active.width(); } |
|||
int yP(float _yUnits) const { return active.bottom() - (_yUnits - yRange.first) / dy * active.height(); } |
|||
QPoint P(float _x, float _y) const { return QPoint(xP(_x), yP(_y)); } |
|||
// Translate direcly from raw indexed data to widget pixels.
|
|||
int xTP(float _dataIndex) const { return active.left() + (xT(_dataIndex) - xRange.first) / dx * active.width(); } |
|||
int yTP(float _dataValue) const { return active.bottom() - (yT(_dataValue) - yRange.first) / dy * active.height(); } |
|||
// Translate back from pixels into graph units.
|
|||
float xU(int _xPixels) const { return float(_xPixels - active.left()) / active.width() * dx + xRange.first; } |
|||
// Translate back from graph units into raw data index.
|
|||
float xR(float _xUnits) const { return (_xUnits - xC) / xM; } |
|||
// Translate directly from pixels into raw data index. xRU(xTP(X)) == X
|
|||
float xRU(int _xPixels) const { return xR(xU(_xPixels)); } |
|||
}; |
|||
|
|||
} |
File diff suppressed because it is too large
@ -1,104 +0,0 @@ |
|||
/*
|
|||
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 <QMenu> |
|||
#include "MainFace.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
|
|||
void AccountNamer::noteKnownChanged() |
|||
{ |
|||
if (m_main) |
|||
m_main->noteKnownAddressesChanged(this); |
|||
} |
|||
|
|||
void AccountNamer::noteNamesChanged() |
|||
{ |
|||
if (m_main) |
|||
m_main->noteAddressNamesChanged(this); |
|||
} |
|||
|
|||
void MainFace::notePlugin(std::function<Plugin*(MainFace*)> const& _new) |
|||
{ |
|||
if (!s_linkedPlugins) |
|||
s_linkedPlugins = new std::vector<std::function<Plugin*(MainFace*)>>(); |
|||
s_linkedPlugins->push_back(_new); |
|||
} |
|||
|
|||
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_dock->setObjectName(_title); |
|||
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); |
|||
} |
|||
|
|||
QAction* Plugin::addMenuItem(QString _n, QString _menuName, bool _sep) |
|||
{ |
|||
QAction* a = new QAction(_n, main()); |
|||
QMenu* m = main()->findChild<QMenu*>(_menuName); |
|||
if (_sep) |
|||
m->addSeparator(); |
|||
m->addAction(a); |
|||
return a; |
|||
} |
|||
|
|||
std::vector<std::function<Plugin*(MainFace*)>>* MainFace::s_linkedPlugins = nullptr; |
|||
|
|||
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(); |
|||
} |
@ -1,167 +0,0 @@ |
|||
/*
|
|||
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" |
|||
|
|||
class QSettings; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
class WebThreeDirect; |
|||
namespace eth { class Client; class LogFilter; } |
|||
namespace shh { class WhisperHost; } |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
#ifndef _MSC_VER // MSVC does not like gcc compiler attributes
|
|||
#define DEV_AZ_NOTE_PLUGIN(ClassName) \ |
|||
static bool s_notePlugin __attribute__((unused)) = [](){ MainFace::notePlugin([](MainFace* m){ return new ClassName(m); }); return true; }() |
|||
#else |
|||
#define DEV_AZ_NOTE_PLUGIN(ClassName) \ |
|||
static bool s_notePlugin = [](){ MainFace::notePlugin([](MainFace* m){ return new ClassName(m); }); return true; }() |
|||
#endif |
|||
|
|||
class Plugin; |
|||
class MainFace; |
|||
class Main; |
|||
class OurWebThreeStubServer; |
|||
|
|||
using WatchHandler = std::function<void(dev::eth::LocalisedLogEntries const&)>; |
|||
|
|||
class AccountNamer |
|||
{ |
|||
friend class Main; |
|||
|
|||
public: |
|||
virtual std::string toName(Address const&) const { return std::string(); } |
|||
virtual Address toAddress(std::string const&) const { return Address(); } |
|||
virtual Addresses knownAddresses() const { return Addresses(); } |
|||
|
|||
protected: |
|||
void noteKnownChanged(); |
|||
void noteNamesChanged(); |
|||
|
|||
private: |
|||
MainFace* m_main = nullptr; |
|||
}; |
|||
|
|||
class MainFace: public QMainWindow, public Context |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit MainFace(QWidget* _parent = nullptr): QMainWindow(_parent) {} |
|||
|
|||
static void notePlugin(std::function<Plugin*(MainFace*)> const& _new); |
|||
|
|||
void adoptPlugin(Plugin* _p); |
|||
void killPlugins(); |
|||
|
|||
void allChange(); |
|||
|
|||
using Context::render; |
|||
|
|||
// 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 OurWebThreeStubServer* web3Server() 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; |
|||
virtual void uninstallWatch(unsigned _id) = 0; |
|||
|
|||
// Account naming API
|
|||
virtual void install(AccountNamer* _adopt) = 0; |
|||
virtual void uninstall(AccountNamer* _kill) = 0; |
|||
virtual void noteKnownAddressesChanged(AccountNamer*) = 0; |
|||
virtual void noteAddressNamesChanged(AccountNamer*) = 0; |
|||
virtual Address toAddress(std::string const&) const = 0; |
|||
virtual std::string toName(Address const&) const = 0; |
|||
virtual Addresses allKnownAddresses() const = 0; |
|||
|
|||
virtual void noteSettingsChanged() = 0; |
|||
|
|||
protected: |
|||
template <class F> void forEach(F const& _f) { for (auto const& p: m_plugins) _f(p.second); } |
|||
std::shared_ptr<Plugin> takePlugin(std::string const& _name) { auto it = m_plugins.find(_name); std::shared_ptr<Plugin> ret; if (it != m_plugins.end()) { ret = it->second; m_plugins.erase(it); } return ret; } |
|||
|
|||
static std::vector<std::function<Plugin*(MainFace*)>>* s_linkedPlugins; |
|||
|
|||
signals: |
|||
void knownAddressesChanged(); |
|||
void addressNamesChanged(); |
|||
void keyManagerChanged(); |
|||
|
|||
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() const { 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); |
|||
QAction* addMenuItem(QString _name, QString _menuName, bool _separate = false); |
|||
|
|||
virtual void onAllChange() {} |
|||
virtual void readSettings(QSettings const&) {} |
|||
virtual void writeSettings(QSettings&) {} |
|||
|
|||
private: |
|||
MainFace* m_main = nullptr; |
|||
std::string m_name; |
|||
QDockWidget* m_dock = nullptr; |
|||
}; |
|||
|
|||
class AccountNamerPlugin: public Plugin, public AccountNamer |
|||
{ |
|||
protected: |
|||
AccountNamerPlugin(MainFace* _m, std::string const& _name): Plugin(_m, _name) { main()->install(this); } |
|||
~AccountNamerPlugin() { main()->uninstall(this); } |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
File diff suppressed because it is too large
@ -1,303 +0,0 @@ |
|||
/*
|
|||
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 MainWin.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#ifdef Q_MOC_RUN |
|||
#define BOOST_MPL_IF_HPP_INCLUDED |
|||
#endif |
|||
|
|||
#include <map> |
|||
#include <QtNetwork/QNetworkAccessManager> |
|||
#include <QtCore/QAbstractListModel> |
|||
#include <QtCore/QMutex> |
|||
#include <QtWidgets/QMainWindow> |
|||
#include <libdevcore/RLP.h> |
|||
#include <libethcore/Common.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#include <libethereum/State.h> |
|||
#include <libethereum/Executive.h> |
|||
#include <libwebthree/WebThree.h> |
|||
#include <libsolidity/CompilerStack.h> |
|||
#include "Context.h" |
|||
#include "Transact.h" |
|||
#include "NatspecHandler.h" |
|||
#include "Connect.h" |
|||
#include "MainFace.h" |
|||
|
|||
class QListWidgetItem; |
|||
class QActionGroup; |
|||
|
|||
namespace Ui { |
|||
class Main; |
|||
} |
|||
|
|||
namespace jsonrpc { |
|||
class HttpServer; |
|||
} |
|||
|
|||
class QWebEnginePage; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth |
|||
{ |
|||
class Client; |
|||
class State; |
|||
} |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
class OurWebThreeStubServer; |
|||
class DappLoader; |
|||
class DappHost; |
|||
struct Dapp; |
|||
|
|||
QString contentsOfQResource(std::string const& res); |
|||
|
|||
class Main: public MainFace |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit Main(QWidget *parent = 0); |
|||
~Main(); |
|||
|
|||
WebThreeDirect* web3() const override { return m_webThree.get(); } |
|||
OurWebThreeStubServer* web3Server() const override { return m_server.get(); } |
|||
eth::Client* ethereum() const override { return m_webThree->ethereum(); } |
|||
std::shared_ptr<shh::WhisperHost> whisper() const override { return m_webThree->whisper(); } |
|||
|
|||
bool confirm() const; |
|||
NatSpecFace* natSpec() { return &m_natSpecDB; } |
|||
|
|||
std::string pretty(dev::Address const& _a) const override; |
|||
std::string prettyU256(u256 const& _n) const override; |
|||
std::string render(dev::Address const& _a) const override; |
|||
std::pair<Address, bytes> fromString(std::string const& _a) const override; |
|||
std::string renderDiff(eth::StateDiff const& _d) const override; |
|||
|
|||
u256 gasPrice() const override; |
|||
|
|||
eth::KeyManager& keyManager() override { return m_keyManager; } |
|||
void noteKeysChanged() override { refreshBalances(); } |
|||
bool doConfirm(); |
|||
|
|||
Secret retrieveSecret(Address const& _address) const override; |
|||
|
|||
// Account naming API.
|
|||
void install(AccountNamer* _adopt) override; |
|||
void uninstall(AccountNamer* _kill) override; |
|||
void noteKnownAddressesChanged(AccountNamer*) override; |
|||
void noteAddressNamesChanged(AccountNamer*) override; |
|||
Address toAddress(std::string const&) const override; |
|||
std::string toName(Address const&) const override; |
|||
Addresses allKnownAddresses() const override; |
|||
|
|||
void noteSettingsChanged() override { writeSettings(); } |
|||
|
|||
public slots: |
|||
void load(QString _file); |
|||
void note(QString _entry); |
|||
void debug(QString _entry); |
|||
void warn(QString _entry); |
|||
QString contents(QString _file); |
|||
|
|||
int authenticate(QString _title, QString _text); |
|||
|
|||
void onKeysChanged(); |
|||
|
|||
private slots: |
|||
void eval(QString const& _js); |
|||
void addConsoleMessage(QString const& _js, QString const& _s); |
|||
|
|||
// Application
|
|||
void on_about_triggered(); |
|||
void on_quit_triggered() { close(); } |
|||
|
|||
// Network
|
|||
void on_go_triggered(); |
|||
void on_net_triggered(); |
|||
void on_connect_triggered(); |
|||
void on_idealPeers_valueChanged(int); |
|||
|
|||
// Mining
|
|||
void on_mine_triggered(); |
|||
void on_prepNextDAG_triggered(); |
|||
|
|||
// View
|
|||
void on_refresh_triggered(); |
|||
void on_showAll_triggered() { refreshBlockChain(); } |
|||
void on_preview_triggered(); |
|||
|
|||
// Account management
|
|||
void on_killAccount_triggered(); |
|||
void on_importKey_triggered(); |
|||
void on_reencryptKey_triggered(); |
|||
void on_reencryptAll_triggered(); |
|||
void on_importKeyFile_triggered(); |
|||
void on_claimPresale_triggered(); |
|||
void on_importPresale_triggered(); |
|||
void on_exportKey_triggered(); |
|||
|
|||
// Tools
|
|||
void on_newTransaction_triggered(); |
|||
void on_loadJS_triggered(); |
|||
|
|||
// Stuff concerning the blocks/transactions/accounts panels
|
|||
void on_ourAccounts_itemClicked(QListWidgetItem* _i); |
|||
void on_ourAccounts_doubleClicked(); |
|||
void on_transactionQueue_currentItemChanged(); |
|||
void on_blockChainFilter_textChanged(); |
|||
void on_blocks_currentItemChanged(); |
|||
|
|||
// Misc
|
|||
void on_urlEdit_returnPressed(); |
|||
void on_jsInput_returnPressed(); |
|||
void on_nameReg_textChanged(); |
|||
|
|||
// Special (debug) stuff
|
|||
void on_paranoia_triggered(); |
|||
void on_killBlockchain_triggered(); |
|||
void on_clearPending_triggered(); |
|||
void on_injectBlock_triggered(); |
|||
void on_forceMining_triggered(); |
|||
void on_usePrivate_triggered(); |
|||
void on_turboMining_triggered(); |
|||
void on_retryUnknown_triggered(); |
|||
void on_vmInterpreter_triggered(); |
|||
void on_vmJIT_triggered(); |
|||
void on_vmSmart_triggered(); |
|||
void on_rewindChain_triggered(); |
|||
|
|||
// Debugger
|
|||
void on_debugCurrent_triggered(); |
|||
void on_debugPending_triggered(); |
|||
void on_debugDumpState_triggered() { debugDumpState(1); } |
|||
void on_debugDumpStatePre_triggered() { debugDumpState(0); } |
|||
void on_dumpBlockState_triggered(); |
|||
|
|||
// Config
|
|||
void on_gasPrices_triggered(); |
|||
void on_sentinel_triggered(); |
|||
|
|||
void refreshBlockChain(); |
|||
|
|||
// Dapps
|
|||
void dappLoaded(Dapp& _dapp); //qt does not support rvalue refs for signals
|
|||
void pageLoaded(QByteArray const& _content, QString const& _mimeType, QUrl const& _uri); |
|||
|
|||
signals: |
|||
void poll(); |
|||
|
|||
private: |
|||
template <class P> void loadPlugin() { Plugin* p = new P(this); initPlugin(p); } |
|||
void initPlugin(Plugin* _p); |
|||
void finalisePlugin(Plugin* _p); |
|||
void unloadPlugin(std::string const& _name); |
|||
|
|||
void debugDumpState(int _add); |
|||
|
|||
p2p::NetworkPreferences netPrefs() const; |
|||
|
|||
QString lookup(QString const& _n) const; |
|||
Address getNameReg() const; |
|||
Address getCurrencies() const; |
|||
|
|||
void updateFee(); |
|||
void readSettings(bool _skipGeometry = false, bool _onlyGeometry = false); |
|||
void writeSettings(); |
|||
|
|||
void setPrivateChain(QString const& _private, bool _forceConfigure = false); |
|||
|
|||
unsigned installWatch(eth::LogFilter const& _tf, WatchHandler const& _f) override; |
|||
unsigned installWatch(h256 const& _tf, WatchHandler const& _f) override; |
|||
void uninstallWatch(unsigned _w) override; |
|||
|
|||
void keysChanged(); |
|||
|
|||
void onNewPending(); |
|||
void onNewBlock(); |
|||
void onNameRegChange(); |
|||
void onCurrenciesChange(); |
|||
void onBalancesChange(); |
|||
|
|||
void installWatches(); |
|||
void installCurrenciesWatch(); |
|||
void installNameRegWatch(); |
|||
void installBalancesWatch(); |
|||
|
|||
virtual void timerEvent(QTimerEvent*) override; |
|||
|
|||
void refreshNetwork(); |
|||
void refreshMining(); |
|||
void refreshCache(); |
|||
|
|||
void refreshAll(); |
|||
void refreshPending(); |
|||
void refreshBlockCount(); |
|||
void refreshBalances(); |
|||
|
|||
void setBeneficiary(Address const& _b); |
|||
std::string getPassword(std::string const& _title, std::string const& _for, std::string* _hint = nullptr, bool* _ok = nullptr); |
|||
|
|||
std::unique_ptr<Ui::Main> ui; |
|||
|
|||
std::unique_ptr<WebThreeDirect> m_webThree; |
|||
|
|||
std::map<unsigned, WatchHandler> m_handlers; |
|||
unsigned m_nameRegFilter = (unsigned)-1; |
|||
unsigned m_currenciesFilter = (unsigned)-1; |
|||
unsigned m_balancesFilter = (unsigned)-1; |
|||
|
|||
QByteArray m_networkConfig; |
|||
QStringList m_servers; |
|||
eth::KeyManager m_keyManager; |
|||
QString m_privateChain; |
|||
dev::Address m_nameReg; |
|||
dev::Address m_beneficiary; |
|||
|
|||
QActionGroup* m_vmSelectionGroup = nullptr; |
|||
|
|||
QList<QPair<QString, QString>> m_consoleHistory; |
|||
|
|||
std::unique_ptr<jsonrpc::HttpServer> m_httpConnector; |
|||
std::unique_ptr<OurWebThreeStubServer> m_server; |
|||
|
|||
static std::string fromRaw(h256 const& _n, unsigned* _inc = nullptr); |
|||
NatspecHandler m_natSpecDB; |
|||
|
|||
Transact* m_transact; |
|||
std::unique_ptr<DappHost> m_dappHost; |
|||
DappLoader* m_dappLoader; |
|||
QWebEnginePage* m_webPage; |
|||
|
|||
Connect m_connect; |
|||
|
|||
std::unordered_set<AccountNamer*> m_namers; |
|||
|
|||
bool m_destructing = false; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,116 +0,0 @@ |
|||
/*
|
|||
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 MiningView.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "MiningView.h" |
|||
|
|||
#include <QtWidgets> |
|||
#include <QtCore> |
|||
#include <libethereum/Client.h> |
|||
#include "Grapher.h" |
|||
|
|||
using namespace std; |
|||
using namespace lb; |
|||
// do *not* use eth since unsigned conflicts with Qt's global unit definition
|
|||
// using namespace dev;
|
|||
using namespace dev::az; |
|||
using namespace dev::eth; |
|||
using dev::eth::MineInfo; |
|||
using dev::eth::WorkingProgress; |
|||
using dev::toString; |
|||
using dev::trimFront; |
|||
|
|||
string id(float _y) { return toString(_y); } |
|||
string s(float _x){ return toString(round(_x * 1000) / 1000) + (!_x ? "s" : ""); } |
|||
string sL(float _x, float _y) { return toString(round(_x * 1000)) + "s (" + toString(_y) + ")"; } |
|||
|
|||
MiningView::MiningView(QWidget* _p): QWidget(_p) |
|||
{ |
|||
} |
|||
|
|||
void MiningView::appendStats(list<MineInfo> const& _i, WorkingProgress const& _p) |
|||
{ |
|||
(void)_p; |
|||
if (_i.empty()) |
|||
return; |
|||
|
|||
/* unsigned o = m_values.size();
|
|||
for (MineInfo const& i: _i) |
|||
{ |
|||
m_values.push_back(i.best); |
|||
m_lastBest = min(m_lastBest, i.best); |
|||
m_bests.push_back(m_lastBest); |
|||
m_reqs.push_back(i.requirement); |
|||
if (i.completed) |
|||
{ |
|||
m_completes.push_back(o); |
|||
m_resets.push_back(o); |
|||
m_haveReset = false; |
|||
m_lastBest = 1e99; |
|||
} |
|||
++o; |
|||
} |
|||
if (m_haveReset) |
|||
{ |
|||
m_resets.push_back(o - 1); |
|||
m_lastBest = 1e99; |
|||
m_haveReset = false; |
|||
} |
|||
|
|||
o = max<int>(0, (int)m_values.size() - (int)m_duration); |
|||
trimFront(m_values, o); |
|||
trimFront(m_bests, o); |
|||
trimFront(m_reqs, o); |
|||
|
|||
for (auto& i: m_resets) |
|||
i -= o; |
|||
m_resets.erase(remove_if(m_resets.begin(), m_resets.end(), [](int i){return i < 0;}), m_resets.end()); |
|||
for (auto& i: m_completes) |
|||
i -= o; |
|||
m_completes.erase(remove_if(m_completes.begin(), m_completes.end(), [](int i){return i < 0;}), m_completes.end()); |
|||
|
|||
m_progress = _p; |
|||
update();*/ |
|||
} |
|||
|
|||
void MiningView::resetStats() |
|||
{ |
|||
m_haveReset = true; |
|||
} |
|||
|
|||
void MiningView::paintEvent(QPaintEvent*) |
|||
{ |
|||
/*
|
|||
Grapher g; |
|||
QPainter p(this); |
|||
|
|||
g.init(&p, make_pair(0.f, max((float)m_duration * 0.1f, (float)m_values.size() * 0.1f)), make_pair(0.0f, 255.f - ((float)m_progress.requirement - 4.0f)), s, id, sL); |
|||
g.drawAxes(); |
|||
g.setDataTransform(0.1f, 0, -1.0f, 255.f); |
|||
|
|||
g.drawLineGraph(m_values, QColor(192, 192, 192)); |
|||
g.drawLineGraph(m_bests, QColor(128, 128, 128)); |
|||
g.drawLineGraph(m_reqs, QColor(128, 64, 64)); |
|||
for (auto r: m_resets) |
|||
g.ruleY(r - 1, QColor(128, 128, 128)); |
|||
for (auto r: m_completes) |
|||
g.ruleY(r, QColor(192, 64, 64)); |
|||
*/ |
|||
} |
@ -1,72 +0,0 @@ |
|||
/*
|
|||
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 MiningView.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#ifdef Q_MOC_RUN |
|||
#define BOOST_MPL_IF_HPP_INCLUDED |
|||
#endif |
|||
|
|||
#include <list> |
|||
#include <QtWidgets/QWidget> |
|||
#ifndef Q_MOC_RUN |
|||
#include <libethereum/Client.h> |
|||
#endif |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth |
|||
{ |
|||
struct MineInfo; |
|||
} |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
class MiningView: public QWidget |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
MiningView(QWidget* _p = nullptr); |
|||
|
|||
void appendStats(std::list<dev::eth::MineInfo> const& _l, dev::eth::WorkingProgress const& _p); |
|||
void resetStats(); |
|||
|
|||
protected: |
|||
virtual void paintEvent(QPaintEvent*); |
|||
|
|||
private: |
|||
dev::eth::WorkingProgress m_progress; |
|||
unsigned m_duration = 300; |
|||
std::vector<float> m_values; |
|||
std::vector<float> m_bests; |
|||
std::vector<float> m_reqs; |
|||
std::vector<int> m_resets; |
|||
std::vector<int> m_completes; |
|||
double m_lastBest = 1e31; |
|||
bool m_haveReset = false; |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
@ -1,103 +0,0 @@ |
|||
/*
|
|||
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 NatspecHandler.cpp
|
|||
* @author Lefteris Karapetsas <lefteris@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
#include "NatspecHandler.h" |
|||
#include <string> |
|||
#include <boost/filesystem.hpp> |
|||
|
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/CommonData.h> |
|||
#include <libdevcore/Exceptions.h> |
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libethereum/Defaults.h> |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
using namespace std; |
|||
namespace fs = boost::filesystem; |
|||
|
|||
NatspecHandler::NatspecHandler() |
|||
{ |
|||
string path = Defaults::dbPath(); |
|||
fs::create_directories(path); |
|||
DEV_IGNORE_EXCEPTIONS(fs::permissions(path, fs::owner_all)); |
|||
ldb::Options o; |
|||
o.create_if_missing = true; |
|||
ldb::DB::Open(o, path + "/natspec", &m_db); |
|||
} |
|||
|
|||
NatspecHandler::~NatspecHandler() |
|||
{ |
|||
delete m_db; |
|||
} |
|||
|
|||
void NatspecHandler::add(dev::h256 const& _contractHash, string const& _doc) |
|||
{ |
|||
m_db->Put(m_writeOptions, _contractHash.ref(), _doc); |
|||
cdebug << "Registering NatSpec: " << _contractHash << _doc; |
|||
} |
|||
|
|||
string NatspecHandler::retrieve(dev::h256 const& _contractHash) const |
|||
{ |
|||
string ret; |
|||
m_db->Get(m_readOptions, _contractHash.ref(), &ret); |
|||
cdebug << "Looking up NatSpec: " << _contractHash << ret; |
|||
return ret; |
|||
} |
|||
|
|||
string NatspecHandler::getUserNotice(string const& json, dev::bytes const& _transactionData) |
|||
{ |
|||
Json::Value natspec; |
|||
Json::Value userNotice; |
|||
m_reader.parse(json, natspec); |
|||
|
|||
FixedHash<4> transactionFunctionHash((bytesConstRef(&_transactionData).cropped(0, 4).toBytes())); |
|||
|
|||
Json::Value methods = natspec["methods"]; |
|||
for (Json::ValueIterator it = methods.begin(); it != methods.end(); ++it) |
|||
{ |
|||
Json::Value keyValue = it.key(); |
|||
if (!keyValue.isString()) |
|||
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Illegal Natspec JSON detected")); |
|||
|
|||
string functionSig = keyValue.asString(); |
|||
FixedHash<4> functionHash(dev::sha3(functionSig)); |
|||
|
|||
if (functionHash == transactionFunctionHash) |
|||
{ |
|||
Json::Value val = (*it)["notice"]; |
|||
if (!val.isString()) |
|||
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Illegal Natspec JSON detected")); |
|||
return val.asString(); |
|||
} |
|||
} |
|||
|
|||
// not found
|
|||
return string(); |
|||
} |
|||
|
|||
string NatspecHandler::getUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionData) |
|||
{ |
|||
return getUserNotice(retrieve(_contractHash), _transactionData); |
|||
} |
|||
|
|||
|
@ -1,62 +0,0 @@ |
|||
/*
|
|||
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 NatspecHandler.h
|
|||
* @author Lefteris Karapetsas <lefteris@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libdevcore/db.h> |
|||
#include <json/json.h> |
|||
#include <libdevcore/FixedHash.h> |
|||
#include "Context.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class NatspecHandler: public NatSpecFace |
|||
{ |
|||
public: |
|||
NatspecHandler(); |
|||
~NatspecHandler(); |
|||
|
|||
/// Stores locally in a levelDB a key value pair of contract code hash to natspec documentation
|
|||
virtual void add(dev::h256 const& _contractHash, std::string const& _doc) override; |
|||
/// Retrieves the natspec documentation as a string given a contract code hash
|
|||
std::string retrieve(dev::h256 const& _contractHash) const override; |
|||
|
|||
/// Given a json natspec string and the transaction data return the user notice
|
|||
virtual std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData) override; |
|||
/// Given a contract code hash and the transaction's data retrieve the natspec documention's
|
|||
/// user notice for that transaction.
|
|||
/// @returns The user notice or an empty string if no natspec for the contract exists
|
|||
/// or if the existing natspec does not document the @c _methodName
|
|||
virtual std::string getUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionDacta) override; |
|||
|
|||
private: |
|||
ldb::ReadOptions m_readOptions; |
|||
ldb::WriteOptions m_writeOptions; |
|||
ldb::DB* m_db = nullptr; |
|||
Json::Reader m_reader; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,185 +0,0 @@ |
|||
/*
|
|||
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 OurWebThreeStubServer.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "OurWebThreeStubServer.h" |
|||
#include <QMessageBox> |
|||
#include <QAbstractButton> |
|||
#include <libwebthree/WebThree.h> |
|||
#include <libnatspec/NatspecExpressionEvaluator.h> |
|||
#include "MainWin.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
OurWebThreeStubServer::OurWebThreeStubServer( |
|||
jsonrpc::AbstractServerConnector& _conn, |
|||
Main* _main |
|||
): |
|||
WebThreeStubServer(_conn, *_main->web3(), make_shared<OurAccountHolder>(_main), vector<KeyPair>{}, _main->keyManager(), *static_cast<TrivialGasPricer*>(_main->ethereum()->gasPricer().get())), |
|||
m_main(_main) |
|||
{ |
|||
} |
|||
|
|||
string OurWebThreeStubServer::shh_newIdentity() |
|||
{ |
|||
KeyPair kp = dev::KeyPair::create(); |
|||
emit onNewId(QString::fromStdString(toJS(kp.sec()))); |
|||
return toJS(kp.pub()); |
|||
} |
|||
|
|||
OurAccountHolder::OurAccountHolder(Main* _main): |
|||
AccountHolder([=](){ return _main->ethereum(); }), |
|||
m_main(_main) |
|||
{ |
|||
connect(_main, SIGNAL(poll()), this, SLOT(doValidations())); |
|||
} |
|||
|
|||
bool OurAccountHolder::showAuthenticationPopup(string const& _title, string const& _text) |
|||
{ |
|||
if (!m_main->confirm()) |
|||
{ |
|||
cnote << "Skipping confirmation step for: " << _title << "\n" << _text; |
|||
return true; |
|||
} |
|||
|
|||
QMessageBox userInput; |
|||
userInput.setText(QString::fromStdString(_title)); |
|||
userInput.setInformativeText(QString::fromStdString(_text)); |
|||
userInput.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); |
|||
userInput.button(QMessageBox::Ok)->setText("Allow"); |
|||
userInput.button(QMessageBox::Cancel)->setText("Reject"); |
|||
userInput.setDefaultButton(QMessageBox::Cancel); |
|||
return userInput.exec() == QMessageBox::Ok; |
|||
//QMetaObject::invokeMethod(m_main, "authenticate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, button), Q_ARG(QString, QString::fromStdString(_title)), Q_ARG(QString, QString::fromStdString(_text)));
|
|||
//return button == QMessageBox::Ok;
|
|||
} |
|||
|
|||
bool OurAccountHolder::showCreationNotice(TransactionSkeleton const& _t, bool _toProxy) |
|||
{ |
|||
return showAuthenticationPopup("Contract Creation Transaction", string("ÐApp is attemping to create a contract; ") + (_toProxy ? "(this transaction is not executed directly, but forwarded to another ÐApp) " : "") + "to be endowed with " + formatBalance(_t.value) + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); |
|||
} |
|||
|
|||
bool OurAccountHolder::showSendNotice(TransactionSkeleton const& _t, bool _toProxy) |
|||
{ |
|||
return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to) + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") + |
|||
", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); |
|||
} |
|||
|
|||
bool OurAccountHolder::showUnknownCallNotice(TransactionSkeleton const& _t, bool _toProxy) |
|||
{ |
|||
return showAuthenticationPopup("DANGEROUS! Unknown Contract Transaction!", |
|||
"ÐApp is attempting to call into an unknown contract at address " + |
|||
m_main->pretty(_t.to) + ".\n\n" + |
|||
(_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + |
|||
"Call involves sending " + |
|||
formatBalance(_t.value) + " to the recipient, with additional network fees of up to " + |
|||
formatBalance(_t.gas * _t.gasPrice) + |
|||
"However, this also does other stuff which we don't understand, and does so in your name.\n\n" + |
|||
"WARNING: This is probably going to cost you at least " + |
|||
formatBalance(_t.value + _t.gas * _t.gasPrice) + |
|||
", however this doesn't include any side-effects, which could be of far greater importance.\n\n" + |
|||
"REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"); |
|||
} |
|||
|
|||
h256 OurAccountHolder::authenticate(TransactionSkeleton const& _t) |
|||
{ |
|||
Guard l(x_queued); |
|||
m_queued.push(_t); |
|||
return h256(); |
|||
} |
|||
|
|||
void OurAccountHolder::doValidations() |
|||
{ |
|||
Guard l(x_queued); |
|||
while (!m_queued.empty()) |
|||
{ |
|||
auto t = m_queued.front(); |
|||
m_queued.pop(); |
|||
|
|||
bool proxy = isProxyAccount(t.from); |
|||
if (!proxy && !isRealAccount(t.from)) |
|||
{ |
|||
cwarn << "Trying to send from non-existant account" << t.from; |
|||
return; |
|||
} |
|||
|
|||
// TODO: determine gas price.
|
|||
|
|||
if (!validateTransaction(t, proxy)) |
|||
return; |
|||
|
|||
if (proxy) |
|||
queueTransaction(t); |
|||
else |
|||
// sign and submit.
|
|||
if (Secret s = m_main->retrieveSecret(t.from)) |
|||
m_main->ethereum()->submitTransaction(t, s); |
|||
} |
|||
} |
|||
|
|||
AddressHash OurAccountHolder::realAccounts() const |
|||
{ |
|||
return m_main->keyManager().accountsHash(); |
|||
} |
|||
|
|||
bool OurAccountHolder::validateTransaction(TransactionSkeleton const& _t, bool _toProxy) |
|||
{ |
|||
if (!m_main->doConfirm()) |
|||
return true; |
|||
|
|||
if (_t.creation) |
|||
{ |
|||
// show notice concerning the creation code. TODO: this needs entering into natspec.
|
|||
return showCreationNotice(_t, _toProxy); |
|||
} |
|||
|
|||
h256 contractCodeHash = m_main->ethereum()->postState().codeHash(_t.to); |
|||
if (contractCodeHash == EmptySHA3) |
|||
{ |
|||
// recipient has no code - nothing special about this transaction, show basic value transfer info
|
|||
return showSendNotice(_t, _toProxy); |
|||
} |
|||
|
|||
string userNotice = m_main->natSpec()->getUserNotice(contractCodeHash, _t.data); |
|||
|
|||
if (userNotice.empty()) |
|||
return showUnknownCallNotice(_t, _toProxy); |
|||
|
|||
NatspecExpressionEvaluator evaluator; |
|||
userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); |
|||
|
|||
// otherwise it's a transaction to a contract for which we have the natspec
|
|||
return showAuthenticationPopup("Contract Transaction", |
|||
"ÐApp attempting to conduct contract interaction with " + |
|||
m_main->pretty(_t.to) + |
|||
": <b>" + userNotice + "</b>.\n\n" + |
|||
(_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + |
|||
(_t.value > 0 ? |
|||
"In addition, ÐApp is attempting to send " + |
|||
formatBalance(_t.value) + " to said recipient, with additional network fees of up to " + |
|||
formatBalance(_t.gas * _t.gasPrice) + " = " + |
|||
formatBalance(_t.value + _t.gas * _t.gasPrice) + "." |
|||
: |
|||
"Additional network fees are at most" + |
|||
formatBalance(_t.gas * _t.gasPrice) + ".") |
|||
); |
|||
} |
@ -1,86 +0,0 @@ |
|||
/*
|
|||
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 OurWebThreeStubServer.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include <queue> |
|||
#include <QtCore/QObject> |
|||
#include <libdevcore/Guards.h> |
|||
#include <libethcore/CommonJS.h> |
|||
#include <libdevcrypto/Common.h> |
|||
#include <libweb3jsonrpc/WebThreeStubServer.h> |
|||
#include <libweb3jsonrpc/AccountHolder.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
class Main; |
|||
|
|||
class OurAccountHolder: public QObject, public eth::AccountHolder |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
OurAccountHolder(Main* _main); |
|||
|
|||
public slots: |
|||
void doValidations(); |
|||
|
|||
protected: |
|||
// easiest to return keyManager.addresses();
|
|||
virtual dev::AddressHash realAccounts() const override; |
|||
// use web3 to submit a signed transaction to accept
|
|||
virtual dev::h256 authenticate(dev::eth::TransactionSkeleton const& _t) override; |
|||
|
|||
private: |
|||
bool showAuthenticationPopup(std::string const& _title, std::string const& _text); |
|||
bool showCreationNotice(eth::TransactionSkeleton const& _t, bool _toProxy); |
|||
bool showSendNotice(eth::TransactionSkeleton const& _t, bool _toProxy); |
|||
bool showUnknownCallNotice(eth::TransactionSkeleton const& _t, bool _toProxy); |
|||
|
|||
bool validateTransaction(eth::TransactionSkeleton const& _t, bool _toProxy); |
|||
|
|||
std::queue<eth::TransactionSkeleton> m_queued; |
|||
Mutex x_queued; |
|||
|
|||
Main* m_main; |
|||
}; |
|||
|
|||
class OurWebThreeStubServer: public QObject, public WebThreeStubServer |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, Main* main); |
|||
|
|||
virtual std::string shh_newIdentity() override; |
|||
|
|||
signals: |
|||
void onNewId(QString _s); |
|||
|
|||
private: |
|||
Main* m_main; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
@ -1,631 +0,0 @@ |
|||
/*
|
|||
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 Transact.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
// Make sure boost/asio.hpp is included before windows.h.
|
|||
#include <boost/asio.hpp> |
|||
|
|||
#include "Transact.h" |
|||
|
|||
#include <fstream> |
|||
#include <boost/algorithm/string.hpp> |
|||
#include <QFileDialog> |
|||
#include <QMessageBox> |
|||
#include <QClipboard> |
|||
#include <liblll/Compiler.h> |
|||
#include <liblll/CodeFragment.h> |
|||
#if ETH_SOLIDITY || !ETH_TRUE |
|||
#include <libsolidity/CompilerStack.h> |
|||
#include <libsolidity/Scanner.h> |
|||
#include <libsolidity/AST.h> |
|||
#include <libsolidity/SourceReferenceFormatter.h> |
|||
#endif |
|||
#include <libnatspec/NatspecExpressionEvaluator.h> |
|||
#include <libethereum/Client.h> |
|||
#include <libethereum/Utility.h> |
|||
#include <libethcore/ICAP.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#if ETH_SERPENT |
|||
#include <libserpent/funcs.h> |
|||
#include <libserpent/util.h> |
|||
#endif |
|||
#include "Debugger.h" |
|||
#include "ui_Transact.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
Transact::Transact(MainFace* _c, QWidget* _parent): |
|||
QDialog(_parent), |
|||
ui(new Ui::Transact), |
|||
m_main(_c) |
|||
{ |
|||
ui->setupUi(this); |
|||
|
|||
resetGasPrice(); |
|||
setValueUnits(ui->valueUnits, ui->value, 0); |
|||
|
|||
on_destination_currentTextChanged(QString()); |
|||
} |
|||
|
|||
Transact::~Transact() |
|||
{ |
|||
delete ui; |
|||
} |
|||
|
|||
void Transact::setEnvironment(AddressHash const& _accounts, dev::eth::Client* _eth, NatSpecFace* _natSpecDB) |
|||
{ |
|||
m_accounts = _accounts; |
|||
m_ethereum = _eth; |
|||
m_natSpecDB = _natSpecDB; |
|||
|
|||
auto old = ui->from->currentIndex(); |
|||
ui->from->clear(); |
|||
for (auto const& address: m_accounts) |
|||
{ |
|||
u256 b = ethereum()->balanceAt(address, PendingBlock); |
|||
QString s = QString("%2: %1").arg(formatBalance(b).c_str()).arg(QString::fromStdString(m_main->render(address))); |
|||
ui->from->addItem(s); |
|||
} |
|||
updateDestination(); |
|||
if (old > -1 && old < ui->from->count()) |
|||
ui->from->setCurrentIndex(old); |
|||
else if (ui->from->count()) |
|||
ui->from->setCurrentIndex(0); |
|||
} |
|||
|
|||
void Transact::resetGasPrice() |
|||
{ |
|||
setValueUnits(ui->gasPriceUnits, ui->gasPrice, m_main->gasPrice()); |
|||
} |
|||
|
|||
bool Transact::isCreation() const |
|||
{ |
|||
return ui->destination->currentText().isEmpty() || ui->destination->currentText() == "(Create Contract)"; |
|||
} |
|||
|
|||
u256 Transact::fee() const |
|||
{ |
|||
return gas() * gasPrice(); |
|||
} |
|||
|
|||
u256 Transact::gas() const |
|||
{ |
|||
return ui->gas->value() == -1 ? m_upperBound : ui->gas->value(); |
|||
} |
|||
|
|||
u256 Transact::value() const |
|||
{ |
|||
if (ui->valueUnits->currentIndex() == -1) |
|||
return 0; |
|||
return ui->value->value() * units()[units().size() - 1 - ui->valueUnits->currentIndex()].first; |
|||
} |
|||
|
|||
u256 Transact::gasPrice() const |
|||
{ |
|||
if (ui->gasPriceUnits->currentIndex() == -1) |
|||
return 0; |
|||
return ui->gasPrice->value() * units()[units().size() - 1 - ui->gasPriceUnits->currentIndex()].first; |
|||
} |
|||
|
|||
u256 Transact::total() const |
|||
{ |
|||
return value() + fee(); |
|||
} |
|||
|
|||
void Transact::updateDestination() |
|||
{ |
|||
// TODO: should be a Qt model.
|
|||
ui->destination->clear(); |
|||
ui->destination->addItem("(Create Contract)"); |
|||
QMultiMap<QString, QString> in; |
|||
for (Address const& a: m_main->allKnownAddresses()) |
|||
in.insert(QString::fromStdString(m_main->toName(a) + " (" + ICAP(a).encoded() + ")"), QString::fromStdString(a.hex())); |
|||
for (auto i = in.begin(); i != in.end(); ++i) |
|||
ui->destination->addItem(i.key(), i.value()); |
|||
|
|||
} |
|||
|
|||
void Transact::updateFee() |
|||
{ |
|||
// ui->fee->setText(QString("(gas sub-total: %1)").arg(formatBalance(fee()).c_str()));
|
|||
auto totalReq = total(); |
|||
ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str())); |
|||
|
|||
bool ok = false; |
|||
for (auto const& i: m_accounts) |
|||
if (ethereum()->balanceAt(i) >= totalReq) |
|||
{ |
|||
ok = true; |
|||
break; |
|||
} |
|||
// ui->send->setEnabled(ok);
|
|||
QPalette p = ui->total->palette(); |
|||
p.setColor(QPalette::WindowText, QColor(ok ? 0x00 : 0x80, 0x00, 0x00)); |
|||
ui->total->setPalette(p); |
|||
} |
|||
|
|||
void Transact::on_destination_currentTextChanged(QString) |
|||
{ |
|||
if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)") |
|||
{ |
|||
auto p = toAccount(); |
|||
if (p.first) |
|||
ui->calculatedName->setText(QString::fromStdString(m_main->render(p.first))); |
|||
else |
|||
ui->calculatedName->setText("Unknown Address"); |
|||
|
|||
// ui->calculatedName->setText(m_main->toName(a) + " (" + ICAP(a).encoded() + ")");
|
|||
|
|||
if (!p.second.empty()) |
|||
{ |
|||
m_data = p.second; |
|||
ui->data->setPlainText(QString::fromStdString("0x" + toHex(m_data))); |
|||
ui->data->setEnabled(false); |
|||
} |
|||
else if (!ui->data->isEnabled()) |
|||
{ |
|||
m_data.clear(); |
|||
ui->data->setPlainText(""); |
|||
ui->data->setEnabled(true); |
|||
} |
|||
} |
|||
else |
|||
ui->calculatedName->setText("Create Contract"); |
|||
rejigData(); |
|||
// updateFee();
|
|||
} |
|||
|
|||
void Transact::on_copyUnsigned_clicked() |
|||
{ |
|||
auto a = fromAccount(); |
|||
u256 nonce = ui->autoNonce->isChecked() ? ethereum()->countAt(a, PendingBlock) : ui->nonce->value(); |
|||
|
|||
Transaction t; |
|||
if (isCreation()) |
|||
// If execution is a contract creation, add Natspec to
|
|||
// a local Natspec LEVELDB
|
|||
t = Transaction(value(), gasPrice(), gas(), m_data, nonce); |
|||
else |
|||
// TODO: cache like m_data.
|
|||
t = Transaction(value(), gasPrice(), gas(), toAccount().first, m_data, nonce); |
|||
qApp->clipboard()->setText(QString::fromStdString(toHex(t.rlp()))); |
|||
} |
|||
|
|||
/*static std::string toString(TransactionException _te)
|
|||
{ |
|||
switch (_te) |
|||
{ |
|||
case TransactionException::Unknown: return "Unknown error"; |
|||
case TransactionException::InvalidSignature: return "Permanent Abort: Invalid transaction signature"; |
|||
case TransactionException::InvalidNonce: return "Transient Abort: Invalid transaction nonce"; |
|||
case TransactionException::NotEnoughCash: return "Transient Abort: Not enough cash to pay for transaction"; |
|||
case TransactionException::OutOfGasBase: return "Permanent Abort: Not enough gas to consider transaction"; |
|||
case TransactionException::BlockGasLimitReached: return "Transient Abort: Gas limit of block reached"; |
|||
case TransactionException::BadInstruction: return "VM Error: Attempt to execute invalid instruction"; |
|||
case TransactionException::BadJumpDestination: return "VM Error: Attempt to jump to invalid destination"; |
|||
case TransactionException::OutOfGas: return "VM Error: Out of gas"; |
|||
case TransactionException::OutOfStack: return "VM Error: VM stack limit reached during execution"; |
|||
case TransactionException::StackUnderflow: return "VM Error: Stack underflow"; |
|||
default:; return std::string(); |
|||
} |
|||
}*/ |
|||
|
|||
#if ETH_SOLIDITY |
|||
static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, string const& _contractName) |
|||
{ |
|||
string ret = ""; |
|||
auto const& contract = _compiler.getContractDefinition(_contractName); |
|||
auto interfaceFunctions = contract.getInterfaceFunctions(); |
|||
|
|||
for (auto const& it: interfaceFunctions) |
|||
{ |
|||
ret += it.first.abridged(); |
|||
ret += " :"; |
|||
ret += it.second->getDeclaration().getName() + "\n"; |
|||
} |
|||
return ret; |
|||
} |
|||
#endif |
|||
|
|||
static tuple<vector<string>, bytes, string> userInputToCode(string const& _user, bool _opt) |
|||
{ |
|||
string lll; |
|||
string solidity; |
|||
bytes data; |
|||
vector<string> errors; |
|||
if (_user.find_first_not_of("1234567890abcdefABCDEF\n\t ") == string::npos && _user.size() % 2 == 0) |
|||
{ |
|||
std::string u = _user; |
|||
boost::replace_all_copy(u, "\n", ""); |
|||
boost::replace_all_copy(u, "\t", ""); |
|||
boost::replace_all_copy(u, " ", ""); |
|||
data = fromHex(u); |
|||
} |
|||
#if ETH_SOLIDITY || !ETH_TRUE |
|||
else if (sourceIsSolidity(_user)) |
|||
{ |
|||
dev::solidity::CompilerStack compiler(true); |
|||
try |
|||
{ |
|||
// compiler.addSources(dev::solidity::StandardSources);
|
|||
data = compiler.compile(_user, _opt); |
|||
solidity = "<h4>Solidity</h4>"; |
|||
solidity += "<pre>var " + compiler.defaultContractName() + " = web3.eth.contract(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped().toStdString() + ");</pre>"; |
|||
solidity += "<pre>" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped().toStdString() + "</pre>"; |
|||
solidity += "<pre>" + QString::fromStdString(getFunctionHashes(compiler, "")).toHtmlEscaped().toStdString() + "</pre>"; |
|||
} |
|||
catch (dev::Exception const& exception) |
|||
{ |
|||
ostringstream error; |
|||
solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); |
|||
errors.push_back("Solidity: " + error.str()); |
|||
} |
|||
catch (...) |
|||
{ |
|||
errors.push_back("Solidity: Uncaught exception"); |
|||
} |
|||
} |
|||
#endif |
|||
#if ETH_SERPENT |
|||
else if (sourceIsSerpent(_user)) |
|||
{ |
|||
try |
|||
{ |
|||
data = dev::asBytes(::compile(_user)); |
|||
} |
|||
catch (string const& err) |
|||
{ |
|||
errors.push_back("Serpent " + err); |
|||
} |
|||
} |
|||
#endif |
|||
else |
|||
{ |
|||
data = compileLLL(_user, _opt, &errors); |
|||
if (errors.empty()) |
|||
{ |
|||
auto asmcode = compileLLLToAsm(_user, _opt); |
|||
lll = "<h4>LLL</h4><pre>" + QString::fromStdString(asmcode).toHtmlEscaped().toStdString() + "</pre>"; |
|||
} |
|||
} |
|||
return make_tuple(errors, data, lll + solidity); |
|||
} |
|||
|
|||
string Transact::natspecNotice(Address _to, bytes const& _data) |
|||
{ |
|||
if (ethereum()->codeAt(_to, PendingBlock).size()) |
|||
{ |
|||
string userNotice = m_natSpecDB->getUserNotice(ethereum()->postState().codeHash(_to), _data); |
|||
if (userNotice.empty()) |
|||
return "Destination contract unknown."; |
|||
else |
|||
{ |
|||
NatspecExpressionEvaluator evaluator; |
|||
return evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); |
|||
} |
|||
} |
|||
else |
|||
return "Destination not a contract."; |
|||
} |
|||
|
|||
pair<Address, bytes> Transact::toAccount() |
|||
{ |
|||
pair<Address, bytes> p; |
|||
if (!isCreation()) |
|||
{ |
|||
if (!ui->destination->currentData().isNull() && ui->destination->currentText() == ui->destination->itemText(ui->destination->currentIndex())) |
|||
p.first = Address(ui->destination->currentData().toString().trimmed().toStdString()); |
|||
else |
|||
p = m_main->fromString(ui->destination->currentText().trimmed().toStdString()); |
|||
} |
|||
return p; |
|||
} |
|||
|
|||
void Transact::timerEvent(QTimerEvent*) |
|||
{ |
|||
Address from = fromAccount(); |
|||
Address to = toAccount().first; |
|||
|
|||
if (m_upperBound != m_lowerBound) |
|||
{ |
|||
qint64 mid = (m_lowerBound + m_upperBound) / 2; |
|||
ExecutionResult er; |
|||
if (isCreation()) |
|||
er = ethereum()->create(from, value(), m_data, mid, gasPrice(), PendingBlock, FudgeFactor::Lenient); |
|||
else |
|||
er = ethereum()->call(from, value(), to, m_data, mid, gasPrice(), PendingBlock, FudgeFactor::Lenient); |
|||
if (er.excepted == TransactionException::OutOfGas || er.excepted == TransactionException::OutOfGasBase || er.excepted == TransactionException::OutOfGasIntrinsic || er.codeDeposit == CodeDeposit::Failed) |
|||
m_lowerBound = m_lowerBound == mid ? m_upperBound : mid; |
|||
else |
|||
{ |
|||
m_lastGood = er; |
|||
m_upperBound = m_upperBound == mid ? m_lowerBound : mid; |
|||
} |
|||
|
|||
updateBounds(); |
|||
} |
|||
else |
|||
finaliseBounds(); |
|||
} |
|||
|
|||
void Transact::updateBounds() |
|||
{ |
|||
ui->minGas->setValue(m_lowerBound); |
|||
ui->maxGas->setValue(m_upperBound); |
|||
double oran = m_startUpperBound - m_startLowerBound; |
|||
double nran = m_upperBound - m_lowerBound; |
|||
int x = int(log2(oran / nran) * 100.0 / log2(oran * 2)); |
|||
ui->progressGas->setValue(x); |
|||
ui->progressGas->setVisible(true); |
|||
ui->gas->setSpecialValueText(QString("Auto (%1 gas)").arg(m_upperBound)); |
|||
} |
|||
|
|||
void Transact::finaliseBounds() |
|||
{ |
|||
killTimer(m_gasCalcTimer); |
|||
|
|||
quint64 baseGas = (quint64)Transaction::gasRequired(m_data, 0); |
|||
ui->progressGas->setVisible(false); |
|||
|
|||
quint64 executionGas = m_upperBound - baseGas; |
|||
QString htmlInfo = QString("<div class=\"info\"><span class=\"icon\">INFO</span> Gas required: %1 total = %2 base, %3 exec [%4 refunded later]</div>").arg(m_upperBound).arg(baseGas).arg(executionGas).arg((qint64)m_lastGood.gasRefunded); |
|||
|
|||
auto bail = [&](QString he) { |
|||
ui->send->setEnabled(false); |
|||
ui->code->setHtml(he + htmlInfo + m_dataInfo); |
|||
}; |
|||
|
|||
auto s = fromAccount(); |
|||
auto b = ethereum()->balanceAt(s, PendingBlock); |
|||
|
|||
if (b < value() + baseGas * gasPrice()) |
|||
{ |
|||
// Not enough - bail.
|
|||
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Account doesn't contain enough for paying even the basic amount of gas required.</div>"); |
|||
return; |
|||
} |
|||
if (m_upperBound > m_ethereum->gasLimitRemaining()) |
|||
{ |
|||
// Not enough - bail.
|
|||
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Gas remaining in block isn't enough to allow the gas required.</div>"); |
|||
return; |
|||
} |
|||
if (m_lastGood.excepted != TransactionException::None) |
|||
{ |
|||
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> " + QString::fromStdString(toString(m_lastGood.excepted)) + "</div>"); |
|||
return; |
|||
} |
|||
if (m_lastGood.codeDeposit == CodeDeposit::Failed) |
|||
{ |
|||
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Code deposit failed due to insufficient gas; " + QString::fromStdString(toString(m_lastGood.gasForDeposit)) + " GAS < " + QString::fromStdString(toString(m_lastGood.depositSize)) + " bytes * " + QString::fromStdString(toString(c_createDataGas)) + "GAS/byte</div>"); |
|||
return; |
|||
} |
|||
|
|||
updateFee(); |
|||
ui->code->setHtml(htmlInfo + m_dataInfo); |
|||
ui->send->setEnabled(true); |
|||
} |
|||
|
|||
GasRequirements Transact::determineGasRequirements() |
|||
{ |
|||
// Determine the minimum amount of gas we need to play...
|
|||
qint64 baseGas = (qint64)Transaction::gasRequired(m_data, 0); |
|||
|
|||
Address from = fromAccount(); |
|||
Address to = toAccount().first; |
|||
ExecutionResult lastGood; |
|||
|
|||
m_startLowerBound = baseGas; |
|||
m_startUpperBound = (qint64)ethereum()->gasLimitRemaining(); |
|||
for (unsigned i = 0; i < 30; ++i) |
|||
{ |
|||
qint64 mid = m_startUpperBound; |
|||
ExecutionResult er; |
|||
if (isCreation()) |
|||
er = ethereum()->create(from, value(), m_data, mid, gasPrice(), PendingBlock, FudgeFactor::Lenient); |
|||
else |
|||
er = ethereum()->call(from, value(), to, m_data, mid, gasPrice(), PendingBlock, FudgeFactor::Lenient); |
|||
if (er.excepted == TransactionException::OutOfGas || er.excepted == TransactionException::OutOfGasBase || er.excepted == TransactionException::OutOfGasIntrinsic || er.codeDeposit == CodeDeposit::Failed) |
|||
{ |
|||
m_startLowerBound = mid; |
|||
m_startUpperBound *= 2; |
|||
} |
|||
else |
|||
{ |
|||
// Begin async binary chop for gas calculation..
|
|||
m_lastGood = lastGood; |
|||
m_lowerBound = m_startLowerBound; |
|||
m_upperBound = m_startUpperBound; |
|||
killTimer(m_gasCalcTimer); |
|||
m_gasCalcTimer = startTimer(0); |
|||
return GasRequirements{m_upperBound, baseGas, m_upperBound - baseGas, (qint64)lastGood.gasRefunded, lastGood}; |
|||
} |
|||
} |
|||
return GasRequirements(); |
|||
} |
|||
|
|||
void Transact::rejigData() |
|||
{ |
|||
if (!ethereum()) |
|||
return; |
|||
|
|||
// Determine how much balance we have to play with...
|
|||
//findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice());
|
|||
auto s = fromAccount(); |
|||
if (!s) |
|||
return; |
|||
|
|||
QString htmlInfo; |
|||
|
|||
auto bail = [&](QString he) { |
|||
ui->send->setEnabled(false); |
|||
m_dataInfo = he + htmlInfo; |
|||
ui->code->setHtml(m_dataInfo); |
|||
}; |
|||
|
|||
// Determine m_info.
|
|||
if (isCreation()) |
|||
{ |
|||
string info; |
|||
vector<string> errors; |
|||
tie(errors, m_data, info) = userInputToCode(ui->data->toPlainText().toStdString(), ui->optimize->isChecked()); |
|||
if (errors.size()) |
|||
{ |
|||
// Errors determining transaction data (i.e. init code). Bail.
|
|||
QString htmlErrors; |
|||
for (auto const& i: errors) |
|||
htmlErrors.append("<div class=\"error\"><span class=\"icon\">ERROR</span> " + QString::fromStdString(i).toHtmlEscaped() + "</div>"); |
|||
bail(htmlErrors); |
|||
return; |
|||
} |
|||
htmlInfo = QString::fromStdString(info) + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped(); |
|||
} |
|||
else |
|||
{ |
|||
m_data = parseData(ui->data->toPlainText().toStdString()); |
|||
htmlInfo = "<h4>Dump</h4>" + QString::fromStdString(dev::memDump(m_data, 8, true)); |
|||
} |
|||
|
|||
htmlInfo += "<h4>Hex</h4>" + QString(ETH_HTML_DIV(ETH_HTML_MONO)) + QString::fromStdString(toHex(m_data)) + "</div>"; |
|||
|
|||
// Add Natspec information
|
|||
if (!isCreation()) |
|||
htmlInfo = "<div class=\"info\"><span class=\"icon\">INFO</span> " + QString::fromStdString(natspecNotice(toAccount().first, m_data)).toHtmlEscaped() + "</div>" + htmlInfo; |
|||
|
|||
determineGasRequirements(); |
|||
|
|||
m_dataInfo = htmlInfo; |
|||
ui->code->setHtml(m_dataInfo); |
|||
ui->send->setEnabled(true); |
|||
} |
|||
|
|||
Secret Transact::findSecret(u256 _totalReq) const |
|||
{ |
|||
if (!ethereum()) |
|||
return Secret(); |
|||
|
|||
Address best; |
|||
u256 bestBalance = 0; |
|||
for (auto const& i: m_accounts) |
|||
{ |
|||
auto b = ethereum()->balanceAt(i, PendingBlock); |
|||
if (b >= _totalReq) |
|||
{ |
|||
best = i; |
|||
break; |
|||
} |
|||
if (b > bestBalance) |
|||
bestBalance = b, best = i; |
|||
} |
|||
return m_main->retrieveSecret(best); |
|||
} |
|||
|
|||
Address Transact::fromAccount() |
|||
{ |
|||
if (ui->from->currentIndex() < 0 || ui->from->currentIndex() >= (int)m_accounts.size()) |
|||
return Address(); |
|||
auto it = m_accounts.begin(); |
|||
std::advance(it, ui->from->currentIndex()); |
|||
return *it; |
|||
} |
|||
|
|||
void Transact::updateNonce() |
|||
{ |
|||
u256 n = ethereum()->countAt(fromAccount(), PendingBlock); |
|||
ui->nonce->setMaximum((unsigned)n); |
|||
ui->nonce->setMinimum(0); |
|||
ui->nonce->setValue((unsigned)n); |
|||
} |
|||
|
|||
void Transact::on_send_clicked() |
|||
{ |
|||
// Secret s = findSecret(value() + fee());
|
|||
u256 nonce = ui->autoNonce->isChecked() ? ethereum()->countAt(fromAccount(), PendingBlock) : ui->nonce->value(); |
|||
auto a = fromAccount(); |
|||
auto b = ethereum()->balanceAt(a, PendingBlock); |
|||
|
|||
if (!a || b < value() + fee()) |
|||
{ |
|||
QMessageBox::critical(nullptr, "Transaction Failed", "Couldn't make transaction: account doesn't contain at least the required amount.", QMessageBox::Ok); |
|||
return; |
|||
} |
|||
|
|||
Secret s = m_main->retrieveSecret(a); |
|||
if (!s) |
|||
return; |
|||
|
|||
if (isCreation()) |
|||
{ |
|||
// If execution is a contract creation, add Natspec to
|
|||
// a local Natspec LEVELDB
|
|||
ethereum()->submitTransaction(s, value(), m_data, gas(), gasPrice(), nonce); |
|||
#if ETH_SOLIDITY |
|||
string src = ui->data->toPlainText().toStdString(); |
|||
if (sourceIsSolidity(src)) |
|||
try |
|||
{ |
|||
dev::solidity::CompilerStack compiler(true); |
|||
m_data = compiler.compile(src, ui->optimize->isChecked()); |
|||
for (string const& s: compiler.getContractNames()) |
|||
{ |
|||
h256 contractHash = compiler.getContractCodeHash(s); |
|||
m_natSpecDB->add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); |
|||
} |
|||
} |
|||
catch (...) {} |
|||
#endif |
|||
} |
|||
else |
|||
// TODO: cache like m_data.
|
|||
ethereum()->submitTransaction(s, value(), toAccount().first, m_data, gas(), gasPrice(), nonce); |
|||
close(); |
|||
} |
|||
|
|||
void Transact::on_debug_clicked() |
|||
{ |
|||
// Secret s = findSecret(value() + fee());
|
|||
Address from = fromAccount(); |
|||
auto b = ethereum()->balanceAt(from, PendingBlock); |
|||
if (!from || b < value() + fee()) |
|||
{ |
|||
QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: account doesn't contain at least the required amount."); |
|||
return; |
|||
} |
|||
|
|||
try |
|||
{ |
|||
Block postState(ethereum()->postState()); |
|||
Transaction t = isCreation() ? |
|||
Transaction(value(), gasPrice(), gas(), m_data, postState.transactionsFrom(from)) : |
|||
Transaction(value(), gasPrice(), gas(), toAccount().first, m_data, postState.transactionsFrom(from)); |
|||
t.forceSender(from); |
|||
Debugger dw(m_main, this); |
|||
Executive e(postState, ethereum()->blockChain(), 0); |
|||
dw.populate(e, t); |
|||
dw.exec(); |
|||
} |
|||
catch (dev::Exception const& _e) |
|||
{ |
|||
QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction. Low-level error: " + QString::fromStdString(diagnostic_information(_e))); |
|||
// this output is aimed at developers, reconsider using _e.what for more user friendly output.
|
|||
} |
|||
} |
@ -1,124 +0,0 @@ |
|||
/*
|
|||
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 Transact.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libdevcore/RLP.h> |
|||
#include <libethcore/Common.h> |
|||
#include <libethereum/Transaction.h> |
|||
#include <QDialog> |
|||
#include <QMap> |
|||
#include <QList> |
|||
#include "MainFace.h" |
|||
|
|||
namespace Ui { class Transact; } |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth { class Client; } |
|||
namespace solidity { class CompilerStack; } |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
struct GasRequirements |
|||
{ |
|||
qint64 neededGas; |
|||
qint64 baseGas; |
|||
qint64 executionGas; |
|||
qint64 refundedGas; |
|||
dev::eth::ExecutionResult er; |
|||
}; |
|||
|
|||
class Transact: public QDialog |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit Transact(MainFace* _context, QWidget* _parent = 0); |
|||
~Transact(); |
|||
|
|||
void resetGasPrice(); |
|||
void setEnvironment(dev::AddressHash const& _accounts, dev::eth::Client* _eth, NatSpecFace* _natSpecDB); |
|||
|
|||
private slots: |
|||
void on_from_currentIndexChanged(int) { updateNonce(); rejigData(); } |
|||
void on_destination_currentTextChanged(QString); |
|||
void on_value_valueChanged(int) { updateFee(); rejigData(); } |
|||
void on_gas_valueChanged(int) { updateFee(); rejigData(); } |
|||
void on_valueUnits_currentIndexChanged(int) { updateFee(); rejigData(); } |
|||
void on_gasPriceUnits_currentIndexChanged(int) { updateFee(); rejigData(); } |
|||
void on_gasPrice_valueChanged(int) { updateFee(); rejigData(); } |
|||
void on_data_textChanged() { rejigData(); } |
|||
void on_optimize_clicked() { rejigData(); } |
|||
void on_copyUnsigned_clicked(); |
|||
void on_send_clicked(); |
|||
void on_debug_clicked(); |
|||
void on_cancel_clicked() { close(); } |
|||
|
|||
private: |
|||
dev::eth::Client* ethereum() const { return m_ethereum; } |
|||
void rejigData(); |
|||
void updateNonce(); |
|||
void updateBounds(); |
|||
void finaliseBounds(); |
|||
|
|||
dev::Address fromAccount(); |
|||
std::pair<dev::Address, bytes> toAccount(); |
|||
void updateDestination(); |
|||
void updateFee(); |
|||
bool isCreation() const; |
|||
dev::u256 fee() const; |
|||
dev::u256 gas() const; |
|||
dev::u256 total() const; |
|||
dev::u256 value() const; |
|||
dev::u256 gasPrice() const; |
|||
dev::Address to() const; |
|||
GasRequirements determineGasRequirements(); |
|||
|
|||
std::string natspecNotice(dev::Address _to, dev::bytes const& _data); |
|||
dev::Secret findSecret(dev::u256 _totalReq) const; |
|||
|
|||
void timerEvent(QTimerEvent*) override; |
|||
|
|||
Ui::Transact* ui = nullptr; |
|||
|
|||
unsigned m_backupGas = 0; |
|||
dev::bytes m_data; |
|||
|
|||
dev::AddressHash m_accounts; |
|||
dev::eth::Client* m_ethereum = nullptr; |
|||
MainFace* m_main = nullptr; |
|||
NatSpecFace* m_natSpecDB = nullptr; |
|||
|
|||
QString m_dataInfo; |
|||
qint64 m_startLowerBound = 0; |
|||
qint64 m_startUpperBound = 0; |
|||
qint64 m_lowerBound = 0; |
|||
qint64 m_upperBound = 0; |
|||
eth::ExecutionResult m_lastGood; |
|||
int m_gasCalcTimer = 0; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
@ -1,336 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>Transact</class> |
|||
<widget class="QDialog" name="Transact"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>604</width> |
|||
<height>695</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Transact</string> |
|||
</property> |
|||
<layout class="QGridLayout" name="gridLayout"> |
|||
<item row="10" column="2"> |
|||
<widget class="QPushButton" name="debug"> |
|||
<property name="text"> |
|||
<string>&Debug</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="4" column="1"> |
|||
<widget class="QSpinBox" name="gas"> |
|||
<property name="specialValueText"> |
|||
<string>Automatic</string> |
|||
</property> |
|||
<property name="suffix"> |
|||
<string> gas</string> |
|||
</property> |
|||
<property name="minimum"> |
|||
<number>-1</number> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>430000000</number> |
|||
</property> |
|||
<property name="value"> |
|||
<number>-1</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="3"> |
|||
<widget class="QComboBox" name="valueUnits"/> |
|||
</item> |
|||
<item row="4" column="3"> |
|||
<widget class="QComboBox" name="gasPriceUnits"/> |
|||
</item> |
|||
<item row="2" column="1" colspan="3"> |
|||
<widget class="QLineEdit" name="calculatedName"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="placeholderText"> |
|||
<string/> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="7" column="1"> |
|||
<widget class="QCheckBox" name="optimize"> |
|||
<property name="text"> |
|||
<string>&Optimise</string> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="10" column="3"> |
|||
<widget class="QPushButton" name="send"> |
|||
<property name="text"> |
|||
<string>&Execute</string> |
|||
</property> |
|||
<property name="default"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="7" column="3"> |
|||
<widget class="QSpinBox" name="nonce"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="8" column="0" colspan="4"> |
|||
<widget class="QSplitter" name="splitter_5"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<widget class="QPlainTextEdit" name="data"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
<widget class="QTextEdit" name="code"> |
|||
<property name="focusPolicy"> |
|||
<enum>Qt::ClickFocus</enum> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="1" colspan="2"> |
|||
<widget class="QSpinBox" name="value"> |
|||
<property name="suffix"> |
|||
<string/> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>430000000</number> |
|||
</property> |
|||
<property name="value"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="10" column="1"> |
|||
<widget class="QPushButton" name="copyUnsigned"> |
|||
<property name="text"> |
|||
<string>Copy &Unsigned</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="0" column="1" colspan="3"> |
|||
<widget class="QComboBox" name="from"/> |
|||
</item> |
|||
<item row="4" column="0"> |
|||
<widget class="QLabel" name="label_6"> |
|||
<property name="text"> |
|||
<string>&Gas</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>gas</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" 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>&To</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>destination</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="10" column="0"> |
|||
<widget class="QPushButton" name="cancel"> |
|||
<property name="text"> |
|||
<string>&Cancel</string> |
|||
</property> |
|||
<property name="shortcut"> |
|||
<string>Esc</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="7" column="2"> |
|||
<widget class="QCheckBox" name="autoNonce"> |
|||
<property name="text"> |
|||
<string>Auto Nonce</string> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="autoRepeat"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" column="1" colspan="3"> |
|||
<widget class="QComboBox" name="destination"> |
|||
<property name="editable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<item> |
|||
<property name="text"> |
|||
<string>(Create Contract)</string> |
|||
</property> |
|||
</item> |
|||
</widget> |
|||
</item> |
|||
<item row="9" column="0" colspan="4"> |
|||
<widget class="QLabel" name="total"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string/> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="0"> |
|||
<widget class="QLabel" name="label5_2"> |
|||
<property name="text"> |
|||
<string>&Amount</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>value</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="7" 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>D&ata</string> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>data</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="0" column="0"> |
|||
<widget class="QLabel" name="label"> |
|||
<property name="text"> |
|||
<string>&From</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>from</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="4" column="2"> |
|||
<widget class="QSpinBox" name="gasPrice"> |
|||
<property name="prefix"> |
|||
<string>@ </string> |
|||
</property> |
|||
<property name="minimum"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>430000000</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="5" column="3"> |
|||
<widget class="QSpinBox" name="maxGas"> |
|||
<property name="suffix"> |
|||
<string> gas</string> |
|||
</property> |
|||
<property name="prefix"> |
|||
<string>max </string> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>450000000</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="5" column="2"> |
|||
<widget class="QSpinBox" name="minGas"> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="suffix"> |
|||
<string> gas</string> |
|||
</property> |
|||
<property name="prefix"> |
|||
<string>min </string> |
|||
</property> |
|||
<property name="minimum"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>450000000</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="5" column="1"> |
|||
<widget class="QProgressBar" name="progressGas"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="value"> |
|||
<number>24</number> |
|||
</property> |
|||
<property name="format"> |
|||
<string>Calculating gas...</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>autoNonce</sender> |
|||
<signal>toggled(bool)</signal> |
|||
<receiver>nonce</receiver> |
|||
<slot>setDisabled(bool)</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>374</x> |
|||
<y>196</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>451</x> |
|||
<y>190</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,30 +0,0 @@ |
|||
/*
|
|||
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 WebPage.cpp
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "WebPage.h" |
|||
using namespace dev; |
|||
using namespace az; |
|||
|
|||
void WebPage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel _level, QString const& _message, int _lineNumber, QString const& _sourceID) |
|||
{ |
|||
QString prefix = _level == QWebEnginePage::ErrorMessageLevel ? "error" : _level == QWebEnginePage::WarningMessageLevel ? "warning" : ""; |
|||
emit consoleMessage(QString("%1(%2:%3):%4").arg(prefix).arg(_sourceID).arg(_lineNumber).arg(_message)); |
|||
} |
@ -1,51 +0,0 @@ |
|||
/*
|
|||
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 WebPage.h
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QString> |
|||
#pragma GCC diagnostic push |
|||
#pragma GCC diagnostic ignored "-Wpedantic" //QtWebEngineWidgets/qwebenginecertificateerror.h:78:348: error: extra ';'
|
|||
#include <QtWebEngineWidgets/QWebEnginePage> |
|||
#pragma GCC diagnostic pop |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
class WebPage: public QWebEnginePage |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
WebPage(QObject* _parent): QWebEnginePage(_parent) {} |
|||
|
|||
signals: |
|||
void consoleMessage(QString const& _msg); |
|||
|
|||
protected: |
|||
void javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel _level, const QString& _message, int _lineNumber, const QString& _sourceID) override; |
|||
}; |
|||
|
|||
} |
|||
} |
Binary file not shown.
Before Width: | Height: | Size: 361 KiB |
@ -1 +0,0 @@ |
|||
APP_ICON ICON DISCARDABLE "alethzero.ico" |
@ -1,12 +0,0 @@ |
|||
#include "MainWin.h" |
|||
#include <QtWidgets/QApplication> |
|||
|
|||
int main(int argc, char *argv[]) |
|||
{ |
|||
QApplication a(argc, argv); |
|||
Q_INIT_RESOURCE(js); |
|||
dev::az::Main w; |
|||
w.show(); |
|||
|
|||
return a.exec(); |
|||
} |
@ -1,144 +0,0 @@ |
|||
/*
|
|||
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.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#if ETH_FATDB || !ETH_TRUE |
|||
|
|||
#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; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(AllAccounts); |
|||
|
|||
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->onlyKnown, 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 onlyKnown = m_ui->onlyKnown->isChecked(); |
|||
|
|||
Addresses as; |
|||
if (onlyKnown) |
|||
as = main()->allKnownAddresses(); |
|||
else |
|||
as = ethereum()->addresses(); |
|||
|
|||
for (auto const& i: as) |
|||
{ |
|||
bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3); |
|||
if (!((showContract && isContract) || (showBasic && !isContract))) |
|||
continue; |
|||
string r = static_cast<Context*>(main())->render(i); |
|||
(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)); |
|||
} |
|||
m_ui->accounts->sortItems(); |
|||
#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); |
|||
u256s keys = keysOf(storage); |
|||
sort(keys.begin(), keys.end()); |
|||
for (auto const& i: keys) |
|||
s << "@" << showbase << hex << main()->prettyU256(i) << " " << showbase << hex << main()->prettyU256(storage[i]) << "<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>"; |
|||
s << "<h4>Creation Addresses (" << ethereum()->countAt(address) << "+)</h4>"; |
|||
for (auto i = 0; i < 5; ++i) |
|||
s << ETH_HTML_DIV(ETH_HTML_MONO) << toAddress(address, ethereum()->countAt(address) + i).hex() << "</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()))); |
|||
} |
|||
} |
|||
|
|||
#endif |
@ -1,64 +0,0 @@ |
|||
/*
|
|||
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 |
|||
|
|||
#if ETH_FATDB || !ETH_TRUE |
|||
|
|||
#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; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
#endif |
@ -1,137 +0,0 @@ |
|||
<?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>405</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> |
|||
<property name="checked"> |
|||
<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="onlyKnown"> |
|||
<property name="text"> |
|||
<string>Only Known</string> |
|||
</property> |
|||
<property name="checkable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>true</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> |
@ -1,208 +0,0 @@ |
|||
/*
|
|||
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 |
|||
*/ |
|||
|
|||
#if ETH_FATDB |
|||
|
|||
#include "ExportState.h" |
|||
#include <fstream> |
|||
#include <QFileDialog> |
|||
#include <QTextStream> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_ExportState.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(ExportStateDialog); |
|||
|
|||
ExportStateDialog::ExportStateDialog(MainFace* _m): |
|||
QDialog(_m), |
|||
Plugin(_m, "Export State"), |
|||
m_ui(new Ui::ExportState) |
|||
{ |
|||
m_ui->setupUi(this); |
|||
connect(m_ui->close, &QPushButton::clicked, this, &ExportStateDialog::close); |
|||
connect(m_ui->accounts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); |
|||
connect(m_ui->contracts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); |
|||
fillBlocks(); |
|||
connect(addMenuItem("Export State...", "menuTools", true), SIGNAL(triggered()), SLOT(exec())); |
|||
} |
|||
|
|||
ExportStateDialog::~ExportStateDialog() |
|||
{ |
|||
|
|||
} |
|||
void ExportStateDialog::showEvent(QShowEvent*) |
|||
{ |
|||
m_ui->block->clear(); |
|||
m_ui->block->clearEditText(); |
|||
m_ui->accounts->clear(); |
|||
m_ui->contracts->clear(); |
|||
fillBlocks(); |
|||
} |
|||
|
|||
void ExportStateDialog::on_block_editTextChanged() |
|||
{ |
|||
QString text = m_ui->block->currentText(); |
|||
int i = m_ui->block->count(); |
|||
while (i-- >= 0) |
|||
if (m_ui->block->itemText(i) == text) |
|||
return; |
|||
fillBlocks(); |
|||
} |
|||
|
|||
void ExportStateDialog::on_block_currentIndexChanged(int _index) |
|||
{ |
|||
m_block = m_ui->block->itemData(_index).toUInt(); |
|||
fillContracts(); |
|||
} |
|||
|
|||
void ExportStateDialog::fillBlocks() |
|||
{ |
|||
BlockChain const& bc = ethereum()->blockChain(); |
|||
QStringList filters = m_ui->block->currentText().toLower().split(QRegExp("\\s+"), QString::SkipEmptyParts); |
|||
const unsigned numLastBlocks = 10; |
|||
if (m_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); |
|||
m_ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); |
|||
if (h == bc.genesisHash()) |
|||
break; |
|||
} |
|||
if (m_ui->block->currentIndex() < 0) |
|||
m_ui->block->setCurrentIndex(0); |
|||
m_recentBlocks = numLastBlocks - i; |
|||
} |
|||
|
|||
int i = m_ui->block->count(); |
|||
while (i > 0 && i >= m_recentBlocks) |
|||
m_ui->block->removeItem(i--); |
|||
|
|||
h256Hash 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); |
|||
m_ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); |
|||
} |
|||
} |
|||
|
|||
void ExportStateDialog::fillContracts() |
|||
{ |
|||
m_ui->accounts->clear(); |
|||
m_ui->contracts->clear(); |
|||
m_ui->accounts->setEnabled(true); |
|||
m_ui->contracts->setEnabled(true); |
|||
try |
|||
{ |
|||
for (auto i: ethereum()->addresses(m_block)) |
|||
{ |
|||
string r = main()->render(i); |
|||
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? m_ui->accounts : m_ui->contracts)) |
|||
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); |
|||
} |
|||
} |
|||
catch (InterfaceNotSupported const&) |
|||
{ |
|||
m_ui->accounts->setEnabled(false); |
|||
m_ui->contracts->setEnabled(false); |
|||
m_ui->json->setEnabled(false); |
|||
m_ui->json->setText(QString("This feature requires compilation with FATDB support.")); |
|||
} |
|||
} |
|||
|
|||
void ExportStateDialog::generateJSON() |
|||
{ |
|||
std::stringstream json; |
|||
json << "{\n"; |
|||
std::string prefix; |
|||
for(QListWidgetItem* item: m_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: m_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::unordered_map<u256, u256> storage = ethereum()->storageAt(address, m_block); |
|||
if (!storage.empty()) |
|||
{ |
|||
json << "\t\t\"storage\":\n\t\t{\n"; |
|||
std::string storagePrefix; |
|||
for (auto s: storage) |
|||
{ |
|||
json << storagePrefix << "\t\t\t\"" << toHex(s.first) << "\": \"" << toHex(s.second) << "\""; |
|||
storagePrefix = ",\n"; |
|||
} |
|||
json << "\n\t\t}\n"; |
|||
} |
|||
json << "\t}"; |
|||
prefix = ",\n"; |
|||
} |
|||
json << "\n}"; |
|||
json.flush(); |
|||
|
|||
m_ui->json->setEnabled(true); |
|||
m_ui->json->setText(QString::fromStdString(json.str())); |
|||
m_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 << m_ui->json->toPlainText().toStdString(); |
|||
} |
|||
|
|||
#endif //ETH_FATDB
|
@ -1,70 +0,0 @@ |
|||
/*
|
|||
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 |
|||
|
|||
#if ETH_FATDB |
|||
|
|||
#include <memory> |
|||
#include <QDialog> |
|||
#include <libethcore/Common.h> |
|||
#include "MainFace.h" |
|||
|
|||
namespace Ui { class ExportState; } |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
namespace eth { class Client; } |
|||
|
|||
namespace az |
|||
{ |
|||
|
|||
|
|||
class ExportStateDialog: public QDialog, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
ExportStateDialog(MainFace* _m); |
|||
virtual ~ExportStateDialog(); |
|||
|
|||
private slots: |
|||
void on_block_editTextChanged(); |
|||
void on_block_currentIndexChanged(int _index); |
|||
void on_saveButton_clicked(); |
|||
|
|||
private: |
|||
void showEvent(QShowEvent* _event) override; |
|||
void fillBlocks(); |
|||
void fillContracts(); |
|||
void generateJSON(); |
|||
|
|||
private: |
|||
std::unique_ptr<Ui::ExportState> m_ui; |
|||
int m_recentBlocks = 0; |
|||
eth::BlockNumber m_block = eth::LatestBlock; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
#endif //ETH_FATDB
|
@ -1,183 +0,0 @@ |
|||
<?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> |
@ -1,69 +0,0 @@ |
|||
/*
|
|||
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 BrainWallet.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "BrainWallet.h" |
|||
#include <QMenu> |
|||
#include <QDialog> |
|||
#include <boost/random/random_device.hpp> |
|||
#include <boost/random/uniform_int_distribution.hpp> |
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcrypto/WordList.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_BrainWallet.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(BrainWallet); |
|||
|
|||
BrainWallet::BrainWallet(MainFace* _m): |
|||
Plugin(_m, "BrainWallet") |
|||
{ |
|||
connect(addMenuItem("New Brain Wallet...", "menuTools", true), SIGNAL(triggered()), SLOT(create())); |
|||
} |
|||
|
|||
BrainWallet::~BrainWallet() |
|||
{ |
|||
} |
|||
|
|||
void BrainWallet::create() |
|||
{ |
|||
QDialog d; |
|||
Ui_BrainWallet u; |
|||
u.setupUi(&d); |
|||
d.setWindowTitle("New Brain Wallet"); |
|||
connect(u.generate, &QPushButton::clicked, [&](){ |
|||
boost::random_device d; |
|||
boost::random::uniform_int_distribution<unsigned> pickWord(0, WordList.size() - 1); |
|||
QString t; |
|||
for (int i = 0; i < 13; ++i) |
|||
t += (t.size() ? " " : "") + QString::fromStdString(WordList[pickWord(d)]); |
|||
u.seed->setPlainText(t); |
|||
}); |
|||
|
|||
if (d.exec() == QDialog::Accepted) |
|||
{ |
|||
main()->keyManager().importBrain(u.seed->toPlainText().trimmed().toStdString(), u.name->text().toStdString(), u.hint->toPlainText().toStdString()); |
|||
main()->noteKeysChanged(); |
|||
} |
|||
} |
@ -1,44 +0,0 @@ |
|||
/*
|
|||
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 BrainWallet.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class BrainWallet: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
BrainWallet(MainFace* _m); |
|||
~BrainWallet(); |
|||
|
|||
private slots: |
|||
void create(); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,136 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>BrainWallet</class> |
|||
<widget class="QDialog" name="BrainWallet"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>511</width> |
|||
<height>508</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Dialog</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<widget class="QLabel" name="label"> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">WARNING: Brain wallets, or human-entropic seeds, are generally a Bad Plan. Unless used properly they're a terrible idea for protecteding anything of value. Read up on them and know the risks before using this functionality!</span></p><p>That said, if you're intent on using one, make the phrase as long and random as you can. If you're sensible, you'll use the Generate button and memorise the list of words it gives you. This is the only way to guarantee a strong brainwallet. Write the phrase down on paper and bury it under an oak tree or something - if you forget it, you're screwed.</p></body></html></string> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLineEdit" name="name"> |
|||
<property name="placeholderText"> |
|||
<string>Please name of this account here e.g. My Brain Wallet</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="seed"> |
|||
<property name="placeholderText"> |
|||
<string>Write your seed phrase here. Make it long and random. Don't ever forget it. If you want it to have any chance at being secure, hit the Generate button and memorize what ends up here.</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="label_2"> |
|||
<property name="text"> |
|||
<string><html><head/><body><p>You can leave a hint here if you want; don't rely on it or there's little point in it being a <span style=" font-style:italic;">brain</span> wallet.</p></body></html></string> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="hint"> |
|||
<property name="placeholderText"> |
|||
<string>An optional hint for the text above.</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<item> |
|||
<widget class="QPushButton" name="generate"> |
|||
<property name="text"> |
|||
<string>&Generate</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="cancel"> |
|||
<property name="text"> |
|||
<string>Cancel</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="create"> |
|||
<property name="text"> |
|||
<string>&Create</string> |
|||
</property> |
|||
<property name="default"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>create</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>BrainWallet</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>462</x> |
|||
<y>484</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>449</x> |
|||
<y>504</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>cancel</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>BrainWallet</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>381</x> |
|||
<y>483</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>351</x> |
|||
<y>506</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,222 +0,0 @@ |
|||
/*
|
|||
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 ImportKey.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "ImportKey.h" |
|||
#include <QFileDialog> |
|||
#include <QMessageBox> |
|||
#include <QInputDialog> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#include <libethcore/ICAP.h> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_ImportKey.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(ImportKey); |
|||
|
|||
ImportKey::ImportKey(MainFace* _m): |
|||
Plugin(_m, "ImportKey") |
|||
{ |
|||
connect(addMenuItem("Import Key...", "menuTools", true), SIGNAL(triggered()), SLOT(import())); |
|||
} |
|||
|
|||
ImportKey::~ImportKey() |
|||
{ |
|||
} |
|||
|
|||
void ImportKey::import() |
|||
{ |
|||
QDialog d; |
|||
Ui_ImportKey u; |
|||
u.setupUi(&d); |
|||
d.setWindowTitle("Import Key"); |
|||
|
|||
string lastKey; |
|||
Secret lastSecret; |
|||
string lastPassword; |
|||
Address lastAddress; |
|||
|
|||
auto updateAction = [&](){ |
|||
if (!u.import_2->isEnabled()) |
|||
u.action->clear(); |
|||
else if (lastKey.empty() && !lastSecret) |
|||
u.action->setText("Import brainwallet with given address and hint"); |
|||
else if (!lastKey.empty() && !lastSecret) |
|||
{ |
|||
h256 ph; |
|||
DEV_IGNORE_EXCEPTIONS(ph = h256(u.passwordHash->text().toStdString())); |
|||
if (ph) |
|||
u.action->setText("Import untouched key with given address and hint"); |
|||
else |
|||
u.action->setText("Import untouched key with given address, password hash and hint"); |
|||
} |
|||
else |
|||
{ |
|||
bool mp = u.noPassword->isChecked(); |
|||
if (mp) |
|||
u.action->setText("Import recast key using master password and given hint"); |
|||
else |
|||
u.action->setText("Import recast key with given password and hint"); |
|||
} |
|||
}; |
|||
|
|||
auto updateImport = [&](){ |
|||
u.import_2->setDisabled(u.addressOut->text().isEmpty() || u.name->text().isEmpty() || !(u.oldPassword->isChecked() || u.newPassword->isChecked() || u.noPassword->isChecked())); |
|||
updateAction(); |
|||
}; |
|||
|
|||
auto updateAddress = [&](){ |
|||
lastAddress.clear(); |
|||
string as = u.address->text().toStdString(); |
|||
try |
|||
{ |
|||
lastAddress = eth::toAddress(as); |
|||
u.addressOut->setText(QString::fromStdString(main()->render(lastAddress))); |
|||
} |
|||
catch (...) |
|||
{ |
|||
u.addressOut->setText(""); |
|||
} |
|||
updateImport(); |
|||
}; |
|||
|
|||
auto updatePassword = [&](){ |
|||
u.passwordHash->setText(QString::fromStdString(sha3(u.password->text().toStdString()).hex())); |
|||
updateAction(); |
|||
}; |
|||
|
|||
function<void()> updateKey = [&](){ |
|||
// update according to key.
|
|||
if (lastKey == u.key->text().toStdString()) |
|||
return; |
|||
lastKey = u.key->text().toStdString(); |
|||
lastSecret.clear(); |
|||
u.address->clear(); |
|||
u.oldPassword->setEnabled(false); |
|||
u.oldPassword->setChecked(false); |
|||
bytes b; |
|||
DEV_IGNORE_EXCEPTIONS(b = fromHex(lastKey, WhenError::Throw)); |
|||
if (b.size() == 32) |
|||
{ |
|||
lastSecret = Secret(b); |
|||
bytesRef(&b).cleanse(); |
|||
} |
|||
while (!lastKey.empty() && !lastSecret) |
|||
{ |
|||
bool ok; |
|||
lastPassword = QInputDialog::getText(&d, "Open Key File", "Enter the password protecting this key file. Cancel if you do not want to provide te password.", QLineEdit::Password, QString(), &ok).toStdString(); |
|||
if (!ok) |
|||
{ |
|||
lastSecret.clear(); |
|||
break; |
|||
} |
|||
// Try to open as a file.
|
|||
lastSecret = KeyManager::presaleSecret(contentsString(lastKey), [&](bool first){ return first ? lastPassword : string(); }).secret(); |
|||
if (!lastSecret) |
|||
lastSecret = Secret(SecretStore::secret(contentsString(lastKey), lastPassword)); |
|||
if (!lastSecret && QMessageBox::warning(&d, "Invalid Password or Key File", "The given password could not be used to decrypt the key file given. Are you sure it is a valid key file and that the password is correct?", QMessageBox::Abort, QMessageBox::Retry) == QMessageBox::Abort) |
|||
{ |
|||
u.key->clear(); |
|||
updateKey(); |
|||
return; |
|||
} |
|||
} |
|||
u.oldPassword->setEnabled(!!lastSecret); |
|||
u.newPassword->setEnabled(!!lastSecret); |
|||
u.noPassword->setEnabled(!!lastSecret); |
|||
u.masterLabel->setEnabled(!!lastSecret); |
|||
u.oldLabel->setEnabled(!!lastSecret); |
|||
u.showPassword->setEnabled(!!lastSecret); |
|||
u.password->setEnabled(!!lastSecret); |
|||
u.passwordHash->setReadOnly(!!lastSecret); |
|||
u.address->setReadOnly(!!lastSecret); |
|||
if (lastSecret) |
|||
{ |
|||
u.oldPassword->setEnabled(!lastPassword.empty()); |
|||
if (lastPassword.empty()) |
|||
u.oldPassword->setChecked(false); |
|||
u.address->setText(QString::fromStdString(ICAP(toAddress(lastSecret)).encoded())); |
|||
updateAddress(); |
|||
} |
|||
else |
|||
u.address->clear(); |
|||
updateImport(); |
|||
}; |
|||
|
|||
connect(u.noPassword, &QRadioButton::clicked, [&](){ |
|||
u.passwordHash->clear(); |
|||
u.hint->setText("No additional password (same as master password)."); |
|||
updateAction(); |
|||
}); |
|||
connect(u.oldPassword, &QRadioButton::clicked, [&](){ |
|||
u.passwordHash->setText(QString::fromStdString(sha3(lastPassword).hex())); |
|||
u.hint->setText("Same as original password for file " + QString::fromStdString(lastKey)); |
|||
updateAction(); |
|||
}); |
|||
connect(u.newPassword, &QRadioButton::clicked, [&](){ |
|||
u.hint->setText(""); |
|||
updatePassword(); |
|||
}); |
|||
connect(u.password, &QLineEdit::textChanged, [&](){ updatePassword(); }); |
|||
connect(u.address, &QLineEdit::textChanged, [&](){ updateAddress(); }); |
|||
connect(u.key, &QLineEdit::textEdited, [&](){ updateKey(); }); |
|||
connect(u.name, &QLineEdit::textEdited, [&](){ updateImport(); }); |
|||
connect(u.showPassword, &QCheckBox::toggled, [&](bool show){ u.password->setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password); }); |
|||
connect(u.openKey, &QToolButton::clicked, [&](){ |
|||
QString fn = QFileDialog::getOpenFileName(main(), "Open Key File", QDir::homePath(), "JSON Files (*.json);;All Files (*)"); |
|||
if (!fn.isEmpty()) |
|||
{ |
|||
u.key->setText(fn); |
|||
updateKey(); |
|||
} |
|||
}); |
|||
|
|||
if (d.exec() == QDialog::Accepted) |
|||
{ |
|||
Address a = lastAddress; |
|||
string n = u.name->text().toStdString(); |
|||
string h = u.hint->text().toStdString(); |
|||
|
|||
// check for a brain wallet import
|
|||
if (lastKey.empty() && !lastSecret) |
|||
main()->keyManager().importExistingBrain(a, n, h); |
|||
else if (!lastKey.empty() && !lastSecret) |
|||
{ |
|||
h256 ph; |
|||
DEV_IGNORE_EXCEPTIONS(ph = h256(u.passwordHash->text().toStdString())); |
|||
main()->keyManager().importExisting(main()->keyManager().store().importKey(lastKey), n, a, ph, h); |
|||
} |
|||
else |
|||
{ |
|||
bool mp = u.noPassword->isChecked(); |
|||
string p = mp ? string() : u.oldPassword ? lastPassword : u.password->text().toStdString(); |
|||
if (mp) |
|||
main()->keyManager().import(lastSecret, n); |
|||
else |
|||
main()->keyManager().import(lastSecret, n, p, h); |
|||
} |
|||
|
|||
main()->noteKeysChanged(); |
|||
} |
|||
} |
@ -1,44 +0,0 @@ |
|||
/*
|
|||
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 ImportKey.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class ImportKey: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
ImportKey(MainFace* _m); |
|||
~ImportKey(); |
|||
|
|||
private slots: |
|||
void import(); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,336 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>ImportKey</class> |
|||
<widget class="QDialog" name="ImportKey"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>530</width> |
|||
<height>389</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Dialog</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<layout class="QGridLayout" name="gridLayout"> |
|||
<item row="10" column="2" colspan="3"> |
|||
<widget class="QLineEdit" name="passwordHash"> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="8" column="3" colspan="2"> |
|||
<widget class="QCheckBox" name="showPassword"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Show</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="4" column="0" colspan="2"> |
|||
<widget class="QLabel" name="label_2"> |
|||
<property name="text"> |
|||
<string>&Address:</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>address</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="4"> |
|||
<widget class="QToolButton" name="openKey"> |
|||
<property name="text"> |
|||
<string>...</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="8" column="0" colspan="2"> |
|||
<widget class="QRadioButton" name="newPassword"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="text"> |
|||
<string>New &Password:</string> |
|||
</property> |
|||
<attribute name="buttonGroup"> |
|||
<string notr="true">buttonGroup</string> |
|||
</attribute> |
|||
</widget> |
|||
</item> |
|||
<item row="4" column="2" colspan="3"> |
|||
<widget class="QLineEdit" name="address"> |
|||
<property name="placeholderText"> |
|||
<string>Place the address of the key here</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="0" colspan="2"> |
|||
<widget class="QLabel" name="label_4"> |
|||
<property name="text"> |
|||
<string>&Name:</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>name</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="6" column="0" colspan="2"> |
|||
<widget class="QRadioButton" name="noPassword"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&Master password</string> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<attribute name="buttonGroup"> |
|||
<string notr="true">buttonGroup</string> |
|||
</attribute> |
|||
</widget> |
|||
</item> |
|||
<item row="11" column="2" colspan="3"> |
|||
<widget class="QLineEdit" name="hint"/> |
|||
</item> |
|||
<item row="7" column="0" colspan="2"> |
|||
<widget class="QRadioButton" name="oldPassword"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&Old password</string> |
|||
</property> |
|||
<attribute name="buttonGroup"> |
|||
<string notr="true">buttonGroup</string> |
|||
</attribute> |
|||
</widget> |
|||
</item> |
|||
<item row="8" column="2"> |
|||
<widget class="QLineEdit" name="password"> |
|||
<property name="placeholderText"> |
|||
<string>Enter the password you wish to use for the key here</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="2" colspan="3"> |
|||
<widget class="QLineEdit" name="name"> |
|||
<property name="placeholderText"> |
|||
<string>Enter this key's name here</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="10" column="0" colspan="2"> |
|||
<widget class="QLabel" name="label_3"> |
|||
<property name="text"> |
|||
<string>Password &Hash:</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>passwordHash</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="11" column="0" colspan="2"> |
|||
<widget class="QLabel" name="label_5"> |
|||
<property name="text"> |
|||
<string>Password Hin&t:</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>hint</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="6" column="2" colspan="3"> |
|||
<widget class="QLabel" name="masterLabel"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Use same password for the key as for the master.</string> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="2" colspan="2"> |
|||
<widget class="QLineEdit" name="key"> |
|||
<property name="placeholderText"> |
|||
<string>Brain wallet (no key file)</string> |
|||
</property> |
|||
<property name="clearButtonEnabled"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="0" colspan="2"> |
|||
<widget class="QLabel" name="label"> |
|||
<property name="text"> |
|||
<string>&Key:</string> |
|||
</property> |
|||
<property name="buddy"> |
|||
<cstring>key</cstring> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="7" column="2" colspan="3"> |
|||
<widget class="QLabel" name="oldLabel"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Use the same password as in the key file.</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="5" column="2" colspan="3"> |
|||
<widget class="QLineEdit" name="addressOut"> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
<property name="placeholderText"> |
|||
<string>Unknown Address</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
<item> |
|||
<spacer name="verticalSpacer"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>5</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
<item> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<item> |
|||
<widget class="QLabel" name="action"> |
|||
<property name="text"> |
|||
<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="cancel"> |
|||
<property name="text"> |
|||
<string>Cancel</string> |
|||
</property> |
|||
<property name="shortcut"> |
|||
<string>Esc</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="import_2"> |
|||
<property name="enabled"> |
|||
<bool>false</bool> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&Import</string> |
|||
</property> |
|||
<property name="default"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<tabstops> |
|||
<tabstop>name</tabstop> |
|||
<tabstop>key</tabstop> |
|||
<tabstop>openKey</tabstop> |
|||
<tabstop>address</tabstop> |
|||
<tabstop>addressOut</tabstop> |
|||
<tabstop>noPassword</tabstop> |
|||
<tabstop>oldPassword</tabstop> |
|||
<tabstop>newPassword</tabstop> |
|||
<tabstop>password</tabstop> |
|||
<tabstop>showPassword</tabstop> |
|||
<tabstop>passwordHash</tabstop> |
|||
<tabstop>hint</tabstop> |
|||
<tabstop>cancel</tabstop> |
|||
<tabstop>import_2</tabstop> |
|||
</tabstops> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>import_2</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>ImportKey</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>519</x> |
|||
<y>378</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>449</x> |
|||
<y>388</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>cancel</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>ImportKey</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>433</x> |
|||
<y>378</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>351</x> |
|||
<y>388</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>newPassword</sender> |
|||
<signal>pressed()</signal> |
|||
<receiver>password</receiver> |
|||
<slot>setFocus()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>80</x> |
|||
<y>211</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>185</x> |
|||
<y>215</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
<buttongroups> |
|||
<buttongroup name="buttonGroup"/> |
|||
</buttongroups> |
|||
</ui> |
@ -1,98 +0,0 @@ |
|||
/*
|
|||
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 LogPanel.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "LogPanel.h" |
|||
#include <sstream> |
|||
#include <QClipboard> |
|||
#include <QSettings> |
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libevmcore/Instruction.h> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_LogPanel.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
static QString filterOutTerminal(QString _s) |
|||
{ |
|||
return _s.replace(QRegExp("\x1b\\[(\\d;)?\\d+m"), ""); |
|||
} |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(LogPanel); |
|||
|
|||
LogPanel::LogPanel(MainFace* _m): |
|||
Plugin(_m, "LogPanel"), |
|||
m_ui(new Ui::LogPanel) |
|||
{ |
|||
dock(Qt::RightDockWidgetArea, "Log")->setWidget(new QWidget); |
|||
m_ui->setupUi(dock()->widget()); |
|||
connect(m_ui->verbosity, SIGNAL(valueChanged(int)), SLOT(on_verbosity_valueChanged())); |
|||
|
|||
g_logPost = [=](string const& s, char const* c) |
|||
{ |
|||
simpleDebugOut(s, c); |
|||
m_logLock.lock(); |
|||
m_logHistory.append(filterOutTerminal(QString::fromStdString(s)) + "\n"); |
|||
m_logChanged = true; |
|||
m_logLock.unlock(); |
|||
}; |
|||
startTimer(100); |
|||
|
|||
on_verbosity_valueChanged(); |
|||
} |
|||
|
|||
LogPanel::~LogPanel() |
|||
{ |
|||
// Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor)
|
|||
// *after* the client is dead.
|
|||
g_logPost = simpleDebugOut; |
|||
} |
|||
|
|||
void LogPanel::readSettings(QSettings const& _s) |
|||
{ |
|||
m_ui->verbosity->setValue(_s.value("verbosity", 1).toInt()); |
|||
} |
|||
|
|||
void LogPanel::writeSettings(QSettings& _s) |
|||
{ |
|||
_s.setValue("verbosity", m_ui->verbosity->value()); |
|||
} |
|||
|
|||
void LogPanel::timerEvent(QTimerEvent*) |
|||
{ |
|||
if (m_logChanged) |
|||
{ |
|||
m_logLock.lock(); |
|||
m_logChanged = false; |
|||
m_ui->log->appendPlainText(m_logHistory.mid(0, m_logHistory.length() - 1)); |
|||
m_logHistory.clear(); |
|||
m_logLock.unlock(); |
|||
} |
|||
} |
|||
|
|||
void LogPanel::on_verbosity_valueChanged() |
|||
{ |
|||
g_logVerbosity = m_ui->verbosity->value(); |
|||
m_ui->verbosityLabel->setText(QString::number(g_logVerbosity)); |
|||
} |
|||
|
@ -1,64 +0,0 @@ |
|||
/*
|
|||
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 LogPanel.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QMutex> |
|||
#include <QString> |
|||
#include <QPair> |
|||
#include <QList> |
|||
#include "MainFace.h" |
|||
|
|||
namespace Ui |
|||
{ |
|||
class LogPanel; |
|||
} |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class LogPanel: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
LogPanel(MainFace* _m); |
|||
~LogPanel(); |
|||
|
|||
private slots: |
|||
void on_verbosity_valueChanged(); |
|||
|
|||
private: |
|||
void timerEvent(QTimerEvent*) override; |
|||
void readSettings(QSettings const&) override; |
|||
void writeSettings(QSettings&) override; |
|||
|
|||
Ui::LogPanel* m_ui; |
|||
|
|||
QMutex m_logLock; |
|||
QString m_logHistory; |
|||
bool m_logChanged = true; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,99 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>LogPanel</class> |
|||
<widget class="QWidget" name="LogPanel"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>834</width> |
|||
<height>265</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Form</string> |
|||
</property> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<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> |
|||
<widget class="QPlainTextEdit" name="log"> |
|||
<property name="font"> |
|||
<font> |
|||
<family>Ubuntu Mono</family> |
|||
</font> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="frameShadow"> |
|||
<enum>QFrame::Plain</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="lineWrapMode"> |
|||
<enum>QPlainTextEdit::NoWrap</enum> |
|||
</property> |
|||
<property name="readOnly"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<layout class="QVBoxLayout" name="verticalLayout_6"> |
|||
<property name="spacing"> |
|||
<number>6</number> |
|||
</property> |
|||
<item> |
|||
<widget class="QSlider" name="verbosity"> |
|||
<property name="maximum"> |
|||
<number>20</number> |
|||
</property> |
|||
<property name="value"> |
|||
<number>1</number> |
|||
</property> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="tickPosition"> |
|||
<enum>QSlider::TicksBothSides</enum> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="verbosityLabel"> |
|||
<property name="minimumSize"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>0</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string>20</string> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignCenter</set> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
@ -1,108 +0,0 @@ |
|||
/*
|
|||
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 NameRegNamer.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "NameRegNamer.h" |
|||
#include <QSettings> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethereum/Client.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(NameRegNamer); |
|||
|
|||
NameRegNamer::NameRegNamer(MainFace* _m): |
|||
AccountNamerPlugin(_m, "NameRegNamer") |
|||
{ |
|||
} |
|||
|
|||
NameRegNamer::~NameRegNamer() |
|||
{ |
|||
} |
|||
|
|||
string NameRegNamer::toName(Address const& _a) const |
|||
{ |
|||
for (auto const& r: m_registrars) |
|||
{ |
|||
string n = abiOut<string>(main()->ethereum()->call(Address(1), 0, r, abiIn("name(address)", _a), 1000000, DefaultGasPrice, PendingBlock, FudgeFactor::Lenient).output); |
|||
if (!n.empty()) |
|||
return n; |
|||
} |
|||
return string(); |
|||
} |
|||
|
|||
Address NameRegNamer::toAddress(std::string const& _n) const |
|||
{ |
|||
for (auto const& r: m_registrars) |
|||
if (Address a = abiOut<Address>(main()->ethereum()->call(r, abiIn("addr(string)", _n)).output)) |
|||
return a; |
|||
return Address(); |
|||
} |
|||
|
|||
Addresses NameRegNamer::knownAddresses() const |
|||
{ |
|||
return m_knownCache; |
|||
} |
|||
|
|||
void NameRegNamer::killRegistrar(Address const& _r) |
|||
{ |
|||
if (m_filters.count(_r)) |
|||
{ |
|||
main()->uninstallWatch(m_filters.at(_r)); |
|||
m_filters.erase(_r); |
|||
} |
|||
for (auto i = m_registrars.begin(); i != m_registrars.end();) |
|||
if (*i == _r) |
|||
i = m_registrars.erase(i); |
|||
else |
|||
++i; |
|||
} |
|||
|
|||
void NameRegNamer::updateCache() |
|||
{ |
|||
// m_forwardCache.clear();
|
|||
// m_reverseCache.clear();
|
|||
m_knownCache.clear(); |
|||
#if ETH_FATDB || !ETH_TRUE |
|||
for (auto const& r: m_registrars) |
|||
for (u256 const& a: keysOf(ethereum()->storageAt(r))) |
|||
if (a < u256(1) << 160) |
|||
m_knownCache.push_back(Address((u160)a - 1)); |
|||
#endif |
|||
} |
|||
|
|||
void NameRegNamer::readSettings(QSettings const& _s) |
|||
{ |
|||
(void)_s; |
|||
while (!m_registrars.empty()) |
|||
killRegistrar(m_registrars.back()); |
|||
|
|||
Address a("047cdba9627a8686bb24b3a65d87dab7efa53d31"); |
|||
m_registrars.push_back(a); |
|||
m_filters[a] = main()->installWatch(LogFilter().address(a), [=](LocalisedLogEntries const&){ updateCache(); }); |
|||
|
|||
noteKnownChanged(); |
|||
} |
|||
|
|||
void NameRegNamer::writeSettings(QSettings&) |
|||
{ |
|||
} |
@ -1,59 +0,0 @@ |
|||
/*
|
|||
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 NameRegNamer.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class NameRegNamer: public QObject, public AccountNamerPlugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
NameRegNamer(MainFace* _m); |
|||
~NameRegNamer(); |
|||
|
|||
private: |
|||
void readSettings(QSettings const&) override; |
|||
void writeSettings(QSettings&) override; |
|||
|
|||
std::string toName(Address const&) const override; |
|||
Address toAddress(std::string const&) const override; |
|||
Addresses knownAddresses() const override; |
|||
|
|||
void updateCache(); |
|||
void killRegistrar(Address const& _r); |
|||
|
|||
Addresses m_registrars; |
|||
std::unordered_map<Address, unsigned> m_filters; |
|||
|
|||
mutable Addresses m_knownCache; |
|||
// mutable std::unordered_map<Address, std::string> m_forwardCache;
|
|||
// mutable std::unordered_map<std::string, Address> m_reverseCache;
|
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,171 +0,0 @@ |
|||
/*
|
|||
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 NewAccount.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "NewAccount.h" |
|||
#include <QMenu> |
|||
#include <QDialog> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethcore/KeyManager.h> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_NewAccount.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
bool beginsWith(Address _a, bytes const& _b) |
|||
{ |
|||
for (unsigned i = 0; i < min<unsigned>(20, _b.size()); ++i) |
|||
if (_a[i] != _b[i]) |
|||
return false; |
|||
return true; |
|||
} |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(NewAccount); |
|||
|
|||
NewAccount::NewAccount(MainFace* _m): |
|||
Plugin(_m, "NewAccount") |
|||
{ |
|||
connect(addMenuItem("New Account...", "menuTools", true), SIGNAL(triggered()), SLOT(create())); |
|||
} |
|||
|
|||
NewAccount::~NewAccount() |
|||
{ |
|||
} |
|||
|
|||
void NewAccount::create() |
|||
{ |
|||
QDialog d; |
|||
Ui::NewAccount u; |
|||
u.setupUi(&d); |
|||
d.setWindowTitle("New Account Wallet"); |
|||
u.hexText->setEnabled(false); |
|||
u.passwordText->setEnabled(false); |
|||
u.passwordAgainText->setEnabled(false); |
|||
u.hintText->setEnabled(false); |
|||
|
|||
QStringList items = |
|||
{ |
|||
"No vanity (instant)", |
|||
"Direct ICAP address", |
|||
"Two pairs first (a few seconds)", |
|||
"Two pairs first and second (a few minutes)", |
|||
"Three pairs first (a few minutes)", |
|||
"Four pairs first (several hours)", |
|||
"Specific hex string" |
|||
}; |
|||
u.typeComboBox->addItems(items); |
|||
|
|||
void (QComboBox:: *indexChangedSignal)(int) = &QComboBox::currentIndexChanged; |
|||
connect(u.typeComboBox, indexChangedSignal, [&](int index) |
|||
{ |
|||
u.hexText->setEnabled(index == StringMatch); |
|||
}); |
|||
|
|||
connect(u.additionalCheckBox, &QCheckBox::clicked, [&]() |
|||
{ |
|||
bool checked = u.additionalCheckBox->checkState() == Qt::CheckState::Checked; |
|||
u.passwordText->setEnabled(checked); |
|||
u.passwordAgainText->setEnabled(checked); |
|||
u.hintText->setEnabled(checked); |
|||
}); |
|||
|
|||
connect(u.create, &QPushButton::clicked, [&]() |
|||
{ |
|||
if (u.additionalCheckBox->checkState() == Qt::CheckState::Checked && !validatePassword(u)) |
|||
{ |
|||
u.passwordAgainLabel->setStyleSheet("QLabel { color : red }"); |
|||
u.passwordAgainLabel->setText("Invalid! Please re-enter password correctly:"); |
|||
return; |
|||
} |
|||
|
|||
d.accept(); |
|||
}); |
|||
|
|||
if (d.exec() == QDialog::Accepted) |
|||
onDialogAccepted(u); |
|||
|
|||
} |
|||
|
|||
bool NewAccount::validatePassword(Ui::NewAccount const& _u) |
|||
{ |
|||
return QString::compare(_u.passwordText->toPlainText(), _u.passwordAgainText->toPlainText()) == 0; |
|||
} |
|||
|
|||
void NewAccount::onDialogAccepted(Ui::NewAccount const& _u) |
|||
{ |
|||
Type v = (Type)_u.typeComboBox->currentIndex(); |
|||
bytes bs = fromHex(_u.hexText->toPlainText().toStdString()); |
|||
KeyPair p = newKeyPair(v, bs); |
|||
QString s = _u.nameText->toPlainText(); |
|||
if (_u.additionalCheckBox->checkState() == Qt::CheckState::Checked) |
|||
{ |
|||
std::string hint = _u.hintText->toPlainText().toStdString(); |
|||
std::string password = _u.passwordText->toPlainText().toStdString(); |
|||
main()->keyManager().import(p.secret(), s.toStdString(), password, hint); |
|||
} |
|||
else |
|||
main()->keyManager().import(p.secret(), s.toStdString()); |
|||
|
|||
main()->noteKeysChanged(); |
|||
} |
|||
|
|||
KeyPair NewAccount::newKeyPair(Type _type, bytes const& _prefix) |
|||
{ |
|||
KeyPair p; |
|||
bool keepGoing = true; |
|||
unsigned done = 0; |
|||
function<void()> f = [&]() { |
|||
KeyPair lp; |
|||
while (keepGoing) |
|||
{ |
|||
done++; |
|||
if (done % 1000 == 0) |
|||
cnote << "Tried" << done << "keys"; |
|||
lp = KeyPair::create(); |
|||
auto a = lp.address(); |
|||
if (_type == NoVanity || |
|||
(_type == DirectICAP && !a[0]) || |
|||
(_type == FirstTwo && a[0] == a[1]) || |
|||
(_type == FirstTwoNextTwo && a[0] == a[1] && a[2] == a[3]) || |
|||
(_type == FirstThree && a[0] == a[1] && a[1] == a[2]) || |
|||
(_type == FirstFour && a[0] == a[1] && a[1] == a[2] && a[2] == a[3]) || |
|||
(_type == StringMatch && beginsWith(lp.address(), _prefix)) |
|||
) |
|||
break; |
|||
} |
|||
if (keepGoing) |
|||
p = lp; |
|||
keepGoing = false; |
|||
}; |
|||
|
|||
vector<std::thread*> ts; |
|||
for (unsigned t = 0; t < std::thread::hardware_concurrency() - 1; ++t) |
|||
ts.push_back(new std::thread(f)); |
|||
f(); |
|||
|
|||
for (std::thread* t: ts) |
|||
{ |
|||
t->join(); |
|||
delete t; |
|||
} |
|||
return p; |
|||
} |
@ -1,56 +0,0 @@ |
|||
/*
|
|||
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 NewAccount.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
|
|||
namespace Ui |
|||
{ |
|||
class NewAccount; |
|||
} |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class NewAccount: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
NewAccount(MainFace* _m); |
|||
~NewAccount(); |
|||
|
|||
private slots: |
|||
void create(); |
|||
|
|||
private: |
|||
enum Type { NoVanity = 0, DirectICAP, FirstTwo, FirstTwoNextTwo, FirstThree, FirstFour, StringMatch }; |
|||
bool validatePassword(Ui::NewAccount const& _u); |
|||
void onDialogAccepted(Ui::NewAccount const& _u); |
|||
KeyPair newKeyPair(Type _type, bytes const& _prefix); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,260 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>NewAccount</class> |
|||
<widget class="QDialog" name="NewAccount"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>511</width> |
|||
<height>600</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Dialog</string> |
|||
</property> |
|||
<property name="styleSheet"> |
|||
<string notr="true"/> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<widget class="QLabel" name="typeLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Select new account type:</span></p></body></html></string> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QComboBox" name="typeComboBox"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>16777215</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="hexLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p>Enter some hex digits it should begin with.<br/>NOTE: The more you enter, the longer generation will take.</p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="hexText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="nameLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter this account name:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="nameText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="additionalLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>100</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Would you like to add additional security for this key? This lets you protect it with a different password to other keys, but also means that you need to re-enter the key's password every time you wish to use the account.</span></p></body></html></string> |
|||
</property> |
|||
<property name="wordWrap"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QCheckBox" name="additionalCheckBox"> |
|||
<property name="text"> |
|||
<string>Yes</string> |
|||
</property> |
|||
<property name="checked"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="passwordLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter password:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="passwordText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="passwordAgainLabel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter password again:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="passwordAgainText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>21</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QLabel" name="hintLabel"> |
|||
<property name="text"> |
|||
<string><html><head/><body><p><span style=" font-weight:600;">Enter hint:</span></p></body></html></string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QTextEdit" name="hintText"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>16777215</width> |
|||
<height>50</height> |
|||
</size> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<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="cancel"> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>83</width> |
|||
<height>16777215</height> |
|||
</size> |
|||
</property> |
|||
<property name="layoutDirection"> |
|||
<enum>Qt::LeftToRight</enum> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Cancel</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="create"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="maximumSize"> |
|||
<size> |
|||
<width>83</width> |
|||
<height>16777215</height> |
|||
</size> |
|||
</property> |
|||
<property name="layoutDirection"> |
|||
<enum>Qt::LeftToRight</enum> |
|||
</property> |
|||
<property name="text"> |
|||
<string>&Create</string> |
|||
</property> |
|||
<property name="default"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>cancel</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>NewAccount</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>381</x> |
|||
<y>483</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>351</x> |
|||
<y>506</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,99 +0,0 @@ |
|||
/*
|
|||
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 OtherAccounts.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "OtherAccounts.h" |
|||
#include <QSettings> |
|||
#include <QMessageBox> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethereum/Client.h> |
|||
#include <ui_OtherAccounts.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(OtherAccounts); |
|||
|
|||
OtherAccounts::OtherAccounts(MainFace* _m): |
|||
AccountNamerPlugin(_m, "OtherAccounts") |
|||
{ |
|||
connect(addMenuItem("Register Third-party Address Names...", "menuTools", true), SIGNAL(triggered()), SLOT(import())); |
|||
} |
|||
|
|||
void OtherAccounts::import() |
|||
{ |
|||
QDialog d; |
|||
Ui_OtherAccounts u; |
|||
u.setupUi(&d); |
|||
d.setWindowTitle("Add Named Accounts"); |
|||
if (d.exec() == QDialog::Accepted) |
|||
{ |
|||
QStringList sl = u.accounts->toPlainText().split("\n"); |
|||
unsigned line = 1; |
|||
for (QString const& s: sl) |
|||
{ |
|||
try |
|||
{ |
|||
Address addr = dev::eth::toAddress(s.section(QRegExp("[ \\0\\t]+"), 0, 0).trimmed().toStdString()); |
|||
string name = s.section(QRegExp("[ \\0\\t]+"), 1).trimmed().toStdString(); |
|||
m_toName[addr] = name; |
|||
m_toAddress[name] = addr; |
|||
} |
|||
catch (...) |
|||
{ |
|||
if (QMessageBox::warning(&d, "Invalid Line Format", "Line format or address given on line " + QString::number(line) + " is invalid:\n" + s, QMessageBox::Abort, QMessageBox::Ignore) == QMessageBox::Abort) |
|||
break; |
|||
} |
|||
line++; |
|||
} |
|||
main()->noteSettingsChanged(); |
|||
noteKnownChanged(); |
|||
} |
|||
} |
|||
|
|||
void OtherAccounts::readSettings(QSettings const& _s) |
|||
{ |
|||
m_toName.clear(); |
|||
m_toAddress.clear(); |
|||
for (QVariant const& i: _s.value("OtherAccounts", QVariantList()).toList()) |
|||
{ |
|||
QStringList l = i.toStringList(); |
|||
if (l.size() == 2) |
|||
{ |
|||
m_toName[Address(l[0].toStdString())] = l[1].toStdString(); |
|||
m_toAddress[l[1].toStdString()] = Address(l[0].toStdString()); |
|||
} |
|||
} |
|||
noteKnownChanged(); |
|||
} |
|||
|
|||
void OtherAccounts::writeSettings(QSettings& _s) |
|||
{ |
|||
QVariantList r; |
|||
for (auto const& i: m_toName) |
|||
{ |
|||
QStringList l; |
|||
l += QString::fromStdString(i.first.hex()); |
|||
l += QString::fromStdString(i.second); |
|||
r += QVariant(l); |
|||
} |
|||
_s.setValue("OtherAccounts", r); |
|||
} |
@ -1,55 +0,0 @@ |
|||
/*
|
|||
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 OtherAccounts.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class OtherAccounts: public QObject, public AccountNamerPlugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
OtherAccounts(MainFace* _m); |
|||
|
|||
protected: |
|||
std::string toName(Address const& _a) const override { if (m_toName.count(_a)) return m_toName.at(_a); return std::string(); } |
|||
Address toAddress(std::string const& _n) const override { if (m_toAddress.count(_n)) return m_toAddress.at(_n); return Address(); } |
|||
Addresses knownAddresses() const override { return keysOf(m_toName); } |
|||
|
|||
private slots: |
|||
void import(); |
|||
|
|||
private: |
|||
void readSettings(QSettings const&) override; |
|||
void writeSettings(QSettings&) override; |
|||
|
|||
std::unordered_map<std::string, Address> m_toAddress; |
|||
std::unordered_map<Address, std::string> m_toName; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,95 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>OtherAccounts</class> |
|||
<widget class="QDialog" name="OtherAccounts"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>511</width> |
|||
<height>508</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Dialog</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<widget class="QTextEdit" name="accounts"> |
|||
<property name="placeholderText"> |
|||
<string>Write the accounts you wish to name here, one address/name pair per line, the name following the address split only be a single space character.</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<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="cancel"> |
|||
<property name="text"> |
|||
<string>Cancel</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="create"> |
|||
<property name="text"> |
|||
<string>&Import</string> |
|||
</property> |
|||
<property name="default"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>create</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>OtherAccounts</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>462</x> |
|||
<y>484</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>449</x> |
|||
<y>504</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>cancel</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>OtherAccounts</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>381</x> |
|||
<y>483</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>351</x> |
|||
<y>506</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,67 +0,0 @@ |
|||
/*
|
|||
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 OurAccounts.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "OurAccounts.h" |
|||
#include <libdevcore/Log.h> |
|||
#include <libethereum/Client.h> |
|||
#include <libethcore/KeyManager.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(OurAccounts); |
|||
|
|||
OurAccounts::OurAccounts(MainFace* _m): |
|||
AccountNamerPlugin(_m, "OurAccounts") |
|||
{ |
|||
connect(main(), SIGNAL(keyManagerChanged()), SLOT(updateNames())); |
|||
updateNames(); |
|||
} |
|||
|
|||
OurAccounts::~OurAccounts() |
|||
{ |
|||
} |
|||
|
|||
std::string OurAccounts::toName(Address const& _a) const |
|||
{ |
|||
return main()->keyManager().accountName(_a); |
|||
} |
|||
|
|||
Address OurAccounts::toAddress(std::string const& _n) const |
|||
{ |
|||
if (m_names.count(_n)) |
|||
return m_names.at(_n); |
|||
return Address(); |
|||
} |
|||
|
|||
Addresses OurAccounts::knownAddresses() const |
|||
{ |
|||
return main()->keyManager().accounts(); |
|||
} |
|||
|
|||
void OurAccounts::updateNames() |
|||
{ |
|||
m_names.clear(); |
|||
for (Address const& i: main()->keyManager().accounts()) |
|||
m_names[main()->keyManager().accountName(i)] = i; |
|||
noteKnownChanged(); |
|||
} |
@ -1,52 +0,0 @@ |
|||
/*
|
|||
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 OurAccounts.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class OurAccounts: public QObject, public AccountNamerPlugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
OurAccounts(MainFace* _m); |
|||
~OurAccounts(); |
|||
|
|||
protected: |
|||
std::string toName(Address const& _a) const override; |
|||
Address toAddress(std::string const& _n) const override; |
|||
Addresses knownAddresses() const override; |
|||
|
|||
private slots: |
|||
void updateNames(); |
|||
|
|||
private: |
|||
std::unordered_map<std::string, Address> m_names; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,87 +0,0 @@ |
|||
/*
|
|||
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 InjectTransactions.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "InjectTransactions.h" |
|||
#include <QMessageBox> |
|||
#include <QInputDialog> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethereum/Client.h> |
|||
#include "ui_InjectTransactions.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(InjectTransactions); |
|||
|
|||
InjectTransactions::InjectTransactions(MainFace* _m): |
|||
Plugin(_m, "InjectTransactions") |
|||
{ |
|||
connect(addMenuItem("Inject Transaction...", "menuSpecial", true), SIGNAL(triggered()), SLOT(injectOne())); |
|||
connect(addMenuItem("Bulk Inject Transactions...", "menuSpecial", false), SIGNAL(triggered()), SLOT(injectBulk())); |
|||
} |
|||
|
|||
InjectTransactions::~InjectTransactions() |
|||
{ |
|||
} |
|||
|
|||
void InjectTransactions::injectOne() |
|||
{ |
|||
bool ok; |
|||
QString s = QInputDialog::getText(main(), "Inject Transaction", "Enter transaction dump in hex", QLineEdit::Normal, QString(), &ok); |
|||
if (ok) |
|||
doInject(s); |
|||
} |
|||
|
|||
void InjectTransactions::injectBulk() |
|||
{ |
|||
QDialog d; |
|||
Ui_InjectTransactions u; |
|||
u.setupUi(&d); |
|||
d.setWindowTitle("Bulk Inject Transactions"); |
|||
if (d.exec() == QDialog::Accepted) |
|||
for (QString const& s: u.transactions->toPlainText().split("\n")) |
|||
doInject(s); |
|||
} |
|||
|
|||
void InjectTransactions::doInject(QString _txHex) |
|||
{ |
|||
try |
|||
{ |
|||
bytes b = fromHex(_txHex.toStdString(), WhenError::Throw); |
|||
main()->ethereum()->injectTransaction(b, IfDropped::Retry); |
|||
} |
|||
catch (BadHexCharacter& _e) |
|||
{ |
|||
if (QMessageBox::warning(main(), "Invalid Transaction Hex", "Invalid hex character in:\n" + _txHex + "\nTransaction rejected.", QMessageBox::Ignore, QMessageBox::Abort) == QMessageBox::Abort) |
|||
return; |
|||
} |
|||
catch (Exception& _e) |
|||
{ |
|||
if (QMessageBox::warning(main(), "Transaction Rejected", "Invalid transaction; due to" + QString::fromStdString(_e.what()) + "\n" + _txHex + "\nTransaction rejected.", QMessageBox::Ignore, QMessageBox::Abort) == QMessageBox::Abort) |
|||
return; |
|||
} |
|||
catch (...) |
|||
{ |
|||
// Should not happen under normal circumstances.
|
|||
return; |
|||
} |
|||
} |
@ -1,48 +0,0 @@ |
|||
/*
|
|||
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 InjectTransactions.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "MainFace.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class InjectTransactions: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
InjectTransactions(MainFace* _m); |
|||
~InjectTransactions(); |
|||
|
|||
private slots: |
|||
void injectOne(); |
|||
void injectBulk(); |
|||
|
|||
private: |
|||
void doInject(QString _txHex); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,95 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>InjectTransactions</class> |
|||
<widget class="QDialog" name="InjectTransactions"> |
|||
<property name="geometry"> |
|||
<rect> |
|||
<x>0</x> |
|||
<y>0</y> |
|||
<width>511</width> |
|||
<height>508</height> |
|||
</rect> |
|||
</property> |
|||
<property name="windowTitle"> |
|||
<string>Dialog</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="verticalLayout"> |
|||
<item> |
|||
<widget class="QTextEdit" name="transactions"> |
|||
<property name="placeholderText"> |
|||
<string>Write the transactions you wish to inject here, in hex, one per line.</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<layout class="QHBoxLayout" name="horizontalLayout"> |
|||
<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="cancel"> |
|||
<property name="text"> |
|||
<string>Cancel</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<widget class="QPushButton" name="inject"> |
|||
<property name="text"> |
|||
<string>&Import</string> |
|||
</property> |
|||
<property name="default"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections> |
|||
<connection> |
|||
<sender>inject</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>InjectTransactions</receiver> |
|||
<slot>accept()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>462</x> |
|||
<y>484</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>449</x> |
|||
<y>504</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
<connection> |
|||
<sender>cancel</sender> |
|||
<signal>clicked()</signal> |
|||
<receiver>InjectTransactions</receiver> |
|||
<slot>reject()</slot> |
|||
<hints> |
|||
<hint type="sourcelabel"> |
|||
<x>381</x> |
|||
<y>483</y> |
|||
</hint> |
|||
<hint type="destinationlabel"> |
|||
<x>351</x> |
|||
<y>506</y> |
|||
</hint> |
|||
</hints> |
|||
</connection> |
|||
</connections> |
|||
</ui> |
@ -1,178 +0,0 @@ |
|||
/*
|
|||
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 Whisper.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "Whisper.h" |
|||
#include <QSettings> |
|||
#include <libethereum/Client.h> |
|||
#include <libethereum/Utility.h> |
|||
#include <libwhisper/WhisperHost.h> |
|||
#include <libweb3jsonrpc/WebThreeStubServerBase.h> |
|||
#include "OurWebThreeStubServer.h" |
|||
#include "ui_Whisper.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(Whisper); |
|||
|
|||
static Public stringToPublic(QString const& _a) |
|||
{ |
|||
string sn = _a.toStdString(); |
|||
if (_a.size() == sizeof(Public) * 2) |
|||
return Public(fromHex(_a.toStdString())); |
|||
else if (_a.size() == sizeof(Public) * 2 + 2 && _a.startsWith("0x")) |
|||
return Public(fromHex(_a.mid(2).toStdString())); |
|||
else |
|||
return Public(); |
|||
} |
|||
|
|||
static shh::Topics topicFromText(QString _s) |
|||
{ |
|||
shh::BuildTopic ret; |
|||
while (_s.size()) |
|||
{ |
|||
QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?"); |
|||
QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); |
|||
QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); |
|||
bytes part; |
|||
if (r.exactMatch(_s)) |
|||
{ |
|||
for (auto i: r.cap(2)) |
|||
part.push_back((byte)i.toLatin1()); |
|||
if (r.cap(1) != "$") |
|||
for (int i = r.cap(2).size(); i < 32; ++i) |
|||
part.push_back(0); |
|||
else |
|||
part.push_back(0); |
|||
_s = r.cap(3); |
|||
} |
|||
else if (d.exactMatch(_s)) |
|||
{ |
|||
u256 v(d.cap(2).toStdString()); |
|||
if (d.cap(6) == "szabo") |
|||
v *= szabo; |
|||
else if (d.cap(5) == "finney") |
|||
v *= finney; |
|||
else if (d.cap(4) == "ether") |
|||
v *= ether; |
|||
bytes bs = dev::toCompactBigEndian(v); |
|||
if (d.cap(1) != "$") |
|||
for (auto i = bs.size(); i < 32; ++i) |
|||
part.push_back(0); |
|||
for (auto b: bs) |
|||
part.push_back(b); |
|||
_s = d.cap(7); |
|||
} |
|||
else if (h.exactMatch(_s)) |
|||
{ |
|||
bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString()); |
|||
if (h.cap(1) != "$") |
|||
for (auto i = bs.size(); i < 32; ++i) |
|||
part.push_back(0); |
|||
for (auto b: bs) |
|||
part.push_back(b); |
|||
_s = h.cap(5); |
|||
} |
|||
else |
|||
_s = _s.mid(1); |
|||
ret.shift(part); |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
|
|||
Whisper::Whisper(MainFace* _m): |
|||
Plugin(_m, "Whisper"), |
|||
m_ui(new Ui::Whisper) |
|||
{ |
|||
dock(Qt::RightDockWidgetArea, "Whisper")->setWidget(new QWidget); |
|||
m_ui->setupUi(dock()->widget()); |
|||
connect(addMenuItem("New Whisper identity.", "menuNetwork", true), &QAction::triggered, this, &Whisper::on_newIdentity_triggered); |
|||
connect(_m->web3Server(), &OurWebThreeStubServer::onNewId, this, &Whisper::addNewId); |
|||
} |
|||
|
|||
void Whisper::readSettings(QSettings const& _s) |
|||
{ |
|||
m_myIdentities.clear(); |
|||
QByteArray b = _s.value("identities").toByteArray(); |
|||
if (!b.isEmpty()) |
|||
{ |
|||
Secret k; |
|||
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) |
|||
{ |
|||
memcpy(k.writable().data(), b.data() + i * sizeof(Secret), sizeof(Secret)); |
|||
if (!count(m_myIdentities.begin(), m_myIdentities.end(), KeyPair(k))) |
|||
m_myIdentities.append(KeyPair(k)); |
|||
} |
|||
} |
|||
main()->web3Server()->setIdentities(keysAsVector(m_myIdentities)); |
|||
refreshWhisper(); |
|||
} |
|||
|
|||
void Whisper::writeSettings(QSettings& _s) |
|||
{ |
|||
QByteArray b; |
|||
b.resize(sizeof(Secret) * m_myIdentities.size()); |
|||
auto p = b.data(); |
|||
for (auto i: m_myIdentities) |
|||
{ |
|||
memcpy(p, &(i.secret()), sizeof(Secret)); |
|||
p += sizeof(Secret); |
|||
} |
|||
_s.setValue("identities", b); |
|||
} |
|||
|
|||
void Whisper::addNewId(QString _ids) |
|||
{ |
|||
KeyPair kp(jsToSecret(_ids.toStdString())); |
|||
m_myIdentities.push_back(kp); |
|||
main()->web3Server()->setIdentities(keysAsVector(m_myIdentities)); |
|||
refreshWhisper(); |
|||
} |
|||
|
|||
void Whisper::refreshWhisper() |
|||
{ |
|||
m_ui->shhFrom->clear(); |
|||
for (auto i: main()->web3Server()->ids()) |
|||
m_ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref()))); |
|||
} |
|||
|
|||
void Whisper::on_newIdentity_triggered() |
|||
{ |
|||
KeyPair kp = KeyPair::create(); |
|||
m_myIdentities.append(kp); |
|||
main()->web3Server()->setIdentities(keysAsVector(m_myIdentities)); |
|||
refreshWhisper(); |
|||
} |
|||
|
|||
void Whisper::on_post_clicked() |
|||
{ |
|||
return; |
|||
shh::Message m; |
|||
m.setTo(stringToPublic(m_ui->shhTo->currentText())); |
|||
m.setPayload(parseData(m_ui->shhData->toPlainText().toStdString())); |
|||
Public f = stringToPublic(m_ui->shhFrom->currentText()); |
|||
Secret from; |
|||
if (main()->web3Server()->ids().count(f)) |
|||
from = main()->web3Server()->ids().at(f); |
|||
whisper()->inject(m.seal(from, topicFromText(m_ui->shhTopic->toPlainText()), m_ui->shhTtl->value(), m_ui->shhWork->value())); |
|||
} |
@ -1,60 +0,0 @@ |
|||
/*
|
|||
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 Whisper.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QMutex> |
|||
#include <QString> |
|||
#include <QPair> |
|||
#include <QList> |
|||
#include "MainFace.h" |
|||
|
|||
namespace Ui |
|||
{ |
|||
class Whisper; |
|||
} |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class Whisper: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
Whisper(MainFace* _m); |
|||
|
|||
private: |
|||
void readSettings(QSettings const&) override; |
|||
void writeSettings(QSettings&) override; |
|||
void refreshWhisper(); |
|||
void addNewId(QString _ids); |
|||
void on_newIdentity_triggered(); |
|||
void on_post_clicked(); |
|||
|
|||
Ui::Whisper* m_ui; |
|||
QList<KeyPair> m_myIdentities; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,176 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>Whisper</class> |
|||
<widget class="QWidget" name="WhisperWidget"> |
|||
<layout class="QGridLayout" name="gridLayout_4"> |
|||
<item row="4" column="0" rowspan="2"> |
|||
<widget class="QLabel" name="label_8"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Data</string> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="2" colspan="2"> |
|||
<widget class="QLabel" name="label5_6"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Work to Prove</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="5" column="1" colspan="4"> |
|||
<widget class="QPlainTextEdit" name="shhData"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="1" colspan="4"> |
|||
<widget class="QPlainTextEdit" name="shhTopic"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
<property name="lineWidth"> |
|||
<number>0</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" column="1" colspan="4"> |
|||
<widget class="QComboBox" name="shhFrom"> |
|||
<property name="editable"> |
|||
<bool>false</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="3" column="0"> |
|||
<widget class="QLabel" name="label_9"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>Topic</string> |
|||
</property> |
|||
<property name="alignment"> |
|||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="0" column="0"> |
|||
<widget class="QLabel" name="label5_3"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>To</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="0" column="1" colspan="4"> |
|||
<widget class="QComboBox" name="shhTo"> |
|||
<property name="editable"> |
|||
<bool>true</bool> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="1"> |
|||
<widget class="QSpinBox" name="shhTtl"> |
|||
<property name="suffix"> |
|||
<string> seconds</string> |
|||
</property> |
|||
<property name="minimum"> |
|||
<number>5</number> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>259200</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="0"> |
|||
<widget class="QLabel" name="label5_5"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>TTL</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="1" column="0"> |
|||
<widget class="QLabel" name="label5_4"> |
|||
<property name="sizePolicy"> |
|||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
|||
<horstretch>0</horstretch> |
|||
<verstretch>0</verstretch> |
|||
</sizepolicy> |
|||
</property> |
|||
<property name="text"> |
|||
<string>From</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="2" column="4"> |
|||
<widget class="QSpinBox" name="shhWork"> |
|||
<property name="suffix"> |
|||
<string> ms</string> |
|||
</property> |
|||
<property name="minimum"> |
|||
<number>1</number> |
|||
</property> |
|||
<property name="maximum"> |
|||
<number>1000</number> |
|||
</property> |
|||
<property name="value"> |
|||
<number>50</number> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
<item row="6" column="4"> |
|||
<widget class="QPushButton" name="post"> |
|||
<property name="text"> |
|||
<string>Post</string> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
@ -1,78 +0,0 @@ |
|||
/*
|
|||
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 WhisperPeers.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "WhisperPeers.h" |
|||
#include <QSettings> |
|||
#include <libethereum/Client.h> |
|||
#include <libwhisper/WhisperHost.h> |
|||
#include <libweb3jsonrpc/WebThreeStubServerBase.h> |
|||
#include "OurWebThreeStubServer.h" |
|||
#include "ui_WhisperPeers.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace az; |
|||
using namespace eth; |
|||
|
|||
DEV_AZ_NOTE_PLUGIN(WhisperPeers); |
|||
|
|||
WhisperPeers::WhisperPeers(MainFace* _m): |
|||
Plugin(_m, "WhisperPeers"), |
|||
m_ui(new Ui::WhisperPeers) |
|||
{ |
|||
dock(Qt::RightDockWidgetArea, "Active Whispers")->setWidget(new QWidget); |
|||
m_ui->setupUi(dock()->widget()); |
|||
startTimer(1000); |
|||
} |
|||
|
|||
void WhisperPeers::timerEvent(QTimerEvent*) |
|||
{ |
|||
refreshWhispers(); |
|||
} |
|||
|
|||
void WhisperPeers::refreshWhispers() |
|||
{ |
|||
return; |
|||
m_ui->whispers->clear(); |
|||
for (auto const& w: whisper()->all()) |
|||
{ |
|||
shh::Envelope const& e = w.second; |
|||
shh::Message m; |
|||
for (pair<Public, Secret> const& i: main()->web3Server()->ids()) |
|||
if (!!(m = e.open(shh::Topics(), i.second))) |
|||
break; |
|||
if (!m) |
|||
m = e.open(shh::Topics()); |
|||
|
|||
QString msg; |
|||
if (m.from()) |
|||
// Good message.
|
|||
msg = QString("{%1 -> %2} %3").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str()); |
|||
else if (m) |
|||
// Maybe message.
|
|||
msg = QString("{%1 -> %2} %3 (?)").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str()); |
|||
|
|||
time_t ex = e.expiry(); |
|||
QString t(ctime(&ex)); |
|||
t.chop(1); |
|||
QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topic()).c_str()).arg(msg); |
|||
m_ui->whispers->addItem(item); |
|||
} |
|||
} |
@ -1,55 +0,0 @@ |
|||
/*
|
|||
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 WhisperPeers.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QMutex> |
|||
#include <QString> |
|||
#include <QPair> |
|||
#include <QList> |
|||
#include "MainFace.h" |
|||
|
|||
namespace Ui |
|||
{ |
|||
class WhisperPeers; |
|||
} |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace az |
|||
{ |
|||
|
|||
class WhisperPeers: public QObject, public Plugin |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
WhisperPeers(MainFace* _m); |
|||
|
|||
private: |
|||
void timerEvent(QTimerEvent*) override; |
|||
void refreshWhispers(); |
|||
|
|||
Ui::WhisperPeers* m_ui; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,32 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>WhisperPeers</class> |
|||
<widget class="QWidget" name="whisperPeersWidget"> |
|||
<layout class="QHBoxLayout" name="whisperPeersLayout"> |
|||
<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> |
|||
<widget class="QListWidget" name="whispers"> |
|||
<property name="frameShape"> |
|||
<enum>QFrame::NoFrame</enum> |
|||
</property> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
Loading…
Reference in new issue