address in Solidity v0.5.0

Words
283
Reading
2 min
Listen
Play
8y

cover.001.png

引き続き、Solidity v0.5.0 Breaking Changes から気になったものをピックアップしていくシリーズです。

今回は address について。



address と contract



contract は address のメンバーを含まなくなりました。

すなわち、c を contract としたとき、今までは c.transfer(...) や c.balance が実行できましたが、v0.5.0 では、address(c).transfer(...) や address(c).balance などのように、明示的に address に変換してから実行する必要があります。



address と address payable



address が、address と address payable に分類されるようになりました。以下、関連する仕様をまとめます。

  • address payable に対してのみ .transfer() や .send() が実行可能
    • <address payable>.transfer(...) や <address payable>.send(...) は OK
    • <address>.transfer(...) や <address>.send(...) は NG
  • address payable は address に直接変換可能
  • address は address payable に直接変換不可能
    • uint160 を介せば変換可能
  • contract c が payable fallback function を有する場合のみ address(c) は address payable になる
  • msg.sender は address payable



以下、上記の文章だけでは分かりにくい部分についてコードを交えながら補足します。


address から address payable への変換



address から address payable への暗黙的な直接変換は許してもらえないので、例えば、以下のような function はコンパイルエラーとなります。

 function f(address _addr) public pure returns(address payable) {
     return _addr;
 }



以下のように uint160 を介せば変換可能です。

 function f(address _addr) public pure returns(address payable) {
     return address(uint160(_addr));
 }


contract から address への変換



冒頭で述べた通り、contract に対して .transfer() などを実行する場合は明示的に address に変換する必要があります。このとき、contract が payable fallback function を有しているかどうかで、address と address payable のどちらに変換されるかが決まります。

まず、以下のようなコードを考えます。

 pragma solidity >0.4.99 <0.6.0;

 contract A {}

 contract B {
     function f() payable public {
         A a = new A();
         address(a).transfer(msg.value);
     }
 }



A は payable fallback function を有さないので、address(a) は address payable ではありません。すなわち、address(a) に対して .transfer() を実行することはできません。よって、上記コードはコンパイルエラーとなります。

次に、以下のようなコードを考えます。

 pragma solidity >0.4.99 <0.6.0;

 contract A {
     function () payable external {}
 }

 contract B {
     function f() payable public {
         A a = new A();
         address(a).transfer(msg.value);
     }
 }



A は payable fallback function を有するので、address(a) は address payable です。よって、上記コードのコンパイルは成功します。

address in Solidity v0.5.0 | Ecency