热门标签 | 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()也有同样的问题。


推荐阅读
  • Qtum量子链9月17日-9月23日新闻动态回顾本篇文章会详细回顾Qtum量子链在过去的一周(9月17日-9月23日)新闻动态,新闻回顾后 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • 区块链第三篇
    在之前讲过的“里,我们用“账本”引出了“区块链”的概念,即区块链是一个公共记录账本,其本身有着去中心化和不可篡改等特点。还记得我们当时 ... [详细]
  • Flow 生态案例学习 | Emerald City为Flow上DAO、教育和开发铺平道路
    原文链接:https://www.onflow.org/post/emer ... [详细]
  • [币萌研究院] 项目简报Agoric (BLD)
    [币萌研究院] 项目简报Agoric (BLD) ... [详细]
  • Jump Crypto:从三个层面比较 LayerZero、Wormhole 等跨链桥安全性
    安全性是评估跨链桥的重中之重。原文标题:《听JumpCrypto讲解,LayerZero、Wormhole ... [详细]
  • cBridge 2.0 测试网上线!
    cBridge2.0测试网上线!我们在上个月末发布了cBridge2.0计划,现在我们很高兴地向大家宣布,cBridge2.0测试网正式启动!cBridge2.0建立的目的是为用户 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了sqlserver云存储和本地存储的区别,云存储是将数据存储在网络上,方便查看和调用;本地存储是将数据存储在电脑磁盘上,只能在存储的电脑上查看。同时提供了几种启动sqlserver的方法。此外,还介绍了如何导出数据库的步骤和工具。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • 本文探讨了容器技术在安全方面面临的挑战,并提出了相应的解决方案。多租户保护、用户访问控制、中毒的镜像、验证和加密、容器守护以及容器监控都是容器技术中需要关注的安全问题。通过在虚拟机中运行容器、限制特权升级、使用受信任的镜像库、进行验证和加密、限制容器守护进程的访问以及监控容器栈,可以提高容器技术的安全性。未来,随着容器技术的发展,还需解决诸如硬件支持、软件定义基础设施集成等挑战。 ... [详细]
  • 区块链技术的理想值与现实相比,还差的很远
    在人类历史上,从来没有哪项试验性的技术,能在面世之初就获得如此大量的资金追捧和广泛的关注。古语讲天下熙熙,皆为利来,天下攘 ... [详细]
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社区 版权所有