Solidity

這個競爭條件的例子是如何真正發生的?

  • August 12, 2021

我遇到了一個範例,說明在這種情況下如何發生競爭條件,但我不明白它是如何發生的:

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; 
   }

}

但是,我不明白給定範例如何發生競爭條件。

  1. 這個例子是否暗示即使 Bob 比 Alice 更晚發送了他的交易,Bob 可能支付了更高的 gas 費用,以便他的交易在 Alice 之前被探勘?
  • 如果是這種情況,我們是否假設 Alice 和 Bob 的交易被發送到可能允許這種情況發生的同一個區塊?但這意味著 Bob 必須在 Alice 的交易之後的幾秒鐘內完成他的交易,才能在同一個區塊中,並且還要有足夠的時間讓他的交易在她之前被探勘出來?
  1. 該範例提到 Bob 可以changePrice在 Alice 呼叫後呼叫buy以接收比預期更多的令牌。但我不明白這是怎麼發生的:
  • 假設 Bob 在 Alice 的呼叫之前設法讓他的呼叫changePrice(300)被鎖定buy(150),Alice 的buy(150)呼叫會拋出異常,因為require(msg.value >= price);會返回 false,不是嗎?即,150 >= 300是錯誤的,因此,恢復,不是嗎?

看起來像一個可怕的例子。

首先,關於使用者通過交易發送多少乙太幣的討論為零。這很重要,因為程式碼會對msg.value. 看起來作者只是混淆了msg.value( priceor new_price) 參數。

我不確定您是否可以將區塊鏈中的任何內容稱為競爭條件。我想,如果兩個事務試圖做只有一個事務可以做的同一件事,也許你可以。但術語“競爭條件”通常用於存在一定程度的並行性,而區塊鏈在執行事務時的並行性為零。

無論如何,如果在範例中有一個函式可以購買呼叫者可以使用 X 乙太幣獲得的盡可能多的代幣,那將是另一回事。然後攻擊者(所有者)可以進入一個使代幣價格更高的交易,並且該交易在買方之前被開採。這基本上一直以更複雜的方式發生在去中心化交易所中。

此外,交易不會“發送到區塊”。它們被發送到交易池,礦工決定在哪個區塊中包含哪個交易。

引用自:https://ethereum.stackexchange.com/questions/106985