Contract-Development
在回退函式中記錄錯誤
在程式碼中,我返回任何錯誤發送的 Ether 以與回退函式中
C
的語句進行契約。throw;
我也想記錄一下這個場合。以下程式碼不起作用(throw;
恢復對區塊鏈所做的任何更改)。contract C { event error(uint8 error); function(){ error(1); throw; } }
我的問題:
- 由於我只有 2300 gas 可用,我無法呼叫另一個生成日誌的合約。這是正確的嗎?
- 那我有什麼選擇呢?
- 由於我只有 2300 gas 可用,我無法呼叫另一個生成日誌的合約。這是正確的嗎?
呼叫另一個合約的基本成本是 700 gas(CALL 操作碼的成本)。所以可能會呼叫另一個合約來進行日誌記錄,但是額外的間接級別可能只是混亂。不可能寫入儲存,這是 5,000 gas 的基本成本。
一個備用函式可以獲得超過 2,300 個氣體,但除非您呼叫自己的備用函式,否則您不能假設您的備用函式將有超過 2,300 個氣體。有關更多資訊,請參閱備份函式中可以完成多少計算?
- 那我有什麼選擇呢?
由於在 throw 之前無法記錄,因此當且僅當 ether 被發送時,一個選項是手動退款(並記錄它)。如果手動退款失敗,您強制退款的唯一選擇是,
throw
但無法記錄這種情況。contract C { event error(uint8 error); function() { if (msg.value > 0) { // manual refund and log it if (msg.sender.send(msg.value)) { error(1); } else { // force a refund but cannot log this case throw; } } else { error(2); } } }
請注意,
msg.value > 0
已明確檢查,以便您可以確定在msg.value
為零時要執行的操作。此範例記錄了另一個錯誤程式碼,但您也可以什麼都不做(通過刪除第二個else
子句)。什麼時候msg.value
為零,我認為您不需要error(1)
(如@Xavier 的回答),因為沒有乙太幣被錯誤地發送到契約中,因此沒有退款。