Security
什麼是擊敗搶先攻擊的“預送出”方案?
我寫信是為了詢問可行的策略來解決事務排序依賴 (TOD) 錯誤。
我從最佳實踐指南中了解到,我們可以使用所謂的“預送出”方案來擊敗 TOD 攻擊:https ://consensys.github.io/smart-contract-best-practices/known_attacks/#front-執行-又名-事務-排序-依賴
但是,我仍然不清楚“預先承諾”方案是如何實施的。任何人都可以闡明這種實現的一些亮點或一些程式碼片段嗎?另外,除了這種“預先承諾”的方案,還有什麼辦法可以打敗 TOD 攻擊呢?
========更新=====================
contract TransactionOrdering { uint256 price; address owner; function buy(uint256 amount) { cost = price * amount return cost; } function setPrice(uint256 _price) { // owner can set the price. if (msg.sender == owner) price = _price; } }
假設當合約所有者看到
buy
使用者的一筆交易時,合約所有者會在前端執行一筆setPrice
交易以提高價格。可以使用該pre-committed
模式來擊敗此類攻擊嗎?非常感謝。
假設您有一個抽獎活動並且可以預訂一個號碼
contract Raffle { mapping(uint256 => address) reserved; event Reserved(uint256 value, address owner); function reserve(uint256 value) public { require(reserved[value] == address(0), "Already reserved"); reserved[value] = msg.sender; emit Reserved(value, msg.sender); } }
該合約受搶先交易影響。如果您保留編號 42,任何人都可以在您的交易被探勘之前看到它。惡意行為者可以送出一筆交易,以更高的汽油價格保留相同數量的交易,並使您的保留失敗。
一個常見的解決方案是首先送出雜湊而不是您的數據。在第二步中,您將揭示產生已送出雜湊的數據。
- 通過使用隨機 nonce、值和地址呼叫摘要函式來計算您的雜湊值。隨機數是為了防止攻擊者使用蠻力嘗試從雜湊中獲取您的值。
- 將計算出來的雜湊發送給合約。由於承諾是由使用者儲存的,攻擊者可以發送相同的散列,但不會阻止合法使用者註冊散列。
- 致電reveal以顯示您的數據並進行預訂。這裡所有的數據都可供攻擊者使用,但它在這個階段無法進行保留,並且暴力破解先前保留的雜湊應該是不可行的。
.
contract Raffle { mapping(address => bytes32) commitments; mapping(uint256 => address) reserved; event Reserved(uint256 value, address owner); function commit(bytes32 hash) public { require(commitments[msg.sender] == bytes32(0), "Already committed"); commitments[msg.sender] = hash; } function reveal(uint256 nonce, uint256 value) public { bytes32 d = digest(nonce, value, msg.sender); require(commitments[msg.sender] == d, "Invalid data"); require(reserved[value] == address(0), "Already reserved"); reserved[value] = msg.sender; emit Reserved(value, msg.sender); } function digest(uint256 nonce, uint256 value, address sender) public pure returns (bytes32) { return keccak256(abi.encodePacked(nonce, value, sender)); } }