以太坊智慧型合約到現在,出現了不少由於合約**不嚴謹,導致黑客利用合約**漏洞進行攻擊來獲取暴利。接下來我為大家來介紹一下常見的合約漏洞型別,包含重入攻擊,短位址攻擊,資料溢位攻擊,可**隨機數攻擊,篡改實踐攻擊等。下面大家介紹一下可重入攻擊。
可重入攻擊也就是攻擊方傳送一筆交易,導致合約一致重複執行直到將合約賬戶的資源消耗完。這有點類似於c語言的遞迴函式。攻擊方能成功進行可重入攻擊,主要依賴於soildity為智慧型合約提供的fallback和call函式,下面先對這兩個函式的功能進行介紹。
以太坊的智慧型合約,可以宣告乙個匿名函式(unnamed function),叫做 fallback 函式,這個函式不帶任何引數,也沒有返回值。當向這個合約傳送訊息時,如果沒有找到匹配的函式就會呼叫 fallback 函式。比如向合約轉賬,但要合約接收 ether,那麼 fallback 函式必須宣告為 payable,否則試圖向此合約轉 eth 將失敗。如下:
function() payable public
向合約傳送 send、transfer、call 訊息時候都會呼叫 fallback 函式,不同的是 send 和 transfer 有 2300 gas 的限制,也就是傳遞給 fallback 的只有 2300 gas,這個 gas 只能用於記錄日誌,因為其他操作都將超過 2300 gas。但 call 則會把剩餘的所有 gas 都給 fallback 函式,這有可能導致迴圈呼叫。
call 可導致可重入攻擊,當向合約轉賬的時候,會呼叫 fallback 函式,帶有漏洞的合約**如下:
contract reentrance
// 檢視餘額
function balanceof(address _who) public view returns (uint balance)
// 提現
function withdraw(uint _amount) public
balances[msg.sender] -= _amount;
}} function() public payable {}
}
上述合約**中的withdraw函式的msg.sender.call.value可能成為惡意**攻擊的地方。如果發起交易方也是智慧型合約賬戶,當攻擊方的合約賬戶通過呼叫reentrance合約的withdraw函式進行提現的時候,由於呼叫call函式,將會呼叫攻擊方合約的fallback函式,如果fallback**再次呼叫reentrance合約的withdraw函式就會形成**可重入,將reentrance合約賬戶的金額全部提走而在區塊的記錄僅僅提現了第一筆,攻擊方的合約**如下:
contract reentranceattack
function deposit() public payable
function attack() public
function() public payable
function withdraw() public
}
攻擊的大概過程如下:
比如reentranceattack在reentrance上有10個以太幣,而reentrance合約賬戶本身持有100個以太幣。如果reentranceattack向reentrance發起1個以太坊提幣的請求。經過攻擊,reentranceattack會提走reentrance的100個以太幣,並且在reentrance合約中reentranceattack賬戶持有以太幣的餘額為9,瘋狂吧!
那麼怎麼才能規避可重入攻擊的風險呢?
1.提現操作前加入bool型別的鎖
2.在轉賬前對金額進行算術處理
3.轉賬採用send()或者transfer()來進行轉賬操作(請注意send和transfer的區別)
修改後的智慧型合約**如下:
contract reentrance
// 檢視餘額
function balanceof(address _who) public view returns (uint balance)
// 提現
allow[msg.sender] = false;
function withdraw(uint _amount) public
allow[msg.sender] = false;
} function() public payable {}
}
AQS之可重入鎖ReentrantLock原理
一 經典故事 村子裡面,有一口井水。水質很好,村民們都想打井裡的水。村長這時就制定了規則 井邊安排乙個看井人,維護打水的秩序。打水時,以家庭為單位,哪個家庭任何人先到井邊,就可以先打水,而且如果乙個家庭佔到了打水權,其家人這時候過來打水不用排隊。而那些沒有搶占到打水權的人,乙個乙個挨著在井邊排成一隊...
Qt之可重入與執行緒安全
本篇文章中,術語 可重入性 和 執行緒安全 被用來標記類與函式,以表明它們如何被應用在多執行緒應用程式中。因此,乙個執行緒安全的函式總是可重入的,但乙個可重入的函式並不一定是執行緒安全的。擴充套件開來,乙個可重入的類,指的是它的成員函式可以被多個執行緒安全地呼叫,只要每個執行緒使用這個類的不同的物件...
Qt之可重入與執行緒安全
本篇文章中,術語 可重入性 和 執行緒安全 被用來標記類與函式,以表明它們如何被應用在多執行緒應用程式中。因此,乙個執行緒安全的函式總是可重入的,但乙個可重入的函式並不一定是執行緒安全的。擴充套件開來,乙個可重入的類,指的是它的成員函式可以被多個執行緒安全地呼叫,只要每個執行緒使用這個類的不同的物件...