当前位置: 首页 > news >正文

北大肖臻老师《区块链技术与应用》系列课程学习笔记[28]以太坊-美链

        智能合约中安全漏洞的例子:The DAO(2016年)、美链(2018年04月)。

1.什么是美链        

        美链(Beauty Chain)是一个部署在以太坊上的智能合约,有自己的代币BEC。IPO,Initial Public Offering(首次公开募股);ICO,Initial Coin Offering(首次代币发行)。这些发行的代币没有自己的区块链,而是以智能合约的形式运行在以太坊的EVM平台上。发行代币的智能合约对应的是以太坊状态树中的一个节点。这个节点有他自己的账户余额,相当于这个智能合约一共有多少个以太币,也就是这个发行代币的智能合约的总资产是多少个以太币,然后在这个合约里每个账户上有多少个代币是作为存储树的一个变量存储在智能合约的账户里的。

        代币的发行、转账、销毁都是通过调用智能合约中的函数来实现的。跟以太坊上的以太币不太一样,它不需要通过挖矿来维护一个底层的基础链,像以太坊上每个账户有多少以太币是直接保存在状态树上的变量。以太坊中两个账户转账是通过发布一个交易到区块链上,这个交易会打包到将要发布的区块里,而在代币中如果想要转账的话,实际上是智能合约里两个账户之间转账,通过调用智能合约的函数就可以完成。

        每个代币可以制定自己的发行规则,如某个代币可以是1ETH=100代币,如果从外部账户给智能合约发送1ETH,智能合约就可以给相应的代币账户发送100代币。每个代币账户上有多少代币的信息是维护在发行这个智能合约的存储树上的。

        以太坊平台的出现,为各种代币的发展提供了很多方便。ERC 20(Ethereum Request for Comments)是以太坊上发行代币的一个标准,规范了所有发行代币的合约应该实现的功能和遵循的接口。美链中有一个叫batchTransfer的函数, 它的功能是向多个接收者发送代币,然后把这些代币从调用者的帐户上扣除。

2.batchTransfer的实现

function batchTransfer(address[] _receivers,uint256 _value) public whenMotPaused 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;
}
图1-1

 3.batchTransfer的问题

uint256 amount =uint256(cnt)*_value;

        如果value的值很大话可能会产生溢出,发生溢出之后,amount会变为一个很小的值;这样的话减去的是很小的值,给每个账户增加的是很大的value,相当于系统凭空多发行了很多的代币。

4.攻击细节

图1-2

        第0号参数是_receivers数组在参数列表中的位置,即从第64个byte开始,也就是第2号参数;第2号参数先指明数组长度为2,然后第3号参数和第4号参数表明两个接受者的地址第1号参数是给每个接收者转账的金额,通过这样的参数计算出来的amount恰好溢出为0。

5.发生攻击的实际情况

图1-3

 6.攻击结果

        攻击在2018年4月22日发生,攻击发生后,代币的币值断崖式暴跌。 

图1-4

        发生这个事件之后,发行该代币的交易所马上暂停了提币功能,防止黑客卷款潜逃,两天之后,就决定将交易回滚了。好在这个代币本来就不是很热门,主要是这个交易所在交易,所以没有产生过于严重的后果,远远没有The DAO的盗币事件影响大。

7.反思 

        在进行数学运算的时候,一定要考虑到溢出的可能性。Solidity实际上有一个检测溢出的库——SafeMath库,里面提供的操作运算都会自动检测有没有溢出。SafeMath库里对乘法的运算大致如下:

library SafeNath {
    
    //@dev Multiplies two numbers, throws on overflow.

    function mul(uint256 a,uint256 b) internal pure returns (uint256 c) {
        if (a == 0) {
            return 0;
        }
        c = a * b;
        assert(c / a == b);
        return c;
}
图1-5

         如果出现溢出的话,这里的assert就不会成立,会抛出异常。由于Solidity里面都是256位的整数,所以这里不会存在精度损失而导致的误差。而且观察batchTransfer的代码可以发现,代码中的减法调用的是sub库,加法调用的是add库,实际上加法和减法都有溢出检查,只有乘法不小心,酿成悲剧。

相关文章:

  • 【Unity】U3D ARPG游戏制作实例(二)人物基本动作切换
  • https证书怎么做?
  • Everything 全局搜索之正则表达式Regex
  • python常见错误类型
  • 22-09-01 西安 JUC(04)java内存模型JMM、volatile关键字、原子性类、CAS比较并交换、AQS锁原理
  • 加湿器芯片方案:不要让空调带走你的水分
  • Machine learning week 10(Andrew Ng)
  • spring-cloud-alibaba-Nacos2.0.3:注册中心和配置中心框架学习
  • android studio教程,Android Studio一个完整的APP实例
  • jumpserver堡垒机界面设置及界面功能
  • LeetCode---SQL刷题6
  • React知识总结✨
  • 一周时间深扒事务 总结代码演示篇 拿捏事务
  • 剑指offer79-87二进制枚举、回溯
  • 《Coding Monkey的自我修养》之MyBatis批量插入数据的三种方法
  • Android Volley源码解析
  • Angular 响应式表单之下拉框
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • ESLint简单操作
  • Flannel解读
  • Javascript Math对象和Date对象常用方法详解
  • PHP 的 SAPI 是个什么东西
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • Vue小说阅读器(仿追书神器)
  • 双管齐下,VMware的容器新战略
  • 无服务器化是企业 IT 架构的未来吗?
  • 再次简单明了总结flex布局,一看就懂...
  • ​马来语翻译中文去哪比较好?
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #FPGA(基础知识)
  • (2)STL算法之元素计数
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (Java)【深基9.例1】选举学生会
  • (SpringBoot)第二章:Spring创建和使用
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (小白学Java)Java简介和基本配置
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • . NET自动找可写目录
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NET序列化 serializable,反序列化
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @angular/cli项目构建--Dynamic.Form
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • [android] 请求码和结果码的作用
  • [Assignment] C++1
  • [BT]BUUCTF刷题第9天(3.27)
  • [C++]四种方式求解最大子序列求和问题
  • [Excel VBA]单元格区域引用方式的小结
  • [go] 迭代器模式
  • [HarekazeCTF2019]encode_and_encode 不会编程的崽
  • [Head First设计模式]策略模式
  • [hive] 窗口函数 ROW_NUMBER()
  • [IE6 only]关于Flash/Flex,返回数据产生流错误Error #2032的解决方式