区块链 智能合约安全 对关键状态变量的意外更改
  DJsdk34H4Gbu 2023年11月02日 44 0


合约有状态变量,其中一些可以在合约创建时由创建者实例化,这些在之后是不能更改的,而那些在创建合约时没有实例化的内容可以在之后修改。

由于这些变量可以在之后更改,因此如果该变量对合约的安全性至关重要,那么则需要采取适当的谨慎措施。

以下合约模仿了一个发生在名为Parity的多重签名钱包上的攻击,攻击者盗取了3100万美元。

请注意,实际的攻击涉及的内容要更广泛,但这个简化版的实例展示了它的核心内容。

合约有一个owner,它不是在创建时实例化的,而是在后来通过函数initowner()进行的。

在实例化后,owner可以调用transferTo()并将合约中指定的_amount转给特定的_recipient。

contract UnsafeContract2{

/* Define the contract owner*/

address owner;


/* This function sets the owner of the contract */

function initowner(address _owner) {
owner = _owner;
}


/* Function to transfer the funds in the contract */

function transferTo(uint _amount, address _recipient) {

if (msg.sender == owner)

_recipient.transfer(_amount);

}

}

显然,owner是一个关键的状态变量,应该以适当的方式实例化。

不幸的是, initowner()函数允许任何包括恶意的用户调用,并将owner设置为他选择的任何地址。一旦owner被设置,owner就有可能盗取资金并将其转给任何收款方recipient()。

实例3:终止合约

我们来扩展一下前面的实例,一旦设置了关键变量owner,攻击者就可能调用除transferTo()之外的函数。例如,如果合约为owner提供了一个接口来终止合约,那么整个代码可能会与其他任何状态变量一起被删除。

contract UnsafeContract3{

/* Define the contract owner*/

address owner;

/* This function sets the owner of the contract */

function initowner(address _owner) { owner = _owner; }

/* Function to destroy the contract */

function kill() { if (msg.sender == owner) suicide(owner); }

}

类似的攻击最近发生在Parity上,结果攻击者(或很有可能是一个好奇的新手,信息来源:https://blog.springrole.com/parity-multi-sig-wallets-funds-frozen-explained-768ac072763c?gi=c41592bf2d43)冻结了大约1.5亿美元。


作者:Zilliqa爱好者中文社区


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
DJsdk34H4Gbu