aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Changelog.md2
-rw-r--r--docs/assembly.rst2
-rw-r--r--docs/index.rst5
-rw-r--r--docs/logo.svg27
-rw-r--r--docs/miscellaneous.rst2
-rw-r--r--libevmasm/CommonSubexpressionEliminator.cpp4
-rw-r--r--libevmasm/EVMSchedule.h4
-rw-r--r--libevmasm/GasMeter.cpp6
-rw-r--r--libevmasm/GasMeter.h4
-rw-r--r--libevmasm/Instruction.cpp4
-rw-r--r--libevmasm/Instruction.h2
-rw-r--r--libevmasm/KnownState.cpp20
-rw-r--r--libevmasm/KnownState.h8
-rw-r--r--libsolidity/codegen/ArrayUtils.cpp4
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp2
-rw-r--r--libsolidity/codegen/CompilerUtils.h2
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp8
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp60
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.h7
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp2
-rw-r--r--libsolidity/interface/CompilerStack.cpp19
-rw-r--r--libsolidity/interface/CompilerStack.h20
-rw-r--r--test/contracts/FixedFeeRegistrar.cpp4
-rw-r--r--test/contracts/Wallet.cpp16
-rw-r--r--test/libsolidity/GasMeter.cpp6
-rw-r--r--test/libsolidity/InlineAssembly.cpp8
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp100
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp8
-rw-r--r--test/libsolidity/SolidityOptimizer.cpp80
30 files changed, 254 insertions, 183 deletions
diff --git a/.gitignore b/.gitignore
index 47739568..114420c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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)
}
}
}