合約有狀態變數,其中一些可以在合約創建時由創建者實體化,這些在之后是不能更改的,而那些在創建合約時沒有實體化的內容可以在之后修改,
由于這些變數可以在之后更改,因此如果該變數對合約的安全性至關重要,那么則需要采取適當的謹慎措施,
以下合約模仿了一個發生在名為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愛好者中文社區
鏈接:https://www.jianshu.com/p/5379e44280f5
來源:簡書
著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請注明出處,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/293015.html
標籤:區塊鏈
上一篇:智能合約語言 傳統編程語言 異同
下一篇:區塊鏈 Zilliqa是什么
