From 91d453db92867f2378c7d2e9a2e0f8ef8e9f1b5a Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 20 Feb 2015 22:36:23 +0100 Subject: [PATCH 1/3] DApp load in AZ --- alethzero/CMakeLists.txt | 1 + alethzero/DappHost.cpp | 141 ++++++++++++++++++++++++++ alethzero/DappHost.h | 58 +++++++++++ alethzero/DappLoader.cpp | 203 +++++++++++++++++++++++++++++++++++++ alethzero/DappLoader.h | 94 +++++++++++++++++ alethzero/MainWin.cpp | 71 +++++++++---- alethzero/MainWin.h | 14 ++- alethzero/Transact.cpp | 4 +- alethzero/WebPage.cpp | 29 ++++++ alethzero/WebPage.h | 37 +++++++ mix/FileIo.cpp | 2 +- mix/qml/js/ProjectModel.js | 20 ++-- 12 files changed, 636 insertions(+), 38 deletions(-) create mode 100644 alethzero/DappHost.cpp create mode 100644 alethzero/DappHost.h create mode 100644 alethzero/DappLoader.cpp create mode 100644 alethzero/DappLoader.h create mode 100644 alethzero/WebPage.cpp create mode 100644 alethzero/WebPage.h diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index cbc9e087a..49c847a16 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -56,6 +56,7 @@ target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) target_link_libraries(${EXECUTABLE} natspec) +target_link_libraries(${EXECUTABLE} ${MHD_LIBRARIES}) if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) target_link_libraries(${EXECUTABLE} serpent) diff --git a/alethzero/DappHost.cpp b/alethzero/DappHost.cpp new file mode 100644 index 000000000..22ba41c6c --- /dev/null +++ b/alethzero/DappHost.cpp @@ -0,0 +1,141 @@ +/* + 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 . +*/ +/** @file DappHost.cpp + * @author Arkadiy Paronyan + * @date 2015 + */ + +#include +#include +#include +#include +#include "DappHost.h" + +using namespace dev; + +DappHost::DappHost(int _port, int _threads): + m_port(_port), m_threads(_threads), m_running(false), m_daemon(nullptr) +{ + startListening(); +} + +DappHost::~DappHost() +{ + stopListening(); +} + +void DappHost::startListening() +{ + if(!this->m_running) + { + this->m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, this->m_port, nullptr, nullptr, &DappHost::callback, this, MHD_OPTION_THREAD_POOL_SIZE, this->m_threads, MHD_OPTION_END); + if (this->m_daemon != nullptr) + this->m_running = true; + } +} + +void DappHost::stopListening() +{ + if(this->m_running) + { + MHD_stop_daemon(this->m_daemon); + this->m_running = false; + } +} + +void DappHost::sendOptionsResponse(MHD_Connection* _connection) +{ + MHD_Response *result = MHD_create_response_from_data(0, NULL, 0, 1); + MHD_add_response_header(result, "Allow", "GET, OPTIONS"); + //MHD_add_response_header(result, "Access-Control-Allow-Origin", "*"); + MHD_add_response_header(result, "Access-Control-Allow-Headers", "origin, content-type, accept"); + MHD_add_response_header(result, "DAV", "1"); + MHD_queue_response(_connection, MHD_HTTP_OK, result); + MHD_destroy_response(result); +} + +void DappHost::sendNotAllowedResponse(MHD_Connection* _connection) +{ + MHD_Response *result = MHD_create_response_from_data(0, NULL, 0, 1); + MHD_add_response_header(result, "Allow", "GET, OPTIONS"); + MHD_queue_response(_connection, MHD_HTTP_METHOD_NOT_ALLOWED, result); + MHD_destroy_response(result); +} + +void DappHost::sendResponse(std::string const& _url, MHD_Connection* _connection) +{ + QUrl requestUrl(QString::fromStdString(_url)); + QString path = requestUrl.path().toLower(); + if (path.isEmpty()) + path = "/"; + + bytesConstRef response; + unsigned code = MHD_HTTP_NOT_FOUND; + std::string contentType; + + while (!path.isEmpty()) + { + auto iter = m_entriesByPath.find(path); + if (iter != m_entriesByPath.end()) + { + ManifestEntry const* entry = iter->second; + auto contentIter = m_dapp.content.find(entry->hash); + if (contentIter == m_dapp.content.end()) + break; + + response = bytesConstRef(contentIter->second.data(), contentIter->second.size()); + code = entry->httpStatus != 0 ? entry->httpStatus : MHD_HTTP_OK; + contentType = entry->contentType; + break; + } + path.truncate(path.length() - 1); + path = path.mid(0, path.lastIndexOf('/')); + } + + MHD_Response *result = MHD_create_response_from_data(response.size(), const_cast(response.data()), 0, 1); + if (!contentType.empty()) + MHD_add_response_header(result, "Content-Type", contentType.c_str()); + //MHD_add_response_header(result, "Access-Control-Allow-Origin", "*"); + MHD_queue_response(_connection, code, result); + MHD_destroy_response(result); +} + +int DappHost::callback(void* _cls, MHD_Connection* _connection, char const* _url, char const* _method, char const* _version, char const* _uploadData, size_t* _uploadDataSize, void** _conCls) +{ + (void)_version; + (void)_uploadData; + (void)_uploadDataSize; + (void)_conCls; + DappHost* host = static_cast(_cls); + if (std::string("GET") == _method) + host->sendResponse(std::string(_url), _connection); + else if (std::string("OPTIONS") == _method) + host->sendOptionsResponse(_connection); + else + host->sendNotAllowedResponse(_connection); + return MHD_YES; +} + +QUrl DappHost::hostDapp(Dapp&& _dapp) +{ + m_dapp = std::move(_dapp); + m_entriesByPath.clear(); + for (ManifestEntry const& entry: m_dapp.manifest.entries) + m_entriesByPath[QString::fromStdString(entry.path)] = &entry; + + return QUrl(QString("http://localhost:%1/").arg(m_port)); +} diff --git a/alethzero/DappHost.h b/alethzero/DappHost.h new file mode 100644 index 000000000..985bd34d9 --- /dev/null +++ b/alethzero/DappHost.h @@ -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 . +*/ +/** @file DappHost.h + * @author Arkadiy Paronyan + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include "DappLoader.h" + +struct MHD_Daemon; +struct MHD_Connection; + +/// DApp web server. Servers web content, resolves paths by hashes +class DappHost +{ +public: + /// @param _port Network pork to listen for incoming connections + /// @param _threads Max number of threads to process requests + DappHost(int _port, int _threads = 10); + virtual ~DappHost(); + /// Load and host a dapp. Previsous dapp in discarded. Synchronous + QUrl hostDapp(Dapp&& _dapp); + +private: + void startListening(); + void stopListening(); + void sendOptionsResponse(MHD_Connection* _connection); + void sendNotAllowedResponse(MHD_Connection* _connection); + void sendResponse(std::string const& _url, MHD_Connection* _connection); + static int callback(void* _cls, MHD_Connection* _connection, char const* _url, char const* _method, char const* _version, char const* _uploadData, size_t* _uploadDataSize, void** _conCls); + + int m_port; + int m_threads; + bool m_running; + MHD_Daemon* m_daemon; + Dapp m_dapp; + std::map m_entriesByPath; +}; + diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp new file mode 100644 index 000000000..41ac22b23 --- /dev/null +++ b/alethzero/DappLoader.cpp @@ -0,0 +1,203 @@ +/* + 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 . +*/ +/** @file DappLoader.cpp + * @author Arkadiy Paronyan + * @date 2015 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "DappLoader.h" + +using namespace dev; +using namespace dev::eth; +using namespace dev::crypto; + +Address c_registrar = Address("0000000000000000000000000000000000000a28"); +Address c_urlHint = Address("0000000000000000000000000000000000000a29"); + +QString contentsOfQResource(std::string const& res); + +DappLoader::DappLoader(QObject* _parent, WebThreeDirect* _web3): + QObject(_parent), m_web3(_web3) +{ + connect(&m_net, &QNetworkAccessManager::finished, this, &DappLoader::downloadComplete); +} + +DappLocation DappLoader::resolveAppUri(QString const& _uri) +{ + QUrl url(_uri); + if (!url.scheme().isEmpty() && url.scheme() != "eth") + throw dev::Exception(); //TODO: + + QStringList parts = url.host().split('.', QString::SkipEmptyParts); + QStringList domainParts; + std::reverse(parts.begin(), parts.end()); + parts.append(url.path().split('/', QString::SkipEmptyParts)); + + Address address = c_registrar; + Address lastAddress; + int partIndex = 0; + + h256 contentHash; + + while (address && partIndex < parts.length()) + { + lastAddress = address; + string32 name = { 0 }; + QByteArray utf8 = parts[partIndex].toUtf8(); + std::copy(utf8.data(), utf8.data() + utf8.size(), name.data()); + address = abiOut
(web3()->ethereum()->call(address, abiIn("addr(string32)", name))); + domainParts.append(parts[partIndex]); + if (!address) + { + //we have the address of the last part, try to get content hash + contentHash = abiOut(web3()->ethereum()->call(lastAddress, abiIn("content(string32)", name))); + if (!contentHash) + throw dev::Exception() << errinfo_comment("Can't resolve address"); + } + ++partIndex; + } + + + string32 contentUrl = abiOut(web3()->ethereum()->call(c_urlHint, abiIn("url(hash256)", contentHash))); + QString domain = domainParts.join('/'); + parts.erase(parts.begin(), parts.begin() + partIndex); + QString path = parts.join('/'); + QString contentUrlString = QString::fromUtf8(std::string(contentUrl.data(), contentUrl.size()).c_str()); + if (!contentUrlString.startsWith("http://") || !contentUrlString.startsWith("https://")) + contentUrlString = "http://" + contentUrlString; + return DappLocation { domain, path, contentUrlString, contentHash }; +} + +void DappLoader::downloadComplete(QNetworkReply* _reply) +{ + try + { + //try to interpret as rlp + QByteArray data = _reply->readAll(); + _reply->deleteLater(); + + h256 expected = m_uriHashes[_reply->request().url()]; + bytes package(reinterpret_cast(data.constData()), reinterpret_cast(data.constData() + data.size())); + Secp256k1 dec; + dec.decrypt(expected, package); + h256 got = sha3(package); + if (got != expected) + { + //try base64 + data = QByteArray::fromBase64(data); + package = bytes(reinterpret_cast(data.constData()), reinterpret_cast(data.constData() + data.size())); + dec.decrypt(expected, package); + got = sha3(package); + if (got != expected) + throw dev::Exception() << errinfo_comment("Dapp content hash does not match"); + } + + RLP rlp(package); + loadDapp(rlp); + } + catch (...) + { + qWarning() << tr("Error downloading DApp: ") << boost::current_exception_diagnostic_information().c_str(); + emit dappError(); + } + +} + +void DappLoader::loadDapp(RLP const& _rlp) +{ + Dapp dapp; + unsigned len = _rlp.itemCountStrict(); + dapp.manifest = loadManifest(_rlp[0].toString()); + for (unsigned c = 1; c < len; ++c) + { + bytesConstRef content = _rlp[c].toBytesConstRef(); + h256 hash = sha3(content); + auto entry = std::find_if(dapp.manifest.entries.cbegin(), dapp.manifest.entries.cend(), [=](ManifestEntry const& _e) { return _e.hash == hash; }); + if (entry != dapp.manifest.entries.cend()) + { + if (entry->path == "/deployment.js") + { + //inject web3 code + QString code; + code += contentsOfQResource(":/js/bignumber.min.js"); + code += "\n"; + code += contentsOfQResource(":/js/webthree.js"); + code += "\n"; + code += contentsOfQResource(":/js/setup.js"); + code += "\n"; + QByteArray res = code.toLatin1(); + bytes b(res.data(), res.data() + res.size()); + b.insert(b.end(), content.begin(), content.end()); + dapp.content[hash] = b; + } + else + dapp.content[hash] = content.toBytes(); + } + else + throw dev::Exception() << errinfo_comment("Dapp content hash does not match"); + } + emit dappReady(dapp); +} + +Manifest DappLoader::loadManifest(std::string const& _manifest) +{ + /// https://github.com/ethereum/go-ethereum/wiki/URL-Scheme + Manifest manifest; + Json::Reader jsonReader; + Json::Value root; + jsonReader.parse(_manifest, root, false); + + Json::Value entries = root["entries"]; + for (Json::ValueIterator it = entries.begin(); it != entries.end(); ++it) + { + Json::Value const& entryValue = *it; + std::string path = entryValue["path"].asString(); + if (path.size() == 0 || path[0] != '/') + path = "/" + path; + std::string contentType = entryValue["contentType"].asString(); + std::string strHash = entryValue["hash"].asString(); + if (strHash.length() == 64) + strHash = "0x" + strHash; + h256 hash = jsToFixed<32>(strHash); + unsigned httpStatus = entryValue["status"].asInt(); + manifest.entries.push_back(ManifestEntry{ path, hash, contentType, httpStatus }); + } + return manifest; +} + +void DappLoader::loadDapp(QString const& _uri) +{ + DappLocation location = resolveAppUri(_uri); + QUrl uri(location.contentUri); + QNetworkRequest request(uri); + m_uriHashes[uri] = location.contentHash; + m_net.get(request); +} + diff --git a/alethzero/DappLoader.h b/alethzero/DappLoader.h new file mode 100644 index 000000000..463b65d0a --- /dev/null +++ b/alethzero/DappLoader.h @@ -0,0 +1,94 @@ +/* + 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 . +*/ +/** @file DappLoader.h + * @author Arkadiy Paronyan + * @date 2015 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace dev +{ + class WebThreeDirect; + class RLP; +} + +struct ManifestEntry +{ + std::string path; + dev::h256 hash; + std::string contentType; + unsigned httpStatus; +}; + +struct Manifest +{ + std::vector entries; +}; + +struct Dapp +{ + Manifest manifest; + std::map content; +}; + + +struct DappLocation +{ + QString canonDomain; + QString path; + QString contentUri; + dev::h256 contentHash; +}; + +///Downloads, unpacks and prepares DApps for hosting +class DappLoader: public QObject +{ + Q_OBJECT +public: + DappLoader(QObject* _parent, dev::WebThreeDirect* _web3); + ///Load a new DApp. Resolves a name with a name reg contract. Asynchronous. dappReady is emitted once everything is read, dappError othervise + ///@param _uri Eth name path + void loadDapp(QString const& _uri); + +signals: + void dappReady(Dapp& _dapp); + void dappError(); + +private slots: + void downloadComplete(QNetworkReply* _reply); + +private: + dev::WebThreeDirect* web3() const { return m_web3; } + DappLocation resolveAppUri(QString const& _uri); + void loadDapp(dev::RLP const& _rlp); + Manifest loadManifest(std::string const& _manifest); + + dev::WebThreeDirect* m_web3; + QNetworkAccessManager m_net; + std::map m_uriHashes; +}; + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 88b9103cb..ab8e07e7c 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -19,7 +19,6 @@ * @date 2014 */ -#define QWEBENGINEINSPECTOR 1 #include // Make sure boost/asio.hpp is included before windows.h. @@ -68,6 +67,9 @@ #include "OurWebThreeStubServer.h" #include "Transact.h" #include "Debugger.h" +#include "DappLoader.h" +#include "DappHost.h" +#include "WebPage.h" #include "ui_Main.h" using namespace std; using namespace dev; @@ -116,7 +118,9 @@ Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b"); Main::Main(QWidget *parent) : QMainWindow(parent), ui(new Ui::Main), - m_transact(this, this) + m_transact(this, this), + m_dappLoader(nullptr), + m_webPage(nullptr) { QtWebEngine::initialize(); setWindowFlags(Qt::Window); @@ -166,10 +170,12 @@ Main::Main(QWidget *parent) : m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); + WebPage* webPage= new WebPage(this); + m_webPage = webPage; + connect(webPage, &WebPage::consoleMessage, [this](QString const& _msg) { Main::addConsoleMessage(_msg, QString()); }); + ui->webView->setPage(m_webPage); connect(ui->webView, &QWebEngineView::loadFinished, [this]() { -// f->disconnect(); -// f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership); auto f = ui->webView->page(); f->runJavaScript(contentsOfQResource(":/js/bignumber.min.js")); f->runJavaScript(contentsOfQResource(":/js/webthree.js")); @@ -181,6 +187,9 @@ Main::Main(QWidget *parent) : ui->tabWidget->setTabText(0, ui->webView->title()); }); + m_dappHost.reset(new DappHost(8081)); + m_dappLoader = new DappLoader(this, web3()); + connect(m_dappLoader, &DappLoader::dappReady, this, &Main::dappLoaded); // ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true); // QWebEngineInspector* inspector = new QWebEngineInspector(); // inspector->setPage(page); @@ -425,13 +434,7 @@ void Main::eval(QString const& _js) s = "" + jsonEv.toString().toHtmlEscaped() + ""; else s = "unknown type"; - m_consoleHistory.push_back(qMakePair(_js, s)); - s = "" Div(Mono "position: absolute; bottom: 0; border: 0px; margin: 0px; width: 100%"); - for (auto const& i: m_consoleHistory) - s += "
>" + i.first.toHtmlEscaped() + "
" - "
 " + i.second + "
"; - s += ""; - ui->jsConsole->setHtml(s); + addConsoleMessage(_js, s); }; ui->webView->page()->runJavaScript("JSON.stringify(___RET)", f2); }; @@ -439,6 +442,17 @@ void Main::eval(QString const& _js) ui->webView->page()->runJavaScript(c, f); } +void Main::addConsoleMessage(QString const& _js, QString const& _s) +{ + m_consoleHistory.push_back(qMakePair(_js, _s)); + QString r = "" Div(Mono "position: absolute; bottom: 0; border: 0px; margin: 0px; width: 100%"); + for (auto const& i: m_consoleHistory) + r += "
>" + i.first.toHtmlEscaped() + "
" + "
 " + i.second + "
"; + r += ""; + ui->jsConsole->setHtml(r); +} + static Public stringToPublic(QString const& _a) { string sn = _a.toStdString(); @@ -780,15 +794,28 @@ void Main::on_jitvm_triggered() void Main::on_urlEdit_returnPressed() { QString s = ui->urlEdit->text(); - QRegExp r("([a-z]+://)?([^/]*)(.*)"); - if (r.exactMatch(s)) - if (r.cap(2).isEmpty()) - s = (r.cap(1).isEmpty() ? "file://" : r.cap(1)) + r.cap(3); + QUrl url(s); + if (url.scheme().isEmpty() || url.scheme() == "eth") + { + try + { + //try do resolve dapp url + m_dappLoader->loadDapp(s); + } + catch (...) + { + qWarning() << boost::current_exception_diagnostic_information().c_str(); + } + } + + if (url.scheme().isEmpty()) + if (url.path().indexOf('/') < url.path().indexOf('.')) + url.setScheme("file"); else - s = (r.cap(1).isEmpty() ? "http://" : r.cap(1)) + lookup(r.cap(2)) + r.cap(3); - else{} - qDebug() << s; - ui->webView->setUrl(s); + url.setScheme("http"); + else {} + qDebug() << url.toString(); + ui->webView->page()->setUrl(url); } void Main::on_nameReg_textChanged() @@ -1835,3 +1862,9 @@ void Main::refreshWhispers() ui->whispers->addItem(item); } } + +void Main::dappLoaded(Dapp& _dapp) +{ + QUrl url = m_dappHost->hostDapp(std::move(_dapp)); + ui->webView->page()->setUrl(url); +} diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 378877468..ba89b455a 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -54,8 +54,11 @@ namespace jsonrpc { class HttpServer; } -class QQuickView; +class QWebEnginePage; class OurWebThreeStubServer; +class DappLoader; +class DappHost; +struct Dapp; using WatchHandler = std::function; @@ -99,6 +102,7 @@ public slots: private slots: void eval(QString const& _js); + void addConsoleMessage(QString const& _js, QString const& _s); // Application void on_about_triggered(); @@ -172,6 +176,9 @@ private slots: void refreshBlockChain(); void addNewId(QString _ids); + // Dapps + void dappLoaded(Dapp& _dapp); //qt does not support rvalue refs for signals + signals: void poll(); @@ -234,8 +241,6 @@ private: QString m_privateChain; dev::Address m_nameReg; - QNetworkAccessManager m_webCtrl; - QList> m_consoleHistory; QMutex m_logLock; QString m_logHistory; @@ -248,4 +253,7 @@ private: NatspecHandler m_natSpecDB; Transact m_transact; + std::unique_ptr m_dappHost; + DappLoader* m_dappLoader; + QWebEnginePage* m_webPage; }; diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index df6c5258d..640ffe3d8 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -175,7 +175,7 @@ void Transact::rejigData() m_data = fromHex(src); else if (sourceIsSolidity(src)) { - dev::solidity::CompilerStack compiler; + dev::solidity::CompilerStack compiler(true); try { // compiler.addSources(dev::solidity::StandardSources); @@ -287,7 +287,7 @@ void Transact::on_send_clicked() if (sourceIsSolidity(src)) try { - dev::solidity::CompilerStack compiler; + dev::solidity::CompilerStack compiler(true); m_data = compiler.compile(src, ui->optimize->isChecked()); for (string const& s: compiler.getContractNames()) { diff --git a/alethzero/WebPage.cpp b/alethzero/WebPage.cpp new file mode 100644 index 000000000..f9a307a53 --- /dev/null +++ b/alethzero/WebPage.cpp @@ -0,0 +1,29 @@ +/* + 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 . +*/ +/** @file WebPage.cpp + * @author Arkadiy Paronyan arkadiy@ethdev.com> + * @date 2015 + */ + +#pragma GCC diagnostic ignored "-Wpedantic" //QtWebEngineWidgets/qwebenginecertificateerror.h:78:348: error: extra ';' +#include "WebPage.h" + +void WebPage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel _level, const QString& _message, int _lineNumber, const QString& _sourceID) +{ + QString prefix = _level == QWebEnginePage::ErrorMessageLevel ? "error" : _level == QWebEnginePage::WarningMessageLevel ? "warning" : ""; + emit consoleMessage(QString("%1(%2:%3):%4").arg(prefix).arg(_sourceID).arg(_lineNumber).arg(_message)); +} diff --git a/alethzero/WebPage.h b/alethzero/WebPage.h new file mode 100644 index 000000000..bfb67e749 --- /dev/null +++ b/alethzero/WebPage.h @@ -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 . +*/ +/** @file WebPage.h + * @author Arkadiy Paronyan arkadiy@ethdev.com> + * @date 2015 + */ + +#pragma once + +#include +#include + +class WebPage: public QWebEnginePage +{ + Q_OBJECT +public: + WebPage(QObject* _parent): QWebEnginePage(_parent) { } +signals: + void consoleMessage(QString const& _msg); + +protected: + void javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel _level, const QString& _message, int _lineNumber, const QString& _sourceID) override; +}; diff --git a/mix/FileIo.cpp b/mix/FileIo.cpp index 449512975..bf0351ee3 100644 --- a/mix/FileIo.cpp +++ b/mix/FileIo.cpp @@ -158,6 +158,7 @@ QStringList FileIo::makePackage(QString const& _deploymentFolder) } rlpStr.appendList(k); + manifest["entries"] = entries; std::stringstream jsonStr; jsonStr << manifest; QByteArray b = QString::fromStdString(jsonStr.str()).toUtf8(); @@ -166,7 +167,6 @@ QStringList FileIo::makePackage(QString const& _deploymentFolder) for (unsigned int k = 0; k < files.size(); k++) rlpStr.append(files.at(k)); - manifest["entries"] = entries; bytes dapp = rlpStr.out(); dev::h256 dappHash = dev::sha3(dapp); //encrypt diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index d308119ae..35c793dd3 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -377,8 +377,6 @@ function finalizeDeployment(deploymentId, addresses) { else insertAt += 6; html = html.substr(0, insertAt) + - "" + - "" + "" + html.substr(insertAt); fileIo.writeFile(deploymentDir + doc.fileName, html); @@ -388,9 +386,8 @@ function finalizeDeployment(deploymentId, addresses) { } //write deployment js var deploymentJs = - "// Autogenerated by Mix\n" + - "web3 = require(\"web3\");\n" + - "contracts = {};\n"; + "// Autogenerated by Mix\n" + + "contracts = {};\n"; for (var c in codeModel.contracts) { var contractAccessor = "contracts[\"" + codeModel.contracts[c].contract.name + "\"]"; deploymentJs += contractAccessor + " = {\n" + @@ -400,9 +397,6 @@ function finalizeDeployment(deploymentId, addresses) { contractAccessor + ".contract = web3.eth.contract(" + contractAccessor + ".address, " + contractAccessor + ".interface);\n"; } fileIo.writeFile(deploymentDir + "deployment.js", deploymentJs); - //copy scripts - fileIo.copyFile("qrc:///js/bignumber.min.js", deploymentDir + "bignumber.min.js"); - fileIo.copyFile("qrc:///js/webthree.js", deploymentDir + "ethereum.js"); deploymentAddresses = addresses; saveProject(); @@ -435,7 +429,7 @@ function checkEthPath(dappUrl, callBack) //register() jsonrpc: "2.0", method: "eth_call", - params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x6be16bed" + str.encodeValueAsString() } ], + params: [ { "gas": 150000, "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x6be16bed" + str.encodeValueAsString() } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -472,7 +466,7 @@ function checkRegistration(dappUrl, addr, callBack) //getOwner() jsonrpc: "2.0", method: "eth_call", - params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x893d20e8" } ], + params: [ { "gas" : 2000, "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x893d20e8" } ], id: jsonRpcRequestId++ }); @@ -537,7 +531,7 @@ function checkRegistration(dappUrl, addr, callBack) //setRegister() jsonrpc: "2.0", method: "eth_transact", - params: [ { "from": deploymentDialog.currentAccount, "gas": 2000, "to": '0x' + addr, "data": "0x96077307" + crLevel + deploymentDialog.pad(newCtrAddress) } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "to": '0x' + addr, "data": "0x96077307" + crLevel + deploymentDialog.pad(newCtrAddress) } ], id: jsonRpcRequestId++ }); @@ -570,7 +564,7 @@ function registerContentHash(registrar, callBack) //setContent() jsonrpc: "2.0", method: "eth_transact", - params: [ { "from": deploymentDialog.currentAccount, "gas": 2000, "gasPrice": "10", "to": '0x' + registrar, "data": "0x5d574e32" + paramTitle.encodeValueAsString() + deploymentDialog.packageHash } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "gasPrice": "10", "to": '0x' + registrar, "data": "0x5d574e32" + paramTitle.encodeValueAsString() + deploymentDialog.packageHash } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -587,7 +581,7 @@ function registerToUrlHint() //urlHint => suggestUrl jsonrpc: "2.0", method: "eth_transact", - params: [ { "to": '0x' + deploymentDialog.urlHintContract, "gas": 2000, "data": "0x4983e19c" + deploymentDialog.packageHash + paramUrlHttp.encodeValueAsString() } ], + params: [ { "to": '0x' + deploymentDialog.urlHintContract, "gas": 30000, "data": "0x4983e19c" + deploymentDialog.packageHash + paramUrlHttp.encodeValueAsString() } ], id: jsonRpcRequestId++ }); From 33d4f6049957a5bb4f89b26cb4c0c0e9c9466ab1 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 10 Mar 2015 18:57:07 +0100 Subject: [PATCH 2/3] gcc build fixed --- alethzero/WebPage.cpp | 1 - alethzero/WebPage.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/alethzero/WebPage.cpp b/alethzero/WebPage.cpp index f9a307a53..08c5c3cc6 100644 --- a/alethzero/WebPage.cpp +++ b/alethzero/WebPage.cpp @@ -19,7 +19,6 @@ * @date 2015 */ -#pragma GCC diagnostic ignored "-Wpedantic" //QtWebEngineWidgets/qwebenginecertificateerror.h:78:348: error: extra ';' #include "WebPage.h" void WebPage::javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel _level, const QString& _message, int _lineNumber, const QString& _sourceID) diff --git a/alethzero/WebPage.h b/alethzero/WebPage.h index bfb67e749..5f1bb1dc8 100644 --- a/alethzero/WebPage.h +++ b/alethzero/WebPage.h @@ -22,7 +22,10 @@ #pragma once #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" //QtWebEngineWidgets/qwebenginecertificateerror.h:78:348: error: extra ';' #include +#pragma GCC diagnostic pop class WebPage: public QWebEnginePage { From bbb72e7e8470a379abaa1ac763be1a7733c5a789 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 10 Mar 2015 18:11:40 +0200 Subject: [PATCH 3/3] fixed msvc build --- alethzero/DappHost.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/alethzero/DappHost.cpp b/alethzero/DappHost.cpp index 22ba41c6c..fd73c1b17 100644 --- a/alethzero/DappHost.cpp +++ b/alethzero/DappHost.cpp @@ -19,11 +19,11 @@ * @date 2015 */ +#include "DappHost.h" +#include #include #include #include -#include -#include "DappHost.h" using namespace dev; @@ -61,7 +61,6 @@ void DappHost::sendOptionsResponse(MHD_Connection* _connection) { MHD_Response *result = MHD_create_response_from_data(0, NULL, 0, 1); MHD_add_response_header(result, "Allow", "GET, OPTIONS"); - //MHD_add_response_header(result, "Access-Control-Allow-Origin", "*"); MHD_add_response_header(result, "Access-Control-Allow-Headers", "origin, content-type, accept"); MHD_add_response_header(result, "DAV", "1"); MHD_queue_response(_connection, MHD_HTTP_OK, result); @@ -109,7 +108,6 @@ void DappHost::sendResponse(std::string const& _url, MHD_Connection* _connection MHD_Response *result = MHD_create_response_from_data(response.size(), const_cast(response.data()), 0, 1); if (!contentType.empty()) MHD_add_response_header(result, "Content-Type", contentType.c_str()); - //MHD_add_response_header(result, "Access-Control-Allow-Origin", "*"); MHD_queue_response(_connection, code, result); MHD_destroy_response(result); }