Support address().codehash

This commit is contained in:
Alex Beregszaszi
2020-12-09 14:58:27 +00:00
parent fca8026250
commit ad6739d0f6
12 changed files with 83 additions and 4 deletions
+11
View File
@@ -2924,6 +2924,17 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
annotation.isPure = true;
}
if (
_memberAccess.expression().annotation().type->category() == Type::Category::Address &&
memberName == "codehash" &&
!m_evmVersion.hasExtCodeHash()
)
m_errorReporter.typeError(
7598_error,
_memberAccess.location(),
"\"codehash\" is not supported by the VM version."
);
if (!annotation.isPure.set())
annotation.isPure = false;
+1 -1
View File
@@ -356,7 +356,7 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess)
switch (_memberAccess.expression().annotation().type->category())
{
case Type::Category::Address:
if (member == "balance")
if (member == "balance" || member == "codehash")
mutability = StateMutability::View;
break;
case Type::Category::Magic:
+1
View File
@@ -456,6 +456,7 @@ MemberList::MemberMap AddressType::nativeMembers(ASTNode const*) const
{
MemberList::MemberMap members = {
{"balance", TypeProvider::uint256()},
{"codehash", TypeProvider::fixedBytes(32)},
{"call", TypeProvider::function(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareCall, false, StateMutability::Payable)},
{"callcode", TypeProvider::function(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareCallCode, false, StateMutability::Payable)},
{"delegatecall", TypeProvider::function(strings{"bytes memory"}, strings{"bool", "bytes memory"}, FunctionType::Kind::BareDelegateCall, false, StateMutability::NonPayable)},
@@ -1508,6 +1508,15 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
);
m_context << Instruction::BALANCE;
}
else if (member == "codehash")
{
utils().convertType(
*_memberAccess.expression().annotation().type,
*TypeProvider::address(),
true
);
m_context << Instruction::EXTCODEHASH;
}
else if ((set<string>{"send", "transfer"}).count(member))
{
solAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable, "");
@@ -1622,6 +1622,11 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
"balance(" <<
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
")\n";
else if (member == "codehash")
define(_memberAccess) <<
"extcodehash(" <<
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
")\n";
else if (set<string>{"send", "transfer"}.count(member))
{
solAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable, "");