Merge pull request #4438 from ethereum/address_members_external_tests_docs

Address members used by contracts: update external tests and docs
This commit is contained in:
chriseth
2018-07-13 01:28:29 +02:00
committed by GitHub
11 changed files with 25 additions and 22 deletions
+8 -9
View File
@@ -406,7 +406,7 @@ Constant State Variables
State variables can be declared as ``constant``. In this case, they have to be
assigned from an expression which is a constant at compile time. Any expression
that accesses storage, blockchain data (e.g. ``now``, ``this.balance`` or
that accesses storage, blockchain data (e.g. ``now``, ``address(this).balance`` or
``block.number``) or
execution data (``msg.value`` or ``gasleft()``) or make calls to external contracts are disallowed. Expressions
that might have a side-effect on memory allocation are allowed, but those that
@@ -505,7 +505,7 @@ Functions can be declared ``pure`` in which case they promise not to read from o
In addition to the list of state modifying statements explained above, the following are considered reading from the state:
#. Reading from state variables.
#. Accessing ``this.balance`` or ``<address>.balance``.
#. Accessing ``address(this).balance`` or ``<address>.balance``.
#. Accessing any of the members of ``block``, ``tx``, ``msg`` (with the exception of ``msg.sig`` and ``msg.data``).
#. Calling any function not marked ``pure``.
#. Using inline assembly that contains certain opcodes.
@@ -580,7 +580,7 @@ Like any function, the fallback function can execute complex operations as long
but do not define a fallback function
throw an exception, sending back the Ether (this was different
before Solidity v0.4.0). So if you want your contract to receive Ether,
you have to implement a fallback function.
you have to implement a payable fallback function.
.. warning::
A contract without a payable fallback function can receive Ether as a recipient of a `coinbase transaction` (aka `miner block reward`)
@@ -588,11 +588,11 @@ Like any function, the fallback function can execute complex operations as long
A contract cannot react to such Ether transfers and thus also cannot reject them. This is a design choice of the EVM and Solidity cannot work around it.
It also means that ``this.balance`` can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the fallback function).
It also means that ``address(this).balance`` can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the fallback function).
::
pragma solidity ^0.4.0;
pragma solidity >0.4.24;
contract Test {
// This function is called for all messages sent to
@@ -613,14 +613,13 @@ Like any function, the fallback function can execute complex operations as long
contract Caller {
function callTest(Test test) public {
test.call(abi.encodeWithSignature("nonExistingFunction()"));
address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
// results in test.x becoming == 1.
// The following will not compile, but even
// if someone sends ether to that contract,
// If someone sends ether to that contract,
// the transaction will fail and reject the
// Ether.
//test.send(2 ether);
address(test).send(2 ether);
}
}
+4 -4
View File
@@ -418,18 +418,18 @@ a message string for ``require``, but not for ``assert``.
::
pragma solidity ^0.4.22;
pragma solidity >0.4.24;
contract Sharer {
function sendHalf(address addr) public payable returns (uint balance) {
require(msg.value % 2 == 0, "Even value required.");
uint balanceBeforeTransfer = this.balance;
uint balanceBeforeTransfer = address(this).balance;
addr.transfer(msg.value / 2);
// Since transfer throws an exception on failure and
// cannot call back here, there should be no way for us to
// still have half of the money.
assert(this.balance == balanceBeforeTransfer - msg.value / 2);
return this.balance;
assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
return address(this).balance;
}
}
+4
View File
@@ -180,6 +180,10 @@ For more information, see the section on :ref:`address`.
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
Use a pattern where the recipient withdraws the money.
.. note::
Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example ``this.balance``.
This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``.
.. note::
If storage variables are accessed via a low-level delegatecall, the storage layout of the two contracts
must align in order for the called contract to correctly access the storage variables of the calling contract by name.
+1 -1
View File
@@ -231,7 +231,7 @@ contract ico is safeMath {
require( ! aborted );
require( token(tokenAddr).mint(foundationAddress, token(tokenAddr).totalSupply() * 96 / 100) );
require( premium(premiumAddr).mint(foundationAddress, totalMint / 5000 - totalPremiumMint) );
require( foundationAddress.send(this.balance) );
require( foundationAddress.send(address(this).balance) );
require( token(tokenAddr).closeIco() );
require( premium(premiumAddr).closeIco() );
}
+2 -2
View File
@@ -95,8 +95,8 @@ contract module {
if ( _balance > 0 ) {
require( abstractModuleHandler(moduleHandlerAddress).transfer(address(this), newModuleAddress, _balance, false) );
}
if ( this.balance > 0 ) {
require( newModuleAddress.send(this.balance) );
if ( address(this).balance > 0 ) {
require( newModuleAddress.send(address(this).balance) );
}
moduleStatus = status.Disconnected;
}
+1 -1
View File
@@ -73,7 +73,7 @@ contract token is safeMath, module, announcementTypes {
if ( ! forReplace ) {
require( db.replaceOwner(this) );
assert( genesisAddr.length == genesisValue.length );
require( this.balance >= genesisAddr.length * 0.2 ether );
require( address(this).balance >= genesisAddr.length * 0.2 ether );
for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) {
genesis[genesisAddr[a]] = true;
require( db.increase(genesisAddr[a], genesisValue[a]) );
+1 -1
View File
@@ -55,7 +55,7 @@ contract Bounty is PullPayment, Destructible {
if (target.checkInvariant()) {
throw;
}
asyncSend(researcher, this.balance);
asyncSend(researcher, address(this).balance);
claimed = true;
}
@@ -23,7 +23,7 @@ contract LimitBalance {
* @dev Checks if limit was reached. Case true, it throws.
*/
modifier limitedPayable() {
if (this.balance > limit) {
if (address(this).balance > limit) {
throw;
}
_;
@@ -37,7 +37,7 @@ contract RefundVault is Ownable {
require(state == State.Active);
state = State.Closed;
emit Closed();
wallet.transfer(this.balance);
wallet.transfer(address(this).balance);
}
function enableRefunds() public onlyOwner {
@@ -37,7 +37,7 @@ contract HasNoEther is Ownable {
* @dev Transfer all Ether held by the contract to the owner.
*/
function reclaimEther() external onlyOwner {
if(!owner.send(this.balance)) {
if(!owner.send(address(this).balance)) {
throw;
}
}
@@ -36,7 +36,7 @@ contract PullPayment {
throw;
}
if (this.balance < payment) {
if (address(this).balance < payment) {
throw;
}