Introduce block.chainid

This commit is contained in:
Alex Beregszaszi 2020-09-22 18:12:01 +01:00
parent d0551b67d7
commit 7cd05bf603
13 changed files with 42 additions and 2 deletions

View File

@ -22,6 +22,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: Introduce ``block.chainid`` for retrieving the current chain id.
* 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.
* View Pure Checker: Mark ``chainid`` as view.

View File

@ -82,6 +82,7 @@ Global Variables
the given arguments starting from the second and prepends the given four-byte selector
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)```
- ``block.chainid`` (``uint``): current chain id
- ``block.coinbase`` (``address payable``): current block miner's address
- ``block.difficulty`` (``uint``): current block difficulty
- ``block.gaslimit`` (``uint``): current block gaslimit

View File

@ -69,6 +69,7 @@ Block and Transaction Properties
--------------------------------
- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks
- ``block.chainid`` (``uint``): current chain id
- ``block.coinbase`` (``address payable``): current block miner's address
- ``block.difficulty`` (``uint``): current block difficulty
- ``block.gaslimit`` (``uint``): current block gaslimit

View File

@ -2922,6 +2922,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
(memberName == "min" || memberName == "max")
)
annotation.isPure = true;
else if (magicType->kind() == MagicType::Kind::Block && memberName == "chainid" && !m_evmVersion.hasChainID())
m_errorReporter.typeError(
3081_error,
_memberAccess.location(),
"\"chainid\" is not supported by the VM version."
);
}
if (

View File

@ -368,7 +368,6 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess)
{MagicType::Kind::ABI, "encodePacked"},
{MagicType::Kind::ABI, "encodeWithSelector"},
{MagicType::Kind::ABI, "encodeWithSignature"},
{MagicType::Kind::Block, "blockhash"},
{MagicType::Kind::Message, "data"},
{MagicType::Kind::Message, "sig"},
{MagicType::Kind::MetaType, "creationCode"},

View File

@ -3825,7 +3825,8 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const
{"blockhash", TypeProvider::function(strings{"uint"}, strings{"bytes32"}, FunctionType::Kind::BlockHash, false, StateMutability::View)},
{"difficulty", TypeProvider::uint256()},
{"number", TypeProvider::uint256()},
{"gaslimit", TypeProvider::uint256()}
{"gaslimit", TypeProvider::uint256()},
{"chainid", TypeProvider::uint256()}
});
case Kind::Message:
return MemberList::MemberMap({

View File

@ -1576,6 +1576,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
m_context << Instruction::ORIGIN;
else if (member == "gasprice")
m_context << Instruction::GASPRICE;
else if (member == "chainid")
m_context << Instruction::CHAINID;
else if (member == "data")
m_context << u256(0) << Instruction::CALLDATASIZE;
else if (member == "sig")

View File

@ -1688,6 +1688,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
define(_memberAccess) << "origin()\n";
else if (member == "gasprice")
define(_memberAccess) << "gasprice()\n";
else if (member == "chainid")
define(_memberAccess) << "chainid()\n";
else if (member == "data")
{
IRVariable var(_memberAccess);

View File

@ -0,0 +1,12 @@
contract C {
function f() public returns (uint) {
return block.chainid;
}
}
// ====
// EVMVersion: >=istanbul
// compileViaYul: also
// ----
// f() -> 1
// f() -> 1
// f() -> 1

View File

@ -11,6 +11,11 @@ contract C {
function i() public view returns (uint) {
return block.timestamp;
}
function j() public view returns (uint) {
return block.chainid;
}
}
// ====
// EVMVersion: <istanbul
// ----
// TypeError 3081: (420-433): "chainid" is not supported by the VM version.

View File

@ -11,6 +11,9 @@ contract C {
function i() public view returns (uint) {
return block.timestamp;
}
function j() public view returns (uint) {
return block.chainid;
}
}
// ====
// EVMVersion: >=istanbul

View File

@ -2,8 +2,12 @@ contract C {
function f() public pure {
assembly { pop(chainid()) }
}
function g() public pure returns (uint) {
return block.chainid;
}
}
// ====
// EVMVersion: >=istanbul
// ----
// TypeError 2527: (67-76): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".
// TypeError 2527: (147-160): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".

View File

@ -2,6 +2,9 @@ contract C {
function f() public view {
assembly { pop(chainid()) }
}
function g() public view returns (uint) {
return block.chainid;
}
}
// ====
// EVMVersion: >=istanbul