发送ETH
这章的标题让我觉得奇怪,因为先前我也发送ETH,如上一篇提到的recieve和fallback函数。
重现了教程中的代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
contract sendeth{
// 这个事件是为了打log,记录收到的eth和剩余的gas fee
event log(uint amount,uint gas);
receive() external payable {
emit log(msg.value,gasleft());
}
function get_balance() public view returns (uint _balance){
// 这个balance的单位并不是eth而是最小单位wei
_balance = address(this).balance;
}
}
本章的重心在于:
Solidity有三种方法向其他合约发送ETH,他们是:transfer(),send()和call(),其中call()是被鼓励的用法.
下面就实现一些方法向合约内发送eth
Transfer
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
contract sendeth{
// 这个事件是为了打log,记录收到的eth和剩余的gas fee
event log(uint amount,uint gas);
receive() external payable {
emit log(msg.value,gasleft());
}
function get_balance() public view returns (uint _balance){
// 这个balance的单位并不是eth而是最小单位wei
_balance = address(this).balance;
}
}
contract sendeth_send{
// 构造函数使用payable使得部署的时候可以转eth进去 我怎么没看懂?
constructor() payable {}
// 在接收eth时会触发这个函数
receive() external payable { }
// external只能被外部函数调用 public可以被内外函数进行调用
// 为什么使用external而不使用public呢
function transfereth(address payable add,uint256 amount) external payable{
// add是接收合约的地址,amount是转账的金额
// transfer是address类内部实现的一个方法
add.transfer(amount);
}
}
这里是使用transfer方法
send
send方法和transfer的用法是差不多的,同样可以理解为address类内部实现的方法,可以使用add.send()的方式进行使用。
send的gas fee是很低的,合约的fallback()和receive()不能实现太复杂的逻辑。
send的返回值是一个bool,需要额外的逻辑处理转账失败。
call
contract sendeth_send{
// 构造函数使用payable使得部署的时候可以转eth进去 我怎么没看懂?
constructor() payable {}
// 在接收eth时会触发这个函数
receive() external payable { }
// external只能被外部函数调用 public可以被内外函数进行调用
// 为什么使用external而不使用public呢
function transfereth(address payable add,uint256 amount) external payable{
// add是接收合约的地址,amount是转账的金额
// transfer是address类内部实现的一个方法
add.transfer(amount);
}
// 这个是send方法 为什么这个address要使用payable?
function sendseth(address payable add,uint256 amount) external payable {
// 返回值需要显示的表明
bool success = add.send(amount);
// 如果send方法返回一个false就表示
if (!success){
revert Sendfailed();
}
}
function sendethcall(address payable add,uint256 amount) external payable {
(bool success,) = add.call{value:amount}("");
if(!success){
revert Callfailed();
}
}
}
方法的使用差不多。