Events
當我的合約方法中的函式呼叫失敗時會發生什麼?
我最感興趣的是以下幾個方面:
- 整個堆棧會放鬆嗎?
- 如果整個堆棧展開,這是否會導致合約對狀態所做的所有更改都被還原?
- 事件會恢復嗎?我想事件儲存在(全域)狀態中,並且恢復狀態也會刪除事件。
這取決於如何撥打電話。
// 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,並生成具有新狀態的事件。