主页 > imtoken新版本 > 为什么以太坊智能合约安全漏洞频发?

为什么以太坊智能合约安全漏洞频发?

imtoken新版本 2023-12-23 05:09:17

智能合约 以太坊_以太坊智能合约原理_以太坊智能合约是什么

近期,随着DeFi的火爆,以太坊智能合约的安全漏洞频发。 究竟是什么导致了它,我们如何才能更好地防范这些漏洞?

概述

与比特币相比,以太坊更容易发生安全事件。 这主要是因为以太坊虚拟机是图灵完备的,以太坊可以实现函数之间的相互调用、嵌套调用、智能合约之间的相互调用等各种复杂的逻辑。 而比特币只是实现了一个基于栈的非图灵完备虚拟机,只能通过操作码进行出栈操作。 另外,比特币没有复杂的DApp应用,逻辑简单,安全漏洞空间不大。

以太坊上各种DApp复杂的智能合约逻辑是造成安全漏洞的主要原因。 以太坊智能合约的安全漏洞主要分为逻辑问题和合约代码问题。

逻辑问题

近期频发的“闪贷”攻击就是典型的逻辑问题引发的安全漏洞。 你可以在各种闪贷攻击中看到明显的逻辑问题。 只要攻击者在两个系统之间制造价格差异,他就可以从闪贷攻击中获利。

闪电贷攻击的逻辑细节可以阅读之前专门针对闪电贷的文章:。 本文主要讨论合约代码的问题。

合约代码问题

智能合约 以太坊_以太坊智能合约是什么_以太坊智能合约原理

我们知道,几乎任何稍微复杂一点的代码都会或多或少地存在问题(bug)。 了解问题发生的原因,并对其进行分类,可以帮助我们更好地预防问题。 以下是Ownbit钱包团队整理的关于以太坊智能合约安全问题最多的几点。

1.重入

这是第一个问题。 所谓“可重入”,就是一个方法被反复调用。 而这通常是合约开发者意想不到的。 例如,一个提款合约:

function withdrawEther(public {    uint amount = userBalances[msg.sender];    (bool success, ) = msg.sender.call.value(amount)(""); // 这里重入    require(success);    userBalances[msg.sender] = 0;}

这是一个非常简单的提款合约,允许用户提取他的 ETH 余额。 开发人员不知道此代码可以重入。 方法是:只要调用者是合约账户,msg.sender.call默认会调用合约账户的fallback函数。 攻击者只需要在回退函数中再次调用withdrawEther,就可以不断地取走ETH。

2016年6月,导致ETC分叉的著名The DAO攻击就是通过同样的方式进行的。 事后看来,这只是一个小程序问题(后果如此严重)。 解决这个问题也很容易,只需调换两行代码的顺序即可:

    userBalances[msg.sender] = 0;    (bool success, ) = msg.sender.call.value(amount)(""); 

以太坊智能合约是什么_智能合约 以太坊_以太坊智能合约原理

2. 保持你的交易未打包

以太坊区块的打包机制是基于给定的矿工费(GasPrice),每个区块都有一个总的GasLimit限额(目前每个区块1200万个Gas)。 因此,攻击者可以创建大量使用非常大的GasLimit和非常高的GasPrice的交易,让它们先占满区块,从而无法打包目标交易。

因此,在编写合约逻辑时,不能假设你的交易会在限定时间内被打包,否则你很容易受到此类攻击。 著名的“Fomo3D”事件就使用了这样的攻击方式。

Fomo3D 的游戏规则是奖励最后一个购买产品的人。 每购买一件物品,该物品的计时器将被重置,如果在计时器到0之前没有其他买家,您将获得系统奖励。 攻击者在Fomo3D购买商品,然后同时发送大量占用区块的攻击交易,使得在接下来的13个区块中,无法打包其他买家的交易。 此时计时器达到 0,并假定没有其他买家。 攻击者获得奖励并完成攻击。

3. tx.origin 的错误使用

如果您发现使用 tx.origin 的合约,请留意可能存在的漏洞。 在大多数情况下,我们应该使用 msg.sender 而不是 tx.origin,因为使用 tx.origin 很容易造成安全漏洞。

很多时候,合约开发人员假设 msg.sender 和 tx.origin 是相等的,但事实并非如此。 例如:用户A调用合约B,合约B又调用合约C,则在合约B和C中,tx.origin为A,msg.sender为A和B。

以太坊智能合约是什么_智能合约 以太坊_以太坊智能合约原理

一般情况下,攻击者会引诱A调用一个诱导合约B,然后B调用A部署的目标合约C,因为合约C使用tx. 控制完成攻击。

4.溢出攻击

智能合约中的数据可能会溢出,比如:uint256,你觉得很大:2^256。 真的很大,但还是能溢出来。 例如,一个合约允许对一个数据进行加减,而攻击可以通过对该数据进行精心策划的调用来实现,使其溢出以允许执行某些逻辑。

5.回退可以恢复

Fallback是可以reverted的,也就是说,如果你把ether转给对方,对方可以让你一直不成功。

例如,如果你编写一个合约并依赖你成功地将以太币转移到某个地址,那么攻击可以部署一个合约并将其回退写为 revert 以使你的调用始终失败:

function () public payable {   revert () ; }

以太坊智能合约原理_智能合约 以太坊_以太坊智能合约是什么

6. selfdestruct 可以定义任意受益人而不调用fallback

当你认为你可以通过 revert 阻止每个人向你支付以太币时,你可能又错了。 攻击者创建合约智能合约 以太坊,然后销毁合约。 以太坊会返还一部分以太作为销毁合约的激励,这笔返还可以指定任何受益人,对方的fallback函数不会被调用。

也就是说,开发人员应该意识到,没有办法完全阻止其他人将以太币转移到你的合约账户。

7.delegatecall的错误使用

使用 delegatecall 时注意上下文(即 msg.sender 等)的变化。 使用 call 调用合约时,上下文会切换到被调用的合约。 使用 delegatecall 调用合约时,上下文还在这个合约中。

delegatecall和call调用上下文的不同也是合约安全漏洞经常出现的地方。

8.不同的空气传输方式不同

以太坊智能合约是什么_以太坊智能合约原理_智能合约 以太坊

我们在传输以太币的时候,不同的气体传输方式(Gas)是不一样的。 使用 send() 和 transfer() 转移 gas 只有 2300,而使用 call.value()() 将转移所有剩余的 gas。 因此智能合约 以太坊,最新的安全规范建议使用 call 代替 send 或 transfer 进行以太币转账。

如果您发现某个合约仍然使用 send 或 transfer,那么您可以创建一个目标合约来 transfer Out of Gas。

结语

以上几点是合约代码中最常见的问题。 每个错误的原因都是相对原子化的,了解相应的原理可以帮助我们有效避免这些问题。 当合约逻辑复杂时,必然存在更复杂、更深层次的隐藏逻辑问题。 这个时候检查这些原子点还是可以帮助我们找到它们的。

以太坊智能合约的安全问题主要是由于其“过于灵活”造成的。 灵活性和安全性就像天平的两端。 以太坊选择了灵活性,在一定程度上将安全的潜在风险留给了市场。

一个DeFi项目能否安全稳定运行,会不会被黑客攻击,取决于合约开发者对原理的理解,对细节的把控,以及认真的态度。 在线合约出错的代价是巨大的,这对合约开发者提出了更高的要求!

智能合约 以太坊_以太坊智能合约是什么_以太坊智能合约原理

使用最安全的多重签名和冷钱包存币:Ownbit

以太坊智能合约原理_以太坊智能合约是什么_智能合约 以太坊

下载网址: