From b067d3e65a6bde105bfa7d14b8fb24ac061740f5 Mon Sep 17 00:00:00 2001 From: arkpar Date: Wed, 28 Jan 2015 22:45:28 +0100 Subject: [PATCH] fixed std contracts loading by placing them into single compilation unit --- mix/ClientModel.cpp | 2 +- mix/CodeHighlighter.cpp | 3 +- mix/CodeModel.cpp | 15 +++-- mix/CodeModel.h | 4 +- mix/QContractDefinition.cpp | 2 - mix/qml/ContractLibrary.qml | 8 +-- mix/res.qrc | 1 + mix/stdc/std.sol | 124 ++++++++++++++++++++++++++++++++++++ 8 files changed, 141 insertions(+), 18 deletions(-) create mode 100644 mix/stdc/std.sol diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index f3455b4ce..31a02caae 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -179,7 +179,7 @@ void ClientModel::executeSequence(std::vector const& _seque if (!transaction.stdContractUrl.isEmpty()) { //std contract - dev::bytes const& stdContractCode = m_context->codeModel()->getStdContractCode(transaction.stdContractUrl); + dev::bytes const& stdContractCode = m_context->codeModel()->getStdContractCode(transaction.functionId, transaction.stdContractUrl); Address address = deployContract(stdContractCode, transaction); m_stdContractAddresses[transaction.functionId] = address; m_stdContractNames[address] = transaction.functionId; diff --git a/mix/CodeHighlighter.cpp b/mix/CodeHighlighter.cpp index ab8a61ff5..49d01b418 100644 --- a/mix/CodeHighlighter.cpp +++ b/mix/CodeHighlighter.cpp @@ -102,7 +102,8 @@ void CodeHighlighter::processAST(dev::solidity::ASTNode const& _ast) void CodeHighlighter::processError(dev::Exception const& _exception) { Location const* location = boost::get_error_info(_exception); - m_formats.push_back(FormatRange(CodeHighlighterSettings::CompilationError, *location)); + if (location) + m_formats.push_back(FormatRange(CodeHighlighterSettings::CompilationError, *location)); } void CodeHighlighter::processComments(std::string const& _source) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index fb6e88076..4d1febf97 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -190,19 +190,22 @@ void CodeModel::updateFormatting(QTextDocument* _document) m_result->codeHighlighter()->updateFormatting(_document, *m_codeHighlighterSettings); } -dev::bytes const& CodeModel::getStdContractCode(const QString &_url) +dev::bytes const& CodeModel::getStdContractCode(const QString& _contractName, const QString& _url) { - auto cached = m_compiledContracts.find(_url); + auto cached = m_compiledContracts.find(_contractName); if (cached != m_compiledContracts.end()) return cached->second; FileIo fileIo; std::string source = fileIo.readFile(_url).toStdString(); - solidity::CompilerStack cs; + solidity::CompilerStack cs(false); cs.setSource(source); cs.compile(false); - dev::bytes code = cs.getBytecode(); - m_compiledContracts.insert(std::make_pair(_url, std::move(code))); - return m_compiledContracts.at(_url); + for(std::string name: cs.getContractNames()) + { + dev::bytes code = cs.getBytecode(name); + m_compiledContracts.insert(std::make_pair(QString::fromStdString(name), std::move(code))); + } + return m_compiledContracts.at(_contractName); } diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 3d2f2c7ed..5f2add874 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -133,7 +133,7 @@ public: /// Apply text document formatting. @todo Move this to editor module void updateFormatting(QTextDocument* _document); /// Get contract code by url. Contract is compiled on first access and cached - dev::bytes const& getStdContractCode(QString const& _url); + dev::bytes const& getStdContractCode(QString const& _contractName, QString const& _url); signals: /// Emited on compilation state change @@ -166,7 +166,7 @@ private: QThread m_backgroundThread; BackgroundWorker m_backgroundWorker; int m_backgroundJobId = 0; //protects from starting obsolete compilation job - std::map m_compiledContracts; //by url + std::map m_compiledContracts; //by name friend class BackgroundWorker; }; diff --git a/mix/QContractDefinition.cpp b/mix/QContractDefinition.cpp index 091f9d86b..1610106ed 100644 --- a/mix/QContractDefinition.cpp +++ b/mix/QContractDefinition.cpp @@ -47,8 +47,6 @@ QContractDefinition::QContractDefinition(dev::solidity::ContractDefinition const QFunctionDefinition* QContractDefinition::getFunction(dev::FixedHash<4> _hash) { - if (m_constructor->hash() == _hash) - return m_constructor; for (auto const& f: m_functions) if (f->hash() == _hash) return f; diff --git a/mix/qml/ContractLibrary.qml b/mix/qml/ContractLibrary.qml index 9fe8fa679..557f1cc53 100644 --- a/mix/qml/ContractLibrary.qml +++ b/mix/qml/ContractLibrary.qml @@ -9,17 +9,13 @@ Item { Component.onCompleted: { //TODO: load a list, dependencies, ets, from external files - var configSource = fileIo.readFile("qrc:///stdc/config.sol"); - var nameRegSource = fileIo.readFile("qrc:///stdc/namereg.sol"); contractListModel.append({ name: "Config", - url: "qrc:///stdc/config.sol", - source: configSource + url: "qrc:///stdc/std.sol", }); contractListModel.append({ name: "NameReg", - url: "qrc:///stdc/namereg.sol", - source: nameRegSource + url: "qrc:///stdc/std.sol", }); } } diff --git a/mix/res.qrc b/mix/res.qrc index a64b3a8ba..f009ab923 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -48,6 +48,7 @@ qml/ContractLibrary.qml stdc/config.sol stdc/namereg.sol + stdc/std.sol qml/TransactionLog.qml diff --git a/mix/stdc/std.sol b/mix/stdc/std.sol new file mode 100644 index 000000000..97a74ac56 --- /dev/null +++ b/mix/stdc/std.sol @@ -0,0 +1,124 @@ +//TODO: use imports +contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;} +contract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }} + +//sol Config +// Simple global configuration registrar. +// @authors: +// Gav Wood + + +contract Config is mortal { + function register(uint id, address service) { + if (tx.origin != owner) + return; + services[id] = service; + log1(0, id); + } + + function unregister(uint id) { + if (msg.sender != owner && services[id] != msg.sender) + return; + services[id] = address(0); + log1(0, id); + } + + function lookup(uint service) constant returns(address a) { + return services[service]; + } + + mapping (uint => address) services; +} + +/* + +// Solidity Interface: +contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}} + +// Example Solidity use: +address addrConfig = 0xf025d81196b72fba60a1d4dddad12eeb8360d828; +address addrNameReg = Config(addrConfig).lookup(1); + +// JS Interface: +var abiConfig = [{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"service","type":"uint256"}],"name":"lookup","outputs":[{"name":"a","type":"address"}]},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"service","type":"address"}],"name":"register","outputs":[]},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"unregister","outputs":[]}]; + +// Example JS use: +var addrConfig = "0x661005d2720d855f1d9976f88bb10c1a3398c77f"; +var addrNameReg; +web3.eth.contract(addrConfig, abiConfig).lookup(1).call().then(function(r){ addrNameReg = r; }) + +*/ + +//sol NameReg +// Simple global name registrar. +// @authors: +// kobigurk (from #ethereum-dev) +// Gav Wood + +contract NameRegister { + function getAddress(string32 _name) constant returns (address o_owner) {} + function getName(address _owner) constant returns (string32 o_name) {} +} + +contract NameReg is owned, NameRegister { + function NameReg() { + address addrConfig = 0xf025d81196b72fba60a1d4dddad12eeb8360d828; + toName[addrConfig] = "Config"; + toAddress["Config"] = addrConfig; + toName[this] = "NameReg"; + toAddress["NameReg"] = this; + Config(addrConfig).register(1, this); + log1(0, hash256(addrConfig)); + log1(0, hash256(this)); + } + + function register(string32 name) { + // Don't allow the same name to be overwritten. + if (toAddress[name] != address(0)) + return; + // Unregister previous name if there was one. + if (toName[msg.sender] != "") + toAddress[toName[msg.sender]] = 0; + + toName[msg.sender] = name; + toAddress[name] = msg.sender; + log1(0, hash256(msg.sender)); + } + + function unregister() { + string32 n = toName[msg.sender]; + if (n == "") + return; + log1(0, hash256(toAddress[n])); + toName[msg.sender] = ""; + toAddress[n] = address(0); + } + + function addressOf(string32 name) constant returns (address addr) { + return toAddress[name]; + } + + function nameOf(address addr) constant returns (string32 name) { + return toName[addr]; + } + + mapping (address => string32) toName; + mapping (string32 => address) toAddress; +} + + +/* + +// Solidity Interface: +contract NameReg{function kill(){}function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}} + +// Example Solidity use: +NameReg(addrNameReg).register("Some Contract"); + +// JS Interface: +var abiNameReg = [{"constant":true,"inputs":[{"name":"name","type":"string32"}],"name":"addressOf","outputs":[{"name":"addr","type":"address"}]},{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"nameOf","outputs":[{"name":"name","type":"string32"}]},{"constant":false,"inputs":[{"name":"name","type":"string32"}],"name":"register","outputs":[]},{"constant":false,"inputs":[],"name":"unregister","outputs":[]}]; + +// Example JS use: +web3.eth.contract(addrNameReg, abiNameReg).register("My Name").transact(); + +*/