Events

當我的合約方法中的函式呼叫失敗時會發生什麼?

  • November 30, 2017

我最感興趣的是以下幾個方面:

  1. 整個堆棧會放鬆嗎?
  2. 如果整個堆棧展開,這是否會導致合約對狀態所做的所有更改都被還原?
  3. 事件會恢復嗎?我想事件儲存在(全域)狀態中,並且恢復狀態也會刪除事件。

這取決於如何撥打電話。

// Interface to contract A
contract A { 
   function foo() public; 
}

contract B {
   uint public status = 0;
   event logNewStatus(uint status);

   function bar(address a) public {
       status = 1;
       logNewStatus(status);

       // Call using A's interface
       A contractA = A(a);
       contractA.foo();

       status = 2;
       logNewStatus(status);
   }
}

如果我們使用該介面呼叫合約 A 的函式,並且foo()失敗,它將撤消所有操作,狀態將保持為 0,並且不會將任何事件記錄在區塊鏈中。

我們可以使用低級函式call來獲得更大的靈活性

function bar(address a) public {
   status = 1;
   logNewStatus(status);

   // Call using low level function
   // It returns true when call have succeeded and false otherwise
   bool result = a.call(bytes4(keccak256("foo()"));
   if (result) {
       status = 2;
       logNewStatus(status);
   } else {
       status = 3;
       logNewStatus(status);
   }
}

使用call它會在成功時返回 true,否則返回 false。因此,您可以決定還原更改,還是繼續。

在範例中沒有還原,因此如果事務失敗,它將設置狀態為 3,並生成具有新狀態的事件。

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