mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2317 from ethereum/keccak256
Use keccak256 in tests and replace the SHA3 instruction in assembly
This commit is contained in:
commit
d4a57d81ba
@ -1,9 +1,11 @@
|
|||||||
### 0.4.12 (unreleased)
|
### 0.4.12 (unreleased)
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
* Assembler: renamed ``SHA3`` to `KECCAK256``.
|
||||||
* AST: export all attributes to Json format
|
* AST: export all attributes to Json format
|
||||||
* Inline Assembly: Present proper error message when not supplying enough arguments to a functional
|
* Inline Assembly: Present proper error message when not supplying enough arguments to a functional
|
||||||
instruction.
|
instruction.
|
||||||
|
* Inline Assembly: introduce ``keccak256`` as an opcode. ``sha3`` is still a valid alias.
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Unused variable warnings no longer issued for variables used inside inline assembly
|
* Unused variable warnings no longer issued for variables used inside inline assembly
|
||||||
|
@ -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 |
|
| 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))) |
|
| sha3(p, n) | | keccak(mem[p...(p+n))) |
|
||||||
+-------------------------+------+-----------------------------------------------------------------+
|
+-------------------------+------+-----------------------------------------------------------------+
|
||||||
| jump(label) | `-` | jump to label / code position |
|
| jump(label) | `-` | jump to label / code position |
|
||||||
|
@ -234,7 +234,7 @@ void CSECodeGenerator::addDependencies(Id _c)
|
|||||||
if (expr.item && expr.item->type() == Operation && (
|
if (expr.item && expr.item->type() == Operation && (
|
||||||
expr.item->instruction() == Instruction::SLOAD ||
|
expr.item->instruction() == Instruction::SLOAD ||
|
||||||
expr.item->instruction() == Instruction::MLOAD ||
|
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
|
// 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:
|
case Instruction::MLOAD:
|
||||||
knownToBeIndependent = m_expressionClasses.knownToBeDifferentBy32(slot, slotToLoadFrom);
|
knownToBeIndependent = m_expressionClasses.knownToBeDifferentBy32(slot, slotToLoadFrom);
|
||||||
break;
|
break;
|
||||||
case Instruction::SHA3:
|
case Instruction::KECCAK256:
|
||||||
{
|
{
|
||||||
Id length = expr.arguments.at(1);
|
Id length = expr.arguments.at(1);
|
||||||
AssemblyItem offsetInstr(Instruction::SUB, expr.item->location());
|
AssemblyItem offsetInstr(Instruction::SUB, expr.item->location());
|
||||||
|
@ -32,8 +32,8 @@ struct EVMSchedule
|
|||||||
unsigned stackLimit = 1024;
|
unsigned stackLimit = 1024;
|
||||||
unsigned expGas = 10;
|
unsigned expGas = 10;
|
||||||
unsigned expByteGas = 10;
|
unsigned expByteGas = 10;
|
||||||
unsigned sha3Gas = 30;
|
unsigned keccak256Gas = 30;
|
||||||
unsigned sha3WordGas = 6;
|
unsigned keccak256WordGas = 6;
|
||||||
unsigned sloadGas = 200;
|
unsigned sloadGas = 200;
|
||||||
unsigned sstoreSetGas = 20000;
|
unsigned sstoreSetGas = 20000;
|
||||||
unsigned sstoreResetGas = 5000;
|
unsigned sstoreResetGas = 5000;
|
||||||
|
@ -96,9 +96,9 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
|
|||||||
classes.find(AssemblyItem(1))
|
classes.find(AssemblyItem(1))
|
||||||
}));
|
}));
|
||||||
break;
|
break;
|
||||||
case Instruction::SHA3:
|
case Instruction::KECCAK256:
|
||||||
gas = GasCosts::sha3Gas;
|
gas = GasCosts::keccak256Gas;
|
||||||
gas += wordGas(GasCosts::sha3WordGas, m_state->relativeStackElement(-1));
|
gas += wordGas(GasCosts::keccak256WordGas, m_state->relativeStackElement(-1));
|
||||||
gas += memoryGas(0, -1);
|
gas += memoryGas(0, -1);
|
||||||
break;
|
break;
|
||||||
case Instruction::CALLDATACOPY:
|
case Instruction::CALLDATACOPY:
|
||||||
|
@ -48,8 +48,8 @@ namespace GasCosts
|
|||||||
static unsigned const balanceGas = 400;
|
static unsigned const balanceGas = 400;
|
||||||
static unsigned const expGas = 10;
|
static unsigned const expGas = 10;
|
||||||
static unsigned const expByteGas = 50;
|
static unsigned const expByteGas = 50;
|
||||||
static unsigned const sha3Gas = 30;
|
static unsigned const keccak256Gas = 30;
|
||||||
static unsigned const sha3WordGas = 6;
|
static unsigned const keccak256WordGas = 6;
|
||||||
static unsigned const sloadGas = 200;
|
static unsigned const sloadGas = 200;
|
||||||
static unsigned const sstoreSetGas = 20000;
|
static unsigned const sstoreSetGas = 20000;
|
||||||
static unsigned const sstoreResetGas = 5000;
|
static unsigned const sstoreResetGas = 5000;
|
||||||
|
@ -53,7 +53,7 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions =
|
|||||||
{ "ADDMOD", Instruction::ADDMOD },
|
{ "ADDMOD", Instruction::ADDMOD },
|
||||||
{ "MULMOD", Instruction::MULMOD },
|
{ "MULMOD", Instruction::MULMOD },
|
||||||
{ "SIGNEXTEND", Instruction::SIGNEXTEND },
|
{ "SIGNEXTEND", Instruction::SIGNEXTEND },
|
||||||
{ "SHA3", Instruction::SHA3 },
|
{ "KECCAK256", Instruction::KECCAK256 },
|
||||||
{ "ADDRESS", Instruction::ADDRESS },
|
{ "ADDRESS", Instruction::ADDRESS },
|
||||||
{ "BALANCE", Instruction::BALANCE },
|
{ "BALANCE", Instruction::BALANCE },
|
||||||
{ "ORIGIN", Instruction::ORIGIN },
|
{ "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::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } },
|
||||||
{ Instruction::MULMOD, { "MULMOD", 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::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::ADDRESS, { "ADDRESS", 0, 0, 1, false, Tier::Base } },
|
||||||
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Balance } },
|
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Balance } },
|
||||||
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } },
|
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } },
|
||||||
|
@ -62,7 +62,7 @@ enum class Instruction: uint8_t
|
|||||||
NOT, ///< bitwise NOT opertation
|
NOT, ///< bitwise NOT opertation
|
||||||
BYTE, ///< retrieve single byte from word
|
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
|
ADDRESS = 0x30, ///< get address of currently executing account
|
||||||
BALANCE, ///< get balance of the given account
|
BALANCE, ///< get balance of the given account
|
||||||
|
@ -136,10 +136,10 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool
|
|||||||
m_stackHeight + _item.deposit(),
|
m_stackHeight + _item.deposit(),
|
||||||
loadFromMemory(arguments[0], _item.location())
|
loadFromMemory(arguments[0], _item.location())
|
||||||
);
|
);
|
||||||
else if (_item.instruction() == Instruction::SHA3)
|
else if (_item.instruction() == Instruction::KECCAK256)
|
||||||
setStackElement(
|
setStackElement(
|
||||||
m_stackHeight + _item.deposit(),
|
m_stackHeight + _item.deposit(),
|
||||||
applySha3(arguments.at(0), arguments.at(1), _item.location())
|
applyKeccak256(arguments.at(0), arguments.at(1), _item.location())
|
||||||
);
|
);
|
||||||
else
|
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);
|
return m_memoryContent[_slot] = m_expressionClasses->find(item, {_slot}, true, m_sequenceNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
KnownState::Id KnownState::applySha3(
|
KnownState::Id KnownState::applyKeccak256(
|
||||||
Id _start,
|
Id _start,
|
||||||
Id _length,
|
Id _length,
|
||||||
SourceLocation const& _location
|
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.
|
// Special logic if length is a short constant, otherwise we cannot tell.
|
||||||
u256 const* l = m_expressionClasses->knownConstant(_length);
|
u256 const* l = m_expressionClasses->knownConstant(_length);
|
||||||
// unknown or too large length
|
// unknown or too large length
|
||||||
if (!l || *l > 128)
|
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;
|
vector<Id> arguments;
|
||||||
for (u256 i = 0; i < *l; i += 32)
|
for (u256 i = 0; i < *l; i += 32)
|
||||||
@ -368,10 +368,10 @@ KnownState::Id KnownState::applySha3(
|
|||||||
);
|
);
|
||||||
arguments.push_back(loadFromMemory(slot, _location));
|
arguments.push_back(loadFromMemory(slot, _location));
|
||||||
}
|
}
|
||||||
if (m_knownSha3Hashes.count(arguments))
|
if (m_knownKeccak256Hashes.count(arguments))
|
||||||
return m_knownSha3Hashes.at(arguments);
|
return m_knownKeccak256Hashes.at(arguments);
|
||||||
Id v;
|
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); }))
|
if (all_of(arguments.begin(), arguments.end(), [this](Id _a) { return !!m_expressionClasses->knownConstant(_a); }))
|
||||||
{
|
{
|
||||||
bytes data;
|
bytes data;
|
||||||
@ -381,8 +381,8 @@ KnownState::Id KnownState::applySha3(
|
|||||||
v = m_expressionClasses->find(AssemblyItem(u256(dev::keccak256(data)), _location));
|
v = m_expressionClasses->find(AssemblyItem(u256(dev::keccak256(data)), _location));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
v = m_expressionClasses->find(sha3Item, {_start, _length}, true, m_sequenceNumber);
|
v = m_expressionClasses->find(keccak256Item, {_start, _length}, true, m_sequenceNumber);
|
||||||
return m_knownSha3Hashes[arguments] = v;
|
return m_knownKeccak256Hashes[arguments] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
set<u256> KnownState::tagsInExpression(KnownState::Id _expressionId)
|
set<u256> KnownState::tagsInExpression(KnownState::Id _expressionId)
|
||||||
|
@ -150,8 +150,8 @@ private:
|
|||||||
StoreOperation storeInMemory(Id _slot, Id _value, SourceLocation const& _location);
|
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.
|
/// Retrieves the current value at the given slot in memory or creates a new special mload class.
|
||||||
Id loadFromMemory(Id _slot, SourceLocation const& _location);
|
Id loadFromMemory(Id _slot, SourceLocation const& _location);
|
||||||
/// Finds or creates a new expression that applies the sha3 hash function to the contents in memory.
|
/// Finds or creates a new expression that applies the Keccak-256 hash function to the contents in memory.
|
||||||
Id applySha3(Id _start, Id _length, SourceLocation const& _location);
|
Id applyKeccak256(Id _start, Id _length, SourceLocation const& _location);
|
||||||
|
|
||||||
/// @returns a new or already used Id representing the given set of tags.
|
/// @returns a new or already used Id representing the given set of tags.
|
||||||
Id tagUnion(std::set<u256> _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
|
/// Knowledge about memory content. Keys are memory addresses, note that the values overlap
|
||||||
/// and are not contained here if they are not completely known.
|
/// and are not contained here if they are not completely known.
|
||||||
std::map<Id, Id> m_memoryContent;
|
std::map<Id, Id> m_memoryContent;
|
||||||
/// Keeps record of all sha3 hashes that are computed.
|
/// Keeps record of all Keccak-256 hashes that are computed.
|
||||||
std::map<std::vector<Id>, Id> m_knownSha3Hashes;
|
std::map<std::vector<Id>, Id> m_knownKeccak256Hashes;
|
||||||
/// Structure containing the classes of equivalent expressions.
|
/// Structure containing the classes of equivalent expressions.
|
||||||
std::shared_ptr<ExpressionClasses> m_expressionClasses;
|
std::shared_ptr<ExpressionClasses> m_expressionClasses;
|
||||||
/// Container for unions of tags stored on the stack.
|
/// Container for unions of tags stored on the stack.
|
||||||
|
@ -449,7 +449,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord
|
|||||||
m_context << Instruction::DUP3 << Instruction::ADD << Instruction::SWAP2;
|
m_context << Instruction::DUP3 << Instruction::ADD << Instruction::SWAP2;
|
||||||
if (_sourceType.isDynamicallySized())
|
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;
|
m_context << Instruction::SWAP1;
|
||||||
utils.computeHashStatic();
|
utils.computeHashStatic();
|
||||||
m_context << Instruction::SWAP1;
|
m_context << Instruction::SWAP1;
|
||||||
@ -731,7 +731,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
|
|||||||
_context << Instruction::POP;
|
_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
|
// stack: ref new_length old_length
|
||||||
// store new length
|
// store new length
|
||||||
_context << Instruction::DUP2;
|
_context << Instruction::DUP2;
|
||||||
|
@ -934,7 +934,7 @@ unsigned CompilerUtils::sizeOnStack(vector<shared_ptr<Type const>> const& _varia
|
|||||||
void CompilerUtils::computeHashStatic()
|
void CompilerUtils::computeHashStatic()
|
||||||
{
|
{
|
||||||
storeInMemory(0);
|
storeInMemory(0);
|
||||||
m_context << u256(32) << u256(0) << Instruction::SHA3;
|
m_context << u256(32) << u256(0) << Instruction::KECCAK256;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::storeStringData(bytesConstRef _data)
|
void CompilerUtils::storeStringData(bytesConstRef _data)
|
||||||
|
@ -166,7 +166,7 @@ public:
|
|||||||
static unsigned sizeOnStack(std::vector<T> const& _variables);
|
static unsigned sizeOnStack(std::vector<T> const& _variables);
|
||||||
static unsigned sizeOnStack(std::vector<std::shared_ptr<Type const>> const& _variableTypes);
|
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();
|
void computeHashStatic();
|
||||||
|
|
||||||
/// Bytes we need to the start of call data.
|
/// Bytes we need to the start of call data.
|
||||||
|
@ -110,7 +110,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
|
|||||||
// move key to memory.
|
// move key to memory.
|
||||||
utils().copyToStackTop(paramTypes.size() - i, 1);
|
utils().copyToStackTop(paramTypes.size() - i, 1);
|
||||||
utils().storeInMemory(0);
|
utils().storeInMemory(0);
|
||||||
m_context << u256(64) << u256(0) << Instruction::SHA3;
|
m_context << u256(64) << u256(0) << Instruction::KECCAK256;
|
||||||
// push offset
|
// push offset
|
||||||
m_context << u256(0);
|
m_context << u256(0);
|
||||||
returnType = mappingType->valueType();
|
returnType = mappingType->valueType();
|
||||||
@ -674,7 +674,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
utils().encodeToMemory(argumentTypes, TypePointers(), function.padArguments(), true);
|
utils().encodeToMemory(argumentTypes, TypePointers(), function.padArguments(), true);
|
||||||
utils().toSizeAfterFreeMemoryPointer();
|
utils().toSizeAfterFreeMemoryPointer();
|
||||||
m_context << Instruction::SHA3;
|
m_context << Instruction::KECCAK256;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FunctionType::Kind::Log0:
|
case FunctionType::Kind::Log0:
|
||||||
@ -721,7 +721,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
utils().toSizeAfterFreeMemoryPointer();
|
utils().toSizeAfterFreeMemoryPointer();
|
||||||
m_context << Instruction::SHA3;
|
m_context << Instruction::KECCAK256;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
utils().convertType(
|
utils().convertType(
|
||||||
@ -1214,7 +1214,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
|||||||
utils().storeInMemoryDynamic(IntegerType(256));
|
utils().storeInMemoryDynamic(IntegerType(256));
|
||||||
m_context << u256(0);
|
m_context << u256(0);
|
||||||
}
|
}
|
||||||
m_context << Instruction::SHA3;
|
m_context << Instruction::KECCAK256;
|
||||||
m_context << u256(0);
|
m_context << u256(0);
|
||||||
setLValueToStorageItem(_indexAccess);
|
setLValueToStorageItem(_indexAccess);
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,8 @@ std::map<string, dev::solidity::Instruction> const& Parser::instructions()
|
|||||||
|
|
||||||
// add alias for suicide
|
// add alias for suicide
|
||||||
s_instructions["suicide"] = solidity::Instruction::SELFDESTRUCT;
|
s_instructions["suicide"] = solidity::Instruction::SELFDESTRUCT;
|
||||||
|
// add alis for sha3
|
||||||
|
s_instructions["sha3"] = solidity::Instruction::KECCAK256;
|
||||||
}
|
}
|
||||||
return s_instructions;
|
return s_instructions;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ contract FixedFeeRegistrar is Registrar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function disown(string _name, address _refund) onlyrecordowner(_name) {
|
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))
|
if (!_refund.send(c_fee))
|
||||||
throw;
|
throw;
|
||||||
Changed(_name);
|
Changed(_name);
|
||||||
@ -118,7 +118,7 @@ contract FixedFeeRegistrar is Registrar {
|
|||||||
|
|
||||||
Record[2**253] m_recordData;
|
Record[2**253] m_recordData;
|
||||||
function m_record(string _name) constant internal returns (Record storage o_record) {
|
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;
|
uint constant c_fee = 69 ether;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ contract multiowned {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replaces an owner `_from` with another `_to`.
|
// 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;
|
if (isOwner(_to)) return;
|
||||||
uint ownerIndex = m_ownerIndex[uint(_from)];
|
uint ownerIndex = m_ownerIndex[uint(_from)];
|
||||||
if (ownerIndex == 0) return;
|
if (ownerIndex == 0) return;
|
||||||
@ -140,7 +140,7 @@ contract multiowned {
|
|||||||
OwnerChanged(_from, _to);
|
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;
|
if (isOwner(_owner)) return;
|
||||||
|
|
||||||
clearPending();
|
clearPending();
|
||||||
@ -154,7 +154,7 @@ contract multiowned {
|
|||||||
OwnerAdded(_owner);
|
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)];
|
uint ownerIndex = m_ownerIndex[uint(_owner)];
|
||||||
if (ownerIndex == 0) return;
|
if (ownerIndex == 0) return;
|
||||||
if (m_required > m_numOwners - 1) return;
|
if (m_required > m_numOwners - 1) return;
|
||||||
@ -166,7 +166,7 @@ contract multiowned {
|
|||||||
OwnerRemoved(_owner);
|
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;
|
if (_newRequired > m_numOwners) return;
|
||||||
m_required = _newRequired;
|
m_required = _newRequired;
|
||||||
clearPending();
|
clearPending();
|
||||||
@ -293,11 +293,11 @@ contract daylimit is multiowned {
|
|||||||
m_lastDay = today();
|
m_lastDay = today();
|
||||||
}
|
}
|
||||||
// (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent 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;
|
m_dailyLimit = _newLimit;
|
||||||
}
|
}
|
||||||
// (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.
|
// (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;
|
m_spentToday = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +374,7 @@ contract Wallet is multisig, multiowned, daylimit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// destroys the contract sending everything to `_to`.
|
// 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);
|
selfdestruct(_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +398,7 @@ contract Wallet is multisig, multiowned, daylimit {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// determine our operation hash.
|
// determine our operation hash.
|
||||||
_r = sha3(msg.data, block.number);
|
_r = keccak256(msg.data, block.number);
|
||||||
if (!confirm(_r) && m_txs[_r].to == 0) {
|
if (!confirm(_r) && m_txs[_r].to == 0) {
|
||||||
m_txs[_r].to = _to;
|
m_txs[_r].to = _to;
|
||||||
m_txs[_r].value = _value;
|
m_txs[_r].value = _value;
|
||||||
|
@ -151,20 +151,20 @@ BOOST_AUTO_TEST_CASE(simple_contract)
|
|||||||
contract test {
|
contract test {
|
||||||
bytes32 public shaValue;
|
bytes32 public shaValue;
|
||||||
function f(uint a) {
|
function f(uint a) {
|
||||||
shaValue = sha3(a);
|
shaValue = keccak256(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
testCreationTimeGas(sourceCode);
|
testCreationTimeGas(sourceCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(store_sha3)
|
BOOST_AUTO_TEST_CASE(store_keccak256)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract test {
|
contract test {
|
||||||
bytes32 public shaValue;
|
bytes32 public shaValue;
|
||||||
function test(uint a) {
|
function test(uint a) {
|
||||||
shaValue = sha3(a);
|
shaValue = keccak256(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
@ -481,6 +481,14 @@ BOOST_AUTO_TEST_CASE(revert)
|
|||||||
BOOST_CHECK(successAssemble("{ revert(0, 0) }"));
|
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()
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -1355,7 +1355,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
|
|||||||
function test() {
|
function test() {
|
||||||
data = 8;
|
data = 8;
|
||||||
name = "Celina";
|
name = "Celina";
|
||||||
a_hash = sha3(123);
|
a_hash = keccak256(123);
|
||||||
an_address = address(0x1337);
|
an_address = address(0x1337);
|
||||||
super_secret_data = 42;
|
super_secret_data = 42;
|
||||||
}
|
}
|
||||||
@ -1864,12 +1864,12 @@ BOOST_AUTO_TEST_CASE(selfdestruct)
|
|||||||
BOOST_CHECK_EQUAL(balanceAt(address), amount);
|
BOOST_CHECK_EQUAL(balanceAt(address), amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sha3)
|
BOOST_AUTO_TEST_CASE(keccak256)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function a(bytes32 input) returns (bytes32 sha3hash) {
|
function a(bytes32 input) returns (bytes32 hash) {
|
||||||
return sha3(input);
|
return keccak256(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -1883,6 +1883,23 @@ BOOST_AUTO_TEST_CASE(sha3)
|
|||||||
testContractAgainstCpp("a(bytes32)", f, u256(-1));
|
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)
|
BOOST_AUTO_TEST_CASE(sha256)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
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_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"(
|
char const* sourceCode = R"(
|
||||||
contract c {
|
contract c {
|
||||||
function foo(uint a, uint b, uint c) returns (bytes32 d)
|
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)))));
|
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"(
|
char const* sourceCode = R"(
|
||||||
contract c {
|
contract c {
|
||||||
function foo(uint a, uint16 b) returns (bytes32 d)
|
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))));
|
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"(
|
char const* sourceCode = R"(
|
||||||
contract c {
|
contract c {
|
||||||
function foo() returns (bytes32 d)
|
function foo() returns (bytes32 d)
|
||||||
{
|
{
|
||||||
d = sha3("foo");
|
d = keccak256("foo");
|
||||||
}
|
}
|
||||||
function bar(uint a, uint16 b) returns (bytes32 d)
|
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})));
|
bytes{0x66, 0x6f, 0x6f})));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sha3_with_bytes)
|
BOOST_AUTO_TEST_CASE(keccak256_with_bytes)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract c {
|
contract c {
|
||||||
@ -3185,7 +3202,7 @@ BOOST_AUTO_TEST_CASE(sha3_with_bytes)
|
|||||||
data[0] = "f";
|
data[0] = "f";
|
||||||
data[1] = "o";
|
data[1] = "o";
|
||||||
data[2] = "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_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"(
|
char const* sourceCode = R"(
|
||||||
contract c {
|
contract c {
|
||||||
@ -3204,7 +3221,7 @@ BOOST_AUTO_TEST_CASE(iterated_sha3_with_bytes)
|
|||||||
data[0] = "x";
|
data[0] = "x";
|
||||||
data[1] = "y";
|
data[1] = "y";
|
||||||
data[2] = "z";
|
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"(
|
char const* sourceCode = R"(
|
||||||
contract c {
|
contract c {
|
||||||
function foo(uint a, uint b, uint c) returns (bytes32 d)
|
function foo(uint a, uint b, uint c) returns (bytes32 d)
|
||||||
{
|
{
|
||||||
d = keccak256(a, b, c);
|
d = sha3(a, b, c);
|
||||||
}
|
}
|
||||||
})";
|
})";
|
||||||
compileAndRun(sourceCode);
|
compileAndRun(sourceCode);
|
||||||
@ -3245,7 +3262,7 @@ BOOST_AUTO_TEST_CASE(generic_call)
|
|||||||
function sender() payable {}
|
function sender() payable {}
|
||||||
function doSend(address rec) returns (uint d)
|
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);
|
rec.call.value(2)(signature, 23);
|
||||||
return receiver(rec).received();
|
return receiver(rec).received();
|
||||||
}
|
}
|
||||||
@ -3270,7 +3287,7 @@ BOOST_AUTO_TEST_CASE(generic_callcode)
|
|||||||
function Sender() payable { }
|
function Sender() payable { }
|
||||||
function doSend(address rec) returns (uint d)
|
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);
|
rec.callcode.value(2)(signature, 23);
|
||||||
return Receiver(rec).received();
|
return Receiver(rec).received();
|
||||||
}
|
}
|
||||||
@ -3307,7 +3324,7 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall)
|
|||||||
function Sender() payable {}
|
function Sender() payable {}
|
||||||
function doSend(address rec) 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)) {}
|
if (rec.delegatecall(signature, 23)) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3372,7 +3389,7 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory)
|
|||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract C {
|
contract C {
|
||||||
function f() returns (bytes32) {
|
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;
|
mapping(uint => uint) map;
|
||||||
function f(uint x) returns (uint) {
|
function f(uint x) returns (uint) {
|
||||||
map[x] = x;
|
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)
|
function g(uint a) returns (uint)
|
||||||
{
|
{
|
||||||
@ -9321,6 +9338,45 @@ BOOST_AUTO_TEST_CASE(interface)
|
|||||||
BOOST_CHECK(callContractFunction("f(address)", recipient) == encodeArgs(true));
|
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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2934,12 +2934,12 @@ BOOST_AUTO_TEST_CASE(non_initialized_references)
|
|||||||
CHECK_WARNING(text, "Uninitialized storage pointer");
|
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"(
|
char const* text = R"(
|
||||||
contract c
|
contract c
|
||||||
{
|
{
|
||||||
function f() { sha3(2**500); }
|
function f() { keccak256(2**500); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
CHECK_ERROR(text, TypeError, "");
|
CHECK_ERROR(text, TypeError, "");
|
||||||
@ -5401,7 +5401,7 @@ BOOST_AUTO_TEST_CASE(cyclic_dependency_for_constants)
|
|||||||
contract C {
|
contract C {
|
||||||
uint constant a = b * c;
|
uint constant a = b * c;
|
||||||
uint constant b = 7;
|
uint constant b = 7;
|
||||||
uint constant c = b + uint(sha3(d));
|
uint constant c = b + uint(keccak256(d));
|
||||||
uint constant d = 2 + a;
|
uint constant d = 2 + a;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -5410,7 +5410,7 @@ BOOST_AUTO_TEST_CASE(cyclic_dependency_for_constants)
|
|||||||
contract C {
|
contract C {
|
||||||
uint constant a = b * c;
|
uint constant a = b * c;
|
||||||
uint constant b = 7;
|
uint constant b = 7;
|
||||||
uint constant c = 4 + uint(sha3(d));
|
uint constant c = 4 + uint(keccak256(d));
|
||||||
uint constant d = 2 + b;
|
uint constant d = 2 + b;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
@ -322,18 +322,18 @@ BOOST_AUTO_TEST_CASE(storage_write_in_loops)
|
|||||||
// Information in joining branches is not retained anymore.
|
// Information in joining branches is not retained anymore.
|
||||||
BOOST_AUTO_TEST_CASE(retain_information_in_branches)
|
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"(
|
char const* sourceCode = R"(
|
||||||
contract c {
|
contract c {
|
||||||
bytes32 d;
|
bytes32 d;
|
||||||
uint a;
|
uint a;
|
||||||
function f(uint x, bytes32 y) returns (uint r_a, bytes32 r_d) {
|
function f(uint x, bytes32 y) returns (uint r_a, bytes32 r_d) {
|
||||||
bytes32 z = sha3(y);
|
bytes32 z = keccak256(y);
|
||||||
if (x > 8) {
|
if (x > 8) {
|
||||||
z = sha3(y);
|
z = keccak256(y);
|
||||||
a = x;
|
a = x;
|
||||||
} else {
|
} else {
|
||||||
z = sha3(y);
|
z = keccak256(y);
|
||||||
a = x;
|
a = x;
|
||||||
}
|
}
|
||||||
r_a = a;
|
r_a = a;
|
||||||
@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches)
|
|||||||
bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true);
|
bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true);
|
||||||
size_t numSHA3s = 0;
|
size_t numSHA3s = 0;
|
||||||
eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) {
|
eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) {
|
||||||
if (_instr == Instruction::SHA3)
|
if (_instr == Instruction::KECCAK256)
|
||||||
numSHA3s++;
|
numSHA3s++;
|
||||||
});
|
});
|
||||||
// TEST DISABLED - OPTIMIZER IS NOT EFFECTIVE ON THIS ONE ANYMORE
|
// 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)
|
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.
|
// the stack at the same position.
|
||||||
// Without storing tags as unions, the return from the shared function would not know where to
|
// 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
|
// 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 {
|
contract test {
|
||||||
bytes32 data;
|
bytes32 data;
|
||||||
function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
|
function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
|
||||||
r_d = sha3(y);
|
r_d = keccak256(y);
|
||||||
shared(y);
|
shared(y);
|
||||||
r_d = sha3(y);
|
r_d = keccak256(y);
|
||||||
r_a = 5;
|
r_a = 5;
|
||||||
}
|
}
|
||||||
function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
|
function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
|
||||||
r_d = sha3(y);
|
r_d = keccak256(y);
|
||||||
shared(y);
|
shared(y);
|
||||||
r_d = bytes32(uint(sha3(y)) + 2);
|
r_d = bytes32(uint(keccak256(y)) + 2);
|
||||||
r_a = 7;
|
r_a = 7;
|
||||||
}
|
}
|
||||||
function shared(bytes32 y) internal {
|
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);
|
bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "test", true);
|
||||||
size_t numSHA3s = 0;
|
size_t numSHA3s = 0;
|
||||||
eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) {
|
eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) {
|
||||||
if (_instr == Instruction::SHA3)
|
if (_instr == Instruction::KECCAK256)
|
||||||
numSHA3s++;
|
numSHA3s++;
|
||||||
});
|
});
|
||||||
// TEST DISABLED UNTIL 93693404 IS IMPLEMENTED
|
// 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)
|
BOOST_AUTO_TEST_CASE(incorrect_storage_access_bug)
|
||||||
{
|
{
|
||||||
// This bug appeared because a sha3 operation with too low sequence number was used,
|
// This bug appeared because a Keccak-256 operation with too low sequence number was used,
|
||||||
// resulting in memory not being rewritten before the sha3. The fix was to
|
// 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.
|
// take the max of the min sequence numbers when merging the states.
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract C
|
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{
|
AssemblyItems input{
|
||||||
u256(0),
|
u256(0),
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
Instruction::SHA3
|
Instruction::KECCAK256
|
||||||
};
|
};
|
||||||
checkCSE(input, {
|
checkCSE(input, {
|
||||||
u256(dev::keccak256(bytesConstRef()))
|
u256(dev::keccak256(bytesConstRef()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(cse_partial_sha3)
|
BOOST_AUTO_TEST_CASE(cse_partial_keccak256)
|
||||||
{
|
{
|
||||||
AssemblyItems input{
|
AssemblyItems input{
|
||||||
u256(0xabcd) << (256 - 16),
|
u256(0xabcd) << (256 - 16),
|
||||||
@ -841,7 +841,7 @@ BOOST_AUTO_TEST_CASE(cse_partial_sha3)
|
|||||||
Instruction::MSTORE,
|
Instruction::MSTORE,
|
||||||
u256(2),
|
u256(2),
|
||||||
u256(0),
|
u256(0),
|
||||||
Instruction::SHA3
|
Instruction::KECCAK256
|
||||||
};
|
};
|
||||||
checkCSE(input, {
|
checkCSE(input, {
|
||||||
u256(0xabcd) << (256 - 16),
|
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{
|
AssemblyItems input{
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
Instruction::DUP1,
|
Instruction::DUP1,
|
||||||
Instruction::MSTORE,
|
Instruction::MSTORE,
|
||||||
u256(64),
|
u256(64),
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
Instruction::SHA3,
|
Instruction::KECCAK256,
|
||||||
u256(64),
|
u256(64),
|
||||||
Instruction::DUP3,
|
Instruction::DUP3,
|
||||||
Instruction::SHA3
|
Instruction::KECCAK256
|
||||||
};
|
};
|
||||||
checkCSE(input, {
|
checkCSE(input, {
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
@ -871,27 +871,27 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_location)
|
|||||||
Instruction::MSTORE,
|
Instruction::MSTORE,
|
||||||
u256(64),
|
u256(64),
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
Instruction::SHA3,
|
Instruction::KECCAK256,
|
||||||
Instruction::DUP1
|
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{
|
AssemblyItems input{
|
||||||
Instruction::DUP1,
|
Instruction::DUP1,
|
||||||
u256(0x80),
|
u256(0x80),
|
||||||
Instruction::MSTORE, // m[128] = DUP1
|
Instruction::MSTORE, // m[128] = DUP1
|
||||||
u256(0x20),
|
u256(0x20),
|
||||||
u256(0x80),
|
u256(0x80),
|
||||||
Instruction::SHA3, // sha3(m[128..(128+32)])
|
Instruction::KECCAK256, // keccak256(m[128..(128+32)])
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
u256(12),
|
u256(12),
|
||||||
Instruction::MSTORE, // m[12] = DUP1
|
Instruction::MSTORE, // m[12] = DUP1
|
||||||
u256(0x20),
|
u256(0x20),
|
||||||
u256(12),
|
u256(12),
|
||||||
Instruction::SHA3 // sha3(m[12..(12+32)])
|
Instruction::KECCAK256 // keccak256(m[12..(12+32)])
|
||||||
};
|
};
|
||||||
checkCSE(input, {
|
checkCSE(input, {
|
||||||
u256(0x80),
|
u256(0x80),
|
||||||
@ -900,7 +900,7 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content)
|
|||||||
Instruction::MSTORE,
|
Instruction::MSTORE,
|
||||||
u256(0x20),
|
u256(0x20),
|
||||||
Instruction::SWAP1,
|
Instruction::SWAP1,
|
||||||
Instruction::SHA3,
|
Instruction::KECCAK256,
|
||||||
u256(12),
|
u256(12),
|
||||||
Instruction::DUP3,
|
Instruction::DUP3,
|
||||||
Instruction::SWAP1,
|
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,
|
// Keccak-256 twice from different dynamic location but with same content,
|
||||||
// dynamic mstore in between, which forces us to re-calculate the sha3
|
// dynamic mstore in between, which forces us to re-calculate the hash
|
||||||
AssemblyItems input{
|
AssemblyItems input{
|
||||||
u256(0x80),
|
u256(0x80),
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
@ -921,7 +921,7 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_dynamic_store_in_between)
|
|||||||
u256(0x20),
|
u256(0x20),
|
||||||
Instruction::DUP1,
|
Instruction::DUP1,
|
||||||
Instruction::DUP3,
|
Instruction::DUP3,
|
||||||
Instruction::SHA3, // sha3(m[128..(128+32)])
|
Instruction::KECCAK256, // keccak256(m[128..(128+32)])
|
||||||
u256(12),
|
u256(12),
|
||||||
Instruction::DUP5,
|
Instruction::DUP5,
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
@ -932,15 +932,15 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_dynamic_store_in_between)
|
|||||||
Instruction::SWAP2,
|
Instruction::SWAP2,
|
||||||
Instruction::SWAP1,
|
Instruction::SWAP1,
|
||||||
Instruction::SWAP2,
|
Instruction::SWAP2,
|
||||||
Instruction::SHA3 // sha3(m[12..(12+32)])
|
Instruction::KECCAK256 // keccak256(m[12..(12+32)])
|
||||||
};
|
};
|
||||||
checkCSE(input, input);
|
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,
|
// Keccak-256 twice from different dynamic location but with same content,
|
||||||
// dynamic mstore in between, but does not force us to re-calculate the sha3
|
// dynamic mstore in between, but does not force us to re-calculate the hash
|
||||||
AssemblyItems input{
|
AssemblyItems input{
|
||||||
u256(0x80),
|
u256(0x80),
|
||||||
Instruction::DUP2,
|
Instruction::DUP2,
|
||||||
@ -949,7 +949,7 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between
|
|||||||
u256(0x20),
|
u256(0x20),
|
||||||
Instruction::DUP1,
|
Instruction::DUP1,
|
||||||
Instruction::DUP3,
|
Instruction::DUP3,
|
||||||
Instruction::SHA3, // sha3(m[128..(128+32)])
|
Instruction::KECCAK256, // keccak256(m[128..(128+32)])
|
||||||
u256(12),
|
u256(12),
|
||||||
Instruction::DUP5,
|
Instruction::DUP5,
|
||||||
Instruction::DUP2,
|
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
|
Instruction::MSTORE, // does not destoy memory knowledge
|
||||||
u256(0x20),
|
u256(0x20),
|
||||||
u256(12),
|
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
|
// if this changes too often, only count the number of SHA3 and MSTORE instructions
|
||||||
AssemblyItems output = CSE(input);
|
AssemblyItems output = CSE(input);
|
||||||
BOOST_CHECK_EQUAL(4, count(output.begin(), output.end(), AssemblyItem(Instruction::MSTORE)));
|
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)
|
BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack)
|
||||||
@ -1296,7 +1296,7 @@ BOOST_AUTO_TEST_CASE(constant_optimization_early_exit)
|
|||||||
// Store and hash
|
// Store and hash
|
||||||
assembly {
|
assembly {
|
||||||
mstore(32, x)
|
mstore(32, x)
|
||||||
ret := sha3(0, 40)
|
ret := keccak256(0, 40)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user