From 5789eaa78d0e00f6289101e02f7de5e9decdc7e5 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 14 Nov 2016 11:46:43 +0100 Subject: Metadata stamp. --- libsolidity/interface/CompilerStack.cpp | 98 +++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 18 deletions(-) (limited to 'libsolidity/interface/CompilerStack.cpp') diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9305c5e3..ed44b109 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -38,7 +38,10 @@ #include #include -#include + +#include + +#include #include #include @@ -79,6 +82,8 @@ void CompilerStack::reset(bool _keepSources) { m_sources.clear(); } + m_optimize = false; + m_optimizeRuns = 200; m_globalContext.reset(); m_sourceOrder.clear(); m_contracts.clear(); @@ -217,17 +222,22 @@ vector CompilerStack::contractNames() const } -bool CompilerStack::compile(bool _optimize, unsigned _runs) +bool CompilerStack::compile(bool _optimize, unsigned _runs, map const& _libraries) { if (!m_parseSuccessful) if (!parse()) return false; + m_optimize = _optimize; + m_optimizeRuns = _runs; + m_libraries = _libraries; + map compiledContracts; for (Source const* source: m_sourceOrder) for (ASTPointer const& node: source->ast->nodes()) if (auto contract = dynamic_cast(node.get())) - compileContract(_optimize, _runs, *contract, compiledContracts); + compileContract(*contract, compiledContracts); + this->link(); return true; } @@ -236,13 +246,13 @@ bool CompilerStack::compile(string const& _sourceCode, bool _optimize) return parse(_sourceCode) && compile(_optimize); } -void CompilerStack::link(const std::map& _libraries) +void CompilerStack::link() { for (auto& contract: m_contracts) { - contract.second.object.link(_libraries); - contract.second.runtimeObject.link(_libraries); - contract.second.cloneObject.link(_libraries); + contract.second.object.link(m_libraries); + contract.second.runtimeObject.link(m_libraries); + contract.second.cloneObject.link(m_libraries); } } @@ -352,24 +362,31 @@ Json::Value const& CompilerStack::interface(string const& _contractName) const } Json::Value const& CompilerStack::metadata(string const& _contractName, DocumentationType _type) const +{ + if (!m_parseSuccessful) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); + + return metadata(contract(_contractName), _type); +} + +Json::Value const& CompilerStack::metadata(Contract const& _contract, DocumentationType _type) const { if (!m_parseSuccessful) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); std::unique_ptr* doc; - Contract const& currentContract = contract(_contractName); // checks wheather we already have the documentation switch (_type) { case DocumentationType::NatspecUser: - doc = ¤tContract.userDocumentation; + doc = &_contract.userDocumentation; break; case DocumentationType::NatspecDev: - doc = ¤tContract.devDocumentation; + doc = &_contract.devDocumentation; break; case DocumentationType::ABIInterface: - doc = ¤tContract.interface; + doc = &_contract.interface; break; default: BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal documentation type.")); @@ -377,11 +394,19 @@ Json::Value const& CompilerStack::metadata(string const& _contractName, Document // caches the result if (!*doc) - doc->reset(new Json::Value(InterfaceHandler::documentation(*currentContract.contract, _type))); + doc->reset(new Json::Value(InterfaceHandler::documentation(*_contract.contract, _type))); return *(*doc); } +string const& CompilerStack::onChainMetadata(string const& _contractName) const +{ + if (!m_parseSuccessful) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); + + return contract(_contractName).onChainMetadata; +} + Scanner const& CompilerStack::scanner(string const& _sourceName) const { return *source(_sourceName).scanner; @@ -572,8 +597,6 @@ string CompilerStack::absolutePath(string const& _path, string const& _reference } void CompilerStack::compileContract( - bool _optimize, - unsigned _runs, ContractDefinition const& _contract, map& _compiledContracts ) @@ -581,19 +604,21 @@ void CompilerStack::compileContract( if (_compiledContracts.count(&_contract) || !_contract.annotation().isFullyImplemented) return; for (auto const* dependency: _contract.annotation().contractDependencies) - compileContract(_optimize, _runs, *dependency, _compiledContracts); + compileContract(*dependency, _compiledContracts); - shared_ptr compiler = make_shared(_optimize, _runs); - compiler->compileContract(_contract, _compiledContracts); + shared_ptr compiler = make_shared(m_optimize, m_optimizeRuns); Contract& compiledContract = m_contracts.at(_contract.name()); + string onChainMetadata = createOnChainMetadata(compiledContract); + compiler->compileContract(_contract, _compiledContracts, dev::swarmHash(onChainMetadata)); compiledContract.compiler = compiler; compiledContract.object = compiler->assembledObject(); compiledContract.runtimeObject = compiler->runtimeObject(); + compiledContract.onChainMetadata = onChainMetadata; _compiledContracts[compiledContract.contract] = &compiler->assembly(); try { - Compiler cloneCompiler(_optimize, _runs); + Compiler cloneCompiler(m_optimize, m_optimizeRuns); cloneCompiler.compileClone(_contract, _compiledContracts); compiledContract.cloneObject = cloneCompiler.assembledObject(); } @@ -637,6 +662,43 @@ CompilerStack::Source const& CompilerStack::source(string const& _sourceName) co return it->second; } +string CompilerStack::createOnChainMetadata(Contract const& _contract) const +{ + Json::Value meta; + meta["version"] = 1; + meta["language"] = "Solidity"; + meta["compiler"]["version"] = VersionString; + meta["compilationTarget"] = + _contract.contract->sourceUnitName() + + ":" + + _contract.contract->annotation().canonicalName; + + for (auto const& s: m_sources) + { + solAssert(s.second.scanner, "Scanner not available"); + meta["sources"][s.first]["swarm"] = + "0x" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes()); + } + meta["settings"]["optimizer"]["enabled"] = m_optimize; + meta["settings"]["optimizer"]["runs"] = m_optimizeRuns; + + set remappings; + for (auto const& r: m_remappings) + remappings.insert(r.context + ":" + r.prefix + "=" + r.target); + for (auto const& r: remappings) + meta["settings"]["remappings"].append(r); + + for (auto const& library: m_libraries) + meta["settings"]["libraries"][library.first] = "0x" + toHex(library.second.asBytes()); + + meta["output"]["abi"] = metadata(_contract, DocumentationType::ABIInterface); + meta["output"]["natspec"] = metadata(_contract, DocumentationType::NatspecUser); + + Json::FastWriter writer; + writer.omitEndingLineFeed(); + return writer.write(meta); +} + string CompilerStack::computeSourceMapping(eth::AssemblyItems const& _items) const { string ret; -- cgit From e666f8cda70ad5e03bc00f4509fc51571fff90a7 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 16 Nov 2016 14:36:19 +0100 Subject: Incorporate comments. --- libsolidity/interface/CompilerStack.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'libsolidity/interface/CompilerStack.cpp') diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index ed44b109..0f861302 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -40,6 +40,7 @@ #include #include +#include #include @@ -668,19 +669,19 @@ string CompilerStack::createOnChainMetadata(Contract const& _contract) const meta["version"] = 1; meta["language"] = "Solidity"; meta["compiler"]["version"] = VersionString; - meta["compilationTarget"] = - _contract.contract->sourceUnitName() + - ":" + - _contract.contract->annotation().canonicalName; for (auto const& s: m_sources) { solAssert(s.second.scanner, "Scanner not available"); - meta["sources"][s.first]["swarm"] = - "0x" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes()); + meta["sources"][s.first]["keccak256"] = + "0x" + toHex(dev::keccak256(s.second.scanner->source()).asBytes()); + meta["sources"][s.first]["url"] = + "bzzr://" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes()); } meta["settings"]["optimizer"]["enabled"] = m_optimize; meta["settings"]["optimizer"]["runs"] = m_optimizeRuns; + meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] = + _contract.contract->annotation().canonicalName; set remappings; for (auto const& r: m_remappings) @@ -692,11 +693,10 @@ string CompilerStack::createOnChainMetadata(Contract const& _contract) const meta["settings"]["libraries"][library.first] = "0x" + toHex(library.second.asBytes()); meta["output"]["abi"] = metadata(_contract, DocumentationType::ABIInterface); - meta["output"]["natspec"] = metadata(_contract, DocumentationType::NatspecUser); + meta["output"]["userdoc"] = metadata(_contract, DocumentationType::NatspecUser); + meta["output"]["devdoc"] = metadata(_contract, DocumentationType::NatspecDev); - Json::FastWriter writer; - writer.omitEndingLineFeed(); - return writer.write(meta); + return jsonCompactPrint(meta); } string CompilerStack::computeSourceMapping(eth::AssemblyItems const& _items) const -- cgit From 659b635b2d8274f870ebe487a73b431a2398b741 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 23 Nov 2016 19:04:50 +0100 Subject: Make sure some keys are present. --- libsolidity/interface/CompilerStack.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libsolidity/interface/CompilerStack.cpp') diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 0f861302..e77836ef 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -670,6 +670,7 @@ string CompilerStack::createOnChainMetadata(Contract const& _contract) const meta["language"] = "Solidity"; meta["compiler"]["version"] = VersionString; + meta["sources"] = Json::objectValue; for (auto const& s: m_sources) { solAssert(s.second.scanner, "Scanner not available"); @@ -683,12 +684,14 @@ string CompilerStack::createOnChainMetadata(Contract const& _contract) const meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] = _contract.contract->annotation().canonicalName; + meta["settings"]["remappings"] = Json::arrayValue; set remappings; for (auto const& r: m_remappings) remappings.insert(r.context + ":" + r.prefix + "=" + r.target); for (auto const& r: remappings) meta["settings"]["remappings"].append(r); + meta["settings"]["libraries"] = Json::objectValue; for (auto const& library: m_libraries) meta["settings"]["libraries"][library.first] = "0x" + toHex(library.second.asBytes()); -- cgit From 91ecc4533dffbe67fa27adfaff27780ddf69c21a Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 24 Nov 2016 10:32:52 +0100 Subject: Add swarm hash to the end of the bytecode. --- libsolidity/interface/CompilerStack.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'libsolidity/interface/CompilerStack.cpp') diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index e77836ef..357b18bd 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -375,6 +375,7 @@ Json::Value const& CompilerStack::metadata(Contract const& _contract, Documentat if (!m_parseSuccessful) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); + solAssert(_contract.contract, ""); std::unique_ptr* doc; // checks wheather we already have the documentation -- cgit From 6a7ff039df15be59fbb71dc3dfaad09fb0b8961f Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 29 Nov 2016 17:47:47 +0100 Subject: Use CBOR encoding. --- libsolidity/interface/CompilerStack.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/CompilerStack.cpp') diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 357b18bd..d79345f0 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -611,7 +611,14 @@ void CompilerStack::compileContract( shared_ptr compiler = make_shared(m_optimize, m_optimizeRuns); Contract& compiledContract = m_contracts.at(_contract.name()); string onChainMetadata = createOnChainMetadata(compiledContract); - compiler->compileContract(_contract, _compiledContracts, dev::swarmHash(onChainMetadata)); + bytes cborEncodedMetadata = + // CBOR-encoding of {"bzzr0": dev::swarmHash(onChainMetadata)} + bytes{0xa1, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} + + dev::swarmHash(onChainMetadata).asBytes(); + solAssert(cborEncodedMetadata.size() <= 0xffff, "Metadata too large"); + // 16-bit big endian length + cborEncodedMetadata += toCompactBigEndian(cborEncodedMetadata.size(), 2); + compiler->compileContract(_contract, _compiledContracts, cborEncodedMetadata); compiledContract.compiler = compiler; compiledContract.object = compiler->assembledObject(); compiledContract.runtimeObject = compiler->runtimeObject(); -- cgit From f1907bbb12ce6a65d781bee1e1faebd6cde261bd Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Dec 2016 11:44:13 +0100 Subject: Add the `_runs` parameter. --- libsolidity/interface/CompilerStack.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libsolidity/interface/CompilerStack.cpp') diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index d79345f0..b4fd6d87 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -242,9 +242,9 @@ bool CompilerStack::compile(bool _optimize, unsigned _runs, map co return true; } -bool CompilerStack::compile(string const& _sourceCode, bool _optimize) +bool CompilerStack::compile(string const& _sourceCode, bool _optimize, unsigned _runs) { - return parse(_sourceCode) && compile(_optimize); + return parse(_sourceCode) && compile(_optimize, _runs); } void CompilerStack::link() -- cgit