Solidity

設計模式檢查-效果-互動模式

  • December 8, 2019

我正在研究設計模式 Checks-Effects-Interactions Pattern 並發現下面的連結有一個類似的問題,但在我正在查看的方向上..

Checks-Effects-Interactions 模式 - 未達到外部呼叫

在 Checks-Effects-Interactions Pattern 中,如果在進行外部呼叫或在外部呼叫過程中出現錯誤怎麼辦..

如何管理合約的狀態?我們是否需要對系統進行一些制衡才能自行管理。

問候

歸根結底,您的契約狀態是契約的責任,因此在保證中進行設計的責任在於作者。

分解每個步驟要解決的問題可能會有所幫助。

檢查

輸入是否可以接受?如果不是,那麼要麼“提前失敗,努力失敗”,要麼返回 false。作為預設方法,fail hard 可確保整個交易恢復,包括涉及的所有合約中的所有功能。這免除了呼叫者處理“失敗”案例的責任。

require(someCondition);

效果

假設互動成功,樂觀地將合約更新到新的有效狀態。這可以保護合約免受重入和競爭條件的影響。為了強調,它必須是一個完全有效的新狀態。

balance[msg.sender] = 0;

互動

.send().transfer()以及對“不受信任”合約的呼叫.call()function您通常應該將互動限制為一個“不受信任”的契約。您必須檢查結果,否則編譯器會發出警告。

如果被呼叫的合約“失敗”,require()revert()沒有什麼可檢查的。如果出現問題,整個事情都會恢復。transfer()這是使用發送 ETH的優勢之一。如果是契約returns(bool success),那麼您需要檢查false條件並決定要做什麼。這將始終涉及撤消“樂觀會計”。如果你想繼續,然後手動展開它。

if(!msg.sender.send(amount)) {
  balances[msg.sender] += amount; // because we zeroed it out in step 2

如果您不想繼續,您可以將整個事情還原並恢復到原始狀態。

require(msg.sender.send(amount)); // this is what `transfer` does

也可以使用它來呼叫合約函式。如果他們退回一些東西,請檢查它。

require(otherContract.doSomething()); // where it returns a bool

或者

bool success = otherContract.doSomething();
if(!success) { 
 // time to undo the "optimistic" accounting (effects) if we want to continue 

如果一筆交易的gas用完,交易將恢復。

關於契約中可能出現的模式和非明顯漏洞的基本原理可以說更多。

希望能幫助到你。

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