mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10557 from ethereum/chainid
[BREAKING] Introduce block.chainid
This commit is contained in:
commit
eb7b191726
@ -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 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 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: 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: 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.
|
* Type System: Unary negation can only be used on signed integers, not on unsigned integers.
|
||||||
* View Pure Checker: Mark ``chainid`` as view.
|
* View Pure Checker: Mark ``chainid`` as view.
|
||||||
|
@ -82,6 +82,7 @@ Global Variables
|
|||||||
the given arguments starting from the second and prepends the given four-byte selector
|
the given arguments starting from the second and prepends the given four-byte selector
|
||||||
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent
|
- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent
|
||||||
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)```
|
to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)```
|
||||||
|
- ``block.chainid`` (``uint``): current chain id
|
||||||
- ``block.coinbase`` (``address payable``): current block miner's address
|
- ``block.coinbase`` (``address payable``): current block miner's address
|
||||||
- ``block.difficulty`` (``uint``): current block difficulty
|
- ``block.difficulty`` (``uint``): current block difficulty
|
||||||
- ``block.gaslimit`` (``uint``): current block gaslimit
|
- ``block.gaslimit`` (``uint``): current block gaslimit
|
||||||
|
@ -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
|
- ``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.coinbase`` (``address payable``): current block miner's address
|
||||||
- ``block.difficulty`` (``uint``): current block difficulty
|
- ``block.difficulty`` (``uint``): current block difficulty
|
||||||
- ``block.gaslimit`` (``uint``): current block gaslimit
|
- ``block.gaslimit`` (``uint``): current block gaslimit
|
||||||
|
@ -2922,6 +2922,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
|||||||
(memberName == "min" || memberName == "max")
|
(memberName == "min" || memberName == "max")
|
||||||
)
|
)
|
||||||
annotation.isPure = true;
|
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 (
|
if (
|
||||||
|
@ -368,7 +368,6 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess)
|
|||||||
{MagicType::Kind::ABI, "encodePacked"},
|
{MagicType::Kind::ABI, "encodePacked"},
|
||||||
{MagicType::Kind::ABI, "encodeWithSelector"},
|
{MagicType::Kind::ABI, "encodeWithSelector"},
|
||||||
{MagicType::Kind::ABI, "encodeWithSignature"},
|
{MagicType::Kind::ABI, "encodeWithSignature"},
|
||||||
{MagicType::Kind::Block, "blockhash"},
|
|
||||||
{MagicType::Kind::Message, "data"},
|
{MagicType::Kind::Message, "data"},
|
||||||
{MagicType::Kind::Message, "sig"},
|
{MagicType::Kind::Message, "sig"},
|
||||||
{MagicType::Kind::MetaType, "creationCode"},
|
{MagicType::Kind::MetaType, "creationCode"},
|
||||||
|
@ -3825,7 +3825,8 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const
|
|||||||
{"blockhash", TypeProvider::function(strings{"uint"}, strings{"bytes32"}, FunctionType::Kind::BlockHash, false, StateMutability::View)},
|
{"blockhash", TypeProvider::function(strings{"uint"}, strings{"bytes32"}, FunctionType::Kind::BlockHash, false, StateMutability::View)},
|
||||||
{"difficulty", TypeProvider::uint256()},
|
{"difficulty", TypeProvider::uint256()},
|
||||||
{"number", TypeProvider::uint256()},
|
{"number", TypeProvider::uint256()},
|
||||||
{"gaslimit", TypeProvider::uint256()}
|
{"gaslimit", TypeProvider::uint256()},
|
||||||
|
{"chainid", TypeProvider::uint256()}
|
||||||
});
|
});
|
||||||
case Kind::Message:
|
case Kind::Message:
|
||||||
return MemberList::MemberMap({
|
return MemberList::MemberMap({
|
||||||
|
@ -1576,6 +1576,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
m_context << Instruction::ORIGIN;
|
m_context << Instruction::ORIGIN;
|
||||||
else if (member == "gasprice")
|
else if (member == "gasprice")
|
||||||
m_context << Instruction::GASPRICE;
|
m_context << Instruction::GASPRICE;
|
||||||
|
else if (member == "chainid")
|
||||||
|
m_context << Instruction::CHAINID;
|
||||||
else if (member == "data")
|
else if (member == "data")
|
||||||
m_context << u256(0) << Instruction::CALLDATASIZE;
|
m_context << u256(0) << Instruction::CALLDATASIZE;
|
||||||
else if (member == "sig")
|
else if (member == "sig")
|
||||||
|
@ -1688,6 +1688,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
|||||||
define(_memberAccess) << "origin()\n";
|
define(_memberAccess) << "origin()\n";
|
||||||
else if (member == "gasprice")
|
else if (member == "gasprice")
|
||||||
define(_memberAccess) << "gasprice()\n";
|
define(_memberAccess) << "gasprice()\n";
|
||||||
|
else if (member == "chainid")
|
||||||
|
define(_memberAccess) << "chainid()\n";
|
||||||
else if (member == "data")
|
else if (member == "data")
|
||||||
{
|
{
|
||||||
IRVariable var(_memberAccess);
|
IRVariable var(_memberAccess);
|
||||||
|
12
test/libsolidity/semanticTests/state/block_chainid.sol
Normal file
12
test/libsolidity/semanticTests/state/block_chainid.sol
Normal 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
|
@ -11,6 +11,11 @@ contract C {
|
|||||||
function i() public view returns (uint) {
|
function i() public view returns (uint) {
|
||||||
return block.timestamp;
|
return block.timestamp;
|
||||||
}
|
}
|
||||||
|
function j() public view returns (uint) {
|
||||||
|
return block.chainid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ====
|
// ====
|
||||||
// EVMVersion: <istanbul
|
// EVMVersion: <istanbul
|
||||||
|
// ----
|
||||||
|
// TypeError 3081: (420-433): "chainid" is not supported by the VM version.
|
||||||
|
@ -11,6 +11,9 @@ contract C {
|
|||||||
function i() public view returns (uint) {
|
function i() public view returns (uint) {
|
||||||
return block.timestamp;
|
return block.timestamp;
|
||||||
}
|
}
|
||||||
|
function j() public view returns (uint) {
|
||||||
|
return block.chainid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ====
|
// ====
|
||||||
// EVMVersion: >=istanbul
|
// EVMVersion: >=istanbul
|
||||||
|
@ -2,8 +2,12 @@ contract C {
|
|||||||
function f() public pure {
|
function f() public pure {
|
||||||
assembly { pop(chainid()) }
|
assembly { pop(chainid()) }
|
||||||
}
|
}
|
||||||
|
function g() public pure returns (uint) {
|
||||||
|
return block.chainid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ====
|
// ====
|
||||||
// EVMVersion: >=istanbul
|
// 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: (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".
|
||||||
|
@ -2,6 +2,9 @@ contract C {
|
|||||||
function f() public view {
|
function f() public view {
|
||||||
assembly { pop(chainid()) }
|
assembly { pop(chainid()) }
|
||||||
}
|
}
|
||||||
|
function g() public view returns (uint) {
|
||||||
|
return block.chainid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ====
|
// ====
|
||||||
// EVMVersion: >=istanbul
|
// EVMVersion: >=istanbul
|
||||||
|
Loading…
Reference in New Issue
Block a user