Solidity
這個競爭條件的例子是如何真正發生的?
我遇到了一個範例,說明在這種情況下如何發生競爭條件,但我不明白它是如何發生的:
Bob 創建 RaceCondition(100, token)。Alice 信任 RaceCondition 及其所有代幣。Alice 呼叫 buy(150) Bob 看到交易,並呼叫 changePrice(300)。Bob 的交易在 Alice 之前被探勘,因此 Bob 收到了 300 個代幣。
範常式式碼是這樣的:
contract RaceCondition{ address private owner; uint public price; ERC20 token; function RaceCondition(uint _price, ERC20 _token) public { owner = msg.sender; price = _price; token = _token; } // If the owner sees someone calls buy // he can call changePrice to set a new price // If his transaction is mined first, he can // receive more tokens than excepted by the new buyer function buy(uint new_price) payable public { require(msg.value >= price); // we assume that the RaceCondition contract // has enough allowance token.transferFrom(msg.sender, owner, price); price = new_price; owner = msg.sender; } function changePrice(uint new_price){ require(msg.sender == owner); price = new_price; } }
但是,我不明白給定範例如何發生競爭條件。
- 這個例子是否暗示即使 Bob 比 Alice 更晚發送了他的交易,Bob 可能支付了更高的 gas 費用,以便他的交易在 Alice 之前被探勘?
- 如果是這種情況,我們是否假設 Alice 和 Bob 的交易被發送到可能允許這種情況發生的同一個區塊?但這意味著 Bob 必須在 Alice 的交易之後的幾秒鐘內完成他的交易,才能在同一個區塊中,並且還要有足夠的時間讓他的交易在她之前被探勘出來?
- 該範例提到 Bob 可以
changePrice
在 Alice 呼叫後呼叫buy
以接收比預期更多的令牌。但我不明白這是怎麼發生的:
- 假設 Bob 在 Alice 的呼叫之前設法讓他的呼叫
changePrice(300)
被鎖定buy(150)
,Alice 的buy(150)
呼叫會拋出異常,因為require(msg.value >= price);
會返回 false,不是嗎?即,150 >= 300
是錯誤的,因此,恢復,不是嗎?
看起來像一個可怕的例子。
首先,關於使用者通過交易發送多少乙太幣的討論為零。這很重要,因為程式碼會對
msg.value
. 看起來作者只是混淆了msg.value
(price
ornew_price
) 參數。我不確定您是否可以將區塊鏈中的任何內容稱為競爭條件。我想,如果兩個事務試圖做只有一個事務可以做的同一件事,也許你可以。但術語“競爭條件”通常用於存在一定程度的並行性,而區塊鏈在執行事務時的並行性為零。
無論如何,如果在範例中有一個函式可以購買呼叫者可以使用 X 乙太幣獲得的盡可能多的代幣,那將是另一回事。然後攻擊者(所有者)可以進入一個使代幣價格更高的交易,並且該交易在買方之前被開採。這基本上一直以更複雜的方式發生在去中心化交易所中。
此外,交易不會“發送到區塊”。它們被發送到交易池,礦工決定在哪個區塊中包含哪個交易。