Solidity

沒有實現的介面或函式有什麼用?

  • February 20, 2020

以這段程式碼為例。該介面包含沒有實現的功能,所以它是如何有用的。

pragma solidity ^0.5.0;

interface Calculator {
  function getResult() external view returns(uint);
}
contract Test is Calculator {
  constructor() public {}
  function getResult() external view returns(uint){
     uint a = 1; 
     uint b = 2;
     uint result = a + b;
     return result;
  }
}

此程式碼的工作方式與第一個程式碼有何不同?使用沒有實現的介面或函式有什麼好處?

pragma solidity ^0.5.0;

contract Test {
  constructor() public {}
  function getResult() external view returns(uint){
     uint a = 1; 
     uint b = 2;
     uint result = a + b;
     return result;
  }
}
  • 在呼叫合約中節省字節碼大小。
  • 建立標準並確保合規。
  • 檢測開發人員的錯誤和疏忽。

節約

考慮將與 Test 互動的合約客戶端。可以在客戶端創建一個 Test 實例,如下所示:

contract Client {

 Test t;

 constructor(address test) public {
   t = Test(test);
 }
}

這會起作用,但問題是客戶端的字節碼大小將是測試大小加上客戶端大小,因為編譯器會將完整的測試實現匯總到客戶端中。客戶端不需要所有這些程式碼。它只需要它要呼叫的函式的介面。

如果改用介面契約(在您的範例中為計算器,或者像 ITest 這樣的命名,這是事實上的命名標準),它可以用更小的字節碼實現相同的結果。

contract Client {

 Calculator c;

 constructor(address calculator) public {
   c = Calculator(calculator);
 }
}

順便說一句,您可以將輸入(仍然是地址)轉換為合約類型:

constructor(Calculator calculator) public {
 c = calculator;
}

甜的。

標準

許多標準被定義為功能介面和精確行為規範。例如,ERC20 是一個介面,但沒有特定的實現,只要功能以某種方式工作 - 可以通過測試套件確認。通常會看到類似的內容:

contract MyToken is IERC20 {
 ...

其中 IERC20 是 ERC20 合約的定義介面。

如果 MyToken 是可部署的,那麼這就確定了 IERC20 介面所需的每個函式都有一個實現(不是未定義的)。這與…有關

開發人員錯誤

在開發階段,不一致可能會蔓延到復雜的系統中。審稿人發現不一致也可能在認知上很繁重。介面可以用作一種錯誤檢測。

假設有人決定getResult()需要一個論點,例如getResult(address user) ...。這是一個重要的設計更改,會影響很多事情。因為contract Test is Calculator {除非更新介面,否則不會部署測試。

為什麼/如何?

函式簽名是函式名稱和參數散列的前 4 個字節,因此getResult()getResult(uint)字節碼級別是完全不同的函式。實際上,這意味著 Test 將編譯,但不會部署,因為它不會定義繼承介面中定義的強制函式之一。

這正是我們想要的,因為要麼 a) 介面已重新定義,這意味著所有客戶端都需要調整,要麼 b) 實現不正確,這意味著添加該參數是不可接受的,或者 c) 缺少實現並且提供的是除了強制性功能,但不是替代品(兩者都需要)。

為了樣式和一致性,在 1:1 的基礎上為實現定義介面可能是一個好習慣。

希望能幫助到你。

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