查看原文
其他

以太坊智能合约 | 存储记录模式和漏洞是关键

小雪 看雪学院 2019-05-25


上周四,看雪讲师,看雪区块链小组成员、上海交通大学密码学实验室成员Xrosheart王艺卓,为区块链爱好者们分享了新一轮的知识——以太坊账户/余额模式和智能合约的两个漏洞。


以太坊智能合约有一个明显的优势——“钱”的存储记录模式。


有两种非常流行的记录模式——UTXO(未使用交易输出)模型,账户/余额模型。其中,UTXO模型由比特币使用,而以太坊使用账户/余额模型。


账户/余额模式的好处就在于可以让我们的账户和银行卡一样,涉及到的支出或收入可直接在余额上加减,其弊端是存在许多漏洞,对安全性发出了挑战,这一弊端伴随着智能合约。



合约漏洞



本次课程主要介绍了整型溢出漏洞(Arithmetic Issues)和重入漏洞。


  • 整型溢出漏洞:


在solidity语言(以太坊智能合约语言,类似JavaScript)中,当一个整型变量高手或者低于它所能承受的范围时就会发生溢出,导致发生一些不可预期的情况。


比如,忽略了整型溢出漏洞,那么当用户输入转账数值,超过设定的最大值时,只要账户余额>0,就可以直接将巨额的币“转走”,这就让黑客有了攻击的机会,最终可能导致一些严重的经济损失。



  • 重入漏洞


何谓“重入”呢?


调用外部合约或将以太发送到地址的操作需要合约提交外部调用。这些外部调用可能被攻击者劫持,迫使合约执行进一步的代码(即通过Fallback函数),包括回调自身。因此代码执行“重新进入”合约>科普:回退函数(fallback)是一个特殊的函数,没有函数名,每个合约都有,主要是用于接受以太的。通过一个攻击合约实现重入攻击就是这个流程。


但是,重入和正常的调用一样,都需要gas来执行transaction操作。所以,这里对转账方法有一定要求。 


每次余额的变化会产生一个新的状态。balances[msg.sender]=0,就意味着状态变化。状态变化是在转账之后。


虽然转账的操作中有require进行判断,但是因为转账在状态变化之前,因此require判断的对象一直是转账之前的状态。


判定成功且转账成功,这里直接把钱都提取(withdraw)出来,余额就变成了0。



提问

问题一:


学员:攻击时转账成功但是判断失败吗?


王艺卓:因为转账在状态变化之前,因此虽然钱转了,但状态还没来得及变化。然后被重入了,原状态还是有钱的,因此,require判定成功,继续转账。转账完同样来不及改状态,就又被重入了。



问题二:


学员:那withdraw函数是判断sender账户余额是都为0,如果不是,则全取出来(变为0),是吗?


王艺卓:withdraw——提款。也就是说,重入攻击转出来的钱都是凭空出现的。



问题三:


学员:这个状态是全网账户的状态吗?


王艺卓:可以理解为全网账户的状态。



问题四:


学员:为啥不是减去msg.value,而是0?


王艺卓:这里直接把钱都提取出来了,余额就变成了0,你理解一下call那句语句。



问题五:


学员:短时间内大量转?


王艺卓:计算机里就是瞬间的事情。



问题六:


学员:这个状态没改变是指以太坊每十几秒改变一次吗?


王艺卓:不是啊,智能合约的语句回改变状态。比如刚刚那句balance=0。状态机了解一下,给一个输入,状态就会变化。这个输入就是balance[msg.sender]。以太坊的钱就是:地址address——余额balance的对应关系。先balances[msg.sender]=0;再require(msg.sender.call.value(balances[msg.sender])());状态变化在转账之前。

......



想要了解更多以太坊智能合约?那就关注下面的活动吧~



11月30日(本周五)19:00~20:00将由看雪讲师、看雪区块链研究员roysue为大家分享~!



扫面海报二维码,即可添加看雪工作人员,入群免费学习~





- End -


往期热门资讯:                                        




公众号ID:ikanxue

官方微博:看雪安全

商务合作:wsc@kanxue.com



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存