公明网站建设怎么做,网页设计大赛新闻稿,中牟县建设局网站,app软件怎么开发这两天币圈链圈被美链BEC智能合约的漏洞导致代币价值几乎归零的事件刷遍朋友圈。这篇文章就来分析下BEC智能合约的漏洞 !-- more -- 漏洞攻击交易 我们先来还原下攻击交易#xff0c;这个交易可以在这个链接查询到。我截图给大家看一下#xff1a; 攻击者向两个账号转… 这两天币圈链圈被美链BEC智能合约的漏洞导致代币价值几乎归零的事件刷遍朋友圈。这篇文章就来分析下BEC智能合约的漏洞 !-- more -- 漏洞攻击交易 我们先来还原下攻击交易这个交易可以在这个链接查询到。我截图给大家看一下 攻击者向两个账号转移57896044618...000.792003956564819968个BEC相当于BEC凭空进行了一个巨大的增发几乎导致BEC价格瞬间归零。下面我们来分析下这个攻击过程。 合约漏洞分析 我们先来看看BEC智能合约的代码BEC在合约中加入一个批量转账的函数它的实现如下 function batchTransfer(address[] _receivers, uint256 _value) public whenNotPaused returns (bool) {uint cnt _receivers.length;uint256 amount uint256(cnt) * _value;require(cnt 0 cnt 20);require(_value 0 balances[msg.sender] amount);balances[msg.sender] balances[msg.sender].sub(amount);for (uint i 0; i cnt; i) {balances[_receivers[i]] balances[_receivers[i]].add(_value);Transfer(msg.sender, _receivers[i], _value);}return true; 这个函数的作用是调用者传入若干个地址和转账金额在经过一些条件检查之后对msg.sender的余额进行减操作对每一个对每一个传入的地址进行加操作以实现BEC的转移。问题出在 uint256 amount uint256(cnt) * _value; 这句代码当传入值_value过大时接近uint256的取值范围的最大值uint256 amount uint256(cnt) * _value计算时会发生溢出导致amount实际的值是一个非常小的数此时amount不再是cnt * _value的实际值amount很小也使得后面对调用者余额校验可正常通过即require(_value 0 balances[msg.sender] amount)语句通过。 我们来结合实际攻击交易使用的参数来分析一下 batchTransfer的参数_value值为16进制的800000000000000000000...参数_receivers数组的大小为2相乘之后刚好可超过uint256所能表示的整数大小上限引发溢出问题amount实际的值为0后面的转账操作实际上msg.sender的余额减0 而对两个账号进行了加16进制的800000000000000000000...最终的结果是相当于增发了2 * 16进制的800000000000000000000...。 实际上对于这种整数溢出漏洞最简单的方法是采用 SafeMath 数学计算库来避免。有趣的是BEC智能合约代码中其实其他的都使用了SafeMath 而关键的uint256 amount uint256(cnt) * _value却没有使用。心痛程序员也心痛韭菜。这句代码改为uint256 amount _value.mul(uint256(cnt));就可以防止溢出问题 所以在做加减乘除的时候请记得一定使用SafeMath代码在这里 溢出补充说明 溢出补充说明为小专栏订阅用户福利小专栏的文章内介绍了什么时候会发生上溢什么时候会发生下溢并且给出了代码事例。大家可请前往我的小专栏阅读。 ☛ 深入浅出区块链 - 系统学习区块链打造最好的区块链技术博客。 ☛ 我的知识星球为各位解答区块链技术问题欢迎加入讨论。 ☛ 关注公众号“深入浅出区块链技术”第一时间获取区块链技术信息。