在Solidity 0.5.x中,地址类型被细分为address
和address payable
,那么,这两种类型有什么区别?如何将address
类型转换为address paybale
类型,或者反向转换?本文将给出这些问题,并指出Solidity进行地址类型细分的目的。数组
solidity 0.5将地址类型细分为address
和address payable
的目的在于,它有助于强制智能合约开发人员认真考虑一个地址是否应当接收以太币,若是该地址根本不须要接收以太币,那么就应当使用address
类型。当地址被声明为address
类型后,若是开发者试图向该地址转入以太币,就会致使编译时类型错误。区块链
address
和address payable
类型都用来存储160位的以太坊地址,二者的区别仅在编译时存在,在编译后的合约代码中就没有区别了 —— 也就是说,引入地址类型细分的惟一目的就是帮助开发者在编译期理清一个地址的实际用途。测试
address payable
和address
类型的变量都表示以太坊地址,均可以使用底层的.call()
方法。从字面意思看,address payable
表示可用于支付的地址,所以在address payable
类型的变量上,你可使用.transfer()
和.send()
方法,可是address
类型的变量则不能使用这些方法。ui
所以,address payable
类型的功能要强于address
类型,容易理解,address payable
向address
类型的转换要容易一些(降级使用),而从address
类型向address payable
类型的转换,则须要稍微转个弯。code
address payable
类型的变量能够显式或隐式地转换为address类型:blog
address payable addr1 = msg.sender; address addr2 = addr1; // 正确 address addr3 = address(addr1); // 正确
address
类型的变量只能显式地转换为address payable
,须要首先转换为整数类型(例如uint160),而后再将该整型值转换为address类型,就能够获得address payable
:开发
address addr1 = msg.sender; address payable addr2 = addr1; // 错误,address不能隐式地转换为address payable address payable addr3 = address(uint160(addr1)); // 正确,先转换为uint160,而后转换为address payable
虽然单个address payable
变量能够转换为address
类型,或者反之,可是不能直接将整个数组进行转换。例如:rem
function testCast(address payable[] memory _addresses) returns (address[] memory) { return _addresses; // 错误! }
在Solidity的内置变量中,如下几个变量的类型都是address payable
:get
你可使用在线的Solidity IDE来测试本文中的Soldity代码,以便更好地理解在Soldity 0.5中的address payable
和address
类型的区别与相互转换。it