Browse Source

fixed std contracts loading by placing them into single compilation unit

cl-refactor
arkpar 10 years ago
parent
commit
b067d3e65a
  1. 2
      mix/ClientModel.cpp
  2. 1
      mix/CodeHighlighter.cpp
  3. 15
      mix/CodeModel.cpp
  4. 4
      mix/CodeModel.h
  5. 2
      mix/QContractDefinition.cpp
  6. 8
      mix/qml/ContractLibrary.qml
  7. 1
      mix/res.qrc
  8. 124
      mix/stdc/std.sol

2
mix/ClientModel.cpp

@ -179,7 +179,7 @@ void ClientModel::executeSequence(std::vector<TransactionSettings> const& _seque
if (!transaction.stdContractUrl.isEmpty()) if (!transaction.stdContractUrl.isEmpty())
{ {
//std contract //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); Address address = deployContract(stdContractCode, transaction);
m_stdContractAddresses[transaction.functionId] = address; m_stdContractAddresses[transaction.functionId] = address;
m_stdContractNames[address] = transaction.functionId; m_stdContractNames[address] = transaction.functionId;

1
mix/CodeHighlighter.cpp

@ -102,6 +102,7 @@ void CodeHighlighter::processAST(dev::solidity::ASTNode const& _ast)
void CodeHighlighter::processError(dev::Exception const& _exception) void CodeHighlighter::processError(dev::Exception const& _exception)
{ {
Location const* location = boost::get_error_info<errinfo_sourceLocation>(_exception); Location const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
if (location)
m_formats.push_back(FormatRange(CodeHighlighterSettings::CompilationError, *location)); m_formats.push_back(FormatRange(CodeHighlighterSettings::CompilationError, *location));
} }

15
mix/CodeModel.cpp

@ -190,19 +190,22 @@ void CodeModel::updateFormatting(QTextDocument* _document)
m_result->codeHighlighter()->updateFormatting(_document, *m_codeHighlighterSettings); 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()) if (cached != m_compiledContracts.end())
return cached->second; return cached->second;
FileIo fileIo; FileIo fileIo;
std::string source = fileIo.readFile(_url).toStdString(); std::string source = fileIo.readFile(_url).toStdString();
solidity::CompilerStack cs; solidity::CompilerStack cs(false);
cs.setSource(source); cs.setSource(source);
cs.compile(false); cs.compile(false);
dev::bytes code = cs.getBytecode(); for(std::string name: cs.getContractNames())
m_compiledContracts.insert(std::make_pair(_url, std::move(code))); {
return m_compiledContracts.at(_url); dev::bytes code = cs.getBytecode(name);
m_compiledContracts.insert(std::make_pair(QString::fromStdString(name), std::move(code)));
}
return m_compiledContracts.at(_contractName);
} }

4
mix/CodeModel.h

@ -133,7 +133,7 @@ public:
/// Apply text document formatting. @todo Move this to editor module /// Apply text document formatting. @todo Move this to editor module
void updateFormatting(QTextDocument* _document); void updateFormatting(QTextDocument* _document);
/// Get contract code by url. Contract is compiled on first access and cached /// 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: signals:
/// Emited on compilation state change /// Emited on compilation state change
@ -166,7 +166,7 @@ private:
QThread m_backgroundThread; QThread m_backgroundThread;
BackgroundWorker m_backgroundWorker; BackgroundWorker m_backgroundWorker;
int m_backgroundJobId = 0; //protects from starting obsolete compilation job int m_backgroundJobId = 0; //protects from starting obsolete compilation job
std::map<QString, dev::bytes> m_compiledContracts; //by url std::map<QString, dev::bytes> m_compiledContracts; //by name
friend class BackgroundWorker; friend class BackgroundWorker;
}; };

2
mix/QContractDefinition.cpp

@ -47,8 +47,6 @@ QContractDefinition::QContractDefinition(dev::solidity::ContractDefinition const
QFunctionDefinition* QContractDefinition::getFunction(dev::FixedHash<4> _hash) QFunctionDefinition* QContractDefinition::getFunction(dev::FixedHash<4> _hash)
{ {
if (m_constructor->hash() == _hash)
return m_constructor;
for (auto const& f: m_functions) for (auto const& f: m_functions)
if (f->hash() == _hash) if (f->hash() == _hash)
return f; return f;

8
mix/qml/ContractLibrary.qml

@ -9,17 +9,13 @@ Item {
Component.onCompleted: { Component.onCompleted: {
//TODO: load a list, dependencies, ets, from external files //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({ contractListModel.append({
name: "Config", name: "Config",
url: "qrc:///stdc/config.sol", url: "qrc:///stdc/std.sol",
source: configSource
}); });
contractListModel.append({ contractListModel.append({
name: "NameReg", name: "NameReg",
url: "qrc:///stdc/namereg.sol", url: "qrc:///stdc/std.sol",
source: nameRegSource
}); });
} }
} }

1
mix/res.qrc

@ -48,6 +48,7 @@
<file>qml/ContractLibrary.qml</file> <file>qml/ContractLibrary.qml</file>
<file>stdc/config.sol</file> <file>stdc/config.sol</file>
<file>stdc/namereg.sol</file> <file>stdc/namereg.sol</file>
<file>stdc/std.sol</file>
<file>qml/TransactionLog.qml</file> <file>qml/TransactionLog.qml</file>
</qresource> </qresource>
</RCC> </RCC>

124
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 <g@ethdev.com>
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 <g@ethdev.com>
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();
*/
Loading…
Cancel
Save