ABI encoding functions are pure and should be usable in constants.

This commit is contained in:
chriseth 2018-05-15 13:04:49 +02:00
parent dce6224052
commit dac0029d16
5 changed files with 18 additions and 3 deletions

View File

@ -18,6 +18,7 @@ Bugfixes:
* Code Generator: Fix ``revert`` with reason coming from a state or local string variable.
* Type Checker: Show proper error when trying to ``emit`` a non-event.
* Type Checker: Warn about empty tuple components (this will turn into an error with version 0.5.0).
* Type Checker: The ABI encoding functions are pure and thus can be used for constants.
### 0.4.23 (2018-04-19)

View File

@ -2093,6 +2093,9 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
if (auto tt = dynamic_cast<TypeType const*>(exprType.get()))
if (tt->actualType()->category() == Type::Category::Enum)
annotation.isPure = true;
if (auto magicType = dynamic_cast<MagicType const*>(exprType.get()))
if (magicType->kind() == MagicType::Kind::ABI)
annotation.isPure = true;
return false;
}

View File

@ -2865,7 +2865,11 @@ bool FunctionType::isPure() const
m_kind == Kind::RIPEMD160 ||
m_kind == Kind::AddMod ||
m_kind == Kind::MulMod ||
m_kind == Kind::ObjectCreation;
m_kind == Kind::ObjectCreation ||
m_kind == Kind::ABIEncode ||
m_kind == Kind::ABIEncodePacked ||
m_kind == Kind::ABIEncodeWithSelector ||
m_kind == Kind::ABIEncodeWithSignature;
}
TypePointers FunctionType::parseElementaryTypeVector(strings const& _types)

View File

@ -1046,8 +1046,8 @@ public:
return *m_declaration;
}
bool hasDeclaration() const { return !!m_declaration; }
/// @returns true if the result of this function only depends on its arguments
/// and it does not modify the state.
/// @returns true if the result of this function only depends on its arguments,
/// does not modify the state and is a compile-time constant.
/// Currently, this will only return true for internal functions like keccak and ecrecover.
bool isPure() const;
bool isPayable() const { return m_stateMutability == StateMutability::Payable; }

View File

@ -0,0 +1,7 @@
contract C {
bytes32 constant a = keccak256(abi.encode(1, 2));
bytes32 constant b = keccak256(abi.encodePacked(uint(1), a));
bytes32 constant c = keccak256(abi.encodeWithSelector(0x12345678, b, 2));
bytes32 constant d = keccak256(abi.encodeWithSignature("f()", 1, 2));
}
// ----