Reentrant-Attacks
不同的代理程式碼升級智能合約和重入攻擊
我正在嘗試升級乙太坊中的智能合約。我發現代理模式可以幫助我解決這個問題。在 openzeppelin 文件中,我應該
fallback
在合約的函式中添加以下程式碼:assembly { let ptr := mload(0x40) // (1) copy incoming call data calldatacopy(ptr, 0, calldatasize) // (2) forward call to logic contract let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0) let size := returndatasize // (3) retrieve return data returndatacopy(ptr, 0, size) // (4) forward return data back to caller switch result case 0 { revert(ptr, size) } default { return(ptr, size) } }
看來我應該轉發呼叫並檢索返回數據。但是,在某些合約中,他們只是使用如下程式碼升級合約:
/** * Resolves asset implementation contract for the caller and forwards there transaction data, * along with the value. This allows for proxy interface growth. */ function () payable { _getAsset().__process.value(msg.value)(msg.data, msg.sender); }
我有兩個問題:
- 第二個程式碼也可以升級智能合約嗎?
- 我認為
fallback
在我的合約中添加函式中的第一個程式碼會導致重入攻擊,這是真的嗎?謝謝!
它們是使合約可升級的兩種方法。
- 第一個使用 DELEGATECALL 操作碼。它不會改變 msg.sender。它必須使用彙編來恢復返回值。它們有一些限制,您必須在使用它們之前了解它們https://blog.openzeppelin.com/the-transparent-proxy-pattern/>,<https://blog.openzeppelin.com/proxy-patterns/。
- 其次使用正常的 CALL 操作碼。它改變了 msg.sender 所以程式碼必須適應它。它不支持 getters 函式,因為它忽略了返回值。
這兩個選項都沒有提供針對重入攻擊的保護,這取決於實現。