重入(reentrant或re-entrancy)攻击

可重入

若一个程序或子程序可以「在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错」,则称其为可重入(reentrant或re-entrancy)的。

例子如下:

function withdraw(uint_amount) public {
	if(balances[msg.sender] >= _amount) { 
		if(!msg.sender.call.value(_amount)) { throw; } 
		balances[msg.sender] -= _amount; 
	}
}

上面的代码中,如果攻击者写一个合约来调用这个代码。那msg.sender就是攻击者的合约。msg.sender.call.value(_amount) 就是当前合约向攻击者合约发送eth,也就是当前合约调用攻击者合约的fallback函数。 如果攻击者合约的fallback函数里面,再调用当前合约的withdraw。进而重复执行msg.sender.call.value(_amount),直到gas全部消耗完毕或者合约中的以太余额全部被取完。于是就给黑客实现 reentrancy 攻击创造了条件。

解决方式:

在调用转账之前,先把余额减掉。

functionwithdraw(uint_amount) public {
	if(balances[msg.sender] >= _amount) { 
		balances[msg.sender] -= _amount; 
		if(!msg.sender.call.value(_amount)) { throw; } 
	}
}

参考文档: http://baijiahao.baidu.com/s?id=1601249165343265192&wfr=spider&for=pc

转载于:https://my.oschina.net/kunBlog/blog/1835206

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值