mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4911 from ethereum/addressPayable
Payable and non-payable address type.
This commit is contained in:
@@ -68,7 +68,7 @@ This is as opposed to the more intuitive sending pattern:
|
||||
pragma solidity >0.4.24;
|
||||
|
||||
contract SendContract {
|
||||
address public richest;
|
||||
address payable public richest;
|
||||
uint public mostSent;
|
||||
|
||||
constructor() public payable {
|
||||
|
||||
+10
-5
@@ -334,7 +334,7 @@ inheritable properties of contracts and may be overridden by derived contracts.
|
||||
|
||||
contract owned {
|
||||
constructor() public { owner = msg.sender; }
|
||||
address owner;
|
||||
address payable owner;
|
||||
|
||||
// This contract only defines a modifier but does not use
|
||||
// it: it will be used in derived contracts.
|
||||
@@ -650,9 +650,14 @@ Like any function, the fallback function can execute complex operations as long
|
||||
require(success);
|
||||
// results in test.x becoming == 1.
|
||||
|
||||
// address(test) will not allow to call ``send`` directly, since ``test`` has no payable
|
||||
// fallback function. It has to be converted to the ``address payable`` type via an
|
||||
// intermediate conversion to ``uint160`` to even allow calling ``send`` on it.
|
||||
address payable testPayable = address(uint160(address(test)));
|
||||
|
||||
// If someone sends ether to that contract,
|
||||
// the transfer will fail, i.e. this returns false here.
|
||||
return address(test).send(2 ether);
|
||||
return testPayable.send(2 ether);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -891,7 +896,7 @@ Details are given in the following example.
|
||||
|
||||
contract owned {
|
||||
constructor() public { owner = msg.sender; }
|
||||
address owner;
|
||||
address payable owner;
|
||||
}
|
||||
|
||||
// Use `is` to derive from another contract. Derived
|
||||
@@ -963,7 +968,7 @@ seen in the following example::
|
||||
|
||||
contract owned {
|
||||
constructor() public { owner = msg.sender; }
|
||||
address owner;
|
||||
address payable owner;
|
||||
}
|
||||
|
||||
contract mortal is owned {
|
||||
@@ -992,7 +997,7 @@ derived override, but this function will bypass
|
||||
|
||||
contract owned {
|
||||
constructor() public { owner = msg.sender; }
|
||||
address owner;
|
||||
address payable owner;
|
||||
}
|
||||
|
||||
contract mortal is owned {
|
||||
|
||||
@@ -421,7 +421,7 @@ a message string for ``require``, but not for ``assert``.
|
||||
pragma solidity >0.4.24;
|
||||
|
||||
contract Sharer {
|
||||
function sendHalf(address addr) public payable returns (uint balance) {
|
||||
function sendHalf(address payable addr) public payable returns (uint balance) {
|
||||
require(msg.value % 2 == 0, "Even value required.");
|
||||
uint balanceBeforeTransfer = address(this).balance;
|
||||
addr.transfer(msg.value / 2);
|
||||
|
||||
@@ -329,7 +329,7 @@ Global Variables
|
||||
starting from the second and prepends the given four-byte selector
|
||||
- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)```
|
||||
- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``.
|
||||
- ``block.coinbase`` (``address``): current block miner's address
|
||||
- ``block.coinbase`` (``address payable``): current block miner's address
|
||||
- ``block.difficulty`` (``uint``): current block difficulty
|
||||
- ``block.gaslimit`` (``uint``): current block gaslimit
|
||||
- ``block.number`` (``uint``): current block number
|
||||
@@ -337,11 +337,11 @@ Global Variables
|
||||
- ``gasleft() returns (uint256)``: remaining gas
|
||||
- ``msg.data`` (``bytes``): complete calldata
|
||||
- ``msg.gas`` (``uint``): remaining gas - deprecated in version 0.4.21 and to be replaced by ``gasleft()``
|
||||
- ``msg.sender`` (``address``): sender of the message (current call)
|
||||
- ``msg.sender`` (``address payable``): sender of the message (current call)
|
||||
- ``msg.value`` (``uint``): number of wei sent with the message
|
||||
- ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``)
|
||||
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
||||
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
|
||||
- ``tx.origin`` (``address payable``): sender of the transaction (full call chain)
|
||||
- ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error)
|
||||
- ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component)
|
||||
- ``require(bool condition, string message)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component). Also provide error message.
|
||||
@@ -360,8 +360,8 @@ Global Variables
|
||||
- ``selfdestruct(address recipient)``: destroy the current contract, sending its funds to the given address
|
||||
- ``suicide(address recipient)``: a deprecated alias to ``selfdestruct``
|
||||
- ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei
|
||||
- ``<address>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`, returns ``false`` on failure
|
||||
- ``<address>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure
|
||||
- ``<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
|
||||
|
||||
.. note::
|
||||
Do not rely on ``block.timestamp``, ``now`` and ``blockhash`` as a source of randomness,
|
||||
|
||||
@@ -192,7 +192,7 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
function transferTo(address dest, uint amount) public {
|
||||
function transferTo(address payable dest, uint amount) public {
|
||||
require(tx.origin == owner);
|
||||
dest.transfer(amount);
|
||||
}
|
||||
@@ -205,11 +205,11 @@ Now someone tricks you into sending ether to the address of this attack wallet:
|
||||
pragma solidity >0.4.24;
|
||||
|
||||
interface TxUserWallet {
|
||||
function transferTo(address dest, uint amount) external;
|
||||
function transferTo(address payable dest, uint amount) external;
|
||||
}
|
||||
|
||||
contract TxAttackWallet {
|
||||
address owner;
|
||||
address payable owner;
|
||||
|
||||
constructor() public {
|
||||
owner = msg.sender;
|
||||
|
||||
@@ -231,7 +231,7 @@ activate themselves.
|
||||
// Parameters of the auction. Times are either
|
||||
// absolute unix timestamps (seconds since 1970-01-01)
|
||||
// or time periods in seconds.
|
||||
address public beneficiary;
|
||||
address payable public beneficiary;
|
||||
uint public auctionEndTime;
|
||||
|
||||
// Current state of the auction.
|
||||
@@ -258,7 +258,7 @@ activate themselves.
|
||||
/// beneficiary address `_beneficiary`.
|
||||
constructor(
|
||||
uint _biddingTime,
|
||||
address _beneficiary
|
||||
address payable _beneficiary
|
||||
) public {
|
||||
beneficiary = _beneficiary;
|
||||
auctionEndTime = now + _biddingTime;
|
||||
@@ -396,7 +396,7 @@ high or low invalid bids.
|
||||
uint deposit;
|
||||
}
|
||||
|
||||
address public beneficiary;
|
||||
address payable public beneficiary;
|
||||
uint public biddingEnd;
|
||||
uint public revealEnd;
|
||||
bool public ended;
|
||||
@@ -421,7 +421,7 @@ high or low invalid bids.
|
||||
constructor(
|
||||
uint _biddingTime,
|
||||
uint _revealTime,
|
||||
address _beneficiary
|
||||
address payable _beneficiary
|
||||
) public {
|
||||
beneficiary = _beneficiary;
|
||||
biddingEnd = now + _biddingTime;
|
||||
@@ -545,8 +545,8 @@ Safe Remote Purchase
|
||||
|
||||
contract Purchase {
|
||||
uint public value;
|
||||
address public seller;
|
||||
address public buyer;
|
||||
address payable public seller;
|
||||
address payable public buyer;
|
||||
enum State { Created, Locked, Inactive }
|
||||
State public state;
|
||||
|
||||
@@ -990,11 +990,11 @@ The full contract
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
contract SimplePaymentChannel {
|
||||
address public sender; // The account sending payments.
|
||||
address public recipient; // The account receiving the payments.
|
||||
address payable public sender; // The account sending payments.
|
||||
address payable public recipient; // The account receiving the payments.
|
||||
uint256 public expiration; // Timeout in case the recipient never closes.
|
||||
|
||||
constructor (address _recipient, uint256 duration)
|
||||
constructor (address payable _recipient, uint256 duration)
|
||||
public
|
||||
payable
|
||||
{
|
||||
|
||||
+20
-7
@@ -99,6 +99,15 @@ Address
|
||||
-------
|
||||
|
||||
``address``: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as a base for all contracts.
|
||||
``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``.
|
||||
|
||||
Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable`` are
|
||||
not possible (the only way to perform such a conversion is by using an intermediate conversion to ``uint160``).
|
||||
Conversions of the form ``address payable(x)`` are not allowed. Instead the result of a conversion of the form ``address(x)``
|
||||
has the type ``address payable``, if ``x`` is of integer or fixed bytes type, a literal or a contract with a payable fallback function.
|
||||
If ``x`` is a contract without payable fallback function ``address(x)`` will be of type ``address``. The type of address literals
|
||||
is ``address payable``.
|
||||
In external function signatures ``address`` is used for both the ``address`` and the ``address payable`` type.
|
||||
|
||||
Operators:
|
||||
|
||||
@@ -113,7 +122,8 @@ Operators:
|
||||
or you can use ``address(uint160(uint256(b)))``, which results in ``0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc``.
|
||||
|
||||
.. note::
|
||||
Starting with version 0.5.0 contracts do not derive from the address type, but can still be explicitly converted to address.
|
||||
Starting with version 0.5.0 contracts do not derive from the address type, but can still be explicitly converted to
|
||||
``address`` or to ``address payable``, if they have a payable fallback function.
|
||||
|
||||
.. _members-of-addresses:
|
||||
|
||||
@@ -125,11 +135,11 @@ Members of Addresses
|
||||
For a quick reference, see :ref:`address_related`.
|
||||
|
||||
It is possible to query the balance of an address using the property ``balance``
|
||||
and to send Ether (in units of wei) to an address using the ``transfer`` function:
|
||||
and to send Ether (in units of wei) to a payable address using the ``transfer`` function:
|
||||
|
||||
::
|
||||
|
||||
address x = 0x123;
|
||||
address payable x = address(0x123);
|
||||
address myAddress = this;
|
||||
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);
|
||||
|
||||
@@ -211,11 +221,14 @@ Contract Types
|
||||
|
||||
Every :ref:`contract<contracts>` defines its own type.
|
||||
You can implicitly convert contracts to contracts they inherit from,
|
||||
and explicitly convert them to and from the ``address`` type.
|
||||
and explicitly convert them to and from the ``address`` type, if they have no
|
||||
payable fallback functions, or to and from the ``address payable`` type, if they do
|
||||
have payable fallback functions.
|
||||
|
||||
.. note::
|
||||
Starting with version 0.5.0 contracts do not derive from the address type,
|
||||
but can still be explicitly converted to address.
|
||||
but can still be explicitly converted to ``address``, resp. to ``address payable``,
|
||||
if they have a payable fallback function.
|
||||
|
||||
If you declare a local variable of contract type (`MyContract c`), you can call
|
||||
functions on that contract. Take care to assign it from somewhere that is the
|
||||
@@ -860,7 +873,7 @@ shown in the following example:
|
||||
}
|
||||
|
||||
struct Campaign {
|
||||
address beneficiary;
|
||||
address payable beneficiary;
|
||||
uint fundingGoal;
|
||||
uint numFunders;
|
||||
uint amount;
|
||||
@@ -870,7 +883,7 @@ shown in the following example:
|
||||
uint numCampaigns;
|
||||
mapping (uint => Campaign) campaigns;
|
||||
|
||||
function newCampaign(address beneficiary, uint goal) public returns (uint campaignID) {
|
||||
function newCampaign(address payable beneficiary, uint goal) public returns (uint campaignID) {
|
||||
campaignID = numCampaigns++; // campaignID is return variable
|
||||
// Creates new struct and saves in storage. We leave out the mapping type.
|
||||
campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
|
||||
|
||||
@@ -57,7 +57,7 @@ Block and Transaction Properties
|
||||
--------------------------------
|
||||
|
||||
- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``.
|
||||
- ``block.coinbase`` (``address``): current block miner's address
|
||||
- ``block.coinbase`` (``address payable``): current block miner's address
|
||||
- ``block.difficulty`` (``uint``): current block difficulty
|
||||
- ``block.gaslimit`` (``uint``): current block gaslimit
|
||||
- ``block.number`` (``uint``): current block number
|
||||
@@ -65,12 +65,12 @@ Block and Transaction Properties
|
||||
- ``gasleft() returns (uint256)``: remaining gas
|
||||
- ``msg.data`` (``bytes``): complete calldata
|
||||
- ``msg.gas`` (``uint``): remaining gas - deprecated in version 0.4.21 and to be replaced by ``gasleft()``
|
||||
- ``msg.sender`` (``address``): sender of the message (current call)
|
||||
- ``msg.sender`` (``address payable``): sender of the message (current call)
|
||||
- ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier)
|
||||
- ``msg.value`` (``uint``): number of wei sent with the message
|
||||
- ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``)
|
||||
- ``tx.gasprice`` (``uint``): gas price of the transaction
|
||||
- ``tx.origin`` (``address``): sender of the transaction (full call chain)
|
||||
- ``tx.origin`` (``address payable``): sender of the transaction (full call chain)
|
||||
|
||||
.. note::
|
||||
The values of all members of ``msg``, including ``msg.sender`` and
|
||||
@@ -161,9 +161,9 @@ Address Related
|
||||
|
||||
``<address>.balance`` (``uint256``):
|
||||
balance of the :ref:`address` in Wei
|
||||
``<address>.transfer(uint256 amount)``:
|
||||
``<address payable>.transfer(uint256 amount)``:
|
||||
send given amount of Wei to :ref:`address`, throws on failure, forwards 2300 gas stipend, not adjustable
|
||||
``<address>.send(uint256 amount) returns (bool)``:
|
||||
``<address payable>.send(uint256 amount) returns (bool)``:
|
||||
send given amount of Wei to :ref:`address`, returns ``false`` on failure, forwards 2300 gas stipend, not adjustable
|
||||
``<address>.call(bytes memory) returns (bool)``:
|
||||
issue low-level ``CALL`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable
|
||||
@@ -204,10 +204,10 @@ Contract Related
|
||||
``this`` (current contract's type):
|
||||
the current contract, explicitly convertible to :ref:`address`
|
||||
|
||||
``selfdestruct(address recipient)``:
|
||||
``selfdestruct(address payable recipient)``:
|
||||
destroy the current contract, sending its funds to the given :ref:`address`
|
||||
|
||||
``suicide(address recipient)``:
|
||||
``suicide(address payable recipient)``:
|
||||
deprecated alias to ``selfdestruct``
|
||||
|
||||
Furthermore, all functions of the current contract are callable directly including the current function.
|
||||
|
||||
Reference in New Issue
Block a user