热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

区块链研究实验室|停止使用Solidity的transfer()函数

区块链研究实验室|停止使用Solidity的transfer()函数

以太坊看起来EIP 1884正在伊斯坦布尔硬叉前进。这一变化增加了sload操作的gas成本,因此打破了一些现有的智能合约。

这些合约将破裂,因为它们的fallback函数过去消耗的gas少于2300,现在它们将消耗更多。为什么2300gas是重要的? 如果通过Solidity的transfer()或send()方法调用合约的fallback函数,则它是合约的fallback函数。

自从transfer()引入以来,它通常被安全社区推荐,因为它有助于防止重入攻击。在gas成本不变的假设下,这一指导意见是有意义的,但事实证明这一假设是错误的。我们现在建议避免transfer()和send()。

气体成本可以也将改变

evm支持的每个操作码都有一个相关的gas成本。例如,sload从存储器中读取一个单词,目前(但不是很长时间)需要200气体。gas的价格不是随意的。它们旨在反映构成以太坊的节点上每个操作所消耗的底层资源。

EIP的动机部分:

操作价格与资源消耗(CPU时间、内存等)之间的不平衡有几个缺点:

  • 它可以用于攻击,通过填充区块与定价过低的操作,导致区块处理时间过长。

  • 定价过低的操作码会导致区块gas限值倾斜,有时区块气体快速完成,但其他类似gas使用的块体缓慢完成。

  • 如果操作平衡,我们可以最大限度地提高区块气限,并有一个更稳定的处理时间。

sload历来定价过低,而eip 1884纠正了这一点。

智能合约不能依赖气体成本

如果gas成本会发生变化,那么智能合约就不能依赖于任何特定的gas成本。

任何使用transfer()或send()的智能合约都会通过转发固定gas数量2300来严格依赖gas成本。

我们的建议是停止在代码中使用transfer()和send(),改为使用call():

区块链研究实验室|停止使用Solidity的transfer()函数

这两份智能合约除了gas的传输数量不同,其余都是相等的。

可重入性?(Reentrancy )

希望您在看到上述代码时首先考虑过这个问题。引入transfer()和send()的全部原因是为了解决DAO臭名昭着的黑客攻击的原因。 其思想是2300 gas足以发出一个日志条目,但不足以发出一个可重入调用,然后修改存储。

不过,请记住,gas成本可能会发生变化,这意味着无论如何,这是解决重入问题的糟糕方法。今年早些时候,君士坦丁堡叉子被推迟了,因为降低gas成本导致先前安全的代码无法再进入。

如果我们不再使用transfer()和send(),我们将不得不以更健壮的方式防止重入。幸运的是,这个问题有很好的解决方案。

检查 - 效果 - 交互模式

消除重入错误的最简单方法是使用检查-效果-交互模式。这是一个可重入错误的典型例子:

区块链研究实验室|停止使用Solidity的transfer()函数

 

如果msg.sender是智能合约,它在第6行有机会在第7行发生之前再次调用withdraw()。在第二次调用中,balanceOf [msg.sender]仍然是原始金额,因此将再次传输。这可以根据需要重复多次以消耗智能合约。

检查 - 效果 - 交互模式的想法是确保所有交互(外部调用)最终发生。上述代码的典型修复方法如下:

区块链研究实验室|停止使用Solidity的transfer()函数

请注意,在此代码中,余额在传输之前被清零,因此尝试对withdraw()进行可重入调用将不会使攻击者受益。

使用Reentrancy 保护

防止重入的另一种方法是明确检查和拒绝此类调用。这是一个简单版本的reentrancy 保护,你可以看到这个想法:

区块链研究实验室|停止使用Solidity的transfer()函数

使用此代码,如果尝试重入调用,第7行上的require将拒绝它,因为lock仍设置为true。

在OpenZeppelin的ReentrancyGuard合同中可以找到一个更复杂、更省gas的版本。如果从ReentrancyGuard继承,则只需使用nonReentrant修饰函数以防止重入。

请注意,此方法仅在显式将其应用于所有正确的函数时才保护您。由于需要在储存中保持一定的价值,这也增加了gas成本。

Vyper如何?

Vyper的send()函数使用与Solidity的transfer()相同的硬编码gas,因此也应避免使用。你可以改用raw_call。

Vyper内置了一个@nonreentrant()装饰器,其工作方式与OpenZeppelin的ReentrancyGuard类似。

总结

  1. 在假定gas成本不变的情况下,推荐transfer()是有意义的。

  2. gas成本并不恒定。智能合同对这个事实应该是健全的。Solidity的transfer()和send()使用硬编码的gas量。

  3. 应该避免这些方法。请改用.call.value(...)(“”)。

  4. 这就带来了重新进入的风险。请确保使用可用于防止重入漏洞的健壮方法之一。

  5. vyper的send()也有同样的问题。


推荐阅读
  • Flow 生态案例学习 | Emerald City为Flow上DAO、教育和开发铺平道路
    原文链接:https://www.onflow.org/post/emer ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • 区块链第三篇
    在之前讲过的“里,我们用“账本”引出了“区块链”的概念,即区块链是一个公共记录账本,其本身有着去中心化和不可篡改等特点。还记得我们当时 ... [详细]
  • [币萌研究院] 项目简报Agoric (BLD)
    [币萌研究院] 项目简报Agoric (BLD) ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 数字化转型_2021数博会现场直击丨工业互联网如何驱动产业数字化转型?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了2021数博会现场直击丨工业互联网如何驱动产业数字化转型?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 提到区块链,总会离不开“去中心化”“不可篡改”“智能合约”“透明化”等等一系列很专业的词汇。聊起来更是云里雾里,仿佛共产主义社会马上就要实现一般 ... [详细]
author-avatar
枫叶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有