每个发行的代币会在以太坊上部署一个智能合约,智能合约管控代币的发行、相互之间的转化。
这里是从2015年8月份到最近一个月的数据,这个数据表明每个月新部署的智能合约数据。蒋涛谈到以太坊最火爆的时候是2017年的下半年中国开发者加入的时候,而5月份智能合约数据开始获得了长足增长,2017年9月份由于国家政策监管原因,开始下滑,但2017年10月份数据又得到长足增长,然后慢慢稳定下来,2018年的4月份数据开始慢慢降落了。
这个发展背后伴随着我们不想看到的一系列安全事件,出现在区块链的各个环节包括:交易所、矿池、钱包、智能合约 。关于交易所,今年年初3月份出现了交易所被攻击的事件;关于矿池,在上个月遭到了51%算力的攻击,引起了“双花现象”;关于钱包,2018年4月份全球最大基于网页的数字钱包的域名被劫持;关于智能合约 ,2018年4月份公布了关于美链智能合约漏洞等,5月份则陆续出现了智能合约漏洞 。
已公开的漏洞直接影响各大交易所停止了代币发行的充值或取现,目前还有不少未公开的漏洞 ,我们会联系相关的项目方和相关交易所,逐步和他们验证相关的数据。
因为这个是开发者社区,接下来我们会挑两个例子,跟大家分享一下漏洞的原理,大家以后再做项目开发时,就能够避免相关问题:
第一个漏洞,关于TransferFlaw,这是大家理解的偷币漏洞 。如果用户有一个代币,背后对应的智能合约有安全漏洞 ,攻击者可以把这些代币从你的钱包里全部转走。这里列出了有漏洞的TransferFlaw,TransferFlaw里面有三个参数,这是交易的数值,代码49-51行做初步的检查,确保这个参数是有效的,但在代码53行和54行计算了转出方本身有的余额保存在fromBalance,同时统计了这次允许转出的额度,根据计算出来的变量,在代码行56行和57行,跟当前交易的数值做比较,然后计算两个条件判断是否本次交易转出方有足够的帐户余额允许做交易,转出方是不是有足够的授权做交易。
大家要关注一下代码行58行,简单验证一下如果把这部分钱或者代币转入转入方,转入方的余额会不会造成溢出。这三个条件加起来就是代码行满足条件下授权这次交易。大家能够意识到代码行里的判断条件,特别是在56行,如果判断交易的转出方有足够余额时,后面的fromBalance不是小于等于value,应该是大于等于value,57行应该是也大于等于value,58行也不应该是大于,而应该是小于。
这里有两个数字钱包,左边数字钱包是一个普通者用户,他有1.2345个UET代币,是我们自己花钱去买的。右边的数字钱包是攻击者的,攻击者开始的代币余额是零,攻击发生的时候这些UET代币是怎么从用户的数字钱包转到了攻击者钱包?因为这个漏洞的存在,即使这个用户用的是这些冷钱包,这些钱都可以被转走。
第二个漏洞,multiOverflow。multiOverflow是每次交易都去做的话可能引起比较高的交易费用,这个函数的作用是把多笔的单笔交易组成一个批处理。它有两个参数,就是转入方和转入的数值,这里面拥有多笔交易,它做成数组,代码行227和228数值长度是一样的,才是个有效的数据,数值长度就变成当前有多少个单个交易。
代码行249-251相当于把这些要转出的交易的数值做了一个加法,获取总值之后判断转出方有足够的余额去授权管理,但因为这个漏洞存在,能够感觉到这个变量有可能溢出,有可能变成零。
假设这个数值有两个地址,一个1、一个2,数值等于2的225次方,2个225次方相加得到256次方,造成条件相当于转出方的余额大于等于1,后面的循环会把单笔交易的value转到转入方,同时转出方做相减,转出方加这个值等于2的255次方,造成无限生成代币漏洞 。