address类型由20个字节组成,address类型有成员,作为所有合约的基础。
address成员:
-
balance
和transfer
balance:用于查询地址的余额,单位是wei。
transfer:向一个地址发送以太币,单位是wei。如果发送失败会抛出异常,并以太币被退回。
注:1ETH=1018wei。
示例:
pragma solidity ^0.4.21;
contract AddressDemo{
address public a;
function AddressDemo() public{
a =msg.sender;
}
function getBalance() public returns (uint256 bal){
return a.balance;
}
function pay() public {
a.transfer(100);
}
}
-
send
send
主要作用发送以太币,send
函数比transfer
函数更为底层。如果send
在执行过程中失败,正在执行合约不会被中断和抛出异常,但会返回fasle
。注意:如果调用栈深度超过1024或是gas不够,转账操作都会失败。为了确保以太币转账安全,如果用
send
就必须每次都要检查返回值。使用transfer
无须检查,因为会抛出异常。
-
call
,callcode
anddeledatecall
call
函数主要作用:为了不依赖与ABI的合约进行交互,该函数接受任意类型的任意数量的参数。参数被填充成32个字节链接起来,有一种情况是例外:当第一个参数被加密成4个字节,是不允许使用call
方法。call
函数返回布尔值。正常结束返回true
,一场结束返回fasle
,不能获得真实返回的数据(因此我们需要预先知道数据编码方式和数据大小)
使用
.gas()
修饰器调整gas:namReg.call.gas(1000000)("register", "MyName");
同样,使用
.value()
修饰器控制Ether:nameReg.call.value(1 ether)("register", "MyName");
修饰器可以混合使用,修饰器调用顺序无所谓:
nameReg.call.gas(1000000).value(1 ether)("register", "MyName");
按同样的方式使用
delegatecall
函数,和call函数区别是能调用指定好地址的代码,所有其他方面(存储、余额等)都是从当前合约获得。delegatecall
的目的是用于调用存储在另一个合约的库代码。所以开发者需要保证两个合约的存储设计都能是适合delegatecall
调用。在homestead阶段之前,只有一个callcode可用,但callcode没有提供对msg.sender
和msg.value
的访问权限。call
,delegate
和callcode
是非常底层函数,由于这些函数会破坏Solidity的类型安全所以只有万不得已的情况才能使用。.gas()
都可以被以上3个方法使用,但.value()
不支持被deletecall
使用。
注释:所有合约都继承address的成员,查询当前合约余额金额使用
this.balance
。callcode
不鼓励使用,以后会移除该方法。
警告:
call
,delegate
和callcode
都是底层函数,请小心使用。特别地,任何未知的合约都可能有恶意攻击存在,假如你调用未知的合约,将会把控制权交给你所在合约调用的合约,调用返回参数会修改状态变量。
网友评论