assert(a == 0 || c / a == b);
首先 uint256(cnt) 是把cnt 转成了 uint256范例
其实他思量了,
也就不会产生溢出了...
当前amount 是0,所以当前用户代币的余额没有变换
我能想到的是,快照在裂痕之前,所有用户的余额环境
uint cnt = _receivers.length;
safeMath 是为了计较安详 而写的一个library
我们一行一行的来表明
而require的话,则只是耗损掉当前执行的gas
代码必然要测试!
uintx 范例的取值范畴是 0 到 2的x次方 -1
uint256
那么,开拓者有没有思量到溢出问题呢?
假如在上面计较 amount的时候,用了 mul的话, 则 c / a == b 也就是 验证 amount / cnt == _value
57896044618658097711785492504343953926634992332820282019728792003956564819968 个代币!!!
return c;
总结
用了assert的话,则措施的gas limit 会耗损完毕
http://www.bibaodao.com/blockchain/
}
所以 _receivers 中地点的余额,则加了
除了amount的计较外, 其他的给用户转钱 都用了safeMath 的要领(sub,add)
那么当我 0 - 1 的时候,功效是啥呢?功效会酿成255
balances[_receivers[i]] = balances[_receivers[i]].add(_value);
_value 的值是 8000000000000000000000000000000000000000000000000000000000000000
然后扣掉你发送的总金额
这句会执行报错的,因为 0 / cnt 不便是 _value
啥是safeMath
总结
这句是当前用户的余额 - amount
然后你要发送的总金额 = 发送的人数* 发送的金额
代码必然要review!
0x0e823ffe018727585eaf5bc769fa80472f76c3d7
那么 我们如何制止这种问题呢?
我们可以看到执行的要领是 batchTransfer
那么 尚有一个小问题,这里的 assert 好 require 仿佛是干的同一件事
0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f
那么 我们回到上面的代码中,
这句是遍历 _receivers中的地点, 对每个地点做以下操纵
我小我私家观点是
那这个要领是干嘛的呢?(给指定的几个地点,发送沟通数量的代币)
然后 要求你当前的余额大于 发送的总金额
从上面我们已经知道了 uint8 最小是0,最大是255
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
我们再查察代码(如下图)
然后刊行新的token,给之前的用户 发送等额的代币...
是获取 _receivers 内里有几个地点,我们从上面可以看到 参数内里只有两个地点,所以 cnt=2,也就是 给两个地点发送代币
我们看看他干了啥?为啥能担保计较安详.
Transfer(msg.sender, _receivers[i], _value); } 这句则只是把赠送代币的记录存下来!!!
uint256 amount = uint256(cnt) * _value;
因为uint256的取值太大了,所以用uint8来 举例。。。
那么他俩有啥区别呢?
如上面的乘法. 他在计较后,用assert 验证了下功效是否正确!
可以看到 _value = 57896044618658097711785492504343953926634992332820282019728792003956564819968
整体逻辑是
可以在查察上面看到 uint256取值范畴最大为 115792089237316195423570985008687907853269984665640564039457584007913129639935
_receivers
我们的cnt便是2,通过!
那么 amount = _value*2 = 115792089237316195423570985008687907853269984665640564039457584007913129639936
_value
balances[msg.sender] = balances[msg.sender].sub(amount);
}
0 到115792089237316195423570985008687907853269984665640564039457584007913129639935
下面我来带各人看看,黑客是如何实现的!
也就是 0 到255
amount = uint256(cnt) * _value
那笔操纵记录是
0 - 2的256次方-1 也就是
可是此时 _value 是16进制的,我们把他转成 10进制
也就是 如果是 uint8的话
不外已经产生了的工作咋办呢?
balances[_receivers[i]] = balances[_receivers[i]].add(_value); _receivers中的地点 的余额 = 原本余额+value
_receivers 的值是个列表,内里有两个地点
这句要求 value 大于0,我们的value是大于0 的 且,当前用户拥有的代币余额大于便是 amount,因为amount便是0,所以 就算你一个代币没有,,也是满意的!
那么当我 255 + 2 的时候,功效是啥呢?功效会酿成1
那么 为啥就偏偏这一句没有用safeMath的要领呢。。。
这件过后需要如那里理惩罚呢?
Transfer(msg.sender, _receivers[i], _value);
你传几个地点给我(receivers),然后再传给我你要给每小我私家几多代币(value)
然后 给receivers 内里的每小我私家发送 指定的金额(value)
require(_value > 0 && balances[msg.sender] >= amount);
则 uint8的取值范畴是 0 到 2的8次方 -1
此时,amout已经高出了最大值,溢出 则 amount = 0
for (uint i = 0; i < cnt; i++) {
都是为了验证 某条语句是否正确!
下一行代码 require(cnt > 0 && cnt <= 20); require 语句是暗示该语句必然要是正确的,也就是 cnt 必需大于0 且 小于便是20
那么,什么是uint256范例?可能说uint256范例的取值范畴是几多...
0xb4d30cac5124b46c2df0cf3e3e1be05f42119033
所以措施会报错!
本日有人在群里说,Beauty Chain 美蜜 代码内里有bug,已经有人操作该bug得到了 57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968 个 BEC
(python 16进制转10进制)
这就要用写代码的人了。。。
须要时,要请专门做代码审计的公司来 测试代码
可是这段代码却犯了一个很傻的错!
只要涉及到计较,必然要用safeMath
就一个简朴的溢出裂痕,导致BEC代币的市值靠近归0
从逻辑上看,这边是没有任何问题的,你想给别人发送代币,那么你自己的余额必然要大于发送的总金额的!
代码表明
那么uint256 的取值范畴是
这个要了解传入两个参数
uint256 c = a * b;
举个例子来说明
则 amount = 2* _value
那么当我 0 - 2 的时候,功效是啥呢?功效会酿成254
那么当我 255 + 1 的时候,功效是啥呢?功效会酿成0
今朝,该要领已经暂停了(还好可以暂停)所以看过文章的伴侣 不要去测试了...
那么如果说 配置的值高出了 取值范畴怎么办?这种环境称为 溢出
python 算 2的256次方是几多?
可以看如上截图
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。