Solidity Address Payable – Storing and Sending Address Later in Solidity 0.5.0

address.transferdata-typeserrorsolidity

Solidity 0.5.0 has separated the "address" type into two types: address payable and address. Only address payable have the address.transfer method. I don't want to use the withdrawal mechanism.

When I store the address in an array, and try to access it later I get an error from solc:

Member "transfer" not found or not visible after argument-dependent
lookup in address.

I guess it's because the address that I stored is not of type "address payable" (it wouldn't hurt to make this error more clear btw). But it is said in the documentation that the address returned by msg.sender is of type "address payable". So I don't quite understand. It is also said that a conversion using the type uint160 is possible, but I don't know how. Any help would be greatly appreciated

Here is a useless sample code which reproduce the problem:

pragma solidity >0.4.99 <0.6.0;
contract simple{

  address payable[] private addressIndex;
  uint price = 100;

  /* Distribute all the fund to the clients */
  function distribute() private returns (uint) {

    uint amount = (address(this).balance-1) / addressIndex.length;
    for (uint i = 0; i < addressIndex.length; i++) {
      addressIndex[i].transfer(amount); //error
    }
    return amount;
  }

  function () external payable {

    if ( msg.value != price ) { revert(); }
    addressIndex.push(msg.sender);
    distribute();
  }

}

EDIT 1: With the Solidity compiler solc v0.5.0, I had to declare all "address" variables which will receive fund in the future as "address payable". For security reasons no implicit conversion of the type "address" will be made to "address payable". Only "address payable" have the ".transfer" method. Therefore my addressIndex array of address should be declared as:

address payable[] addressIndex;

Best Answer

UPDATE:

Solidity 0.6.x now have explicit conversions to payable:

payable(userAddress)

And for smart contracts:

payable(address(smartContract))

Old answer for Solidity 0.5.x:

Here is how to cast address to address payable:

address(uint160(userAddress))

And contract cast to address payable (thx to @Cyril):

address(uint160(address(smartContract)));
Related Topic