Soildity安全之未檢查低級調(diào)用的返回值區(qū)塊鏈
WF曲速未來:Soildity作為編寫智能合約的語言,已經(jīng)被廣泛的應(yīng)用。但同時,開發(fā)者和用戶也得到了慘痛的教訓,智能合約的安全問題層出不窮。因此,我們總結(jié)了一些常見的Solidity安全問題。前車之鑒,后車之師,希望后來者能有所警惕。
區(qū)塊鏈安全公司W(wǎng)F曲速未來 安全開課:
Soildity作為編寫智能合約的語言,已經(jīng)被廣泛的應(yīng)用。但同時,開發(fā)者和用戶也得到了慘痛的教訓,智能合約的安全問題層出不窮。因此,我們總結(jié)了一些常見的Solidity安全問題。前車之鑒,后車之師,希望后來者能有所警惕。
未檢查低級調(diào)用的返回值
其中的Solidity的更深層次的特點是低級別的功能函數(shù)call(),callcode(),delegatecall()和send()。它們在計算錯誤時的行為與其他的Solidity函數(shù)完全不同,因為它們不會繼續(xù)向前同時不會導致當前執(zhí)行的完全回滾。相反,它們將返回將Boolean 設(shè)置為false,代碼將繼續(xù)運行。如果未檢查此類低級調(diào)用的返回值,則可能導致打開失敗和其他不需要的結(jié)果。發(fā)送可能會失敗!
代碼案例
上面的代碼是一個調(diào)用send()忘記檢查返回值時可能出錯的示例。如果將ETH發(fā)送到不接受它們的智能合約(例如,因為它沒有應(yīng)付回退功的能),則EVM將用其替換其返回值false。由于在我們的示例中未檢查返回值,因此函數(shù)對合約狀態(tài)的更改將不會被還原,并且etherLeft變量將最終跟蹤不正確的值:
相關(guān)事件
King of the Ether“紛爭時代”
KotET游戲中,玩家需要發(fā)送給合約一些ETH,從而獲得“王位”。只要拿到了王位,玩家就會被加到皇庭,并且永遠地被記錄在區(qū)塊鏈上。更重要地是,后來的國王有權(quán)去獲得新國王的ETH。隨著國王數(shù)量增多,成為國王的代價也會越來越貴。如果14天過去了,還沒有新的繼承者,那么王位就會重置,并且游戲也全部重新開始。
KotET合約的正常運作(基本上)是這樣的:
1.假設(shè)王位的當前價格是10 ETH。
2.你想成為國王/王后,所以你向合約發(fā)送10 ETH。
3.合約將您的10 ETH(少于1%傭金)發(fā)送給之前的國王/王后,作為“賠償金”。
4.合約使你成為以太王座的新王/王后。
5.在這種情況下,寶座的新索賠價格上漲50%,達到15 ETH。
6.如果一個篡位者愿意支付15ETH,他們會讓你成為國王/王后,并且你會收到他們的15ETH作為你的“賠償金”。
基于以太坊的交易,例如向合約發(fā)送付款或簽訂合約,都要花費“gas”。消耗的“gas”量取決于您調(diào)用的合約的操作類型(以及合約數(shù)量)。這種“gas”是支付給礦工的小額支付,有助于提供Etherum網(wǎng)絡(luò)和區(qū)塊鏈存儲。gas由“外部擁有的賬戶”支付,該賬戶盯著交易。在進行交易時,交易需要包含一點gas(未使用的gas將被退還)。
那什么時候會出錯?
KotET游戲在所有情況下都表現(xiàn)正確,除了它向“合約賬戶”發(fā)送付款時,例如以太坊Mist“基于合約的錢包”為例。
當KotET的合約向“合約賬戶”發(fā)送付款時,它僅包含了少量的gas。對于以太坊Mist“基于合約的錢包”合約而言,這并不足以成功處理付款 ,相反,付款失敗了。
當錢包合約未能處理KotET合約發(fā)送給它的付款時,支付的ETH被退還給KotET合約。KotET并不知道付款失敗并繼續(xù)處理,盡管補償金尚未發(fā)送給前任君主,但仍然會通知已到賬。
觀點:
開發(fā)人員在編寫合約時要考慮到這個問題,同時可以考慮用通throw函數(shù)將全額退款發(fā)送回,而不是使用send/call。同時在合約上線前要進行嚴格的審計,保證安全。
1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉(zhuǎn)載的稿件都會明確標注作者和來源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請轉(zhuǎn)載時務(wù)必注明文章作者和"來源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為TMT觀察網(wǎng)或?qū)⒆肪控熑危?br>
3.作者投稿可能會經(jīng)TMT觀察網(wǎng)編輯修改或補充。