文章前言
返回值调用验证问题多出现在和转币相关的智能合约中,故又称作静默失败发送或未经检查发送,在Solidity中存在transfer()、send()、call.value()等转币方法,都可以用于向某一地址发送Ether,其区别在于:
- transfer发送失败时会throw,并且进行状态回滚,只会传递2300gas供调用,防止重入攻击
- send发送失败时会返回false,只会传递2300gas供调用,防止重入攻击
- call.value发送失败时会返回false,传递所有可用gas进行调用(可通过传入gas_value参数进行限制),不能有效防止重入攻击。
演示示例
示例代码如下:
function withdraw(uint256 _amount) public {
require(balances[msg.sender] >= _amount);
balances[msg.sender] -= _amount;
etherLeft -= _amount;
msg.sender.send(_amount);
}
上面代码忘记检查send函数的返回值,如果Ether发送失败,由于没有自定义回滚机制,etherLeft将出现异常,从而导致msg.sender用户的币白白转丢,但是接受者的账户却没有收到任何代币。
防御措施
使用send和call.value进行转账操作时对返回值进行检查。
智能合约安全:未检查的转币返回值风险与防御
本文介绍了Solidity智能合约中常见的安全问题——未检查send和call.value返回值的调用,这种做法可能导致资金丢失且无法回滚。当转账失败时,合约可能会继续执行,造成状态异常。示例代码展示了如何在withdraw函数中忽略send返回值导致的问题。防御措施是务必检查转账函数的返回值,确保转账成功后再执行后续操作。
873

被折叠的 条评论
为什么被折叠?



