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);
}
}
-
sendsend主要作用发送以太币,send函数比transfer函数更为底层。如果send在执行过程中失败,正在执行合约不会被中断和抛出异常,但会返回fasle。注意:如果调用栈深度超过1024或是gas不够,转账操作都会失败。为了确保以太币转账安全,如果用
send就必须每次都要检查返回值。使用transfer无须检查,因为会抛出异常。
-
call,callcodeanddeledatecallcall函数主要作用:为了不依赖与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都是底层函数,请小心使用。特别地,任何未知的合约都可能有恶意攻击存在,假如你调用未知的合约,将会把控制权交给你所在合约调用的合约,调用返回参数会修改状态变量。











网友评论