這篇文章背後的動機是我試圖了解智能合約中的一些常見漏洞。

我們可能聽說過著名的DAO攻擊,它導致了以太坊經典的誕生。被攻擊者利用的漏洞稱為“可重入性”。

什麼是重入攻擊?

假設有兩個合約A和合約B,合約A調用合約B。在這種攻擊中,當第一個調用仍在執行時,合約B調用合約A,這在某種程度上導致了一個循環。

我們將在下面給出的示例的幫助下嘗試更好地理解攻擊。我們有一個名為EtherStore的智能合約,用戶可以在其中存、取款和查看智能合約的當前餘額。

EtherStore.sol

我們看到提款功能有一個檢查,不允許用戶取比他們擁有的更多的錢,但是bug出現在第16行。每當我們將以太坊發送到智能合約地址時,我們都會定義我們所說的fallback函數。在大多數情況下,這只是一個空函數,但攻擊者足夠聰明,這是放置實際利用代碼的地方。

攻擊

攻擊者調用exploit函數,在EtherStore合約中存入1個以太坊,以通過EtherStor合約的第14行檢查。當代碼到達第16行時,攻擊者會調用攻擊者合約的fallback函數,攻擊者在其中調用EtherStore上的withdraw函數,直到耗盡資金。

Reentrancy.sol

解決方案

這種攻擊是可能的,因為代碼從來沒有達到EtherStore合約的第20行,在這裡我們減去了從EtherStore合約中提取的金額。為了解決這個問題,我們有兩個解決方案。首先是在轉移餘額重新定位從用戶那裡減去餘額的邏輯。

修改後的提款()函數

第二個解決方案是使用noReentrancy保護修改器,它在執行時鎖定合約,並在執行結束時解鎖。

noReentrancy 守衛修改器

Source:https://zuhaibmd.medium.com/reentrancy-hack-solidity-1-aad0154a3a6b