subtly
10 years ago
70 changed files with 4437 additions and 652 deletions
@ -1 +1 @@ |
|||||
Subproject commit 66d5a2b5cdf1361dcf0205b191dd12be090ed224 |
Subproject commit 3df5a125fa0baa579528abce80402118cad803fd |
@ -0,0 +1,171 @@ |
|||||
|
/*
|
||||
|
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 AssemblyDebuggerControl.cpp
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
* display opcode debugging. |
||||
|
*/ |
||||
|
|
||||
|
#include <QtConcurrent/QtConcurrent> |
||||
|
#include <QDebug> |
||||
|
#include <QVariableDefinition.h> |
||||
|
#include <QQmlContext> |
||||
|
#include <QModelIndex> |
||||
|
#include <libdevcore/CommonJS.h> |
||||
|
#include <libethereum/Transaction.h> |
||||
|
#include "AssemblyDebuggerModel.h" |
||||
|
#include "AssemblyDebuggerControl.h" |
||||
|
#include "KeyEventManager.h" |
||||
|
#include "AppContext.h" |
||||
|
#include "DebuggingStateWrapper.h" |
||||
|
#include "TransactionListModel.h" |
||||
|
#include "QContractDefinition.h" |
||||
|
#include "QVariableDeclaration.h" |
||||
|
#include "ContractCallDataEncoder.h" |
||||
|
using namespace dev::eth; |
||||
|
using namespace dev::mix; |
||||
|
|
||||
|
AssemblyDebuggerControl::AssemblyDebuggerControl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) |
||||
|
{ |
||||
|
qRegisterMetaType<QVariableDefinition*>("QVariableDefinition*"); |
||||
|
qRegisterMetaType<QVariableDefinitionList*>("QVariableDefinitionList*"); |
||||
|
qRegisterMetaType<QList<QVariableDefinition*>>("QList<QVariableDefinition*>"); |
||||
|
qRegisterMetaType<QList<QVariableDeclaration*>>("QList<QVariableDeclaration*>"); |
||||
|
qRegisterMetaType<QVariableDeclaration*>("QVariableDeclaration*"); |
||||
|
qRegisterMetaType<AssemblyDebuggerData>("AssemblyDebuggerData"); |
||||
|
qRegisterMetaType<DebuggingStatusResult>("DebuggingStatusResult"); |
||||
|
|
||||
|
connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)), |
||||
|
this, SLOT(updateGUI(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)), Qt::QueuedConnection); |
||||
|
|
||||
|
m_modelDebugger = std::unique_ptr<AssemblyDebuggerModel>(new AssemblyDebuggerModel); |
||||
|
m_compilation = std::unique_ptr<ConstantCompilationModel>(new ConstantCompilationModel); |
||||
|
m_doc = _doc; |
||||
|
} |
||||
|
|
||||
|
QString AssemblyDebuggerControl::contentUrl() const |
||||
|
{ |
||||
|
return QStringLiteral("qrc:/qml/Debugger.qml"); |
||||
|
} |
||||
|
|
||||
|
QString AssemblyDebuggerControl::title() const |
||||
|
{ |
||||
|
return QApplication::tr("debugger"); |
||||
|
} |
||||
|
|
||||
|
void AssemblyDebuggerControl::start() const |
||||
|
{ |
||||
|
//start to listen on F5
|
||||
|
m_ctx->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); |
||||
|
} |
||||
|
|
||||
|
void AssemblyDebuggerControl::keyPressed(int _key) |
||||
|
{ |
||||
|
if (_key == Qt::Key_F5) |
||||
|
{ |
||||
|
QtConcurrent::run([this]() |
||||
|
{ |
||||
|
deployContract(m_doc->toPlainText()); |
||||
|
}); |
||||
|
} |
||||
|
else if (_key == Qt::Key_F6) |
||||
|
{ |
||||
|
m_modelDebugger->resetState(); |
||||
|
AppContext::getInstance()->displayMessageDialog(QApplication::tr("State status"), QApplication::tr("State reseted ... need to redeploy contract")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void AssemblyDebuggerControl::callContract(TransactionSettings _tr, dev::Address _contract) |
||||
|
{ |
||||
|
CompilerResult compilerRes = m_compilation->compile(m_doc->toPlainText()); |
||||
|
if (!compilerRes.success) |
||||
|
AppContext::getInstance()->displayMessageDialog("debugger","compilation failed"); |
||||
|
else |
||||
|
{ |
||||
|
ContractCallDataEncoder c; |
||||
|
std::shared_ptr<QContractDefinition> contractDef = QContractDefinition::Contract(m_doc->toPlainText()); |
||||
|
QFunctionDefinition* f = nullptr; |
||||
|
for (int k = 0; k < contractDef->functions().size(); k++) |
||||
|
{ |
||||
|
if (contractDef->functions().at(k)->name() == _tr.functionId) |
||||
|
{ |
||||
|
f = (QFunctionDefinition*)contractDef->functions().at(k); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (!f) |
||||
|
AppContext::getInstance()->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("function not found. Please redeploy this contract.")); |
||||
|
else |
||||
|
{ |
||||
|
c.encode(f->index()); |
||||
|
for (int k = 0; k < f->parameters().size(); k++) |
||||
|
{ |
||||
|
QVariableDeclaration* var = (QVariableDeclaration*)f->parameters().at(k); |
||||
|
c.encode(var, _tr.parameterValues[var->name()]); |
||||
|
} |
||||
|
DebuggingContent debuggingContent = m_modelDebugger->callContract(_contract, c.encodedData(), _tr); |
||||
|
debuggingContent.returnParameters = c.decode(f->returnParameters(), debuggingContent.returnValue); |
||||
|
finalizeExecution(debuggingContent); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void AssemblyDebuggerControl::deployContract(QString _source) |
||||
|
{ |
||||
|
CompilerResult compilerRes = m_compilation->compile(_source); |
||||
|
if (!compilerRes.success) |
||||
|
emit dataAvailable(false, DebuggingStatusResult::Compilationfailed); |
||||
|
else |
||||
|
{ |
||||
|
m_previousDebugResult = m_modelDebugger->deployContract(compilerRes.bytes); |
||||
|
finalizeExecution(m_previousDebugResult); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void AssemblyDebuggerControl::finalizeExecution(DebuggingContent _debuggingContent) |
||||
|
{ |
||||
|
//we need to wrap states in a QObject before sending to QML.
|
||||
|
QList<QObject*> wStates; |
||||
|
for(int i = 0; i < _debuggingContent.machineStates.size(); i++) |
||||
|
{ |
||||
|
QPointer<DebuggingStateWrapper> s(new DebuggingStateWrapper(_debuggingContent.executionCode, _debuggingContent.executionData.toBytes())); |
||||
|
s->setState(_debuggingContent.machineStates.at(i)); |
||||
|
wStates.append(s); |
||||
|
} |
||||
|
AssemblyDebuggerData code = DebuggingStateWrapper::getHumanReadableCode(_debuggingContent.executionCode); |
||||
|
emit dataAvailable(true, DebuggingStatusResult::Ok, _debuggingContent.returnParameters, wStates, code); |
||||
|
} |
||||
|
|
||||
|
void AssemblyDebuggerControl::updateGUI(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParam, QList<QObject*> const& _wStates, AssemblyDebuggerData const& _code) |
||||
|
{ |
||||
|
Q_UNUSED(_reason); |
||||
|
if (_success) |
||||
|
{ |
||||
|
m_appEngine->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); |
||||
|
m_appEngine->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); |
||||
|
m_appEngine->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); |
||||
|
m_appEngine->rootContext()->setContextProperty("contractCallReturnParameters", QVariant::fromValue(new QVariableDefinitionList(_returnParam))); |
||||
|
this->addContentOn(this); |
||||
|
} |
||||
|
else |
||||
|
m_ctx->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("compilation failed")); |
||||
|
} |
||||
|
|
||||
|
void AssemblyDebuggerControl::runTransaction(TransactionSettings const& _tr) |
||||
|
{ |
||||
|
QtConcurrent::run([this, _tr]() |
||||
|
{ |
||||
|
callContract(_tr, m_previousDebugResult.contractAddress); |
||||
|
}); |
||||
|
} |
@ -0,0 +1,84 @@ |
|||||
|
/*
|
||||
|
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 AssemblyDebuggerControl.h
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
* Extension which display debugging steps in assembly code. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <QKeySequence> |
||||
|
#include <QTextDocument> |
||||
|
#include "Extension.h" |
||||
|
#include "ConstantCompilationModel.h" |
||||
|
#include "TransactionListModel.h" |
||||
|
#include "AssemblyDebuggerModel.h" |
||||
|
#include "AppContext.h" |
||||
|
|
||||
|
using AssemblyDebuggerData = std::tuple<QList<QObject*>, dev::mix::QQMLMap*>; |
||||
|
enum DebuggingStatusResult |
||||
|
{ |
||||
|
Ok, |
||||
|
Compilationfailed |
||||
|
}; |
||||
|
|
||||
|
Q_DECLARE_METATYPE(AssemblyDebuggerData) |
||||
|
Q_DECLARE_METATYPE(DebuggingStatusResult) |
||||
|
Q_DECLARE_METATYPE(dev::mix::DebuggingContent) |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
/**
|
||||
|
* @brief Extension which display transaction creation or transaction call debugging. handle: F5 to deploy contract, F6 to reset state. |
||||
|
*/ |
||||
|
class AssemblyDebuggerControl: public Extension |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
AssemblyDebuggerControl(QTextDocument* _doc); |
||||
|
~AssemblyDebuggerControl() {} |
||||
|
void start() const override; |
||||
|
QString title() const override; |
||||
|
QString contentUrl() const override; |
||||
|
|
||||
|
private: |
||||
|
void deployContract(QString _source); |
||||
|
void callContract(TransactionSettings _tr, Address _contract); |
||||
|
void finalizeExecution(DebuggingContent _content); |
||||
|
|
||||
|
std::unique_ptr<AssemblyDebuggerModel> m_modelDebugger; |
||||
|
std::unique_ptr<ConstantCompilationModel> m_compilation; |
||||
|
DebuggingContent m_previousDebugResult; //TODO: to be replaced in a more consistent struct. Used for now to keep the contract address in case of future transaction call.
|
||||
|
QTextDocument* m_doc; |
||||
|
|
||||
|
public slots: |
||||
|
/// Handle key pressed. F5 deploy contract - F6 reset state.
|
||||
|
void keyPressed(int); |
||||
|
/// Update UI with machine states result. Display a modal dialog.
|
||||
|
void updateGUI(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParams = QList<QVariableDefinition*>(), QList<QObject*> const& _wStates = QList<QObject*>(), AssemblyDebuggerData const& _code = AssemblyDebuggerData()); |
||||
|
/// Run the given transaction.
|
||||
|
void runTransaction(TransactionSettings const& _tr); |
||||
|
|
||||
|
signals: |
||||
|
/// Emited when machine states are available.
|
||||
|
void dataAvailable(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParams = QList<QVariableDefinition*>(), QList<QObject*> const& _wStates = QList<QObject*>(), AssemblyDebuggerData const& _code = AssemblyDebuggerData()); |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -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 AssemblyDebuggerCtrl.h
|
|
||||
* @author Yann yann@ethdev.com |
|
||||
* @date 2014 |
|
||||
* display opcode debugging. |
|
||||
*/ |
|
||||
|
|
||||
#include <QtConcurrent/QtConcurrent> |
|
||||
#include <QDebug> |
|
||||
#include <QQmlContext> |
|
||||
#include <QModelIndex> |
|
||||
#include "libethereum/Transaction.h" |
|
||||
#include "AssemblyDebuggerModel.h" |
|
||||
#include "AssemblyDebuggerCtrl.h" |
|
||||
#include "TransactionBuilder.h" |
|
||||
#include "KeyEventManager.h" |
|
||||
#include "AppContext.h" |
|
||||
#include "DebuggingStateWrapper.h" |
|
||||
using namespace dev::mix; |
|
||||
|
|
||||
AssemblyDebuggerCtrl::AssemblyDebuggerCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) |
|
||||
{ |
|
||||
qRegisterMetaType<AssemblyDebuggerData>(); |
|
||||
qRegisterMetaType<DebuggingStatusResult>(); |
|
||||
connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList<QObject*>, AssemblyDebuggerData)), |
|
||||
this, SLOT(updateGUI(bool, DebuggingStatusResult, QList<QObject*>, AssemblyDebuggerData)), Qt::QueuedConnection); |
|
||||
m_modelDebugger = std::unique_ptr<AssemblyDebuggerModel>(new AssemblyDebuggerModel); |
|
||||
m_doc = _doc; |
|
||||
} |
|
||||
|
|
||||
QString AssemblyDebuggerCtrl::contentUrl() const |
|
||||
{ |
|
||||
return QStringLiteral("qrc:/qml/Debugger.qml"); |
|
||||
} |
|
||||
|
|
||||
QString AssemblyDebuggerCtrl::title() const |
|
||||
{ |
|
||||
return QApplication::tr("debugger"); |
|
||||
} |
|
||||
|
|
||||
void AssemblyDebuggerCtrl::start() const |
|
||||
{ |
|
||||
//start to listen on F5
|
|
||||
m_ctx->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); |
|
||||
} |
|
||||
|
|
||||
void AssemblyDebuggerCtrl::keyPressed(int _key) |
|
||||
{ |
|
||||
if (_key == Qt::Key_F5) |
|
||||
{ |
|
||||
QString code = m_doc->toPlainText(); |
|
||||
QtConcurrent::run([this, code]() |
|
||||
{ |
|
||||
if (!m_modelDebugger->compile(m_doc->toPlainText())) |
|
||||
{ |
|
||||
emit dataAvailable(false, DebuggingStatusResult::Compilationfailed); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
u256 gasPrice = 10000000000000; |
|
||||
u256 gas = 1000000; |
|
||||
u256 amount = 100; |
|
||||
DebuggingContent debuggingContent = m_modelDebugger->getContractInitiationDebugStates(amount, gasPrice, gas, m_doc->toPlainText()); |
|
||||
|
|
||||
//we need to wrap states in a QObject before sending to QML.
|
|
||||
QList<QObject*> wStates; |
|
||||
for(int i = 0; i < debuggingContent.states.size(); i++) |
|
||||
{ |
|
||||
DebuggingStateWrapper* s = new DebuggingStateWrapper(debuggingContent.executionCode, debuggingContent.executionData.toBytes(), this); |
|
||||
s->setState(debuggingContent.states.at(i)); |
|
||||
wStates.append(s); |
|
||||
} |
|
||||
AssemblyDebuggerData code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode, this); |
|
||||
emit dataAvailable(true, DebuggingStatusResult::Ok, wStates, code); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void AssemblyDebuggerCtrl::updateGUI(bool success, DebuggingStatusResult reason, QList<QObject*> _wStates, AssemblyDebuggerData _code) |
|
||||
{ |
|
||||
Q_UNUSED(reason); |
|
||||
if (success) |
|
||||
{ |
|
||||
m_appEngine->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); |
|
||||
m_appEngine->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); |
|
||||
m_appEngine->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); |
|
||||
this->addContentOn(this); |
|
||||
} |
|
||||
else |
|
||||
m_ctx->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("compilation failed")); |
|
||||
} |
|
@ -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 AssemblyDebuggerCtrl.h
|
|
||||
* @author Yann yann@ethdev.com |
|
||||
* @date 2014 |
|
||||
* Ethereum IDE client. |
|
||||
*/ |
|
||||
|
|
||||
#pragma once |
|
||||
|
|
||||
#include <QKeySequence> |
|
||||
#include "QTextDocument" |
|
||||
#include "Extension.h" |
|
||||
#include "ConstantCompilationModel.h" |
|
||||
#include "AssemblyDebuggerModel.h" |
|
||||
#include "AppContext.h" |
|
||||
|
|
||||
using AssemblyDebuggerData = std::tuple<QList<QObject*>, dev::mix::QQMLMap*>; |
|
||||
enum DebuggingStatusResult |
|
||||
{ |
|
||||
Ok, |
|
||||
Compilationfailed |
|
||||
}; |
|
||||
|
|
||||
Q_DECLARE_METATYPE(AssemblyDebuggerData) |
|
||||
Q_DECLARE_METATYPE(DebuggingStatusResult) |
|
||||
|
|
||||
namespace dev |
|
||||
{ |
|
||||
namespace mix |
|
||||
{ |
|
||||
|
|
||||
class AssemblyDebuggerCtrl: public Extension |
|
||||
{ |
|
||||
Q_OBJECT |
|
||||
|
|
||||
public: |
|
||||
AssemblyDebuggerCtrl(QTextDocument*); |
|
||||
~AssemblyDebuggerCtrl() {} |
|
||||
void start() const override; |
|
||||
QString title() const override; |
|
||||
QString contentUrl() const override; |
|
||||
|
|
||||
private: |
|
||||
std::unique_ptr<AssemblyDebuggerModel> m_modelDebugger; |
|
||||
QTextDocument* m_doc; |
|
||||
|
|
||||
public slots: |
|
||||
void keyPressed(int); |
|
||||
void updateGUI(bool success, DebuggingStatusResult reason, QList<QObject*> _wStates = QList<QObject*>(), AssemblyDebuggerData _code = AssemblyDebuggerData()); |
|
||||
|
|
||||
signals: |
|
||||
void dataAvailable(bool success, DebuggingStatusResult reason, QList<QObject*> _wStates = QList<QObject*>(), AssemblyDebuggerData _code = AssemblyDebuggerData()); |
|
||||
|
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
} |
|
@ -0,0 +1,131 @@ |
|||||
|
/*
|
||||
|
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 ContractCallDataEncoder.cpp
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#include <QDebug> |
||||
|
#include <QMap> |
||||
|
#include <QStringList> |
||||
|
#include <libdevcore/CommonJS.h> |
||||
|
#include <libsolidity/AST.h> |
||||
|
#include "QVariableDeclaration.h" |
||||
|
#include "QVariableDefinition.h" |
||||
|
#include "ContractCallDataEncoder.h" |
||||
|
using namespace dev; |
||||
|
using namespace dev::solidity; |
||||
|
using namespace dev::mix; |
||||
|
|
||||
|
bytes ContractCallDataEncoder::encodedData() |
||||
|
{ |
||||
|
return m_encodedData; |
||||
|
} |
||||
|
|
||||
|
void ContractCallDataEncoder::encode(int _functionIndex) |
||||
|
{ |
||||
|
bytes i = jsToBytes(std::to_string(_functionIndex)); |
||||
|
m_encodedData.insert(m_encodedData.end(), i.begin(), i.end()); |
||||
|
} |
||||
|
|
||||
|
void ContractCallDataEncoder::encode(QVariableDeclaration* _dec, bool _value) |
||||
|
{ |
||||
|
return encode(_dec, QString(formatBool(_value))); |
||||
|
} |
||||
|
|
||||
|
void ContractCallDataEncoder::encode(QVariableDeclaration* _dec, QString _value) |
||||
|
{ |
||||
|
int padding = this->padding(_dec->type()); |
||||
|
bytes data = padded(jsToBytes(_value.toStdString()), padding); |
||||
|
m_encodedData.insert(m_encodedData.end(), data.begin(), data.end()); |
||||
|
} |
||||
|
|
||||
|
void ContractCallDataEncoder::encode(QVariableDeclaration* _dec, u256 _value) |
||||
|
{ |
||||
|
int padding = this->padding(_dec->type()); |
||||
|
std::ostringstream s; |
||||
|
s << std::hex << "0x" << _value; |
||||
|
bytes data = padded(jsToBytes(s.str()), padding); |
||||
|
m_encodedData.insert(m_encodedData.end(), data.begin(), data.end()); |
||||
|
encodedData(); |
||||
|
} |
||||
|
|
||||
|
QList<QVariableDefinition*> ContractCallDataEncoder::decode(QList<QVariableDeclaration*> _returnParameters, bytes _value) |
||||
|
{ |
||||
|
QList<QVariableDefinition*> r; |
||||
|
std::string returnValue = toJS(_value); |
||||
|
returnValue = returnValue.substr(2, returnValue.length() - 1); |
||||
|
for (int k = 0; k <_returnParameters.length(); k++) |
||||
|
{ |
||||
|
QVariableDeclaration* dec = (QVariableDeclaration*)_returnParameters.at(k); |
||||
|
int padding = this->padding(dec->type()); |
||||
|
std::string rawParam = returnValue.substr(0, padding * 2); |
||||
|
r.append(new QVariableDefinition(dec, convertToReadable(unpadLeft(rawParam), dec))); |
||||
|
returnValue = returnValue.substr(rawParam.length(), returnValue.length() - 1); |
||||
|
} |
||||
|
return r; |
||||
|
} |
||||
|
|
||||
|
int ContractCallDataEncoder::padding(QString type) |
||||
|
{ |
||||
|
// TODO : to be improved (load types automatically from solidity library).
|
||||
|
if (type.indexOf("uint") != -1) |
||||
|
return integerPadding(type.remove("uint").toInt()); |
||||
|
else if (type.indexOf("int") != -1) |
||||
|
return integerPadding(type.remove("int").toInt()); |
||||
|
else if (type.indexOf("bool") != -1) |
||||
|
return 1; |
||||
|
else if ((type.indexOf("address") != -1)) |
||||
|
return 20; |
||||
|
else |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int ContractCallDataEncoder::integerPadding(int bitValue) |
||||
|
{ |
||||
|
return bitValue / 8; |
||||
|
} |
||||
|
|
||||
|
QString ContractCallDataEncoder::formatBool(bool _value) |
||||
|
{ |
||||
|
return (_value ? "1" : "0"); |
||||
|
} |
||||
|
|
||||
|
QString ContractCallDataEncoder::convertToReadable(std::string _v, QVariableDeclaration* _dec) |
||||
|
{ |
||||
|
if (_dec->type().indexOf("int") != -1) |
||||
|
return convertToInt(_v); |
||||
|
else if (_dec->type().indexOf("bool") != -1) |
||||
|
return convertToBool(_v); |
||||
|
else |
||||
|
return QString::fromStdString(_v); |
||||
|
} |
||||
|
|
||||
|
QString ContractCallDataEncoder::convertToBool(std::string _v) |
||||
|
{ |
||||
|
return _v == "1" ? "true" : "false"; |
||||
|
} |
||||
|
|
||||
|
QString ContractCallDataEncoder::convertToInt(std::string _v) |
||||
|
{ |
||||
|
//TO DO to be improve to manage all int, uint size (128, 256, ...) in ethereum QML types task #612.
|
||||
|
int x = std::stol(_v, nullptr, 16); |
||||
|
std::stringstream ss; |
||||
|
ss << std::dec << x; |
||||
|
return QString::fromStdString(ss.str()); |
||||
|
} |
@ -0,0 +1,64 @@ |
|||||
|
/*
|
||||
|
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 ContractCallDataEncoder.h
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "QVariableDeclaration.h" |
||||
|
#include "QVariableDefinition.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
/**
|
||||
|
* @brief Encode/Decode data to be sent to a transaction or to be displayed in a view. |
||||
|
*/ |
||||
|
class ContractCallDataEncoder |
||||
|
{ |
||||
|
public: |
||||
|
ContractCallDataEncoder() {} |
||||
|
/// Encode variable in order to be sent as parameter.
|
||||
|
void encode(QVariableDeclaration* _dec, QString _value); |
||||
|
/// Encode variable in order to be sent as parameter.
|
||||
|
void encode(QVariableDeclaration* _dec, u256 _value); |
||||
|
/// Encode variable in order to be sent as parameter.
|
||||
|
void encode(QVariableDeclaration* _dec, bool _value); |
||||
|
/// Encode index of the function to call.
|
||||
|
void encode(int _functionIndex); |
||||
|
/// Decode variable in order to be sent to QML view.
|
||||
|
QList<QVariableDefinition*> decode(QList<QVariableDeclaration*> _dec, bytes _value); |
||||
|
/// Get all encoded data encoded by encode function.
|
||||
|
bytes encodedData(); |
||||
|
|
||||
|
private: |
||||
|
int padding(QString _type); |
||||
|
bytes m_encodedData; |
||||
|
static QString convertToReadable(std::string _v, QVariableDeclaration* _dec); |
||||
|
static QString convertToBool(std::string _v); |
||||
|
static QString convertToInt(std::string _v); |
||||
|
static int integerPadding(int _bitValue); |
||||
|
static QString formatBool(bool _value); |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -1,43 +1,49 @@ |
|||||
/*
|
/*
|
||||
This file is part of cpp-ethereum. |
This file is part of cpp-ethereum. |
||||
|
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify |
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 |
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
(at your option) any later version. |
||||
|
|
||||
cpp-ethereum is distributed in the hope that it will be useful, |
cpp-ethereum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
GNU General Public License for more details. |
||||
|
|
||||
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
*/ |
||||
/** @file TransactionBuilder.h
|
/** @file QBasicNodeDefinition.h
|
||||
* @author Yann yann@ethdev.com |
* @author Yann yann@ethdev.com |
||||
* @date 2014 |
* @date 2014 |
||||
* Ethereum IDE client. |
|
||||
*/ |
*/ |
||||
|
|
||||
#pragma once |
#pragma once |
||||
|
|
||||
#include <QString> |
#include <QObject> |
||||
#include "libdevcore/Common.h" |
#include <libsolidity/AST.h> |
||||
#include "libethereum/Transaction.h" |
|
||||
|
|
||||
namespace dev |
namespace dev |
||||
{ |
{ |
||||
namespace mix |
namespace mix |
||||
{ |
{ |
||||
|
|
||||
class TransactionBuilder |
class QBasicNodeDefinition: public QObject |
||||
{ |
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(QString name READ name CONSTANT) |
||||
|
|
||||
public: |
public: |
||||
TransactionBuilder() {} |
QBasicNodeDefinition(): QObject() {} |
||||
dev::eth::Transaction getBasicTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, |
~QBasicNodeDefinition() {} |
||||
QString address, bytes _data, dev::u256 _nonce, Secret _secret) const; |
QBasicNodeDefinition(solidity::Declaration const* _d): QObject(), m_name(QString::fromStdString(_d->getName())) {} |
||||
dev::eth::Transaction getCreationTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, |
/// Get the name of the node.
|
||||
dev::bytes _data, dev::u256 _nonce, Secret _secret) const; |
QString name() const { return m_name; } |
||||
|
|
||||
|
private: |
||||
|
QString m_name; |
||||
}; |
}; |
||||
|
|
||||
} |
} |
||||
|
|
||||
} |
} |
@ -0,0 +1,48 @@ |
|||||
|
/*
|
||||
|
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 QContractDefinition.cpp
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include <QObject> |
||||
|
#include <libsolidity/CompilerStack.h> |
||||
|
#include <libsolidity/AST.h> |
||||
|
#include <libsolidity/Scanner.h> |
||||
|
#include <libsolidity/Parser.h> |
||||
|
#include <libsolidity/Scanner.h> |
||||
|
#include <libsolidity/NameAndTypeResolver.h> |
||||
|
#include "AppContext.h" |
||||
|
#include "QContractDefinition.h" |
||||
|
using namespace dev::solidity; |
||||
|
using namespace dev::mix; |
||||
|
|
||||
|
std::shared_ptr<QContractDefinition> QContractDefinition::Contract(QString _source) |
||||
|
{ |
||||
|
CompilerStack* comp = AppContext::getInstance()->compiler(); |
||||
|
comp->addSource("contract", _source.toStdString()); |
||||
|
comp->parse(); |
||||
|
ContractDefinition const* def = &comp->getContractDefinition(comp->getContractNames().front()); |
||||
|
return std::make_shared<QContractDefinition>(def); |
||||
|
} |
||||
|
|
||||
|
void QContractDefinition::initQFunctions() |
||||
|
{ |
||||
|
std::vector<FunctionDefinition const*> functions = m_contract->getInterfaceFunctions(); |
||||
|
for (unsigned i = 0; i < functions.size(); i++) |
||||
|
m_functions.append(new QFunctionDefinition(functions.at(i), i)); |
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
/*
|
||||
|
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 QContractDefinition.h
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <QObject> |
||||
|
#include <libsolidity/AST.h> |
||||
|
#include "QFunctionDefinition.h" |
||||
|
#include "QBasicNodeDefinition.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
class QContractDefinition: public QBasicNodeDefinition |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(QList<QFunctionDefinition*> functions READ functions) |
||||
|
|
||||
|
public: |
||||
|
QContractDefinition(solidity::ContractDefinition const* _contract): QBasicNodeDefinition(_contract), m_contract(_contract) { initQFunctions(); } |
||||
|
/// Get all the functions of the contract.
|
||||
|
QList<QFunctionDefinition*> functions() const { return m_functions; } |
||||
|
/// Get the description (functions, parameters, return parameters, ...) of the contract describes by _code.
|
||||
|
static std::shared_ptr<QContractDefinition> Contract(QString _code); |
||||
|
|
||||
|
private: |
||||
|
solidity::ContractDefinition const* m_contract; |
||||
|
QList<QFunctionDefinition*> m_functions; |
||||
|
void initQFunctions(); |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
/*
|
||||
|
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 QFunctionDefinition.cpp
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include <libsolidity/AST.h> |
||||
|
#include "QVariableDeclaration.h" |
||||
|
#include "QFunctionDefinition.h" |
||||
|
using namespace dev::solidity; |
||||
|
using namespace dev::mix; |
||||
|
|
||||
|
void QFunctionDefinition::initQParameters() |
||||
|
{ |
||||
|
std::vector<std::shared_ptr<VariableDeclaration>> parameters = m_functions->getParameterList().getParameters(); |
||||
|
for (unsigned i = 0; i < parameters.size(); i++) |
||||
|
m_parameters.append(new QVariableDeclaration(parameters.at(i).get())); |
||||
|
|
||||
|
std::vector<std::shared_ptr<VariableDeclaration>> returnParameters = m_functions->getReturnParameters(); |
||||
|
for (unsigned i = 0; i < returnParameters.size(); i++) |
||||
|
m_returnParameters.append(new QVariableDeclaration(returnParameters.at(i).get())); |
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
/*
|
||||
|
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 QFunctionDefinition.h
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <QObject> |
||||
|
#include <libsolidity/AST.h> |
||||
|
#include <QVariableDeclaration.h> |
||||
|
#include "QBasicNodeDefinition.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
class QFunctionDefinition: public QBasicNodeDefinition |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(QList<QVariableDeclaration*> parameters READ parameters) |
||||
|
Q_PROPERTY(int index READ index) |
||||
|
|
||||
|
public: |
||||
|
QFunctionDefinition(solidity::FunctionDefinition const* _f, int _index): QBasicNodeDefinition(_f), m_index(_index), m_functions(_f) { initQParameters(); } |
||||
|
/// Get all input parameters of this function.
|
||||
|
QList<QVariableDeclaration*> parameters() const { return m_parameters; } |
||||
|
/// Get all return parameters of this function.
|
||||
|
QList<QVariableDeclaration*> returnParameters() const { return m_returnParameters; } |
||||
|
/// Get the index of this function on the contract ABI.
|
||||
|
int index() const { return m_index; } |
||||
|
|
||||
|
private: |
||||
|
int m_index; |
||||
|
solidity::FunctionDefinition const* m_functions; |
||||
|
QList<QVariableDeclaration*> m_parameters; |
||||
|
QList<QVariableDeclaration*> m_returnParameters; |
||||
|
void initQParameters(); |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
/*
|
||||
|
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 QVariableDeclaration.h
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include <libsolidity/AST.h> |
||||
|
#include "QBasicNodeDefinition.h" |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
class QVariableDeclaration: public QBasicNodeDefinition |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(QString type READ type CONSTANT) |
||||
|
|
||||
|
public: |
||||
|
QVariableDeclaration(solidity::VariableDeclaration const* _v): QBasicNodeDefinition(_v), m_variable(_v) {} |
||||
|
/// Get the type of this variable.
|
||||
|
QString type() const { return QString::fromStdString(m_variable->getType()->toString()); } |
||||
|
|
||||
|
private: |
||||
|
solidity::VariableDeclaration const* m_variable; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Q_DECLARE_METATYPE(dev::mix::QVariableDeclaration*) |
@ -0,0 +1,55 @@ |
|||||
|
/*
|
||||
|
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 QVariableDefinition.h
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include "QVariableDefinition.h" |
||||
|
|
||||
|
using namespace dev::mix; |
||||
|
int QVariableDefinitionList::rowCount(const QModelIndex& _parent) const |
||||
|
{ |
||||
|
Q_UNUSED(_parent); |
||||
|
return m_def.size(); |
||||
|
} |
||||
|
|
||||
|
QVariant QVariableDefinitionList::data(const QModelIndex& _index, int _role) const |
||||
|
{ |
||||
|
if (_role != Qt::DisplayRole) |
||||
|
return QVariant(); |
||||
|
|
||||
|
int i = _index.row(); |
||||
|
if (i < 0 || i >= m_def.size()) |
||||
|
return QVariant(QVariant::Invalid); |
||||
|
|
||||
|
return QVariant::fromValue(m_def.at(i)); |
||||
|
} |
||||
|
|
||||
|
QHash<int, QByteArray> QVariableDefinitionList::roleNames() const |
||||
|
{ |
||||
|
QHash<int, QByteArray> roles; |
||||
|
roles[Qt::DisplayRole] = "variable"; |
||||
|
return roles; |
||||
|
} |
||||
|
|
||||
|
QVariableDefinition* QVariableDefinitionList::val(int _idx) |
||||
|
{ |
||||
|
if (_idx < 0 || _idx >= m_def.size()) |
||||
|
return nullptr; |
||||
|
return m_def.at(_idx); |
||||
|
} |
@ -0,0 +1,72 @@ |
|||||
|
/*
|
||||
|
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 QVariableDefinition.h
|
||||
|
* @author Yann yann@ethdev.com |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <QAbstractListModel> |
||||
|
#include "QVariableDeclaration.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
class QVariableDefinition: public QObject |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(QString value READ value CONSTANT) |
||||
|
Q_PROPERTY(QVariableDeclaration* declaration READ declaration CONSTANT) |
||||
|
|
||||
|
public: |
||||
|
QVariableDefinition(QVariableDeclaration* _def, QString _value): QObject(), m_value(_value), m_dec(_def) {} |
||||
|
|
||||
|
/// Return the associated declaration of this variable definition.
|
||||
|
QVariableDeclaration* declaration() const { return m_dec; } |
||||
|
/// Return the variable value.
|
||||
|
QString value() const { return m_value; } |
||||
|
|
||||
|
private: |
||||
|
QString m_value; |
||||
|
QVariableDeclaration* m_dec; |
||||
|
}; |
||||
|
|
||||
|
class QVariableDefinitionList: public QAbstractListModel |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
QVariableDefinitionList(QList<QVariableDefinition*> _def): m_def(_def) {} |
||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
||||
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
||||
|
QHash<int, QByteArray> roleNames() const override; |
||||
|
/// Return the variable definition at index _idx.
|
||||
|
QVariableDefinition* val(int _idx); |
||||
|
/// Return the list of variables.
|
||||
|
QList<QVariableDefinition*> def() { return m_def; } |
||||
|
|
||||
|
private: |
||||
|
QList<QVariableDefinition*> m_def; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Q_DECLARE_METATYPE(dev::mix::QVariableDefinition*) |
@ -1,40 +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 TransactionBuilder.cpp
|
|
||||
* @author Yann yann@ethdev.com |
|
||||
* @date 2014 |
|
||||
* Ethereum IDE client. |
|
||||
*/ |
|
||||
|
|
||||
#include "libethereum/Executive.h" |
|
||||
#include "libdevcore/CommonJS.h" |
|
||||
#include "libdevcore/Common.h" |
|
||||
#include "AppContext.h" |
|
||||
#include "TransactionBuilder.h" |
|
||||
using namespace dev::mix; |
|
||||
using namespace dev::eth; |
|
||||
using namespace dev; |
|
||||
|
|
||||
Transaction TransactionBuilder::getCreationTransaction(u256 _value, u256 _gasPrice, u256 _gas, |
|
||||
bytes _data, u256 _nonce, Secret _secret) const |
|
||||
{ |
|
||||
return Transaction(_value, _gasPrice, _gas, _data, _nonce, _secret); |
|
||||
} |
|
||||
|
|
||||
Transaction TransactionBuilder::getBasicTransaction(u256 _value, u256 _gasPrice, u256 _gas, |
|
||||
QString _address, bytes _data, u256 _nonce, Secret _secret) const |
|
||||
{ |
|
||||
return Transaction(_value, _gasPrice, _gas, dev::fromString(_address.toStdString()), _data, _nonce, _secret); |
|
||||
} |
|
||||
|
|
@ -0,0 +1,221 @@ |
|||||
|
/*
|
||||
|
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 TransactionListModel.cpp
|
||||
|
* @author Arkadiy Paronyan arkadiy@ethdev.com |
||||
|
* @date 2014 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#include <QObject> |
||||
|
#include <QQmlEngine> |
||||
|
#include <QTextDocument> |
||||
|
#include <QAbstractListModel> |
||||
|
#include <libdevcore/CommonJS.h> |
||||
|
#include "TransactionListModel.h" |
||||
|
#include "QContractDefinition.h" |
||||
|
#include "QFunctionDefinition.h" |
||||
|
#include "QVariableDeclaration.h" |
||||
|
|
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
/// @todo Move this to QML
|
||||
|
u256 fromQString(QString const& _s) |
||||
|
{ |
||||
|
return dev::jsToU256(_s.toStdString()); |
||||
|
} |
||||
|
|
||||
|
/// @todo Move this to QML
|
||||
|
QString toQString(u256 _value) |
||||
|
{ |
||||
|
std::ostringstream s; |
||||
|
s << _value; |
||||
|
return QString::fromStdString(s.str()); |
||||
|
} |
||||
|
|
||||
|
TransactionListItem::TransactionListItem(int _index, TransactionSettings const& _t, QObject* _parent): |
||||
|
QObject(_parent), m_index(_index), m_title(_t.title), m_functionId(_t.functionId), m_value(toQString(_t.value)), |
||||
|
m_gas(toQString(_t.gas)), m_gasPrice(toQString(_t.gasPrice)) |
||||
|
{} |
||||
|
|
||||
|
TransactionListModel::TransactionListModel(QObject* _parent, QTextDocument* _document): |
||||
|
QAbstractListModel(_parent), m_document(_document) |
||||
|
{ |
||||
|
qRegisterMetaType<TransactionListItem*>("TransactionListItem*"); |
||||
|
} |
||||
|
|
||||
|
QHash<int, QByteArray> TransactionListModel::roleNames() const |
||||
|
{ |
||||
|
QHash<int, QByteArray> roles; |
||||
|
roles[TitleRole] = "title"; |
||||
|
roles[IdRole] = "transactionIndex"; |
||||
|
return roles; |
||||
|
} |
||||
|
|
||||
|
int TransactionListModel::rowCount(QModelIndex const& _parent) const |
||||
|
{ |
||||
|
Q_UNUSED(_parent); |
||||
|
return m_transactions.size(); |
||||
|
} |
||||
|
|
||||
|
QVariant TransactionListModel::data(QModelIndex const& _index, int _role) const |
||||
|
{ |
||||
|
if (_index.row() < 0 || _index.row() >= (int)m_transactions.size()) |
||||
|
return QVariant(); |
||||
|
auto const& transaction = m_transactions.at(_index.row()); |
||||
|
switch (_role) |
||||
|
{ |
||||
|
case TitleRole: |
||||
|
return QVariant(transaction.title); |
||||
|
case IdRole: |
||||
|
return QVariant(_index.row()); |
||||
|
default: |
||||
|
return QVariant(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
///@todo: get parameters from code model
|
||||
|
QList<TransactionParameterItem*> buildParameters(QTextDocument* _document, TransactionSettings const& _transaction, QString const& _functionId) |
||||
|
{ |
||||
|
QList<TransactionParameterItem*> params; |
||||
|
try |
||||
|
{ |
||||
|
std::shared_ptr<QContractDefinition> contract = QContractDefinition::Contract(_document->toPlainText()); |
||||
|
auto functions = contract->functions(); |
||||
|
for (auto f : functions) |
||||
|
{ |
||||
|
if (f->name() != _functionId) |
||||
|
continue; |
||||
|
|
||||
|
auto parameters = f->parameters(); |
||||
|
//build a list of parameters for a function. If the function is selected as current, add parameter values as well
|
||||
|
for (auto p : parameters) |
||||
|
{ |
||||
|
QString paramValue; |
||||
|
if (f->name() == _transaction.functionId) |
||||
|
{ |
||||
|
auto paramValueIter = _transaction.parameterValues.find(p->name()); |
||||
|
if (paramValueIter != _transaction.parameterValues.cend()) |
||||
|
paramValue = toQString(paramValueIter->second); |
||||
|
} |
||||
|
|
||||
|
TransactionParameterItem* item = new TransactionParameterItem(p->name(), p->type(), paramValue); |
||||
|
QQmlEngine::setObjectOwnership(item, QQmlEngine::JavaScriptOwnership); |
||||
|
params.append(item); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (boost::exception const&) |
||||
|
{ |
||||
|
//TODO:
|
||||
|
} |
||||
|
|
||||
|
return params; |
||||
|
} |
||||
|
|
||||
|
///@todo: get fnctions from code model
|
||||
|
QList<QString> TransactionListModel::getFunctions() |
||||
|
{ |
||||
|
QList<QString> functionNames; |
||||
|
try |
||||
|
{ |
||||
|
QString code = m_document->toPlainText(); |
||||
|
std::shared_ptr<QContractDefinition> contract(QContractDefinition::Contract(code)); |
||||
|
auto functions = contract->functions(); |
||||
|
for (auto f : functions) |
||||
|
{ |
||||
|
functionNames.append(f->name()); |
||||
|
} |
||||
|
} |
||||
|
catch (boost::exception const&) |
||||
|
{ |
||||
|
} |
||||
|
return functionNames; |
||||
|
} |
||||
|
|
||||
|
QVariantList TransactionListModel::getParameters(int _index, QString const& _functionId) |
||||
|
{ |
||||
|
TransactionSettings const& transaction = (_index >= 0 && _index < (int)m_transactions.size()) ? m_transactions[_index] : TransactionSettings(); |
||||
|
auto plist = buildParameters(m_document, transaction, _functionId); |
||||
|
QVariantList vl; |
||||
|
for (QObject* p : plist) |
||||
|
vl.append(QVariant::fromValue(p)); |
||||
|
return vl; |
||||
|
} |
||||
|
|
||||
|
TransactionListItem* TransactionListModel::getItem(int _index) |
||||
|
{ |
||||
|
TransactionSettings const& transaction = (_index >= 0 && _index < (int)m_transactions.size()) ? m_transactions[_index] : TransactionSettings(); |
||||
|
TransactionListItem* item = new TransactionListItem(_index, transaction, nullptr); |
||||
|
QQmlEngine::setObjectOwnership(item, QQmlEngine::JavaScriptOwnership); |
||||
|
return item; |
||||
|
} |
||||
|
|
||||
|
void TransactionListModel::edit(QObject* _data) |
||||
|
{ |
||||
|
//these properties come from TransactionDialog QML object
|
||||
|
///@todo change the model to a qml component
|
||||
|
int index = _data->property("transactionIndex").toInt(); |
||||
|
QString title = _data->property("transactionTitle").toString(); |
||||
|
QString gas = _data->property("gas").toString(); |
||||
|
QString gasPrice = _data->property("gasPrice").toString(); |
||||
|
QString value = _data->property("transactionValue").toString(); |
||||
|
QString functionId = _data->property("functionId").toString(); |
||||
|
QAbstractListModel* paramsModel = qvariant_cast<QAbstractListModel*>(_data->property("transactionParams")); |
||||
|
TransactionSettings transaction(title, functionId, fromQString(value), fromQString(gas), fromQString(gasPrice)); |
||||
|
int paramCount = paramsModel->rowCount(QModelIndex()); |
||||
|
for (int p = 0; p < paramCount; ++p) |
||||
|
{ |
||||
|
QString paramName = paramsModel->data(paramsModel->index(p, 0), Qt::DisplayRole).toString(); |
||||
|
QString paramValue = paramsModel->data(paramsModel->index(p, 0), Qt::DisplayRole + 2).toString(); |
||||
|
if (!paramValue.isEmpty() && !paramName.isEmpty()) |
||||
|
transaction.parameterValues[paramName] = fromQString(paramValue); |
||||
|
} |
||||
|
|
||||
|
if (index >= 0 && index < (int)m_transactions.size()) |
||||
|
{ |
||||
|
beginRemoveRows(QModelIndex(), index, index); |
||||
|
m_transactions.erase(m_transactions.begin() + index); |
||||
|
endRemoveRows(); |
||||
|
} |
||||
|
else |
||||
|
index = rowCount(QModelIndex()); |
||||
|
|
||||
|
beginInsertRows(QModelIndex(), index, index); |
||||
|
m_transactions.push_back(transaction); |
||||
|
emit countChanged(); |
||||
|
endInsertRows(); |
||||
|
} |
||||
|
|
||||
|
int TransactionListModel::getCount() const |
||||
|
{ |
||||
|
return rowCount(QModelIndex()); |
||||
|
} |
||||
|
|
||||
|
void TransactionListModel::runTransaction(int _index) |
||||
|
{ |
||||
|
TransactionSettings tr = m_transactions.at(_index); |
||||
|
emit transactionStarted(tr); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,168 @@ |
|||||
|
/*
|
||||
|
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 TransactionListView.h
|
||||
|
* @author Arkadiy Paronyan arkadiy@ethdev.com |
||||
|
* @date 2014 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <QObject> |
||||
|
#include <QVariant> |
||||
|
#include <QAbstractListModel> |
||||
|
#include <QHash> |
||||
|
#include <QByteArray> |
||||
|
#include <libdevcore/Common.h> |
||||
|
#include <libethcore/CommonEth.h> |
||||
|
|
||||
|
class QTextDocument; |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
/// Backend transaction config class
|
||||
|
struct TransactionSettings |
||||
|
{ |
||||
|
TransactionSettings(): |
||||
|
value(0), gas(10000), gasPrice(10 * dev::eth::szabo) {} |
||||
|
|
||||
|
TransactionSettings(QString const& _title, QString const& _functionId, u256 _value, u256 _gas, u256 _gasPrice): |
||||
|
title(_title), functionId(_functionId), value(_value), gas(_gas), gasPrice(_gasPrice) {} |
||||
|
|
||||
|
/// User specified transaction title
|
||||
|
QString title; |
||||
|
/// Contract function name
|
||||
|
QString functionId; |
||||
|
/// Transaction value
|
||||
|
u256 value; |
||||
|
/// Gas
|
||||
|
u256 gas; |
||||
|
/// Gas price
|
||||
|
u256 gasPrice; |
||||
|
/// Mapping from contract function parameter name to value
|
||||
|
std::map<QString, u256> parameterValues; |
||||
|
}; |
||||
|
|
||||
|
/// QML transaction parameter class
|
||||
|
class TransactionParameterItem: public QObject |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(QString name READ name CONSTANT) |
||||
|
Q_PROPERTY(QString type READ type CONSTANT) |
||||
|
Q_PROPERTY(QString value READ value CONSTANT) |
||||
|
public: |
||||
|
TransactionParameterItem(QString const& _name, QString const& _type, QString const& _value): |
||||
|
m_name(_name), m_type(_type), m_value(_value) {} |
||||
|
|
||||
|
/// Parameter name, set by contract definition
|
||||
|
QString name() { return m_name; } |
||||
|
/// Parameter type, set by contract definition
|
||||
|
QString type() { return m_type; } |
||||
|
/// Parameter value, set by user
|
||||
|
QString value() { return m_value; } |
||||
|
|
||||
|
private: |
||||
|
QString m_name; |
||||
|
QString m_type; |
||||
|
QString m_value; |
||||
|
}; |
||||
|
|
||||
|
class TransactionListItem: public QObject |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(int index READ index CONSTANT) |
||||
|
Q_PROPERTY(QString title READ title CONSTANT) |
||||
|
Q_PROPERTY(QString functionId READ functionId CONSTANT) |
||||
|
Q_PROPERTY(QString gas READ gas CONSTANT) |
||||
|
Q_PROPERTY(QString gasPrice READ gasPrice CONSTANT) |
||||
|
Q_PROPERTY(QString value READ value CONSTANT) |
||||
|
|
||||
|
public: |
||||
|
TransactionListItem(int _index, TransactionSettings const& _t, QObject* _parent); |
||||
|
|
||||
|
/// User specified transaction title
|
||||
|
QString title() { return m_title; } |
||||
|
/// Gas
|
||||
|
QString gas() { return m_gas; } |
||||
|
/// Gas cost
|
||||
|
QString gasPrice() { return m_gasPrice; } |
||||
|
/// Transaction value
|
||||
|
QString value() { return m_value; } |
||||
|
/// Contract function name
|
||||
|
QString functionId() { return m_functionId; } |
||||
|
/// Index of this transaction in the transactions list
|
||||
|
int index() { return m_index; } |
||||
|
|
||||
|
private: |
||||
|
int m_index; |
||||
|
QString m_title; |
||||
|
QString m_functionId; |
||||
|
QString m_value; |
||||
|
QString m_gas; |
||||
|
QString m_gasPrice; |
||||
|
}; |
||||
|
|
||||
|
/// QML model for a list of transactions
|
||||
|
class TransactionListModel: public QAbstractListModel |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
Q_PROPERTY(int count READ getCount() NOTIFY countChanged()) |
||||
|
|
||||
|
enum Roles |
||||
|
{ |
||||
|
TitleRole = Qt::DisplayRole, |
||||
|
IdRole = Qt::UserRole + 1 |
||||
|
}; |
||||
|
|
||||
|
public: |
||||
|
TransactionListModel(QObject* _parent, QTextDocument* _document); |
||||
|
~TransactionListModel() {} |
||||
|
|
||||
|
QHash<int, QByteArray> roleNames() const override; |
||||
|
int rowCount(QModelIndex const& _parent) const override; |
||||
|
QVariant data(QModelIndex const& _index, int _role) const override; |
||||
|
int getCount() const; |
||||
|
/// Apply changes from transaction dialog. Argument is a dialog model as defined in TransactionDialog.qml
|
||||
|
/// @todo Change that to transaction item
|
||||
|
Q_INVOKABLE void edit(QObject* _data); |
||||
|
/// @returns transaction item for a give index
|
||||
|
Q_INVOKABLE TransactionListItem* getItem(int _index); |
||||
|
/// @returns a list of functions for current contract
|
||||
|
Q_INVOKABLE QList<QString> getFunctions(); |
||||
|
/// @returns function parameters along with parameter values if set. @see TransactionParameterItem
|
||||
|
Q_INVOKABLE QVariantList getParameters(int _id, QString const& _functionId); |
||||
|
/// Launch transaction execution UI handler
|
||||
|
Q_INVOKABLE void runTransaction(int _index); |
||||
|
|
||||
|
signals: |
||||
|
/// Transaction count has changed
|
||||
|
void countChanged(); |
||||
|
/// Transaction has been launched
|
||||
|
void transactionStarted(dev::mix::TransactionSettings); |
||||
|
|
||||
|
private: |
||||
|
std::vector<TransactionSettings> m_transactions; |
||||
|
QTextDocument* m_document; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,56 @@ |
|||||
|
/*
|
||||
|
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 TransactionListView.cpp
|
||||
|
* @author Arkadiy Paronyan arkadiy@ethdev.com |
||||
|
* @date 2014 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#include <QQuickItem> |
||||
|
#include <QApplication> |
||||
|
#include <QQmlApplicationEngine> |
||||
|
#include <QQmlContext> |
||||
|
#include <QDebug> |
||||
|
#include "TransactionListView.h" |
||||
|
#include "TransactionListModel.h" |
||||
|
using namespace dev::mix; |
||||
|
|
||||
|
TransactionListView::TransactionListView(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::RightTab) |
||||
|
{ |
||||
|
m_editor = _doc; |
||||
|
m_model.reset(new TransactionListModel(this, _doc)); |
||||
|
m_appEngine->rootContext()->setContextProperty("transactionListModel", m_model.get()); |
||||
|
} |
||||
|
|
||||
|
TransactionListView::~TransactionListView() |
||||
|
{ |
||||
|
//implementation is in cpp file so that all types deleted are complete
|
||||
|
} |
||||
|
|
||||
|
QString TransactionListView::contentUrl() const |
||||
|
{ |
||||
|
return QStringLiteral("qrc:/qml/TransactionList.qml"); |
||||
|
} |
||||
|
|
||||
|
QString TransactionListView::title() const |
||||
|
{ |
||||
|
return QApplication::tr("Transactions"); |
||||
|
} |
||||
|
|
||||
|
void TransactionListView::start() const |
||||
|
{ |
||||
|
} |
@ -0,0 +1,54 @@ |
|||||
|
/*
|
||||
|
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 TransactionListView.h
|
||||
|
* @author Arkadiy Paronyan arkadiy@ethdev.com |
||||
|
* @date 2014 |
||||
|
* Ethereum IDE client. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <QTextDocument> |
||||
|
#include "Extension.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace mix |
||||
|
{ |
||||
|
|
||||
|
class TransactionListModel; |
||||
|
|
||||
|
/// Transactions list control
|
||||
|
/// @todo This should be moved into state as a sequence
|
||||
|
class TransactionListView: public Extension |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
TransactionListView(QTextDocument*); |
||||
|
~TransactionListView(); |
||||
|
void start() const override; |
||||
|
QString title() const override; |
||||
|
QString contentUrl() const override; |
||||
|
/// @returns the underlying model
|
||||
|
TransactionListModel* model() const { return m_model.get(); } |
||||
|
|
||||
|
private: |
||||
|
QTextDocument* m_editor; |
||||
|
std::unique_ptr<TransactionListModel> m_model; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,219 @@ |
|||||
|
import QtQuick 2.2 |
||||
|
import QtQuick.Controls 1.2 |
||||
|
import QtQuick.Layouts 1.1 |
||||
|
import QtQuick.Window 2.0 |
||||
|
|
||||
|
Window { |
||||
|
modality: Qt.WindowModal |
||||
|
|
||||
|
width:640 |
||||
|
height:480 |
||||
|
|
||||
|
visible: false |
||||
|
|
||||
|
function open() |
||||
|
{ |
||||
|
visible = true; |
||||
|
} |
||||
|
function close() |
||||
|
{ |
||||
|
visible = false; |
||||
|
} |
||||
|
|
||||
|
property alias focus : titleField.focus |
||||
|
property alias transactionTitle : titleField.text |
||||
|
property int transactionIndex |
||||
|
property alias transactionParams : paramsModel; |
||||
|
property alias gas : gasField.text; |
||||
|
property alias gasPrice : gasPriceField.text; |
||||
|
property alias transactionValue : valueField.text; |
||||
|
property alias functionId : functionComboBox.currentText; |
||||
|
property var model; |
||||
|
|
||||
|
signal accepted; |
||||
|
|
||||
|
function reset(index, m) { |
||||
|
model = m; |
||||
|
var item = model.getItem(index); |
||||
|
transactionIndex = index; |
||||
|
transactionTitle = item.title; |
||||
|
gas = item.gas; |
||||
|
gasPrice = item.gasPrice; |
||||
|
transactionValue = item.value; |
||||
|
var functionId = item.functionId; |
||||
|
functionsModel.clear(); |
||||
|
var functionIndex = -1; |
||||
|
var functions = model.getFunctions(); |
||||
|
for (var f = 0; f < functions.length; f++) { |
||||
|
functionsModel.append({ text: functions[f] }); |
||||
|
if (functions[f] === item.functionId) |
||||
|
functionIndex = f; |
||||
|
} |
||||
|
functionComboBox.currentIndex = functionIndex; |
||||
|
} |
||||
|
|
||||
|
function loadParameters() { |
||||
|
if (!paramsModel) |
||||
|
return; |
||||
|
paramsModel.clear(); |
||||
|
if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) { |
||||
|
var parameters = model.getParameters(transactionIndex, functionsModel.get(functionComboBox.currentIndex).text); |
||||
|
for (var p = 0; p < parameters.length; p++) { |
||||
|
paramsModel.append({ name: parameters[p].name, type: parameters[p].type, value: parameters[p].value }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
GridLayout { |
||||
|
id: dialogContent |
||||
|
columns: 2 |
||||
|
anchors.fill: parent |
||||
|
anchors.margins: 10 |
||||
|
rowSpacing: 10 |
||||
|
columnSpacing: 10 |
||||
|
|
||||
|
Label { |
||||
|
text: qsTr("Title") |
||||
|
} |
||||
|
TextField { |
||||
|
id: titleField |
||||
|
focus: true |
||||
|
Layout.fillWidth: true |
||||
|
} |
||||
|
|
||||
|
Label { |
||||
|
text: qsTr("Function") |
||||
|
} |
||||
|
|
||||
|
ComboBox { |
||||
|
id: functionComboBox |
||||
|
Layout.fillWidth: true |
||||
|
currentIndex: -1 |
||||
|
textRole: "text" |
||||
|
editable: false |
||||
|
model: ListModel { |
||||
|
id: functionsModel |
||||
|
} |
||||
|
onCurrentIndexChanged: { |
||||
|
loadParameters(); |
||||
|
} |
||||
|
} |
||||
|
Label { |
||||
|
text: qsTr("Value") |
||||
|
} |
||||
|
TextField { |
||||
|
id: valueField |
||||
|
Layout.fillWidth: true |
||||
|
} |
||||
|
|
||||
|
Label { |
||||
|
text: qsTr("Gas") |
||||
|
} |
||||
|
TextField { |
||||
|
id: gasField |
||||
|
Layout.fillWidth: true |
||||
|
} |
||||
|
|
||||
|
Label { |
||||
|
text: qsTr("Gas price") |
||||
|
} |
||||
|
TextField { |
||||
|
id: gasPriceField |
||||
|
Layout.fillWidth: true |
||||
|
} |
||||
|
|
||||
|
Label { |
||||
|
text: qsTr("Parameters") |
||||
|
} |
||||
|
TableView { |
||||
|
model: paramsModel |
||||
|
Layout.fillWidth: true |
||||
|
|
||||
|
TableViewColumn { |
||||
|
role: "name" |
||||
|
title: "Name" |
||||
|
width: 120 |
||||
|
} |
||||
|
TableViewColumn { |
||||
|
role: "type" |
||||
|
title: "Type" |
||||
|
width: 120 |
||||
|
} |
||||
|
TableViewColumn { |
||||
|
role: "value" |
||||
|
title: "Value" |
||||
|
width: 120 |
||||
|
} |
||||
|
|
||||
|
itemDelegate: { |
||||
|
return editableDelegate; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
RowLayout |
||||
|
{ |
||||
|
anchors.bottom: parent.bottom |
||||
|
anchors.right: parent.right; |
||||
|
|
||||
|
Button { |
||||
|
text: qsTr("Ok"); |
||||
|
onClicked: { |
||||
|
close(); |
||||
|
accepted(); |
||||
|
} |
||||
|
} |
||||
|
Button { |
||||
|
text: qsTr("Cancel"); |
||||
|
onClicked: close(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ListModel { |
||||
|
id: paramsModel |
||||
|
} |
||||
|
|
||||
|
Component { |
||||
|
id: editableDelegate |
||||
|
Item { |
||||
|
|
||||
|
Text { |
||||
|
width: parent.width |
||||
|
anchors.margins: 4 |
||||
|
anchors.left: parent.left |
||||
|
anchors.verticalCenter: parent.verticalCenter |
||||
|
elide: styleData.elideMode |
||||
|
text: styleData.value !== undefined ? styleData.value : "" |
||||
|
color: styleData.textColor |
||||
|
visible: !styleData.selected |
||||
|
} |
||||
|
Loader { |
||||
|
id: loaderEditor |
||||
|
anchors.fill: parent |
||||
|
anchors.margins: 4 |
||||
|
Connections { |
||||
|
target: loaderEditor.item |
||||
|
onTextChanged: { |
||||
|
paramsModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text); |
||||
|
} |
||||
|
} |
||||
|
sourceComponent: (styleData.selected) ? editor : null |
||||
|
Component { |
||||
|
id: editor |
||||
|
TextInput { |
||||
|
id: textinput |
||||
|
color: styleData.textColor |
||||
|
text: styleData.value |
||||
|
MouseArea { |
||||
|
id: mouseArea |
||||
|
anchors.fill: parent |
||||
|
hoverEnabled: true |
||||
|
onClicked: textinput.forceActiveFocus() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,89 @@ |
|||||
|
import QtQuick 2.2 |
||||
|
import QtQuick.Controls.Styles 1.2 |
||||
|
import QtQuick.Controls 1.2 |
||||
|
import QtQuick.Dialogs 1.2 |
||||
|
import QtQuick.Layouts 1.1 |
||||
|
|
||||
|
|
||||
|
Rectangle { |
||||
|
color: "transparent" |
||||
|
id: transactionListContainer |
||||
|
focus: true |
||||
|
anchors.topMargin: 10 |
||||
|
anchors.left: parent.left |
||||
|
height: parent.height |
||||
|
width: parent.width |
||||
|
|
||||
|
ListView { |
||||
|
anchors.top: parent.top |
||||
|
height: parent.height |
||||
|
width: parent.width |
||||
|
id: transactionList |
||||
|
model: transactionListModel |
||||
|
delegate: renderDelegate |
||||
|
} |
||||
|
|
||||
|
Button { |
||||
|
anchors.bottom: parent.bottom |
||||
|
text: qsTr("Add") |
||||
|
onClicked: |
||||
|
{ |
||||
|
// Set next id here to work around Qt bug |
||||
|
// https://bugreports.qt-project.org/browse/QTBUG-41327 |
||||
|
// Second call to signal handle would just edit the item that was just created, no harm done |
||||
|
transactionDialog.reset(transactionListModel.count, transactionListModel); |
||||
|
transactionDialog.open(); |
||||
|
transactionDialog.focus = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
TransactionDialog { |
||||
|
id: transactionDialog |
||||
|
onAccepted: { |
||||
|
transactionListModel.edit(transactionDialog); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Component { |
||||
|
id: renderDelegate |
||||
|
Item { |
||||
|
id: wrapperItem |
||||
|
height: 20 |
||||
|
width: parent.width |
||||
|
RowLayout |
||||
|
{ |
||||
|
anchors.fill: parent |
||||
|
Text { |
||||
|
//anchors.fill: parent |
||||
|
Layout.fillWidth: true |
||||
|
Layout.fillHeight: true |
||||
|
text: title |
||||
|
font.pointSize: 12 |
||||
|
verticalAlignment: Text.AlignBottom |
||||
|
} |
||||
|
ToolButton { |
||||
|
text: qsTr("Edit"); |
||||
|
Layout.fillHeight: true |
||||
|
onClicked: { |
||||
|
transactionDialog.reset(index, transactionListModel); |
||||
|
transactionDialog.open(); |
||||
|
transactionDialog.focus = true; |
||||
|
} |
||||
|
} |
||||
|
ToolButton { |
||||
|
text: qsTr("Delete"); |
||||
|
Layout.fillHeight: true |
||||
|
onClicked: { |
||||
|
} |
||||
|
} |
||||
|
ToolButton { |
||||
|
text: qsTr("Run"); |
||||
|
Layout.fillHeight: true |
||||
|
onClicked: { |
||||
|
transactionListModel.runTransaction(index); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
File diff suppressed because it is too large
Loading…
Reference in new issue