Browse Source

Merge remote-tracking branch 'upstream/develop' into evmjit

cl-refactor
Paweł Bylica 10 years ago
parent
commit
a899ecd4ea
  1. 2
      cmake/EthCompilerSettings.cmake
  2. 8
      libethereum/Client.cpp
  3. 2
      libethereum/Executive.cpp
  4. 1
      mix/AppContext.cpp
  5. 21
      mix/ClientModel.cpp
  6. 25
      mix/ClientModel.h
  7. 12
      mix/FileIo.cpp
  8. 2
      mix/FileIo.h
  9. 6
      mix/MixClient.cpp
  10. 2
      mix/MixClient.h
  11. 56
      mix/qml/Debugger.qml
  12. 304
      mix/qml/DeploymentDialog.qml
  13. 28
      mix/qml/FilesSection.qml
  14. 6
      mix/qml/MainContent.qml
  15. 2
      mix/qml/ProjectFilesStyle.qml
  16. 18
      mix/qml/ProjectList.qml
  17. 19
      mix/qml/ProjectModel.qml
  18. 83
      mix/qml/StatusPane.qml
  19. 39
      mix/qml/TransactionLog.qml
  20. 60
      mix/qml/WebPreview.qml
  21. 316
      mix/qml/js/ProjectModel.js
  22. 24
      mix/qml/js/TransactionHelper.js
  23. 13
      mix/qml/main.qml
  24. 34
      test/SolidityParser.cpp
  25. 5
      test/block.cpp
  26. 69
      test/stMemoryStressTestFiller.json
  27. 68
      test/stMemoryTestFiller.json
  28. 330
      test/stQuadraticComplexityTestFiller.json
  29. 128
      test/stRefundTestFiller.json
  30. 18
      test/state.cpp
  31. 224
      test/vmArithmeticTestFiller.json
  32. 85
      test/vmIOandFlowOperationsTestFiller.json

2
cmake/EthCompilerSettings.cmake

@ -3,7 +3,7 @@
# C++11 check and activation # C++11 check and activation
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -Werror -DSHAREDLIB -fPIC")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE")

8
libethereum/Client.cpp

@ -257,9 +257,13 @@ LocalisedLogEntries Client::peekWatch(unsigned _watchId) const
Guard l(m_filterLock); Guard l(m_filterLock);
try { try {
#if ETH_DEBUG
cdebug << "peekWatch" << _watchId; cdebug << "peekWatch" << _watchId;
#endif
auto& w = m_watches.at(_watchId); auto& w = m_watches.at(_watchId);
#if ETH_DEBUG
cdebug << "lastPoll updated to " << chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count(); cdebug << "lastPoll updated to " << chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
#endif
w.lastPoll = chrono::system_clock::now(); w.lastPoll = chrono::system_clock::now();
return w.changes; return w.changes;
} catch (...) {} } catch (...) {}
@ -273,9 +277,13 @@ LocalisedLogEntries Client::checkWatch(unsigned _watchId)
LocalisedLogEntries ret; LocalisedLogEntries ret;
try { try {
#if ETH_DEBUG
cdebug << "checkWatch" << _watchId; cdebug << "checkWatch" << _watchId;
#endif
auto& w = m_watches.at(_watchId); auto& w = m_watches.at(_watchId);
#if ETH_DEBUG
cdebug << "lastPoll updated to " << chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count(); cdebug << "lastPoll updated to " << chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
#endif
std::swap(ret, w.changes); std::swap(ret, w.changes);
w.lastPoll = chrono::system_clock::now(); w.lastPoll = chrono::system_clock::now();
} catch (...) {} } catch (...) {}

2
libethereum/Executive.cpp

@ -176,7 +176,7 @@ OnOpFunc Executive::simpleTrace()
o << endl << " STACK" << endl; o << endl << " STACK" << endl;
for (auto i: vm.stack()) for (auto i: vm.stack())
o << (h256)i << endl; o << (h256)i << endl;
o << " MEMORY" << endl << memDump(vm.memory()); o << " MEMORY" << endl << (vm.memory().size() > 1000) ? " mem size greater than 1000 bytes " : memDump(vm.memory());
o << " STORAGE" << endl; o << " STORAGE" << endl;
for (auto const& i: ext.state().storage(ext.myAddress)) for (auto const& i: ext.state().storage(ext.myAddress))
o << showbase << hex << i.first << ": " << i.second << endl; o << showbase << hex << i.first << ": " << i.second << endl;

1
mix/AppContext.cpp

@ -73,6 +73,7 @@ void AppContext::load()
qmlRegisterType<QHashType>("org.ethereum.qml.QHashType", 1, 0, "QHashType"); qmlRegisterType<QHashType>("org.ethereum.qml.QHashType", 1, 0, "QHashType");
qmlRegisterType<QBoolType>("org.ethereum.qml.QBoolType", 1, 0, "QBoolType"); qmlRegisterType<QBoolType>("org.ethereum.qml.QBoolType", 1, 0, "QBoolType");
qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration"); qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration");
qmlRegisterType<RecordLogEntry>("org.ethereum.qml.RecordLogEntry", 1, 0, "RecordLogEntry");
QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml")); QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml"));
QObject* projectModel = projectModelComponent.create(); QObject* projectModel = projectModelComponent.create();
if (projectModelComponent.isError()) if (projectModelComponent.isError())

21
mix/ClientModel.cpp

@ -82,7 +82,7 @@ ClientModel::ClientModel(AppContext* _context):
qRegisterMetaType<QInstruction*>("QInstruction"); qRegisterMetaType<QInstruction*>("QInstruction");
qRegisterMetaType<QCode*>("QCode"); qRegisterMetaType<QCode*>("QCode");
qRegisterMetaType<QCallData*>("QCallData"); qRegisterMetaType<QCallData*>("QCallData");
qRegisterMetaType<RecordLogEntry*>("RecordLogEntry"); qRegisterMetaType<RecordLogEntry*>("RecordLogEntry*");
connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection); connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection);
m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString())); m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString()));
@ -325,6 +325,11 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t)
debugDataReady(debugData); debugDataReady(debugData);
} }
void ClientModel::emptyRecord()
{
debugDataReady(new QDebugData());
}
void ClientModel::debugRecord(unsigned _index) void ClientModel::debugRecord(unsigned _index)
{ {
@ -349,6 +354,18 @@ void ClientModel::callContract(Address const& _contract, bytes const& _data, Tra
m_client->transact(m_client->userAccount().secret(), _tr.value, _contract, _data, _tr.gas, _tr.gasPrice); m_client->transact(m_client->userAccount().secret(), _tr.value, _contract, _data, _tr.gas, _tr.gasPrice);
} }
RecordLogEntry* ClientModel::lastBlock() const
{
eth::BlockInfo blockInfo = m_client->blockInfo();
std::stringstream strGas;
strGas << blockInfo.gasUsed;
std::stringstream strNumber;
strNumber << blockInfo.number;
RecordLogEntry* record = new RecordLogEntry(0, QString::fromStdString(strNumber.str()), tr(" - Block - "), tr("Hash: ") + QString(QString::fromStdString(toHex(blockInfo.hash.ref()))), tr("Gas Used: ") + QString::fromStdString(strGas.str()), QString(), QString(), false, RecordLogEntry::RecordType::Block);
QQmlEngine::setObjectOwnership(record, QQmlEngine::JavaScriptOwnership);
return record;
}
void ClientModel::onStateReset() void ClientModel::onStateReset()
{ {
m_contractAddresses.clear(); m_contractAddresses.clear();
@ -424,7 +441,7 @@ void ClientModel::onNewTransaction()
} }
} }
RecordLogEntry* log = new RecordLogEntry(recordIndex, transactionIndex, contract, function, value, address, returned, tr.isCall()); RecordLogEntry* log = new RecordLogEntry(recordIndex, transactionIndex, contract, function, value, address, returned, tr.isCall(), RecordLogEntry::RecordType::Transaction);
QQmlEngine::setObjectOwnership(log, QQmlEngine::JavaScriptOwnership); QQmlEngine::setObjectOwnership(log, QQmlEngine::JavaScriptOwnership);
emit newRecord(log); emit newRecord(log);
} }

25
mix/ClientModel.h

@ -72,6 +72,7 @@ struct TransactionSettings
class RecordLogEntry: public QObject class RecordLogEntry: public QObject
{ {
Q_OBJECT Q_OBJECT
Q_ENUMS(RecordType)
/// Recording index /// Recording index
Q_PROPERTY(unsigned recordIndex MEMBER m_recordIndex CONSTANT) Q_PROPERTY(unsigned recordIndex MEMBER m_recordIndex CONSTANT)
/// Human readable transaction bloack and transaction index /// Human readable transaction bloack and transaction index
@ -88,13 +89,20 @@ class RecordLogEntry: public QObject
Q_PROPERTY(QString returned MEMBER m_returned CONSTANT) Q_PROPERTY(QString returned MEMBER m_returned CONSTANT)
/// true if call, false if transaction /// true if call, false if transaction
Q_PROPERTY(bool call MEMBER m_call CONSTANT) Q_PROPERTY(bool call MEMBER m_call CONSTANT)
/// @returns record type
Q_PROPERTY(RecordType type MEMBER m_type CONSTANT)
public: public:
enum RecordType
{
Transaction,
Block
};
RecordLogEntry(): RecordLogEntry():
m_recordIndex(0), m_call(false) {} m_recordIndex(0), m_call(false), m_type(RecordType::Transaction) {}
RecordLogEntry(unsigned _recordIndex, QString _transactionIndex, QString _contract, QString _function, QString _value, QString _address, QString _returned, bool _call): RecordLogEntry(unsigned _recordIndex, QString _transactionIndex, QString _contract, QString _function, QString _value, QString _address, QString _returned, bool _call, RecordType _type):
m_recordIndex(_recordIndex), m_transactionIndex(_transactionIndex), m_contract(_contract), m_function(_function), m_value(_value), m_address(_address), m_returned(_returned), m_call(_call) {} m_recordIndex(_recordIndex), m_transactionIndex(_transactionIndex), m_contract(_contract), m_function(_function), m_value(_value), m_address(_address), m_returned(_returned), m_call(_call), m_type(_type) {}
private: private:
unsigned m_recordIndex; unsigned m_recordIndex;
@ -105,6 +113,7 @@ private:
QString m_address; QString m_address;
QString m_returned; QString m_returned;
bool m_call; bool m_call;
RecordType m_type;
}; };
/** /**
@ -123,11 +132,12 @@ public:
Q_PROPERTY(bool mining MEMBER m_mining NOTIFY miningStateChanged) Q_PROPERTY(bool mining MEMBER m_mining NOTIFY miningStateChanged)
/// @returns deployed contracts addresses /// @returns deployed contracts addresses
Q_PROPERTY(QVariantMap contractAddresses READ contractAddresses NOTIFY contractAddressesChanged) Q_PROPERTY(QVariantMap contractAddresses READ contractAddresses NOTIFY contractAddressesChanged)
// @returns the last block
Q_PROPERTY(RecordLogEntry* lastBlock READ lastBlock CONSTANT)
/// ethereum.js RPC request entry point /// ethereum.js RPC request entry point
/// @param _message RPC request in Json format /// @param _message RPC request in Json format
/// @returns RPC response in Json format /// @returns RPC response in Json format
Q_INVOKABLE QString apiCall(QString const& _message); Q_INVOKABLE QString apiCall(QString const& _message);
/// Simulate mining. Creates a new block /// Simulate mining. Creates a new block
Q_INVOKABLE void mine(); Q_INVOKABLE void mine();
@ -139,6 +149,8 @@ public slots:
void setupState(QVariantMap _state); void setupState(QVariantMap _state);
/// Show the debugger for a specified record /// Show the debugger for a specified record
Q_INVOKABLE void debugRecord(unsigned _index); Q_INVOKABLE void debugRecord(unsigned _index);
/// Show the debugger for an empty record
Q_INVOKABLE void emptyRecord();
private slots: private slots:
/// Update UI with machine states result. Display a modal dialog. /// Update UI with machine states result. Display a modal dialog.
@ -177,6 +189,7 @@ signals:
void stateCleared(); void stateCleared();
private: private:
RecordLogEntry* lastBlock() const;
QVariantMap contractAddresses() const; QVariantMap contractAddresses() const;
void executeSequence(std::vector<TransactionSettings> const& _sequence, u256 _balance); void executeSequence(std::vector<TransactionSettings> const& _sequence, u256 _balance);
dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings());
@ -199,3 +212,5 @@ private:
} }
} }
Q_DECLARE_METATYPE(dev::mix::RecordLogEntry*)

12
mix/FileIo.cpp

@ -20,6 +20,9 @@
* Ethereum IDE client. * Ethereum IDE client.
*/ */
#include <QDebug>
#include <QDesktopServices>
#include <QMimeDatabase>
#include <QDirIterator> #include <QDirIterator>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
@ -37,6 +40,12 @@ using namespace dev;
using namespace dev::crypto; using namespace dev::crypto;
using namespace dev::mix; using namespace dev::mix;
void FileIo::openFileBrowser(QString const& _dir)
{
QDesktopServices::openUrl(QUrl(_dir));
}
QString FileIo::pathFromUrl(QString const& _url) QString FileIo::pathFromUrl(QString const& _url)
{ {
QUrl url(_url); QUrl url(_url);
@ -126,6 +135,7 @@ QStringList FileIo::makePackage(QString const& _deploymentFolder)
dev::RLPStream rlpStr; dev::RLPStream rlpStr;
int k = 1; int k = 1;
std::vector<bytes> files; std::vector<bytes> files;
QMimeDatabase mimeDb;
for (auto item: deployDir.entryInfoList(QDir::Files)) for (auto item: deployDir.entryInfoList(QDir::Files))
{ {
QFile qFile(item.filePath()); QFile qFile(item.filePath());
@ -137,7 +147,7 @@ QStringList FileIo::makePackage(QString const& _deploymentFolder)
std::string path = fileInfo.fileName() == "index.html" ? "/" : fileInfo.fileName().toStdString(); std::string path = fileInfo.fileName() == "index.html" ? "/" : fileInfo.fileName().toStdString();
jsonValue["path"] = path; //TODO: Manage relative sub folder jsonValue["path"] = path; //TODO: Manage relative sub folder
jsonValue["file"] = "/" + fileInfo.fileName().toStdString(); jsonValue["file"] = "/" + fileInfo.fileName().toStdString();
jsonValue["contentType"] = "text/html"; //TODO: manage multiple content type jsonValue["contentType"] = mimeDb.mimeTypeForFile(qFile.fileName()).name().toStdString();
QByteArray a = qFile.readAll(); QByteArray a = qFile.readAll();
bytes data = bytes(a.begin(), a.end()); bytes data = bytes(a.begin(), a.end());
files.push_back(data); files.push_back(data);

2
mix/FileIo.h

@ -55,6 +55,8 @@ public:
Q_INVOKABLE bool fileExists(QString const& _url); Q_INVOKABLE bool fileExists(QString const& _url);
/// Compress a folder, @returns sha3 of the compressed file. /// Compress a folder, @returns sha3 of the compressed file.
Q_INVOKABLE QStringList makePackage(QString const& _deploymentFolder); Q_INVOKABLE QStringList makePackage(QString const& _deploymentFolder);
/// Open a file browser
Q_INVOKABLE void openFileBrowser(QString const& _dir);
private: private:
QString getHomePath() const; QString getHomePath() const;

6
mix/MixClient.cpp

@ -436,6 +436,12 @@ h256 MixClient::hashFromNumber(unsigned _number) const
eth::BlockInfo MixClient::blockInfo(h256 _hash) const eth::BlockInfo MixClient::blockInfo(h256 _hash) const
{ {
return BlockInfo(bc().block(_hash)); return BlockInfo(bc().block(_hash));
}
eth::BlockInfo MixClient::blockInfo() const
{
return BlockInfo(bc().block());
} }
eth::BlockDetails MixClient::blockDetails(h256 _hash) const eth::BlockDetails MixClient::blockDetails(h256 _hash) const

2
mix/MixClient.h

@ -89,6 +89,8 @@ public:
eth::MineProgress miningProgress() const override; eth::MineProgress miningProgress() const override;
std::pair<h256, u256> getWork() override { return std::pair<h256, u256>(); } std::pair<h256, u256> getWork() override { return std::pair<h256, u256>(); }
bool submitNonce(h256 const&) override { return false; } bool submitNonce(h256 const&) override { return false; }
/// @returns the last mined block information
eth::BlockInfo blockInfo() const;
private: private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call); void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call);

56
mix/qml/Debugger.qml

@ -12,7 +12,7 @@ Rectangle {
id: debugPanel id: debugPanel
property alias transactionLog : transactionLog property alias transactionLog : transactionLog
property string compilationErrorMessage
objectName: "debugPanel" objectName: "debugPanel"
color: "#ededed" color: "#ededed"
clip: true clip: true
@ -23,25 +23,30 @@ Rectangle {
forceActiveFocus(); forceActiveFocus();
} }
function update(data, giveFocus) function displayCompilationErrorIfAny()
{
if (statusPane && codeModel.hasContract)
{
Debugger.init(data);
debugScrollArea.visible = true;
compilationErrorArea.visible = false;
machineStates.visible = true;
}
else
{ {
debugScrollArea.visible = false; debugScrollArea.visible = false;
compilationErrorArea.visible = true; compilationErrorArea.visible = true;
machineStates.visible = false; machineStates.visible = false;
var errorInfo = ErrorLocationFormater.extractErrorInfo(statusPane.result.compilerMessage, false); var errorInfo = ErrorLocationFormater.extractErrorInfo(compilationErrorMessage, false);
errorLocation.text = errorInfo.errorLocation; errorLocation.text = errorInfo.errorLocation;
errorDetail.text = errorInfo.errorDetail; errorDetail.text = errorInfo.errorDetail;
errorLine.text = errorInfo.errorLine; errorLine.text = errorInfo.errorLine;
} }
function update(data, giveFocus)
{
if (data === null)
Debugger.init(null);
else if (data.states.length === 0)
Debugger.init(null);
else if (codeModel.hasContract)
{
Debugger.init(data);
debugScrollArea.visible = true;
compilationErrorArea.visible = false;
machineStates.visible = true;
}
if (giveFocus) if (giveFocus)
forceActiveFocus(); forceActiveFocus();
} }
@ -55,7 +60,15 @@ Rectangle {
Connections { Connections {
target: codeModel target: codeModel
onCompilationComplete: update(null, false); onCompilationComplete:
{
debugPanel.compilationErrorMessage = "";
update(null, false);
}
onCompilationError: {
debugPanel.compilationErrorMessage = _error;
}
} }
Settings { Settings {
@ -73,7 +86,7 @@ Rectangle {
visible: false; visible: false;
id: compilationErrorArea id: compilationErrorArea
width: parent.width - 20 width: parent.width - 20
height: 500 height: 600
color: "#ededed" color: "#ededed"
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
@ -82,7 +95,20 @@ Rectangle {
{ {
width: parent.width width: parent.width
anchors.top: parent.top anchors.top: parent.top
spacing: 25 spacing: 15
Rectangle
{
height: 15
Button {
text: qsTr("Back to Debugger")
onClicked: {
debugScrollArea.visible = true;
compilationErrorArea.visible = false;
machineStates.visible = true;
}
}
}
RowLayout RowLayout
{ {
height: 100 height: 100

304
mix/qml/DeploymentDialog.qml

@ -12,18 +12,20 @@ import "."
Window { Window {
id: modalDeploymentDialog id: modalDeploymentDialog
modality: Qt.ApplicationModal modality: Qt.ApplicationModal
width: 600 width: 930
height: 350 height: 350
visible: false visible: false
property alias applicationUrlEth: applicationUrlEth.text property alias applicationUrlEth: applicationUrlEth.text
property alias applicationUrlHttp: applicationUrlHttp.text property alias applicationUrlHttp: applicationUrlHttp.text
property string urlHintContract: "c83d3e22645fb015d02043a744921cc2f828c64d" property string urlHintContract: "c83d3e22645fb015d02043a744921cc2f828c64d" /* TODO: replace with the good address */
property string packageHash property string packageHash
property alias packageBase64: base64Value.text property alias packageBase64: base64Value.text
property string eth: "afb7cdbd076674fd2c67f8a66518e3145b184ae4"; property string eth: "4c3f7330690ed3657d3fa20fe5717b84010528ae"; /* TODO: replace with the good address */
property string wallet: "c83d3e22645fb015d02043a744921cc2f828c64d"; property string currentAccount
property alias gasToUse: gasToUseInput.text
color: Style.generic.layout.backgroundColor color: Style.generic.layout.backgroundColor
@ -37,6 +39,59 @@ Window {
modalDeploymentDialog.setX((Screen.width - width) / 2); modalDeploymentDialog.setX((Screen.width - width) / 2);
modalDeploymentDialog.setY((Screen.height - height) / 2); modalDeploymentDialog.setY((Screen.height - height) / 2);
visible = true; visible = true;
var requests = [{
//accounts
jsonrpc: "2.0",
method: "eth_accounts",
params: null,
id: 0
}];
TransactionHelper.rpcCall(requests, function(arg1, arg2)
{
modelAccounts.clear();
var ids = JSON.parse(arg2)[0].result;
requests = [];
for (var k in ids)
{
modelAccounts.append({ "id": ids[k] })
requests.push({
//accounts
jsonrpc: "2.0",
method: "eth_balanceAt",
params: [ids[k]],
id: k
});
}
if (ids.length > 0)
currentAccount = modelAccounts.get(0).id;
TransactionHelper.rpcCall(requests, function (request, response){
var balanceRet = JSON.parse(response);
for (var k in balanceRet)
{
var ether = QEtherHelper.createEther(balanceRet[k].result, QEther.Wei);
comboAccounts.balances.push(ether.format());
}
balance.text = comboAccounts.balances[0];
});
});
}
function stopForInputError(inError)
{
errorDialog.text = "";
if (inError.length > 0)
{
errorDialog.text = qsTr("The length of a string cannot exceed 32 characters.\nPlease verify the following value(s):\n\n")
for (var k in inError)
errorDialog.text += inError[k] + "\n";
errorDialog.open();
return true;
}
return false;
} }
function pad(h) function pad(h)
@ -49,6 +104,52 @@ Window {
return h; return h;
} }
function waitForTrCountToIncrement(callBack)
{
poolLog.callBack = callBack;
poolLog.k = -1;
poolLog.elapsed = 0;
poolLog.start();
}
Timer
{
id: poolLog
property var callBack
property int k: -1
property int elapsed
interval: 500
running: false
repeat: true
onTriggered: {
elapsed += interval;
var requests = [];
var jsonRpcRequestId = 0;
requests.push({
jsonrpc: "2.0",
method: "eth_countAt",
params: [ currentAccount ],
id: jsonRpcRequestId++
});
TransactionHelper.rpcCall(requests, function (httpRequest, response){
response = response.replace(/,0+/, ''); // ==> result:27,00000000
var count = JSON.parse(response)[0].result
if (k < parseInt(count) && k > 0)
{
stop();
callBack(1);
}
else if (elapsed > 25000)
{
stop();
callBack(-1);
}
else
k = parseInt(JSON.parse(response)[0].result);
})
}
}
Rectangle Rectangle
{ {
anchors.fill : parent anchors.fill : parent
@ -60,17 +161,65 @@ Window {
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
width: parent.width width: parent.width
DefaultLabel
{
text: qsTr("Account used to deploy:")
}
Rectangle
{
width: 300
height: 25
color: "transparent"
ComboBox {
id: comboAccounts
property var balances: []
onCurrentIndexChanged : {
if (modelAccounts.count > 0)
{
currentAccount = modelAccounts.get(currentIndex).id;
balance.text = balances[currentIndex];
}
}
model: ListModel {
id: modelAccounts
}
}
DefaultLabel
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: comboAccounts.right
anchors.leftMargin: 20
id: balance;
}
}
DefaultLabel DefaultLabel
{ {
text: qsTr("Ethereum Application URL: ") text: qsTr("Ethereum Application URL: ")
} }
DefaultTextField Rectangle
{ {
Layout.fillWidth: true Layout.fillWidth: true
height: 25
color: "transparent"
DefaultTextField
{
width: 350
id: applicationUrlEth id: applicationUrlEth
} }
DefaultLabel
{
anchors.verticalCenter: parent.verticalCenter;
anchors.left: applicationUrlEth.right
text: "/" + projectModel.projectTitle
}
}
DefaultLabel DefaultLabel
{ {
text: qsTr("Web Application Ressources URL: ") text: qsTr("Web Application Ressources URL: ")
@ -82,6 +231,18 @@ Window {
id: applicationUrlHttp id: applicationUrlHttp
} }
DefaultLabel
{
text: qsTr("Amount of gas to use for each contract deployment: ")
}
DefaultTextField
{
text: "20000"
Layout.fillWidth: true
id: gasToUseInput
}
DefaultLabel DefaultLabel
{ {
text: qsTr("Package (Base64): ") text: qsTr("Package (Base64): ")
@ -103,19 +264,50 @@ Window {
icon: StandardIcon.Warning icon: StandardIcon.Warning
} }
MessageDialog {
id: errorDialog
standardButtons: StandardButton.Ok
icon: StandardIcon.Error
}
RowLayout RowLayout
{ {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right; anchors.right: parent.right;
anchors.bottomMargin: 10 anchors.bottomMargin: 10
Button { Button {
text: qsTr("Deploy to Ethereum"); text: qsTr("Deploy contract / Package resources");
tooltip: qsTr("Deploy contract and package resources files.") tooltip: qsTr("Deploy contract and package resources files.")
onClicked: { onClicked: {
var inError = [];
var ethUrl = ProjectModelCode.formatAppUrl(applicationUrlEth.text);
for (var k in ethUrl)
{
if (ethUrl[k].length > 32)
inError.push(qsTr("Member too long: " + ethUrl[k]) + "\n");
}
if (!stopForInputError(inError))
deployWarningDialog.open(); deployWarningDialog.open();
} }
} }
Button {
text: qsTr("Package resources only");
tooltip: qsTr("Package resources files.")
enabled: Object.keys(projectModel.deploymentAddresses).length > 0
onClicked: {
ProjectModelCode.startDeployProject(false);
}
}
Button {
text: qsTr("Open Package Directory");
enabled: projectModel.deploymentDir !== ""
onClicked: {
fileIo.openFileBrowser(projectModel.deploymentDir);
}
}
Button { Button {
text: qsTr("Register Web Application"); text: qsTr("Register Web Application");
tooltip: qsTr("Register hosted Web Application.") tooltip: qsTr("Register hosted Web Application.")
@ -123,10 +315,14 @@ Window {
if (applicationUrlHttp.text === "" || deploymentDialog.packageHash === "") if (applicationUrlHttp.text === "" || deploymentDialog.packageHash === "")
{ {
deployDialog.title = text; deployDialog.title = text;
deployDialog.text = qsTr("Please provide the link where the resources are stored and ensure the package is aleary built using the deployment step. ") deployDialog.text = qsTr("Please provide the link where the resources are stored and ensure the package is aleary built using the deployment step.")
deployDialog.open(); deployDialog.open();
return;
} }
else var inError = [];
if (applicationUrlHttp.text.length > 32)
inError.push(qsTr(applicationUrlHttp.text));
if (!stopForInputError(inError))
ProjectModelCode.registerToUrlHint(); ProjectModelCode.registerToUrlHint();
} }
} }
@ -135,98 +331,6 @@ Window {
text: qsTr("Close"); text: qsTr("Close");
onClicked: close(); onClicked: close();
} }
Button {
text: qsTr("Check Ownership");
visible : false
onClicked: {
var requests = [];
var ethStr = QEtherHelper.createString("wallet");
var ethHash = QEtherHelper.createHash(eth);
requests.push({ //owner
jsonrpc: "2.0",
method: "eth_call",
params: [ { "to": '0x' + modalDeploymentDialog.eth, "data": "0xec7b9200" + ethStr.encodeValueAsString() } ],
id: 3
});
requests.push({ //register
jsonrpc: "2.0",
method: "eth_call",
params: [ { "to": '0x' + modalDeploymentDialog.eth, "data": "0x6be16bed" + ethStr.encodeValueAsString() } ],
id: 4
});
var jsonRpcUrl = "http://localhost:8080";
var rpcRequest = JSON.stringify(requests);
var httpRequest = new XMLHttpRequest();
httpRequest.open("POST", jsonRpcUrl, true);
httpRequest.setRequestHeader("Content-type", "application/json");
httpRequest.setRequestHeader("Content-length", rpcRequest.length);
httpRequest.setRequestHeader("Connection", "close");
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
} else {
var errorText = qsTr("path registration failed ") + httpRequest.status;
console.log(errorText);
}
}
}
httpRequest.send(rpcRequest);
}
}
Button {
text: qsTr("Generate registrar init");
visible: false
onClicked: {
console.log("registering eth/wallet")
var jsonRpcRequestId = 0;
var requests = [];
var walletStr = QEtherHelper.createString("wallet");
requests.push({ //reserve
jsonrpc: "2.0",
method: "eth_transact",
params: [ { "to": '0x' + modalDeploymentDialog.eth, "data": "0x1c83171b" + walletStr.encodeValueAsString() } ],
id: jsonRpcRequestId++
});
requests.push({ //setRegister
jsonrpc: "2.0",
method: "eth_transact",
params: [ { "to": '0x' + modalDeploymentDialog.eth, "data": "0x96077307" + walletStr.encodeValueAsString() + pad(wallet) } ],
id: jsonRpcRequestId++
});
var jsonRpcUrl = "http://localhost:8080";
var rpcRequest = JSON.stringify(requests);
var httpRequest = new XMLHttpRequest();
httpRequest.open("POST", jsonRpcUrl, true);
httpRequest.setRequestHeader("Content-type", "application/json");
httpRequest.setRequestHeader("Content-length", rpcRequest.length);
httpRequest.setRequestHeader("Connection", "close");
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
} else {
var errorText = qsTr("path registration failed ") + httpRequest.status;
console.log(errorText);
}
}
}
httpRequest.send(rpcRequest);
}
}
} }
} }
} }

28
mix/qml/FilesSection.qml

@ -6,17 +6,19 @@ import QtQuick.Controls.Styles 1.3
import "." import "."
ColumnLayout { Rectangle
{
Layout.fillWidth: true
Layout.minimumHeight: hiddenHeightTopLevel()
height: hiddenHeightTopLevel()
Layout.maximumHeight: hiddenHeightTopLevel()
id: wrapperItem id: wrapperItem
signal documentSelected(string doc, string groupName) signal documentSelected(string doc, string groupName)
property alias model: filesList.model property alias model: filesList.model
property string sectionName; property string sectionName;
property variant selManager; property variant selManager;
Layout.fillWidth: true property int index;
Layout.minimumHeight: hiddenHeightTopLevel() color: index % 2 === 0 ? "transparent" : ProjectFilesStyle.title.background
height: hiddenHeightTopLevel()
Layout.maximumHeight: hiddenHeightTopLevel()
spacing: 0
function hiddenHeightTopLevel() function hiddenHeightTopLevel()
{ {
@ -48,6 +50,10 @@ ColumnLayout {
model.remove(i); model.remove(i);
} }
ColumnLayout {
anchors.fill: parent
spacing: 0
SourceSansProRegular SourceSansProRegular
{ {
id: fileNameFont id: fileNameFont
@ -62,8 +68,9 @@ ColumnLayout {
{ {
anchors.top: parent.top anchors.top: parent.top
id: rowCol id: rowCol
width: parent.width
height: ProjectFilesStyle.documentsList.height height: ProjectFilesStyle.documentsList.height
Layout.fillWidth: true
Image { Image {
source: "qrc:/qml/img/opentriangleindicator_filesproject.png" source: "qrc:/qml/img/opentriangleindicator_filesproject.png"
@ -73,7 +80,7 @@ ColumnLayout {
anchors.right: section.left anchors.right: section.left
anchors.rightMargin: 8 anchors.rightMargin: 8
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 6 anchors.topMargin: 10
} }
Text Text
@ -117,6 +124,7 @@ ColumnLayout {
width: parent.width width: parent.width
visible: section.state !== "hidden" visible: section.state !== "hidden"
spacing: 0 spacing: 0
Repeater Repeater
{ {
id: filesList id: filesList
@ -130,7 +138,7 @@ ColumnLayout {
Layout.preferredHeight: wrapperItem.hiddenHeightElement() Layout.preferredHeight: wrapperItem.hiddenHeightElement()
Layout.maximumHeight: wrapperItem.hiddenHeightElement() Layout.maximumHeight: wrapperItem.hiddenHeightElement()
height: wrapperItem.hiddenHeightElement() height: wrapperItem.hiddenHeightElement()
color: isSelected ? ProjectFilesStyle.documentsList.highlightColor : ProjectFilesStyle.documentsList.background color: isSelected ? ProjectFilesStyle.documentsList.highlightColor : "transparent"
property bool isSelected property bool isSelected
property bool renameMode property bool renameMode
Text { Text {
@ -244,5 +252,5 @@ ColumnLayout {
} }
} }
} }
}
} }

6
mix/qml/MainContent.qml

@ -75,6 +75,12 @@ Rectangle {
codeWebSplitter.orientation = (codeWebSplitter.orientation === Qt.Vertical ? Qt.Horizontal : Qt.Vertical); codeWebSplitter.orientation = (codeWebSplitter.orientation === Qt.Vertical ? Qt.Horizontal : Qt.Vertical);
} }
function displayCompilationErrorIfAny()
{
rightView.visible = true;
rightView.displayCompilationErrorIfAny();
}
CodeEditorExtensionManager { CodeEditorExtensionManager {
headerView: headerPaneTabs; headerView: headerPaneTabs;
} }

2
mix/qml/ProjectFilesStyle.qml

@ -25,7 +25,7 @@ QtObject {
property string sectionColor: "#808080" property string sectionColor: "#808080"
property string selectedColor: "white" property string selectedColor: "white"
property string highlightColor: "#4a90e2" property string highlightColor: "#4a90e2"
property int height: 25 property int height: 35
property int fileNameHeight: 30 property int fileNameHeight: 30
property int fontSize: absoluteSize(2)// 13 property int fontSize: absoluteSize(2)// 13
property int sectionFontSize: absoluteSize(2)// 13 property int sectionFontSize: absoluteSize(2)// 13

18
mix/qml/ProjectList.qml

@ -26,11 +26,9 @@ Item {
Image { Image {
id: projectIcon id: projectIcon
source: "qrc:/qml/img/dappProjectIcon.png" source: "qrc:/qml/img/dappProjectIcon.png"
//sourceSize.height: 32
anchors.right: projectTitle.left anchors.right: projectTitle.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 6 anchors.rightMargin: 6
//anchors.centerIn: parent
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
width: 32 width: 32
height: 32 height: 32
@ -65,7 +63,7 @@ Item {
Rectangle Rectangle
{ {
Layout.fillWidth: true Layout.fillWidth: true
height: 10 height: 3
color: ProjectFilesStyle.documentsList.background color: ProjectFilesStyle.documentsList.background
} }
@ -82,14 +80,24 @@ Item {
anchors.top: parent.top anchors.top: parent.top
width: parent.width width: parent.width
spacing: 0 spacing: 0
Repeater { Repeater {
model: [qsTr("Contracts"), qsTr("Javascript"), qsTr("Web Pages"), qsTr("Styles"), qsTr("Images"), qsTr("Misc")]; model: [qsTr("Contracts"), qsTr("Javascript"), qsTr("Web Pages"), qsTr("Styles"), qsTr("Images"), qsTr("Misc")];
signal selected(string doc, string groupName) signal selected(string doc, string groupName)
property int incr: -1;
id: sectionRepeater id: sectionRepeater
FilesSection FilesSection
{ {
id: section;
sectionName: modelData sectionName: modelData
index:
{
for (var k in sectionRepeater.model)
{
if (sectionRepeater.model[k] === modelData)
return k;
}
}
model: sectionModel model: sectionModel
selManager: sectionRepeater selManager: sectionRepeater
@ -170,10 +178,10 @@ Item {
projectModel.openDocument(newDoc.documentId); projectModel.openDocument(newDoc.documentId);
sectionRepeater.selected(newDoc.documentId, modelData); sectionRepeater.selected(newDoc.documentId, modelData);
} }
} }
} }
} }
} }
} }
} }

19
mix/qml/ProjectModel.qml

@ -7,6 +7,7 @@ import Qt.labs.settings 1.0
import "js/ProjectModel.js" as ProjectModelCode import "js/ProjectModel.js" as ProjectModelCode
Item { Item {
id: projectModel id: projectModel
signal projectClosed signal projectClosed
@ -33,6 +34,7 @@ Item {
property string projectTitle: "" property string projectTitle: ""
property string currentDocumentId: "" property string currentDocumentId: ""
property var deploymentAddresses: [] property var deploymentAddresses: []
property string deploymentDir
property var listModel: projectListModel property var listModel: projectListModel
property var stateListModel: projectStateListModel.model property var stateListModel: projectStateListModel.model
property CodeEditorView codeEditor: null property CodeEditorView codeEditor: null
@ -57,6 +59,7 @@ Item {
function addExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); } function addExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); }
function deployProject() { ProjectModelCode.deployProject(false); } function deployProject() { ProjectModelCode.deployProject(false); }
function registerToUrlHint() { ProjectModelCode.registerToUrlHint(); } function registerToUrlHint() { ProjectModelCode.registerToUrlHint(); }
function formatAppUrl() { ProjectModelCode.formatAppUrl(url); }
Connections { Connections {
target: appContext target: appContext
@ -93,28 +96,17 @@ Item {
MessageDialog { MessageDialog {
id: deployWarningDialog id: deployWarningDialog
property bool redeploy
title: qsTr("Project") title: qsTr("Project")
text: text:
{ {
if (Object.keys(projectModel.deploymentAddresses).length > 0) if (Object.keys(projectModel.deploymentAddresses).length > 0)
{ return qsTr("This project has been already deployed to the network. Do you want to redeploy it? (Contract state will be reset)")
redeploy = true
standardButtons = StandardButton.Ok | StandardButton.Reset | StandardButton.Abort;
return qsTr("This project has been already deployed to the network. Do you want to repackage the resources only, or also reset the deployed contract to its initial state?")
}
else else
{
redeploy = false;
standardButtons = StandardButton.Ok | StandardButton.Abort;
return qsTr("This action will deploy to the network. Do you want to deploy it?") return qsTr("This action will deploy to the network. Do you want to deploy it?")
} }
}
icon: StandardIcon.Question icon: StandardIcon.Question
standardButtons: StandardButton.Ok | StandardButton.Abort
onAccepted: { onAccepted: {
ProjectModelCode.startDeployProject(!redeploy);
}
onReset: {
ProjectModelCode.startDeployProject(true); ProjectModelCode.startDeployProject(true);
} }
} }
@ -123,7 +115,6 @@ Item {
id: deployRessourcesDialog id: deployRessourcesDialog
title: qsTr("Project") title: qsTr("Project")
standardButtons: StandardButton.Ok standardButtons: StandardButton.Ok
icon: StandardIcon.Info
} }
DeploymentDialog DeploymentDialog

83
mix/qml/StatusPane.qml

@ -1,6 +1,7 @@
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 1.1 import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.3
import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "." import "."
@ -13,7 +14,7 @@ Rectangle {
if (!message) if (!message)
{ {
status.state = ""; status.state = "";
status.text = qsTr("Compile without errors."); status.text = qsTr("Compile successfully.");
logslink.visible = false; logslink.visible = false;
debugImg.state = "active"; debugImg.state = "active";
} }
@ -35,17 +36,24 @@ Rectangle {
logslink.visible = false; logslink.visible = false;
} }
function errorMessage(text)
{
status.state = "error";
status.text = text
logslink.visible = false;
}
Connections { Connections {
target:clientModel target:clientModel
onRunStarted: infoMessage(qsTr("Running transactions...")); onRunStarted: infoMessage(qsTr("Running transactions..."));
onRunFailed: infoMessage(qsTr("Error running transactions")); onRunFailed: errorMessage(qsTr("Error running transactions"));
onRunComplete: infoMessage(qsTr("Run complete")); onRunComplete: infoMessage(qsTr("Run complete"));
onNewBlock: infoMessage(qsTr("New block created")); onNewBlock: infoMessage(qsTr("New block created"));
} }
Connections { Connections {
target:projectModel target:projectModel
onDeploymentStarted: infoMessage(qsTr("Running deployment...")); onDeploymentStarted: infoMessage(qsTr("Running deployment..."));
onDeploymentError: infoMessage(error); onDeploymentError: errorMessage(error);
onDeploymentComplete: infoMessage(qsTr("Deployment complete")); onDeploymentComplete: infoMessage(qsTr("Deployment complete"));
onDeploymentStepChanged: infoMessage(message); onDeploymentStepChanged: infoMessage(message);
} }
@ -57,6 +65,7 @@ Rectangle {
color: "transparent" color: "transparent"
anchors.fill: parent anchors.fill: parent
Rectangle { Rectangle {
id: statusContainer id: statusContainer
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@ -65,18 +74,21 @@ Rectangle {
width: 500 width: 500
height: 30 height: 30
color: "#fcfbfc" color: "#fcfbfc"
RowLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
spacing: 5
Text { Text {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: StatusPaneStyle.general.statusFontSize font.pointSize: StatusPaneStyle.general.statusFontSize
height: 9 height: 15
font.family: "sans serif" font.family: "sans serif"
objectName: "status" objectName: "status"
wrapMode: Text.WrapAnywhere
elide: Text.ElideRight
maximumLineCount: 1
clip: true
id: status id: status
states:[ states: [
State { State {
name: "error" name: "error"
PropertyChanges { PropertyChanges {
@ -89,24 +101,59 @@ Rectangle {
} }
} }
] ]
onTextChanged:
{
updateWidth()
toolTipInfo.tooltip = text;
} }
Text { function updateWidth()
{
if (text.length > 80)
width = parent.width - 10
else
width = undefined
}
}
Button
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.right
anchors.leftMargin: 10
width: 38
height: 28
visible: false visible: false
font.pointSize: StatusPaneStyle.general.logLinkFontSize text: qsTr("Log")
height: 9
text: qsTr("See Log.")
font.family: "Monospace"
objectName: "status" objectName: "status"
id: logslink id: logslink
color: "#8c8a74" action: displayLogAction
MouseArea { }
Action {
id: displayLogAction
onTriggered: {
mainContent.displayCompilationErrorIfAny();
}
}
Button
{
anchors.fill: parent anchors.fill: parent
onClicked: { id: toolTip
mainContent.ensureRightView(); action: toolTipInfo
text: ""
style:
ButtonStyle {
background:Rectangle {
color: "transparent"
} }
} }
} }
Action {
id: toolTipInfo
tooltip: ""
} }
} }

39
mix/qml/TransactionLog.qml

@ -3,15 +3,13 @@ import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import org.ethereum.qml.RecordLogEntry 1.0
Item { Item {
property bool showLogs: true
property ListModel fullModel: ListModel{} property ListModel fullModel: ListModel{}
property ListModel transactionModel: ListModel{} property ListModel transactionModel: ListModel{}
onShowLogsChanged: { property ListModel callModel: ListModel{}
logTable.model = showLogs ? fullModel : transactionModel
}
Action { Action {
id: addStateAction id: addStateAction
@ -78,13 +76,24 @@ Item {
action: mineAction action: mineAction
} }
CheckBox { ComboBox {
id: recording id: itemFilter
text: qsTr("Record transactions");
checked: true
Layout.fillWidth: true
function getCurrentModel()
{
return currentIndex === 0 ? fullModel : currentIndex === 1 ? transactionModel : currentIndex === 2 ? callModel : fullModel;
}
model: ListModel {
ListElement { text: qsTr("Calls and Transactions"); value: 0; }
ListElement { text: qsTr("Only Transactions"); value: 1; }
ListElement { text: qsTr("Only Calls"); value: 2; }
}
onCurrentIndexChanged:
{
logTable.model = itemFilter.getCurrentModel();
}
} }
} }
TableView { TableView {
@ -125,7 +134,10 @@ Item {
} }
onActivated: { onActivated: {
var item = logTable.model.get(row); var item = logTable.model.get(row);
if (item.type === RecordLogEntry.Transaction)
clientModel.debugRecord(item.recordIndex); clientModel.debugRecord(item.recordIndex);
else
clientModel.emptyRecord();
} }
Keys.onPressed: { Keys.onPressed: {
if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C && currentRow >=0 && currentRow < logTable.model.count) { if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C && currentRow >=0 && currentRow < logTable.model.count) {
@ -141,15 +153,18 @@ Item {
onStateCleared: { onStateCleared: {
fullModel.clear(); fullModel.clear();
transactionModel.clear(); transactionModel.clear();
callModel.clear();
} }
onNewRecord: { onNewRecord: {
if (recording.checked)
{
fullModel.append(_r); fullModel.append(_r);
if (!_r.call) if (!_r.call)
transactionModel.append(_r); transactionModel.append(_r);
else
callModel.append(_r);
} }
onMiningComplete: {
fullModel.append(clientModel.lastBlock);
transactionModel.append(clientModel.lastBlock);
} }
} }
} }

60
mix/qml/WebPreview.qml

@ -26,7 +26,8 @@ Item {
function reload() { function reload() {
if (initialized) { if (initialized) {
updateContract(); updateContract();
webView.runJavaScript("reloadPage()"); //webView.runJavaScript("reloadPage()");
setPreviewUrl(urlInput.text);
} }
} }
@ -55,11 +56,13 @@ Item {
} }
function changePage() { function changePage() {
if (pageCombo.currentIndex >= 0 && pageCombo.currentIndex < pageListModel.count) { setPreviewUrl(urlInput.text);
/*if (pageCombo.currentIndex >= 0 && pageCombo.currentIndex < pageListModel.count) {
urlInput.text = httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId;
setPreviewUrl(httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId); setPreviewUrl(httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId);
} else { } else {
setPreviewUrl(""); setPreviewUrl("");
} }*/
} }
Connections { Connections {
target: appContext target: appContext
@ -98,24 +101,16 @@ Item {
updateDocument(documentId, function(i) { pageListModel.set(i, projectModel.getDocument(documentId)) } ) updateDocument(documentId, function(i) { pageListModel.set(i, projectModel.getDocument(documentId)) } )
} }
onDocumentOpened: {
if (!document.isHtml)
return;
for (var i = 0; i < pageListModel.count; i++) {
var doc = pageListModel.get(i);
if (doc.documentId === document.documentId) {
pageCombo.currentIndex = i;
}
}
}
onProjectLoading: { onProjectLoading: {
for (var i = 0; i < target.listModel.count; i++) { for (var i = 0; i < target.listModel.count; i++) {
var document = target.listModel.get(i); var document = target.listModel.get(i);
if (document.isHtml) { if (document.isHtml) {
pageListModel.append(document); pageListModel.append(document);
if (pageListModel.count === 1) //first page added if (pageListModel.count === 1) //first page added
changePage(); {
urlInput.text = httpServer.url + "/" + document.documentId;
setPreviewUrl(httpServer.url + "/" + document.documentId);
}
} }
} }
} }
@ -151,13 +146,20 @@ Item {
else else
{ {
//document request //document request
if (urlPath === "/")
urlPath = "/index.html";
var documentId = urlPath.substr(urlPath.lastIndexOf("/") + 1); var documentId = urlPath.substr(urlPath.lastIndexOf("/") + 1);
var content = ""; var content = "";
if (projectModel.codeEditor.isDocumentOpen(documentId)) if (projectModel.codeEditor.isDocumentOpen(documentId))
content = projectModel.codeEditor.getDocumentText(documentId); content = projectModel.codeEditor.getDocumentText(documentId);
else else
content = fileIo.readFile(projectModel.getDocument(documentId).path); {
if (documentId === pageListModel.get(pageCombo.currentIndex).documentId) { var doc = projectModel.getDocument(documentId);
if (doc !== undefined)
content = fileIo.readFile(doc.path);
}
if (documentId === urlInput.text.replace(httpServer.url + "/", "")) {
//root page, inject deployment script //root page, inject deployment script
content = "<script>web3=parent.web3;contracts=parent.contracts;</script>\n" + content; content = "<script>web3=parent.web3;contracts=parent.contracts;</script>\n" + content;
_request.setResponseContentType("text/html"); _request.setResponseContentType("text/html");
@ -181,19 +183,23 @@ Item {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 3 anchors.leftMargin: 3
spacing: 3 spacing: 3
DefaultLabel {
text: qsTr("Preview of")
anchors.verticalCenter: parent.verticalCenter
}
ComboBox { DefaultTextField
id: pageCombo {
model: pageListModel id: urlInput
textRole: "name"
currentIndex: -1
onCurrentIndexChanged: changePage()
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
height: 21 height: 21
width: 300
Keys.onEnterPressed:
{
setPreviewUrl(text);
}
Keys.onReturnPressed:
{
setPreviewUrl(text);
}
focus: true
} }
Action { Action {

316
mix/qml/js/ProjectModel.js

@ -20,6 +20,7 @@
* Ethereum IDE client. * Ethereum IDE client.
*/ */
Qt.include("QEtherHelper.js") Qt.include("QEtherHelper.js")
Qt.include("TransactionHelper.js")
var htmlTemplate = "<html>\n<head>\n<script>\n</script>\n</head>\n<body>\n<script>\n</script>\n</body>\n</html>"; var htmlTemplate = "<html>\n<head>\n<script>\n</script>\n</head>\n<body>\n<script>\n</script>\n</body>\n</html>";
var contractTemplate = "contract Contract {\n}\n"; var contractTemplate = "contract Contract {\n}\n";
@ -50,7 +51,8 @@ function saveProject() {
applicationUrlEth: deploymentDialog.applicationUrlEth, applicationUrlEth: deploymentDialog.applicationUrlEth,
applicationUrlHttp: deploymentDialog.applicationUrlHttp, applicationUrlHttp: deploymentDialog.applicationUrlHttp,
packageHash: deploymentDialog.packageHash, packageHash: deploymentDialog.packageHash,
packageBase64: deploymentDialog.packageBase64 packageBase64: deploymentDialog.packageBase64,
deploymentDir: projectModel.deploymentDir
}; };
for (var i = 0; i < projectListModel.count; i++) for (var i = 0; i < projectListModel.count; i++)
projectData.files.push(projectListModel.get(i).fileName) projectData.files.push(projectListModel.get(i).fileName)
@ -68,6 +70,8 @@ function loadProject(path) {
var projectFile = path + projectFileName; var projectFile = path + projectFileName;
var json = fileIo.readFile(projectFile); var json = fileIo.readFile(projectFile);
var projectData = JSON.parse(json); var projectData = JSON.parse(json);
if (projectData.deploymentDir)
projectModel.deploymentDir = projectData.deploymentDir
if (projectData.packageHash) if (projectData.packageHash)
deploymentDialog.packageHash = projectData.packageHash deploymentDialog.packageHash = projectData.packageHash
if (projectData.packageBase64) if (projectData.packageBase64)
@ -303,49 +307,61 @@ function startDeployProject(erasePrevious)
console.log("Deploying " + deploymentId + " to " + jsonRpcUrl); console.log("Deploying " + deploymentId + " to " + jsonRpcUrl);
deploymentStarted(); deploymentStarted();
var requests = []; var ctrNames = Object.keys(codeModel.contracts);
var requestNames = []; var ctrAddresses = {};
setDefaultBlock(0, function() {
deployContracts(0, ctrAddresses, ctrNames, function (){
finalizeDeployment(deploymentId, ctrAddresses);
});
});
}
for (var c in codeModel.contracts) { //TODO: order based on dependencies function setDefaultBlock(val, callBack)
var code = codeModel.contracts[c].codeHex; {
requests.push({ var requests = [{
jsonrpc: "2.0", jsonrpc: "2.0",
method: "eth_transact", method: "eth_setDefaultBlock",
params: [ { "code": code } ], params: [val],
id: jsonRpcRequestId++ id: 0
}];
rpcCall(requests, function (httpCall, response){
callBack();
}); });
requestNames.push(c); }
}
var rpcRequest = JSON.stringify(requests); function deployContracts(ctrIndex, ctrAddresses, ctrNames, callBack)
var httpRequest = new XMLHttpRequest(); {
httpRequest.open("POST", jsonRpcUrl, true); var code = codeModel.contracts[ctrNames[ctrIndex]].codeHex;
httpRequest.setRequestHeader("Content-type", "application/json"); var requests = [{
httpRequest.setRequestHeader("Content-length", rpcRequest.length); jsonrpc: "2.0",
httpRequest.setRequestHeader("Connection", "close"); method: "eth_transact",
httpRequest.onreadystatechange = function() { params: [ { "from": deploymentDialog.currentAccount, "gas": deploymentDialog.gasToUse, "code": code } ],
if (httpRequest.readyState === XMLHttpRequest.DONE) { id: 0
if (httpRequest.status === 200) { }];
var rpcResponse = JSON.parse(httpRequest.responseText); rpcCall(requests, function (httpCall, response){
if (rpcResponse.length === requestNames.length) { var txt = qsTr("Please wait while " + ctrNames[ctrIndex] + " is published ...")
var contractAddresses = {}; deploymentStepChanged(txt);
for (var r = 0; r < rpcResponse.length; r++) console.log(txt);
contractAddresses[requestNames[r]] = rpcResponse[r].result; ctrAddresses[ctrNames[ctrIndex]] = JSON.parse(response)[0].result
finalizeDeployment(deploymentId, contractAddresses); deploymentDialog.waitForTrCountToIncrement(function(status) {
} if (status === -1)
} else { {
var errorText = qsTr("Deployment error: RPC server HTTP status ") + httpRequest.status; trCountIncrementTimeOut();
console.log(errorText); return;
deploymentError(errorText);
}
}
} }
httpRequest.send(rpcRequest); ctrIndex++;
if (ctrIndex < ctrNames.length)
deployContracts(ctrIndex, ctrAddresses, ctrNames, callBack);
else
callBack();
});
});
} }
function finalizeDeployment(deploymentId, addresses) { function finalizeDeployment(deploymentId, addresses) {
deploymentStepChanged(qsTr("Packaging application ...")); deploymentStepChanged(qsTr("Packaging application ..."));
var deploymentDir = projectPath + deploymentId + "/"; var deploymentDir = projectPath + deploymentId + "/";
projectModel.deploymentDir = deploymentDir;
fileIo.makeDir(deploymentDir); fileIo.makeDir(deploymentDir);
for (var i = 0; i < projectListModel.count; i++) { for (var i = 0; i < projectListModel.count; i++) {
var doc = projectListModel.get(i); var doc = projectListModel.get(i);
@ -395,138 +411,171 @@ function finalizeDeployment(deploymentId, addresses) {
deploymentDialog.packageBase64 = packageRet[1]; deploymentDialog.packageBase64 = packageRet[1];
var applicationUrlEth = deploymentDialog.applicationUrlEth; var applicationUrlEth = deploymentDialog.applicationUrlEth;
applicationUrlEth = formatAppUrl(applicationUrlEth);
applicationUrlEth = formatAppUrl(applicationUrlEth);
deploymentStepChanged(qsTr("Registering application on the Ethereum network ...")); deploymentStepChanged(qsTr("Registering application on the Ethereum network ..."));
checkRegistration(applicationUrlEth, deploymentDialog.eth, function () { checkEthPath(applicationUrlEth, function () {
deploymentComplete(); deploymentComplete();
deployRessourcesDialog.text = qsTr("Register Web Application to finalize deployment."); deployRessourcesDialog.text = qsTr("Register Web Application to finalize deployment.");
deployRessourcesDialog.open(); deployRessourcesDialog.open();
setDefaultBlock(-1, function() {});
}); });
} }
function rpcCall(requests, callBack) function checkEthPath(dappUrl, callBack)
{
var jsonRpcUrl = "http://localhost:8080";
var rpcRequest = JSON.stringify(requests);
var httpRequest = new XMLHttpRequest();
httpRequest.open("POST", jsonRpcUrl, true);
httpRequest.setRequestHeader("Content-type", "application/json");
httpRequest.setRequestHeader("Content-length", rpcRequest.length);
httpRequest.setRequestHeader("Connection", "close");
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status !== 200)
{
var errorText = qsTr("Deployment error: Error while registering Dapp ") + httpRequest.status;
console.log(errorText);
deploymentError(errorText);
return;
}
callBack(httpRequest.status, httpRequest.responseText)
}
}
httpRequest.send(rpcRequest);
}
function checkRegistration(dappUrl, addr, callBack)
{ {
var requests = []; if (dappUrl.length === 1)
var data = ""; registerContentHash(deploymentDialog.eth, callBack); // we directly create a dapp under the root registrar.
if (dappUrl.length > 0) else
{ {
//checking path (register). // the first owned reigstrar must have been created to follow the path.
var str = createString(dappUrl[0]); var str = createString(dappUrl[0]);
data = "0x6be16bed" + str.encodeValueAsString(); var requests = [];
console.log("checking if path exists (register) => " + JSON.stringify(dappUrl));
requests.push({ requests.push({
//register()
jsonrpc: "2.0", jsonrpc: "2.0",
method: "eth_call", method: "eth_call",
params: [ { "to": '0x' + addr, "data": data } ], params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x6be16bed" + str.encodeValueAsString() } ],
id: jsonRpcRequestId++ id: jsonRpcRequestId++
}); });
rpcCall(requests, function (httpRequest, response) { rpcCall(requests, function (httpRequest, response) {
var address = JSON.parse(response)[0].result.replace('0x', ''); var res = JSON.parse(response);
if (address === "") var addr = normalizeAddress(res[0].result);
if (addr.replace(/0+/g, "") === "")
{ {
var errorTxt = qsTr("Path does not exists " + JSON.stringify(dappUrl) + " cannot continue"); var errorTxt = qsTr("Path does not exists " + JSON.stringify(dappUrl) + ". Please register using Registration Dapp. Aborting.");
deploymentError(errorTxt); deploymentError(errorTxt);
console.log(errorTxt); console.log(errorTxt);
return;
} }
else
{
dappUrl.splice(0, 1); dappUrl.splice(0, 1);
checkRegistration(dappUrl, address, callBack); checkRegistration(dappUrl, addr, callBack);
}
}); });
} }
}
function checkRegistration(dappUrl, addr, callBack)
{
if (dappUrl.length === 1)
registerContentHash(addr, callBack); // We do not create the register for the last part, just registering the content hash.
else else
{ {
var paramTitle = createString(projectModel.projectTitle); var txt = qsTr("Checking " + JSON.stringify(dappUrl) + " ... in registrar " + addr);
deploymentStepChanged(txt);
console.log(txt);
var requests = [];
var registrar = {}
var str = createString(dappUrl[0]);
requests.push({ requests.push({
//owner() //getOwner()
jsonrpc: "2.0", jsonrpc: "2.0",
method: "eth_call", method: "eth_call",
params: [ { "to": '0x' + addr, "data": "0xec7b9200" + paramTitle.encodeValueAsString() } ], params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x893d20e8" } ],
id: jsonRpcRequestId++ id: jsonRpcRequestId++
}); });
requests.push({ requests.push({
//accounts //register()
jsonrpc: "2.0", jsonrpc: "2.0",
method: "eth_accounts", method: "eth_call",
params: null, params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x6be16bed" + str.encodeValueAsString() } ],
id: jsonRpcRequestId++ id: jsonRpcRequestId++
}); });
rpcCall(requests, function (httpRequest, response) { rpcCall(requests, function (httpRequest, response) {
requests = [];
var res = JSON.parse(response); var res = JSON.parse(response);
var currentOwner = res[0].result; var nextAddr = normalizeAddress(res[1].result);
var noOwner = currentOwner.replace('0x', '').replace(/0/g, '') === ''; var errorTxt;
if (res[1].result === "0x")
if (noOwner)
{ {
errorTxt = qsTr("Error when creating new owned regsitrar. Please use the regsitration Dapp. Aborting");
deploymentError(errorTxt);
console.log(errorTxt);
}
else if (normalizeAddress(deploymentDialog.currentAccount) !== normalizeAddress(res[0].result))
{
errorTxt = qsTr("You are not the owner of " + dappUrl[0] + ". Aborting");
deploymentError(errorTxt);
console.log(errorTxt);
}
else if (nextAddr.replace(/0+/g, "") !== "")
{
dappUrl.splice(0, 1);
checkRegistration(dappUrl, nextAddr, callBack);
}
else
{
var txt = qsTr("Registering sub domain " + dappUrl[0] + " ...");
console.log(txt);
deploymentStepChanged(txt);
//current registrar is owned => ownedregistrar creation and continue.
requests = [];
requests.push({ requests.push({
//reserve()
jsonrpc: "2.0", jsonrpc: "2.0",
method: "eth_transact", method: "eth_transact",
params: [ { "to": '0x' + addr, "data": "0x1c83171b" + paramTitle.encodeValueAsString() } ], params: [ { "from": deploymentDialog.currentAccount, "gas": 20000, "code": "0x60056013565b61059e8061001d6000396000f35b33600081905550560060003560e060020a90048063019848921461009a578063449c2090146100af5780635d574e32146100cd5780635fd4b08a146100e1578063618242da146100f65780636be16bed1461010b5780636c4489b414610129578063893d20e8146101585780639607730714610173578063c284bc2a14610187578063e50f599a14610198578063e5811b35146101af578063ec7b9200146101cd57005b6100a560043561031b565b8060005260206000f35b6100ba6004356103a0565b80600160a060020a031660005260206000f35b6100db600435602435610537565b60006000f35b6100ec600435610529565b8060005260206000f35b6101016004356103dd565b8060005260206000f35b6101166004356103bd565b80600160a060020a031660005260206000f35b61013460043561034b565b82600160a060020a031660005281600160a060020a03166020528060405260606000f35b610160610341565b80600160a060020a031660005260206000f35b6101816004356024356102b4565b60006000f35b6101926004356103fd565b60006000f35b6101a96004356024356044356101f2565b60006000f35b6101ba6004356101eb565b80600160a060020a031660005260206000f35b6101d8600435610530565b80600160a060020a031660005260206000f35b6000919050565b600054600160a060020a031633600160a060020a031614610212576102af565b8160026000858152602001908152602001600020819055508061023457610287565b81600160a060020a0316837f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a3826001600084600160a060020a03168152602001908152602001600020819055505b827f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505050565b600054600160a060020a031633600160a060020a0316146102d457610317565b806002600084815260200190815260200160002060010181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b5050565b60006001600083600160a060020a03168152602001908152602001600020549050919050565b6000600054905090565b6000600060006002600085815260200190815260200160002054925060026000858152602001908152602001600020600101549150600260008581526020019081526020016000206002015490509193909250565b600060026000838152602001908152602001600020549050919050565b600060026000838152602001908152602001600020600101549050919050565b600060026000838152602001908152602001600020600201549050919050565b600054600160a060020a031633600160a060020a03161461041d57610526565b80600160006002600085815260200190815260200160002054600160a060020a031681526020019081526020016000205414610458576104d2565b6002600082815260200190815260200160002054600160a060020a0316817f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a36000600160006002600085815260200190815260200160002054600160a060020a03168152602001908152602001600020819055505b6002600082815260200190815260200160002060008101600090556001810160009055600281016000905550807f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b50565b6000919050565b6000919050565b600054600160a060020a031633600160a060020a0316146105575761059a565b806002600084815260200190815260200160002060020181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505056" } ],
id: jsonRpcRequestId++ id: jsonRpcRequestId++
}); });
}
else
{
var bOwner = false;
currentOwner = normalizeAddress(currentOwner);
for (var u in res[1].result)
{
if (normalizeAddress(res[1].result[u]) === currentOwner)
bOwner = true;
}
if (!bOwner) rpcCall(requests, function(httpRequest, response) {
var newCtrAddress = normalizeAddress(JSON.parse(response)[0].result);
requests = [];
var txt = qsTr("Please wait " + dappUrl[0] + " is registering ...");
deploymentStepChanged(txt);
console.log(txt);
deploymentDialog.waitForTrCountToIncrement(function(status) {
if (status === -1)
{ {
var errorTxt = qsTr("Current user is not the owner of this path. Cannot continue") trCountIncrementTimeOut();
deploymentError(errorTxt);
console.log(errorTxt);
return; return;
} }
var crLevel = createString(dappUrl[0]).encodeValueAsString();
requests.push({
//setRegister()
jsonrpc: "2.0",
method: "eth_transact",
params: [ { "from": deploymentDialog.currentAccount, "gas": 2000, "to": '0x' + addr, "data": "0x96077307" + crLevel + deploymentDialog.pad(newCtrAddress) } ],
id: jsonRpcRequestId++
});
rpcCall(requests, function(request, response){
dappUrl.splice(0, 1);
checkRegistration(dappUrl, newCtrAddress, callBack);
});
});
});
} }
console.log("setContentHash"); });
}
}
function trCountIncrementTimeOut()
{
var error = qsTr("Something went wrong during the deployment. Please verify the amount of gas for this transaction and check your balance.")
console.log(error);
deploymentError(error);
}
function registerContentHash(registrar, callBack)
{
var txt = qsTr("Finalizing Dapp registration ...");
deploymentStepChanged(txt);
console.log(txt);
var requests = [];
var paramTitle = createString(projectModel.projectTitle);
requests.push({ requests.push({
//setContent() //setContent()
jsonrpc: "2.0", jsonrpc: "2.0",
method: "eth_transact", method: "eth_transact",
params: [ { "to": '0x' + addr, "data": "0x5d574e32" + paramTitle.encodeValueAsString() + deploymentDialog.packageHash } ], params: [ { "from": deploymentDialog.currentAccount, "gas": 2000, "gasPrice": "10", "to": '0x' + registrar, "data": "0x5d574e32" + paramTitle.encodeValueAsString() + deploymentDialog.packageHash } ],
id: jsonRpcRequestId++ id: jsonRpcRequestId++
}); });
rpcCall(requests, function (httpRequest, response) { rpcCall(requests, function (httpRequest, response) {
callBack(); callBack();
}); });
});
}
} }
function registerToUrlHint() function registerToUrlHint()
@ -538,7 +587,7 @@ function registerToUrlHint()
//urlHint => suggestUrl //urlHint => suggestUrl
jsonrpc: "2.0", jsonrpc: "2.0",
method: "eth_transact", method: "eth_transact",
params: [ { "to": '0x' + deploymentDialog.urlHintContract, "data": "0x4983e19c" + deploymentDialog.packageHash + paramUrlHttp.encodeValueAsString() } ], params: [ { "to": '0x' + deploymentDialog.urlHintContract, "gas": 2000, "data": "0x4983e19c" + deploymentDialog.packageHash + paramUrlHttp.encodeValueAsString() } ],
id: jsonRpcRequestId++ id: jsonRpcRequestId++
}); });
@ -550,40 +599,35 @@ function registerToUrlHint()
function normalizeAddress(addr) function normalizeAddress(addr)
{ {
addr = addr.replace('0x', ''); addr = addr.replace('0x', '');
var i = 0; if (addr.length <= 40)
for (var k in addr) return addr;
{ var left = addr.length - 40;
if (addr[k] !== "0") return addr.substring(left);
break;
else
i++;
}
return addr.substring(i);
} }
function formatAppUrl(url) function formatAppUrl(url)
{ {
var slash = url.indexOf("/"); if (url.toLowerCase().indexOf("eth://") === 0)
var dot = url.indexOf("."); url = url.substring(6);
if (slash === -1 && dot === -1) if (url === "")
return url; return [projectModel.projectTitle];
if ((slash !== -1 && slash < dot) || dot === -1)
return url.split("/"); var ret;
if (url.indexOf("/") === -1)
ret = url.split('.').reverse();
else else
{ {
var dotted; var slash = url.indexOf("/");
var ret = []; var left = url.substring(0, slash);
if (slash !== -1) var leftA = left.split(".");
{ leftA.reverse();
ret.push(url.split("/"));
dotted = ret[0].split(".");
}
else
dotted = url.split(".");
for (var k in dotted) var right = url.substring(slash + 1);
ret.unshift(dotted[k]); var rightA = right.split('/');
return ret; ret = leftA.concat(rightA);
} }
if (ret[0].toLowerCase() === "eth")
ret.splice(0, 1);
ret.push(projectModel.projectTitle);
return ret;
} }

24
mix/qml/js/TransactionHelper.js

@ -10,3 +10,27 @@ function defaultTransaction()
parameters: {} parameters: {}
}; };
} }
function rpcCall(requests, callBack)
{
var jsonRpcUrl = "http://localhost:8080";
var rpcRequest = JSON.stringify(requests);
var httpRequest = new XMLHttpRequest();
httpRequest.open("POST", jsonRpcUrl, true);
httpRequest.setRequestHeader("Content-type", "application/json");
httpRequest.setRequestHeader("Content-length", rpcRequest.length);
httpRequest.setRequestHeader("Connection", "close");
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status !== 200)
{
var errorText = qsTr("Deployment error: Error while registering Dapp ") + httpRequest.status;
console.log(errorText);
deploymentError(errorText);
}
callBack(httpRequest.status, httpRequest.responseText)
}
}
httpRequest.send(rpcRequest);
}

13
mix/qml/main.qml

@ -56,7 +56,7 @@ ApplicationWindow {
MenuItem { action: toggleTransactionLogAction } MenuItem { action: toggleTransactionLogAction }
MenuItem { action: toggleWebPreviewAction } MenuItem { action: toggleWebPreviewAction }
MenuItem { action: toggleWebPreviewOrientationAction } MenuItem { action: toggleWebPreviewOrientationAction }
MenuItem { action: toggleCallsInLog } //MenuItem { action: toggleCallsInLog }
} }
} }
@ -92,7 +92,7 @@ ApplicationWindow {
Action { Action {
id: mineAction id: mineAction
text: qsTr("Mine") text: qsTr("New Block")
shortcut: "Ctrl+M" shortcut: "Ctrl+M"
onTriggered: clientModel.mine(); onTriggered: clientModel.mine();
enabled: codeModel.hasContract && !clientModel.running && !clientModel.mining enabled: codeModel.hasContract && !clientModel.running && !clientModel.mining
@ -165,15 +165,6 @@ ApplicationWindow {
onTriggered: mainContent.toggleWebPreviewOrientation(); onTriggered: mainContent.toggleWebPreviewOrientation();
} }
Action {
id: toggleCallsInLog
text: qsTr("Show Calls in Transaction Log")
shortcut: ""
checkable: true
checked: mainContent.rightPane.transactionLog.showLogs
onTriggered: mainContent.rightPane.transactionLog.showLogs = !mainContent.rightPane.transactionLog.showLogs
}
Action { Action {
id: toggleRunOnLoadAction id: toggleRunOnLoadAction
text: qsTr("Load State on Startup") text: qsTr("Load State on Startup")

34
test/SolidityParser.cpp

@ -367,6 +367,40 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
BOOST_CHECK_NO_THROW(parseText(text)); BOOST_CHECK_NO_THROW(parseText(text));
} }
BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter)
{
char const* text = R"(
contract test {
function fun(var a) {}
}
)";
BOOST_CHECK_THROW(parseText(text), ParserError);
}
BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
{
char const* text = R"(
contract test {
function fun() {
mapping(var=>hash) d;
}
}
)";
BOOST_CHECK_THROW(parseText(text), ParserError);
}
BOOST_AUTO_TEST_CASE(variable_definition_in_function_return)
{
char const* text = R"(
contract test {
function fun() returns(var d) {
return 1;
}
}
)";
BOOST_CHECK_THROW(parseText(text), ParserError);
}
BOOST_AUTO_TEST_CASE(operator_expression) BOOST_AUTO_TEST_CASE(operator_expression)
{ {
char const* text = "contract test {\n" char const* text = "contract test {\n"

5
test/block.cpp

@ -506,6 +506,11 @@ BOOST_AUTO_TEST_CASE(blInvalidHeaderTest)
dev::test::executeTests("blInvalidHeaderTest", "/BlockTests", dev::test::doBlockTests); dev::test::executeTests("blInvalidHeaderTest", "/BlockTests", dev::test::doBlockTests);
} }
BOOST_AUTO_TEST_CASE(blForkBlocks)
{
dev::test::executeTests("blForkBlocks", "/BlockTests", dev::test::doBlockTests);
}
BOOST_AUTO_TEST_CASE(userDefinedFileBl) BOOST_AUTO_TEST_CASE(userDefinedFileBl)
{ {
dev::test::userDefinedTest("--bltest", dev::test::doBlockTests); dev::test::userDefinedTest("--bltest", dev::test::doBlockTests);

69
test/stMemoryStressTestFiller.json

@ -0,0 +1,69 @@
{
"mload32bitBound": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "17592320524892",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 1 ]] (MLOAD 4294967296) } ",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "175923205248920",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "17592320524892",
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"mload32bitBound2": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "37791080412587",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 1 ]] (MLOAD 6294967296) } ",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "377910804219850",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "37791080412587",
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
}
}

68
test/stMemoryTestFiller.json

@ -67,74 +67,6 @@
} }
}, },
"mload32bitBound": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "17592320524892",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 1 ]] (MLOAD 4294967296) } ",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "175923205248920",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "17592320524892",
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"mload32bitBound2": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "37791080412587",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 1 ]] (MLOAD 6294967296) } ",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "377910804219850",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "37791080412587",
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"mem32kb": { "mem32kb": {
"env" : { "env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",

330
test/stQuadraticComplexityTestFiller.json

File diff suppressed because one or more lines are too long

128
test/stRefundTestFiller.json

@ -304,33 +304,135 @@
"data" : "" "data" : ""
} }
}, },
"RefundOverflow" : { "refund_CallA" : {
"env" : { "env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentDifficulty" : "45678256",
"currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"currentNumber" : "0", "currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1, "currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
}, },
"pre" : { "pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "400", "balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0", "nonce" : "0",
"code" : "{ [[ 0 ]] (CALL 500 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}",
"storage" : { "storage" : {
"0x01" : "0x01"
} }
},
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 1 ]] 0 }",
"storage" : {
"0x01" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "2000",
"nonce" : "0",
"code" : "",
"storage": {}
} }
}, },
"transaction" : { "transaction" : {
"data" : "",
"gasLimit" : "5789604461865809771178549250434395392663499233282028201972879200395656482016",
"gasPrice" : "20",
"nonce" : "0", "nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "1500",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "data" : ""
"value" : ""
} }
},
"refund_CallA2" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (CALL 50 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}",
"storage" : {
"0x01" : "0x01"
} }
},
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 1 ]] 0 }",
"storage" : {
"0x01" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "850",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund_CallA_OOG" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (CALL 1 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}",
"storage" : {
"0x01" : "0x01"
}
},
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 1 ]] 0 }",
"storage" : {
"0x01" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "850",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
}
} }

18
test/state.cpp

@ -177,6 +177,24 @@ BOOST_AUTO_TEST_CASE(stQuadraticComplexityTest)
} }
} }
BOOST_AUTO_TEST_CASE(stMemoryStressTest)
{
for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
{
string arg = boost::unit_test::framework::master_test_suite().argv[i];
if (arg == "--memory" || arg == "--all")
{
auto start = chrono::steady_clock::now();
dev::test::executeTests("stMemoryStressTest", "/StateTests", dev::test::doStateTests);
auto end = chrono::steady_clock::now();
auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
cnote << "test duration: " << duration.count() << " milliseconds.\n";
}
}
}
BOOST_AUTO_TEST_CASE(stSolidityTest) BOOST_AUTO_TEST_CASE(stSolidityTest)
{ {
dev::test::executeTests("stSolidityTest", "/StateTests", dev::test::doStateTests); dev::test::executeTests("stSolidityTest", "/StateTests", dev::test::doStateTests);

224
test/vmArithmeticTestFiller.json

@ -1401,6 +1401,118 @@
} }
}, },
"addmod1_overflowDiff": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADDMOD (- 0 1) (- 0 2) 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"addmod1_overflow2": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADDMOD (- 0 1) 0 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"addmod1_overflow3": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADDMOD (- 0 1) 1 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"addmod1_overflow3": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADDMOD (- 0 1) 2 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"addmod2": { "addmod2": {
"env" : { "env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
@ -1682,6 +1794,118 @@
} }
}, },
"mulmod1_overflow": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (MULMOD (- 0 1) 2 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"mulmod1_overflow2": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (MULMOD 57896044618658097711785492504343953926634992332820282019728792003956564819968 2 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"mulmod1_overflow3": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (MULMOD 57896044618658097711785492504343953926634992332820282019728792003956564819967 2 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"mulmod1_overflow4": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (MULMOD 57896044618658097711785492504343953926634992332820282019728792003956564819969 2 5) } ",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f2947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"mulmod2": { "mulmod2": {
"env" : { "env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",

85
test/vmIOandFlowOperationsTestFiller.json

@ -727,6 +727,91 @@
} }
}, },
"jumpTo1InstructionafterJump": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "0x6003565b6001600055",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"jumpTo1InstructionafterJump_noJumpDest": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "0x6003566001600055",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"jumpTo1InstructionafterJump_jumpdestFirstInstruction": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : "1",
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "0x5b6003565b6001600055",
"storage": {}
}
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000",
"data" : "",
"gasPrice" : "100000000000000",
"gas" : "10000"
}
},
"jumpDynamicJumpSameDest": { "jumpDynamicJumpSameDest": {
"env" : { "env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",

Loading…
Cancel
Save