mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Support address().codehash
This commit is contained in:
parent
fca8026250
commit
ad6739d0f6
@ -21,6 +21,7 @@ Breaking Changes:
|
||||
* Type System: Explicit conversions between two types are disallowed if it changes more than one of sign, width or kind at the same time.
|
||||
* Type System: Explicit conversions from literals to enums are only allowed if the value fits in the enum.
|
||||
* Type System: Explicit conversions from literals to integer type is as strict as implicit conversions.
|
||||
* Type System: Support ``address(...).codehash`` to retrieve the codehash of an account.
|
||||
* Type System: Unary negation can only be used on signed integers, not on unsigned integers.
|
||||
|
||||
Language Features:
|
||||
@ -157,7 +158,6 @@ Bugfixes:
|
||||
Important Bugfixes:
|
||||
* Type Checker: Disallow two or more free functions with identical name (potentially imported and aliased) and parameter types.
|
||||
|
||||
|
||||
Compiler Features:
|
||||
* Export compiler-generated utility sources via standard-json or combined-json.
|
||||
* Optimizer: Optimize ``exp`` when base is 0, 1 or 2.
|
||||
|
@ -67,7 +67,7 @@ The following is the order of precedence for operators, listed in order of evalu
|
||||
| *15* | Comma operator | ``,`` |
|
||||
+------------+-------------------------------------+--------------------------------------------+
|
||||
|
||||
.. index:: assert, block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin, revert, require, keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send
|
||||
.. index:: assert, block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin, revert, require, keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, codehash, send
|
||||
|
||||
Global Variables
|
||||
================
|
||||
@ -114,6 +114,7 @@ Global Variables
|
||||
- ``super``: the contract one level higher in the inheritance hierarchy
|
||||
- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address
|
||||
- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei
|
||||
- ``<address>.codehash`` (``bytes32``): the codehash of the :ref:`address`
|
||||
- ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`,
|
||||
returns ``false`` on failure
|
||||
- ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure
|
||||
|
@ -211,7 +211,7 @@ Mathematical and Cryptographic Functions
|
||||
|
||||
When running ``sha256``, ``ripemd160`` or ``ecrecover`` on a *private blockchain*, you might encounter Out-of-Gas. This is because these functions are implemented as "precompiled contracts" and only really exist after they receive the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution might run into an Out-of-Gas error. A workaround for this problem is to first send Wei (1 for example) to each of the contracts before you use them in your actual contracts. This is not an issue on the main or test net.
|
||||
|
||||
.. index:: balance, send, transfer, call, callcode, delegatecall, staticcall
|
||||
.. index:: balance, codehash, send, transfer, call, callcode, delegatecall, staticcall
|
||||
|
||||
.. _address_related:
|
||||
|
||||
@ -221,6 +221,9 @@ Members of Address Types
|
||||
``<address>.balance`` (``uint256``)
|
||||
balance of the :ref:`address` in Wei
|
||||
|
||||
``<address>.codehash`` (``bytes32``)
|
||||
the codehash of the :ref:`address`
|
||||
|
||||
``<address payable>.transfer(uint256 amount)``
|
||||
send given amount of Wei to :ref:`address`, reverts on failure, forwards 2300 gas stipend, not adjustable
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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, "");
|
||||
|
21
test/libsolidity/semanticTests/various/codehash.sol
Normal file
21
test/libsolidity/semanticTests/various/codehash.sol
Normal file
@ -0,0 +1,21 @@
|
||||
contract C {
|
||||
function f() public returns (bytes32) {
|
||||
// non-existent in tests
|
||||
return address(0).codehash;
|
||||
}
|
||||
function g() public returns (bytes32) {
|
||||
// precompile
|
||||
return address(0x1).codehash;
|
||||
}
|
||||
function h() public returns (bool) {
|
||||
return address(this).codehash != 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// EVMVersion: >=constantinople
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x0
|
||||
// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
|
||||
// h() -> true
|
8
test/libsolidity/syntaxTests/types/address/codehash.sol
Normal file
8
test/libsolidity/syntaxTests/types/address/codehash.sol
Normal file
@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function f() public view returns (bytes32) {
|
||||
return address(this).codehash;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=constantinople
|
||||
// ----
|
@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function f() public view returns (bytes32) {
|
||||
return address(this).codehash;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: <constantinople
|
||||
// ----
|
||||
// TypeError 7598: (77-99): "codehash" is not supported by the VM version.
|
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public view returns (bytes32) {
|
||||
return address(this).codehash;
|
||||
}
|
||||
function g() public view returns (bytes32) {
|
||||
return address(0).codehash;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=constantinople
|
||||
// ----
|
Loading…
Reference in New Issue
Block a user