Solidity
有三種方法向其他合約發送ETH,他們是
transfer()
send()
call()
,(被鼓勵的用法)
- 先部署一個接收ETH合約ReceiveETH。
- ReceiveETH合約裡有一個事件Log,記錄收到的ETH數量和gas剩餘。
- 還有兩個函數,一個是
receive()函數
,收到ETH被觸發,並發送Log事件;另一個是查詢合約ETH餘額的getBalance()函數。
- 用法是接收方地址.send(发送ETH数额)。
- send()的gas限制是2300,足夠用於轉賬,但對方合約的fallback()或receive()函數不能實現太複雜的邏輯。
- send()如果轉帳失敗,不會revert。
- send()的回傳值是bool,代表著轉帳成功或失敗,需要額外程式碼處理一下。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
// 3种方法发送ETH
// transfer: 2300 gas, revert
// send: 2300 gas, return bool
// call: all gas, return (bool, data)
error SendFailed(); // 用send发送ETH失败error
error CallFailed(); // 用call发送ETH失败error
contract SendETH {
// 构造函数,payable使得部署的时候可以转eth进去
constructor() payable{}
// receive方法,接收eth时被触发
receive() external payable{}
// 用transfer()发送ETH
function transferETH(address payable _to, uint256 amount) external payable{
_to.transfer(amount);
}
// send()发送ETH
function sendETH(address payable _to, uint256 amount) external payable{
// 处理下send的返回值,如果失败,revert交易并发送error
bool success = _to.send(amount);
if(!success){
revert SendFailed();
}
}
// call()发送ETH
function callETH(address payable _to, uint256 amount) external payable{
// 处理下call的返回值,如果失败,revert交易并发送error
(bool success,) = _to.call{value: amount}("");
if(!success){
revert CallFailed();
}
}
// 新增函数来检查指定地址的以太币余额
function checkBalance(address _addr) external view returns (uint256) {
return _addr.balance;
}
}
contract ReceiveETH {
// 收到eth事件,记录amount和gas
event Log(uint amount, uint gas);
// receive方法,接收eth时被触发
receive() external payable{
emit Log(msg.value, gasleft());
}
// 返回合约ETH余额
function getBalance() view public returns(uint) {
return address(this).balance;
}
}
- call沒有gas限制,最靈活,是最提倡的方法;
- transfer有2300 gas限制,但是發送失敗會自動revert交易,是次優選擇;
- send有2300 gas限制,而且發送失敗不會自動revert交易,幾乎沒有人使用它。
- 不管成功或失敗都會有 gas消耗,所以要小心使用。