0%

solidity | transfer 和 send

这里讲一下地址类型的 transfersend 的用法。

可以先看一下 address

send

  • 错误时不发生异常返回 false 使用的时候一定要检查返回值
    • 大部分时候用 transfer
  • addr.transfer(y) 等价于 require(addr.send(y))
  • sendtrnasfer 受制于 2300 gas 限制,当合约接受以太币的时候,转账很容易失败

案例

合约给合约转账 TestMainTest 转账。

通过调用 TestMain 中的 transfer 函数,让 TestMain 合约给 Test 合约地址转账。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pragma solidity ^0.4.18;

contract Test{

//回退函数
function() public payable{}

function get_balance() public view returns(uint){
return this.balance;
}
}

contract TestMain{

constructor() payable{}

function transfer(address a) public returns (bool){
a.transfer(1 ether);
return true;
}
}

如果接收合约的函数复杂一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
pragma solidity ^0.4.18;

contract Test{

event log(bytes data);

function() public payable{
emit log(msg.data);
emit log(msg.data);
}

function get_balance() public view returns(uint){
return this.balance;
}
}

contract TestMain{

constructor() payable{}

function transfer(address a) public returns (bool){
a.transfer(1 ether);
return true;
}
}

再次调用 Main 合约的 transfer 就会出现错误,转账失败。

1
2
3
4
5
6
transact to TestMain.transfer errored: VM error: revert.

revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.

如果,把 Main 函数中的 a.trnasfer 换成 a.send ,会发现,上面执行成功,但是,实际上是没有成功的,因为,send 不会返回异常,而是会返回 false

我们可以

require(a.send(1 ether))
或者
assert(a.send(1 ether))

来让其返回异常。

请我喝杯咖啡吧~