diff options
30 files changed, 254 insertions, 183 deletions
@@ -41,3 +41,4 @@ docs/utils/__pycache__ # IDE files .idea browse.VC.db +CMakeLists.txt.user diff --git a/Changelog.md b/Changelog.md index 5ba712f5..b398e014 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,9 +1,11 @@ ### 0.4.12 (unreleased) Features: + * Assembler: renamed ``SHA3`` to `KECCAK256``. * AST: export all attributes to Json format * Inline Assembly: Present proper error message when not supplying enough arguments to a functional instruction. + * Inline Assembly: introduce ``keccak256`` as an opcode. ``sha3`` is still a valid alias. Bugfixes: * Unused variable warnings no longer issued for variables used inside inline assembly diff --git a/docs/assembly.rst b/docs/assembly.rst index 07583a24..90e70031 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -182,6 +182,8 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+------+-----------------------------------------------------------------+ | signextend(i, x) | | sign extend from (i*8+7)th bit counting from least significant | +-------------------------+------+-----------------------------------------------------------------+ +| keccak256(p, n) | | keccak(mem[p...(p+n))) | ++-------------------------+------+-----------------------------------------------------------------+ | sha3(p, n) | | keccak(mem[p...(p+n))) | +-------------------------+------+-----------------------------------------------------------------+ | jump(label) | `-` | jump to label / code position | diff --git a/docs/index.rst b/docs/index.rst index 1312864a..4b48b91c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,11 @@ Solidity ======== +.. image:: logo.svg + :width: 120px + :alt: Solidity logo + :align: center + Solidity is a contract-oriented, high-level language whose syntax is similar to that of JavaScript and it is designed to target the Ethereum Virtual Machine (EVM). diff --git a/docs/logo.svg b/docs/logo.svg new file mode 100644 index 00000000..86b9f499 --- /dev/null +++ b/docs/logo.svg @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" + xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1300px" height="1300px" + viewBox="0 0 1300 1300" enable-background="new 0 0 1300 1300" xml:space="preserve"> +<title>Vector 1</title> +<desc>Created with Sketch.</desc> +<g id="Page-1" sketch:type="MSPage"> + <g id="solidity" transform="translate(402.000000, 118.000000)" sketch:type="MSLayerGroup"> + <g id="Group" sketch:type="MSShapeGroup"> + <path id="Shape" opacity="0.45" enable-background="new " d="M371.772,135.308L241.068,367.61H-20.158l130.614-232.302 + H371.772"/> + <path id="Shape_1_" opacity="0.6" enable-background="new " d="M241.068,367.61h261.318L371.772,135.308H110.456 + L241.068,367.61z"/> + <path id="Shape_2_" opacity="0.8" enable-background="new " d="M110.456,599.822L241.068,367.61L110.456,135.308 + L-20.158,367.61L110.456,599.822z"/> + <path id="Shape_3_" opacity="0.45" enable-background="new " d="M111.721,948.275l130.704-232.303h261.318L373.038,948.275 + H111.721"/> + <path id="Shape_4_" opacity="0.6" enable-background="new " d="M242.424,715.973H-18.893l130.613,232.303h261.317 + L242.424,715.973z"/> + <path id="Shape_5_" opacity="0.8" enable-background="new " d="M373.038,483.761L242.424,715.973l130.614,232.303 + l130.704-232.303L373.038,483.761z"/> + </g> + </g> +</g> +</svg> diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 914dfacd..2e0ccf45 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -371,7 +371,7 @@ Tips and Tricks * Use ``delete`` on arrays to delete all its elements. * Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple SSTORE operations might be combined into a single (SSTORE costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check! -* Make your state variables public - the compiler will create :ref:`getters <visibility-and-getters>` for you for free. +* Make your state variables public - the compiler will create :ref:`getters <visibility-and-getters>` for you automatically. * If you end up checking conditions on input or state a lot at the beginning of your functions, try using :ref:`modifiers`. * If your contract has a function called ``send`` but you want to use the built-in send-function, use ``address(contractVariable).send(amount)``. * Initialise storage structs with a single assignment: ``x = MyStruct({a: 1, b: 2});`` diff --git a/libevmasm/CommonSubexpressionEliminator.cpp b/libevmasm/CommonSubexpressionEliminator.cpp index fd4fffa6..70324e7f 100644 --- a/libevmasm/CommonSubexpressionEliminator.cpp +++ b/libevmasm/CommonSubexpressionEliminator.cpp @@ -234,7 +234,7 @@ void CSECodeGenerator::addDependencies(Id _c) if (expr.item && expr.item->type() == Operation && ( expr.item->instruction() == Instruction::SLOAD || expr.item->instruction() == Instruction::MLOAD || - expr.item->instruction() == Instruction::SHA3 + expr.item->instruction() == Instruction::KECCAK256 )) { // this loads an unknown value from storage or memory and thus, in addition to its @@ -260,7 +260,7 @@ void CSECodeGenerator::addDependencies(Id _c) case Instruction::MLOAD: knownToBeIndependent = m_expressionClasses.knownToBeDifferentBy32(slot, slotToLoadFrom); break; - case Instruction::SHA3: + case Instruction::KECCAK256: { Id length = expr.arguments.at(1); AssemblyItem offsetInstr(Instruction::SUB, expr.item->location()); diff --git a/libevmasm/EVMSchedule.h b/libevmasm/EVMSchedule.h index 65d307ae..1695a59c 100644 --- a/libevmasm/EVMSchedule.h +++ b/libevmasm/EVMSchedule.h @@ -32,8 +32,8 @@ struct EVMSchedule unsigned stackLimit = 1024; unsigned expGas = 10; unsigned expByteGas = 10; - unsigned sha3Gas = 30; - unsigned sha3WordGas = 6; + unsigned keccak256Gas = 30; + unsigned keccak256WordGas = 6; unsigned sloadGas = 200; unsigned sstoreSetGas = 20000; unsigned sstoreResetGas = 5000; diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp index f5fd00ea..260b7439 100644 --- a/libevmasm/GasMeter.cpp +++ b/libevmasm/GasMeter.cpp @@ -96,9 +96,9 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ classes.find(AssemblyItem(1)) })); break; - case Instruction::SHA3: - gas = GasCosts::sha3Gas; - gas += wordGas(GasCosts::sha3WordGas, m_state->relativeStackElement(-1)); + case Instruction::KECCAK256: + gas = GasCosts::keccak256Gas; + gas += wordGas(GasCosts::keccak256WordGas, m_state->relativeStackElement(-1)); gas += memoryGas(0, -1); break; case Instruction::CALLDATACOPY: diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index 3169ff2a..2c3ecf5a 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -48,8 +48,8 @@ namespace GasCosts static unsigned const balanceGas = 400; static unsigned const expGas = 10; static unsigned const expByteGas = 50; - static unsigned const sha3Gas = 30; - static unsigned const sha3WordGas = 6; + static unsigned const keccak256Gas = 30; + static unsigned const keccak256WordGas = 6; static unsigned const sloadGas = 200; static unsigned const sstoreSetGas = 20000; static unsigned const sstoreResetGas = 5000; diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 5e92c6e6..25eab60b 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -53,7 +53,7 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions = { "ADDMOD", Instruction::ADDMOD }, { "MULMOD", Instruction::MULMOD }, { "SIGNEXTEND", Instruction::SIGNEXTEND }, - { "SHA3", Instruction::SHA3 }, + { "KECCAK256", Instruction::KECCAK256 }, { "ADDRESS", Instruction::ADDRESS }, { "BALANCE", Instruction::BALANCE }, { "ORIGIN", Instruction::ORIGIN }, @@ -189,7 +189,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo = { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, - { Instruction::SHA3, { "SHA3", 0, 2, 1, false, Tier::Special } }, + { Instruction::KECCAK256, { "KECCAK256", 0, 2, 1, false, Tier::Special } }, { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1, false, Tier::Base } }, { Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Balance } }, { Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 192fe090..5fec7988 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -62,7 +62,7 @@ enum class Instruction: uint8_t NOT, ///< bitwise NOT opertation BYTE, ///< retrieve single byte from word - SHA3 = 0x20, ///< compute SHA3-256 hash + KECCAK256 = 0x20, ///< compute KECCAK-256 hash ADDRESS = 0x30, ///< get address of currently executing account BALANCE, ///< get balance of the given account diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp index 6e3130dd..e2f10f22 100644 --- a/libevmasm/KnownState.cpp +++ b/libevmasm/KnownState.cpp @@ -136,10 +136,10 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool m_stackHeight + _item.deposit(), loadFromMemory(arguments[0], _item.location()) ); - else if (_item.instruction() == Instruction::SHA3) + else if (_item.instruction() == Instruction::KECCAK256) setStackElement( m_stackHeight + _item.deposit(), - applySha3(arguments.at(0), arguments.at(1), _item.location()) + applyKeccak256(arguments.at(0), arguments.at(1), _item.location()) ); else { @@ -346,18 +346,18 @@ ExpressionClasses::Id KnownState::loadFromMemory(Id _slot, SourceLocation const& return m_memoryContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber); } -KnownState::Id KnownState::applySha3( +KnownState::Id KnownState::applyKeccak256( Id _start, Id _length, SourceLocation const& _location ) { - AssemblyItem sha3Item(Instruction::SHA3, _location); + AssemblyItem keccak256Item(Instruction::KECCAK256, _location); // Special logic if length is a short constant, otherwise we cannot tell. u256 const* l = m_expressionClasses->knownConstant(_length); // unknown or too large length if (!l || *l > 128) - return m_expressionClasses->find(sha3Item, {_start, _length}, true, m_sequenceNumber); + return m_expressionClasses->find(keccak256Item, {_start, _length}, true, m_sequenceNumber); vector<Id> arguments; for (u256 i = 0; i < *l; i += 32) @@ -368,10 +368,10 @@ KnownState::Id KnownState::applySha3( ); arguments.push_back(loadFromMemory(slot, _location)); } - if (m_knownSha3Hashes.count(arguments)) - return m_knownSha3Hashes.at(arguments); + if (m_knownKeccak256Hashes.count(arguments)) + return m_knownKeccak256Hashes.at(arguments); Id v; - // If all arguments are known constants, compute the sha3 here + // If all arguments are known constants, compute the Keccak-256 here if (all_of(arguments.begin(), arguments.end(), [this](Id _a) { return !!m_expressionClasses->knownConstant(_a); })) { bytes data; @@ -381,8 +381,8 @@ KnownState::Id KnownState::applySha3( v = m_expressionClasses->find(AssemblyItem(u256(dev::keccak256(data)), _location)); } else - v = m_expressionClasses->find(sha3Item, {_start, _length}, true, m_sequenceNumber); - return m_knownSha3Hashes[arguments] = v; + v = m_expressionClasses->find(keccak256Item, {_start, _length}, true, m_sequenceNumber); + return m_knownKeccak256Hashes[arguments] = v; } set<u256> KnownState::tagsInExpression(KnownState::Id _expressionId) diff --git a/libevmasm/KnownState.h b/libevmasm/KnownState.h index fd6a26c1..8568b163 100644 --- a/libevmasm/KnownState.h +++ b/libevmasm/KnownState.h @@ -150,8 +150,8 @@ private: StoreOperation storeInMemory(Id _slot, Id _value, SourceLocation const& _location); /// Retrieves the current value at the given slot in memory or creates a new special mload class. Id loadFromMemory(Id _slot, SourceLocation const& _location); - /// Finds or creates a new expression that applies the sha3 hash function to the contents in memory. - Id applySha3(Id _start, Id _length, SourceLocation const& _location); + /// Finds or creates a new expression that applies the Keccak-256 hash function to the contents in memory. + Id applyKeccak256(Id _start, Id _length, SourceLocation const& _location); /// @returns a new or already used Id representing the given set of tags. Id tagUnion(std::set<u256> _tags); @@ -167,8 +167,8 @@ private: /// Knowledge about memory content. Keys are memory addresses, note that the values overlap /// and are not contained here if they are not completely known. std::map<Id, Id> m_memoryContent; - /// Keeps record of all sha3 hashes that are computed. - std::map<std::vector<Id>, Id> m_knownSha3Hashes; + /// Keeps record of all Keccak-256 hashes that are computed. + std::map<std::vector<Id>, Id> m_knownKeccak256Hashes; /// Structure containing the classes of equivalent expressions. std::shared_ptr<ExpressionClasses> m_expressionClasses; /// Container for unions of tags stored on the stack. diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index bdd29abd..6a641b02 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -449,7 +449,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord m_context << Instruction::DUP3 << Instruction::ADD << Instruction::SWAP2; if (_sourceType.isDynamicallySized()) { - // actual array data is stored at SHA3(storage_offset) + // actual array data is stored at KECCAK256(storage_offset) m_context << Instruction::SWAP1; utils.computeHashStatic(); m_context << Instruction::SWAP1; @@ -731,7 +731,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const _context << Instruction::POP; } - // Change of length for a regular array (i.e. length at location, data at sha3(location)). + // Change of length for a regular array (i.e. length at location, data at KECCAK256(location)). // stack: ref new_length old_length // store new length _context << Instruction::DUP2; diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 4ae9a09a..3baaaddf 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -934,7 +934,7 @@ unsigned CompilerUtils::sizeOnStack(vector<shared_ptr<Type const>> const& _varia void CompilerUtils::computeHashStatic() { storeInMemory(0); - m_context << u256(32) << u256(0) << Instruction::SHA3; + m_context << u256(32) << u256(0) << Instruction::KECCAK256; } void CompilerUtils::storeStringData(bytesConstRef _data) diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h index 4140ce8b..a88951bc 100644 --- a/libsolidity/codegen/CompilerUtils.h +++ b/libsolidity/codegen/CompilerUtils.h @@ -166,7 +166,7 @@ public: static unsigned sizeOnStack(std::vector<T> const& _variables); static unsigned sizeOnStack(std::vector<std::shared_ptr<Type const>> const& _variableTypes); - /// Appends code that computes tha SHA3 hash of the topmost stack element of 32 byte type. + /// Appends code that computes tha Keccak-256 hash of the topmost stack element of 32 byte type. void computeHashStatic(); /// Bytes we need to the start of call data. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 0aa82ea8..25154bc0 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -110,7 +110,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& // move key to memory. utils().copyToStackTop(paramTypes.size() - i, 1); utils().storeInMemory(0); - m_context << u256(64) << u256(0) << Instruction::SHA3; + m_context << u256(64) << u256(0) << Instruction::KECCAK256; // push offset m_context << u256(0); returnType = mappingType->valueType(); @@ -674,7 +674,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) utils().fetchFreeMemoryPointer(); utils().encodeToMemory(argumentTypes, TypePointers(), function.padArguments(), true); utils().toSizeAfterFreeMemoryPointer(); - m_context << Instruction::SHA3; + m_context << Instruction::KECCAK256; break; } case FunctionType::Kind::Log0: @@ -721,7 +721,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) true ); utils().toSizeAfterFreeMemoryPointer(); - m_context << Instruction::SHA3; + m_context << Instruction::KECCAK256; } else utils().convertType( @@ -1214,7 +1214,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) utils().storeInMemoryDynamic(IntegerType(256)); m_context << u256(0); } - m_context << Instruction::SHA3; + m_context << Instruction::KECCAK256; m_context << u256(0); setLValueToStorageItem(_indexAccess); } diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 22e43127..3edc01ad 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -139,13 +139,8 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) solAssert(!m_julia, ""); bool success = true; for (auto const& arg: _instr.arguments | boost::adaptors::reversed) - { - int const stackHeight = m_stackHeight; - if (!boost::apply_visitor(*this, arg)) - success = false; - if (!expectDeposit(1, stackHeight, locationOf(arg))) + if (!expectExpression(arg)) success = false; - } // Parser already checks that the number of arguments is correct. solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), ""); if (!(*this)(_instr.instruction)) @@ -260,13 +255,8 @@ bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall) } } for (auto const& arg: _funCall.arguments | boost::adaptors::reversed) - { - int const stackHeight = m_stackHeight; - if (!boost::apply_visitor(*this, arg)) + if (!expectExpression(arg)) success = false; - if (!expectDeposit(1, stackHeight, locationOf(arg))) - success = false; - } m_stackHeight += int(returns) - int(arguments); m_info.stackHeightInfo[&_funCall] = m_stackHeight; return success; @@ -276,20 +266,16 @@ bool AsmAnalyzer::operator()(Switch const& _switch) { bool success = true; - int const initialStackHeight = m_stackHeight; - if (!boost::apply_visitor(*this, *_switch.expression)) + if (!expectExpression(*_switch.expression)) success = false; - expectDeposit(1, initialStackHeight, locationOf(*_switch.expression)); set<tuple<LiteralKind, string>> cases; for (auto const& _case: _switch.cases) { if (_case.value) { - int const initialStackHeight = m_stackHeight; - if (!(*this)(*_case.value)) + if (!expectExpression(*_case.value)) success = false; - expectDeposit(1, initialStackHeight, _case.value->location); m_stackHeight--; /// Note: the parser ensures there is only one default case @@ -349,6 +335,25 @@ bool AsmAnalyzer::operator()(Block const& _block) return success; } +bool AsmAnalyzer::expectExpression(Statement const& _statement) +{ + bool success = true; + int const initialHeight = m_stackHeight; + if (!boost::apply_visitor(*this, _statement)) + success = false; + if (m_stackHeight - initialHeight != 1) + { + m_errorReporter.typeError( + locationOf(_statement), + "Expected expression to return one item to the stack, but did return " + + boost::lexical_cast<string>(m_stackHeight - initialHeight) + + " items." + ); + success = false; + } + return success; +} + bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize) { bool success = true; @@ -401,25 +406,6 @@ bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t return success; } -bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, SourceLocation const& _location) -{ - int stackDiff = m_stackHeight - _oldHeight; - if (stackDiff != _deposit) - { - m_errorReporter.typeError( - _location, - "Expected instruction(s) to deposit " + - boost::lexical_cast<string>(_deposit) + - " item(s) to the stack, but did deposit " + - boost::lexical_cast<string>(stackDiff) + - " item(s)." - ); - return false; - } - else - return true; -} - Scope& AsmAnalyzer::scope(Block const* _block) { solAssert(m_info.scopes.count(_block) == 1, "Scope requested but not present."); diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index 7e4d78df..e52e6302 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -47,6 +47,8 @@ struct StackAssignment; struct FunctionDefinition; struct FunctionCall; struct Switch; +using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Switch, Block>; + struct Scope; @@ -83,10 +85,13 @@ public: bool operator()(assembly::Block const& _block); private: + /// Visits the statement and expects it to deposit one item onto the stack. + bool expectExpression(Statement const& _statement); + /// Verifies that a variable to be assigned to exists and has the same size /// as the value, @a _valueSize, unless that is equal to -1. bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1)); - bool expectDeposit(int _deposit, int _oldHeight, SourceLocation const& _location); + Scope& scope(assembly::Block const* _block); void expectValidType(std::string const& type, SourceLocation const& _location); diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 0f836406..3200b360 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -200,6 +200,8 @@ std::map<string, dev::solidity::Instruction> const& Parser::instructions() // add alias for suicide s_instructions["suicide"] = solidity::Instruction::SELFDESTRUCT; + // add alis for sha3 + s_instructions["sha3"] = solidity::Instruction::KECCAK256; } return s_instructions; } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 44220402..aca9ce39 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -85,6 +85,7 @@ void CompilerStack::reset(bool _keepSources) } else { + m_stackState = Empty; m_sources.clear(); } m_optimize = false; @@ -94,7 +95,6 @@ void CompilerStack::reset(bool _keepSources) m_sourceOrder.clear(); m_contracts.clear(); m_errorReporter.clear(); - m_stackState = Empty; } bool CompilerStack::addSource(string const& _name, string const& _content, bool _isLibrary) @@ -400,15 +400,6 @@ eth::LinkerObject const& CompilerStack::cloneObject(string const& _contractName) return contract(_contractName).cloneObject; } -dev::h256 CompilerStack::contractCodeHash(string const& _contractName) const -{ - auto const& obj = runtimeObject(_contractName); - if (obj.bytecode.empty() || !obj.linkReferences.empty()) - return dev::h256(); - else - return dev::keccak256(obj.bytecode); -} - Json::Value CompilerStack::streamAssembly(ostream& _outStream, string const& _contractName, StringMap _sourceCodes, bool _inJsonFormat) const { Contract const& currentContract = contract(_contractName); @@ -744,14 +735,6 @@ void CompilerStack::compileContract( } } -std::string CompilerStack::defaultContractName() const -{ - if (m_stackState != CompilationSuccessful) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Compilation was not successful.")); - - return contract("").contract->name(); -} - CompilerStack::Contract const& CompilerStack::contract(string const& _contractName) const { if (m_contracts.empty()) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 76d36c7b..bffdeabd 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -117,7 +117,6 @@ public: bool parseAndAnalyze(std::string const& _sourceCode); /// @returns a list of the contract names in the sources. std::vector<std::string> contractNames() const; - std::string defaultContractName() const; /// Compiles the source units that were previously added and parsed. /// @returns false on error. @@ -159,11 +158,6 @@ public: /// @returns either the contract's name or a mixture of its name and source file, sanitized for filesystem use std::string const filesystemFriendlyName(std::string const& _contractName) const; - /// @returns hash of the runtime bytecode for the contract, i.e. the code that is - /// returned by the constructor or the zero-h256 if the contract still needs to be linked or - /// does not have runtime code. - dev::h256 contractCodeHash(std::string const& _contractName = "") const; - /// Streams a verbose version of the assembly to @a _outStream. /// @arg _sourceCodes is the map of input files to source code strings /// @arg _inJsonFromat shows whether the out should be in Json format @@ -197,13 +191,6 @@ public: /// does not exist. ContractDefinition const& contractDefinition(std::string const& _contractName) const; - /// @returns the offset of the entry point of the given function into the list of assembly items - /// or zero if it is not found or does not exist. - size_t functionEntryPoint( - std::string const& _contractName, - FunctionDefinition const& _function - ) const; - /// Helper function for logs printing. Do only use in error cases, it's quite expensive. /// line and columns are numbered starting from 1 with following order: /// start line, start column, end line, end column @@ -272,6 +259,13 @@ private: Json::Value const& contractABI(Contract const&) const; Json::Value const& natspec(Contract const&, DocumentationType _type) const; + /// @returns the offset of the entry point of the given function into the list of assembly items + /// or zero if it is not found or does not exist. + size_t functionEntryPoint( + std::string const& _contractName, + FunctionDefinition const& _function + ) const; + struct Remapping { std::string context; diff --git a/test/contracts/FixedFeeRegistrar.cpp b/test/contracts/FixedFeeRegistrar.cpp index 39c32eb7..d2904b5f 100644 --- a/test/contracts/FixedFeeRegistrar.cpp +++ b/test/contracts/FixedFeeRegistrar.cpp @@ -82,7 +82,7 @@ contract FixedFeeRegistrar is Registrar { } } function disown(string _name, address _refund) onlyrecordowner(_name) { - delete m_recordData[uint(sha3(_name)) / 8]; + delete m_recordData[uint(keccak256(_name)) / 8]; if (!_refund.send(c_fee)) throw; Changed(_name); @@ -118,7 +118,7 @@ contract FixedFeeRegistrar is Registrar { Record[2**253] m_recordData; function m_record(string _name) constant internal returns (Record storage o_record) { - return m_recordData[uint(sha3(_name)) / 8]; + return m_recordData[uint(keccak256(_name)) / 8]; } uint constant c_fee = 69 ether; } diff --git a/test/contracts/Wallet.cpp b/test/contracts/Wallet.cpp index 80f06613..ef345d86 100644 --- a/test/contracts/Wallet.cpp +++ b/test/contracts/Wallet.cpp @@ -128,7 +128,7 @@ contract multiowned { } // Replaces an owner `_from` with another `_to`. - function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data)) external { + function changeOwner(address _from, address _to) onlymanyowners(keccak256(msg.data)) external { if (isOwner(_to)) return; uint ownerIndex = m_ownerIndex[uint(_from)]; if (ownerIndex == 0) return; @@ -140,7 +140,7 @@ contract multiowned { OwnerChanged(_from, _to); } - function addOwner(address _owner) onlymanyowners(sha3(msg.data)) external { + function addOwner(address _owner) onlymanyowners(keccak256(msg.data)) external { if (isOwner(_owner)) return; clearPending(); @@ -154,7 +154,7 @@ contract multiowned { OwnerAdded(_owner); } - function removeOwner(address _owner) onlymanyowners(sha3(msg.data)) external { + function removeOwner(address _owner) onlymanyowners(keccak256(msg.data)) external { uint ownerIndex = m_ownerIndex[uint(_owner)]; if (ownerIndex == 0) return; if (m_required > m_numOwners - 1) return; @@ -166,7 +166,7 @@ contract multiowned { OwnerRemoved(_owner); } - function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data)) external { + function changeRequirement(uint _newRequired) onlymanyowners(keccak256(msg.data)) external { if (_newRequired > m_numOwners) return; m_required = _newRequired; clearPending(); @@ -293,11 +293,11 @@ contract daylimit is multiowned { m_lastDay = today(); } // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today. - function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data)) external { + function setDailyLimit(uint _newLimit) onlymanyowners(keccak256(msg.data)) external { m_dailyLimit = _newLimit; } // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today. - function resetSpentToday() onlymanyowners(sha3(msg.data)) external { + function resetSpentToday() onlymanyowners(keccak256(msg.data)) external { m_spentToday = 0; } @@ -374,7 +374,7 @@ contract Wallet is multisig, multiowned, daylimit { } // destroys the contract sending everything to `_to`. - function kill(address _to) onlymanyowners(sha3(msg.data)) external { + function kill(address _to) onlymanyowners(keccak256(msg.data)) external { selfdestruct(_to); } @@ -398,7 +398,7 @@ contract Wallet is multisig, multiowned, daylimit { return 0; } // determine our operation hash. - _r = sha3(msg.data, block.number); + _r = keccak256(msg.data, block.number); if (!confirm(_r) && m_txs[_r].to == 0) { m_txs[_r].to = _to; m_txs[_r].value = _value; diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index f90cb105..ef560b12 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -151,20 +151,20 @@ BOOST_AUTO_TEST_CASE(simple_contract) contract test { bytes32 public shaValue; function f(uint a) { - shaValue = sha3(a); + shaValue = keccak256(a); } } )"; testCreationTimeGas(sourceCode); } -BOOST_AUTO_TEST_CASE(store_sha3) +BOOST_AUTO_TEST_CASE(store_keccak256) { char const* sourceCode = R"( contract test { bytes32 public shaValue; function test(uint a) { - shaValue = sha3(a); + shaValue = keccak256(a); } } )"; diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index b390a40b..f0543101 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -481,6 +481,14 @@ BOOST_AUTO_TEST_CASE(revert) BOOST_CHECK(successAssemble("{ revert(0, 0) }")); } +BOOST_AUTO_TEST_CASE(keccak256) +{ + BOOST_CHECK(successAssemble("{ 0 0 keccak256 pop }")); + BOOST_CHECK(successAssemble("{ pop(keccak256(0, 0)) }")); + BOOST_CHECK(successAssemble("{ 0 0 sha3 pop }")); + BOOST_CHECK(successAssemble("{ pop(sha3(0, 0)) }")); +} + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 1ff0b6cb..aae8b146 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1355,7 +1355,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) function test() { data = 8; name = "Celina"; - a_hash = sha3(123); + a_hash = keccak256(123); an_address = address(0x1337); super_secret_data = 42; } @@ -1864,12 +1864,12 @@ BOOST_AUTO_TEST_CASE(selfdestruct) BOOST_CHECK_EQUAL(balanceAt(address), amount); } -BOOST_AUTO_TEST_CASE(sha3) +BOOST_AUTO_TEST_CASE(keccak256) { char const* sourceCode = R"( contract test { - function a(bytes32 input) returns (bytes32 sha3hash) { - return sha3(input); + function a(bytes32 input) returns (bytes32 hash) { + return keccak256(input); } } )"; @@ -1883,6 +1883,23 @@ BOOST_AUTO_TEST_CASE(sha3) testContractAgainstCpp("a(bytes32)", f, u256(-1)); } +BOOST_AUTO_TEST_CASE(sha3) +{ + char const* sourceCode = R"( + contract test { + // to confuse the optimiser + function b(bytes32 input) returns (bytes32) { + return sha3(input); + } + function a(bytes32 input) returns (bool) { + return keccak256(input) == b(input); + } + } + )"; + compileAndRun(sourceCode); + BOOST_REQUIRE(callContractFunction("a(bytes32)", u256(42)) == encodeArgs(true)); +} + BOOST_AUTO_TEST_CASE(sha256) { char const* sourceCode = R"( @@ -3110,13 +3127,13 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter) BOOST_CHECK(callContractFunction("f(uint256)", 9) == encodeArgs(9)); } -BOOST_AUTO_TEST_CASE(sha3_multiple_arguments) +BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments) { char const* sourceCode = R"( contract c { function foo(uint a, uint b, uint c) returns (bytes32 d) { - d = sha3(a, b, c); + d = keccak256(a, b, c); } } )"; @@ -3129,13 +3146,13 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments) toBigEndian(u256(13))))); } -BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals) +BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_numeric_literals) { char const* sourceCode = R"( contract c { function foo(uint a, uint16 b) returns (bytes32 d) { - d = sha3(a, b, 145); + d = keccak256(a, b, 145); } } )"; @@ -3148,17 +3165,17 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals) bytes(1, 0x91)))); } -BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) +BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_string_literals) { char const* sourceCode = R"( contract c { function foo() returns (bytes32 d) { - d = sha3("foo"); + d = keccak256("foo"); } function bar(uint a, uint16 b) returns (bytes32 d) { - d = sha3(a, b, 145, "foo"); + d = keccak256(a, b, 145, "foo"); } } )"; @@ -3174,7 +3191,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) bytes{0x66, 0x6f, 0x6f}))); } -BOOST_AUTO_TEST_CASE(sha3_with_bytes) +BOOST_AUTO_TEST_CASE(keccak256_with_bytes) { char const* sourceCode = R"( contract c { @@ -3185,7 +3202,7 @@ BOOST_AUTO_TEST_CASE(sha3_with_bytes) data[0] = "f"; data[1] = "o"; data[2] = "o"; - return sha3(data) == sha3("foo"); + return keccak256(data) == keccak256("foo"); } } )"; @@ -3193,7 +3210,7 @@ BOOST_AUTO_TEST_CASE(sha3_with_bytes) BOOST_CHECK(callContractFunction("foo()") == encodeArgs(true)); } -BOOST_AUTO_TEST_CASE(iterated_sha3_with_bytes) +BOOST_AUTO_TEST_CASE(iterated_keccak256_with_bytes) { char const* sourceCode = R"( contract c { @@ -3204,7 +3221,7 @@ BOOST_AUTO_TEST_CASE(iterated_sha3_with_bytes) data[0] = "x"; data[1] = "y"; data[2] = "z"; - return sha3("b", sha3(data), "a"); + return keccak256("b", keccak256(data), "a"); } } )"; @@ -3214,13 +3231,13 @@ BOOST_AUTO_TEST_CASE(iterated_sha3_with_bytes) )); } -BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments) +BOOST_AUTO_TEST_CASE(sha3_multiple_arguments) { char const* sourceCode = R"( contract c { function foo(uint a, uint b, uint c) returns (bytes32 d) { - d = keccak256(a, b, c); + d = sha3(a, b, c); } })"; compileAndRun(sourceCode); @@ -3245,7 +3262,7 @@ BOOST_AUTO_TEST_CASE(generic_call) function sender() payable {} function doSend(address rec) returns (uint d) { - bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); + bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)"))); rec.call.value(2)(signature, 23); return receiver(rec).received(); } @@ -3270,7 +3287,7 @@ BOOST_AUTO_TEST_CASE(generic_callcode) function Sender() payable { } function doSend(address rec) returns (uint d) { - bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); + bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)"))); rec.callcode.value(2)(signature, 23); return Receiver(rec).received(); } @@ -3307,7 +3324,7 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall) function Sender() payable {} function doSend(address rec) payable { - bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); + bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)"))); if (rec.delegatecall(signature, 23)) {} } } @@ -3372,7 +3389,7 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) char const* sourceCode = R"( contract C { function f() returns (bytes32) { - return sha3("abc", msg.data); + return keccak256("abc", msg.data); } } )"; @@ -5294,7 +5311,7 @@ BOOST_AUTO_TEST_CASE(reusing_memory) mapping(uint => uint) map; function f(uint x) returns (uint) { map[x] = x; - return (new Helper(uint(sha3(this.g(map[x]))))).flag(); + return (new Helper(uint(keccak256(this.g(map[x]))))).flag(); } function g(uint a) returns (uint) { @@ -9321,6 +9338,45 @@ BOOST_AUTO_TEST_CASE(interface) BOOST_CHECK(callContractFunction("f(address)", recipient) == encodeArgs(true)); } +BOOST_AUTO_TEST_CASE(keccak256_assembly) +{ + char const* sourceCode = R"( + contract C { + function f() returns (bytes32 ret) { + assembly { + ret := keccak256(0, 0) + } + } + function g() returns (bytes32 ret) { + assembly { + 0 + 0 + keccak256 + =: ret + } + } + function h() returns (bytes32 ret) { + assembly { + ret := sha3(0, 0) + } + } + function i() returns (bytes32 ret) { + assembly { + 0 + 0 + sha3 + =: ret + } + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); + BOOST_CHECK(callContractFunction("g()") == fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); + BOOST_CHECK(callContractFunction("h()") == fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); + BOOST_CHECK(callContractFunction("i()") == fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 0553c691..71726b93 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -2934,12 +2934,12 @@ BOOST_AUTO_TEST_CASE(non_initialized_references) CHECK_WARNING(text, "Uninitialized storage pointer"); } -BOOST_AUTO_TEST_CASE(sha3_with_large_integer_constant) +BOOST_AUTO_TEST_CASE(keccak256_with_large_integer_constant) { char const* text = R"( contract c { - function f() { sha3(2**500); } + function f() { keccak256(2**500); } } )"; CHECK_ERROR(text, TypeError, ""); @@ -5401,7 +5401,7 @@ BOOST_AUTO_TEST_CASE(cyclic_dependency_for_constants) contract C { uint constant a = b * c; uint constant b = 7; - uint constant c = b + uint(sha3(d)); + uint constant c = b + uint(keccak256(d)); uint constant d = 2 + a; } )"; @@ -5410,7 +5410,7 @@ BOOST_AUTO_TEST_CASE(cyclic_dependency_for_constants) contract C { uint constant a = b * c; uint constant b = 7; - uint constant c = 4 + uint(sha3(d)); + uint constant c = 4 + uint(keccak256(d)); uint constant d = 2 + b; } )"; diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index d705e3c8..bdcdacff 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -322,18 +322,18 @@ BOOST_AUTO_TEST_CASE(storage_write_in_loops) // Information in joining branches is not retained anymore. BOOST_AUTO_TEST_CASE(retain_information_in_branches) { - // This tests that the optimizer knows that we already have "z == sha3(y)" inside both branches. + // This tests that the optimizer knows that we already have "z == keccak256(y)" inside both branches. char const* sourceCode = R"( contract c { bytes32 d; uint a; function f(uint x, bytes32 y) returns (uint r_a, bytes32 r_d) { - bytes32 z = sha3(y); + bytes32 z = keccak256(y); if (x > 8) { - z = sha3(y); + z = keccak256(y); a = x; } else { - z = sha3(y); + z = keccak256(y); a = x; } r_a = a; @@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches) bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true); size_t numSHA3s = 0; eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { - if (_instr == Instruction::SHA3) + if (_instr == Instruction::KECCAK256) numSHA3s++; }); // TEST DISABLED - OPTIMIZER IS NOT EFFECTIVE ON THIS ONE ANYMORE @@ -358,7 +358,7 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches) BOOST_AUTO_TEST_CASE(store_tags_as_unions) { - // This calls the same function from two sources and both calls have a certain sha3 on + // This calls the same function from two sources and both calls have a certain Keccak-256 on // the stack at the same position. // Without storing tags as unions, the return from the shared function would not know where to // jump and thus all jumpdests are forced to clear their state and we do not know about the @@ -370,19 +370,19 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions) contract test { bytes32 data; function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { - r_d = sha3(y); + r_d = keccak256(y); shared(y); - r_d = sha3(y); + r_d = keccak256(y); r_a = 5; } function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { - r_d = sha3(y); + r_d = keccak256(y); shared(y); - r_d = bytes32(uint(sha3(y)) + 2); + r_d = bytes32(uint(keccak256(y)) + 2); r_a = 7; } function shared(bytes32 y) internal { - data = sha3(y); + data = keccak256(y); } } )"; @@ -392,7 +392,7 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions) bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "test", true); size_t numSHA3s = 0; eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { - if (_instr == Instruction::SHA3) + if (_instr == Instruction::KECCAK256) numSHA3s++; }); // TEST DISABLED UNTIL 93693404 IS IMPLEMENTED @@ -401,8 +401,8 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions) BOOST_AUTO_TEST_CASE(incorrect_storage_access_bug) { - // This bug appeared because a sha3 operation with too low sequence number was used, - // resulting in memory not being rewritten before the sha3. The fix was to + // This bug appeared because a Keccak-256 operation with too low sequence number was used, + // resulting in memory not being rewritten before the Keccak-256. The fix was to // take the max of the min sequence numbers when merging the states. char const* sourceCode = R"( contract C @@ -821,19 +821,19 @@ BOOST_AUTO_TEST_CASE(cse_jumpi_jump) }); } -BOOST_AUTO_TEST_CASE(cse_empty_sha3) +BOOST_AUTO_TEST_CASE(cse_empty_keccak256) { AssemblyItems input{ u256(0), Instruction::DUP2, - Instruction::SHA3 + Instruction::KECCAK256 }; checkCSE(input, { u256(dev::keccak256(bytesConstRef())) }); } -BOOST_AUTO_TEST_CASE(cse_partial_sha3) +BOOST_AUTO_TEST_CASE(cse_partial_keccak256) { AssemblyItems input{ u256(0xabcd) << (256 - 16), @@ -841,7 +841,7 @@ BOOST_AUTO_TEST_CASE(cse_partial_sha3) Instruction::MSTORE, u256(2), u256(0), - Instruction::SHA3 + Instruction::KECCAK256 }; checkCSE(input, { u256(0xabcd) << (256 - 16), @@ -851,19 +851,19 @@ BOOST_AUTO_TEST_CASE(cse_partial_sha3) }); } -BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_location) +BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_location) { - // sha3 twice from same dynamic location + // Keccak-256 twice from same dynamic location AssemblyItems input{ Instruction::DUP2, Instruction::DUP1, Instruction::MSTORE, u256(64), Instruction::DUP2, - Instruction::SHA3, + Instruction::KECCAK256, u256(64), Instruction::DUP3, - Instruction::SHA3 + Instruction::KECCAK256 }; checkCSE(input, { Instruction::DUP2, @@ -871,27 +871,27 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_location) Instruction::MSTORE, u256(64), Instruction::DUP2, - Instruction::SHA3, + Instruction::KECCAK256, Instruction::DUP1 }); } -BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content) +BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content) { - // sha3 twice from different dynamic location but with same content + // Keccak-256 twice from different dynamic location but with same content AssemblyItems input{ Instruction::DUP1, u256(0x80), Instruction::MSTORE, // m[128] = DUP1 u256(0x20), u256(0x80), - Instruction::SHA3, // sha3(m[128..(128+32)]) + Instruction::KECCAK256, // keccak256(m[128..(128+32)]) Instruction::DUP2, u256(12), Instruction::MSTORE, // m[12] = DUP1 u256(0x20), u256(12), - Instruction::SHA3 // sha3(m[12..(12+32)]) + Instruction::KECCAK256 // keccak256(m[12..(12+32)]) }; checkCSE(input, { u256(0x80), @@ -900,7 +900,7 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content) Instruction::MSTORE, u256(0x20), Instruction::SWAP1, - Instruction::SHA3, + Instruction::KECCAK256, u256(12), Instruction::DUP3, Instruction::SWAP1, @@ -909,10 +909,10 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content) }); } -BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_dynamic_store_in_between) +BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content_dynamic_store_in_between) { - // sha3 twice from different dynamic location but with same content, - // dynamic mstore in between, which forces us to re-calculate the sha3 + // Keccak-256 twice from different dynamic location but with same content, + // dynamic mstore in between, which forces us to re-calculate the hash AssemblyItems input{ u256(0x80), Instruction::DUP2, @@ -921,7 +921,7 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_dynamic_store_in_between) u256(0x20), Instruction::DUP1, Instruction::DUP3, - Instruction::SHA3, // sha3(m[128..(128+32)]) + Instruction::KECCAK256, // keccak256(m[128..(128+32)]) u256(12), Instruction::DUP5, Instruction::DUP2, @@ -932,15 +932,15 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_dynamic_store_in_between) Instruction::SWAP2, Instruction::SWAP1, Instruction::SWAP2, - Instruction::SHA3 // sha3(m[12..(12+32)]) + Instruction::KECCAK256 // keccak256(m[12..(12+32)]) }; checkCSE(input, input); } -BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between) +BOOST_AUTO_TEST_CASE(cse_keccak256_twice_same_content_noninterfering_store_in_between) { - // sha3 twice from different dynamic location but with same content, - // dynamic mstore in between, but does not force us to re-calculate the sha3 + // Keccak-256 twice from different dynamic location but with same content, + // dynamic mstore in between, but does not force us to re-calculate the hash AssemblyItems input{ u256(0x80), Instruction::DUP2, @@ -949,7 +949,7 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between u256(0x20), Instruction::DUP1, Instruction::DUP3, - Instruction::SHA3, // sha3(m[128..(128+32)]) + Instruction::KECCAK256, // keccak256(m[128..(128+32)]) u256(12), Instruction::DUP5, Instruction::DUP2, @@ -962,12 +962,12 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between Instruction::MSTORE, // does not destoy memory knowledge u256(0x20), u256(12), - Instruction::SHA3 // sha3(m[12..(12+32)]) + Instruction::KECCAK256 // keccak256(m[12..(12+32)]) }; // if this changes too often, only count the number of SHA3 and MSTORE instructions AssemblyItems output = CSE(input); BOOST_CHECK_EQUAL(4, count(output.begin(), output.end(), AssemblyItem(Instruction::MSTORE))); - BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::SHA3))); + BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::KECCAK256))); } BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack) @@ -1296,7 +1296,7 @@ BOOST_AUTO_TEST_CASE(constant_optimization_early_exit) // Store and hash assembly { mstore(32, x) - ret := sha3(0, 40) + ret := keccak256(0, 40) } } } |