Solidity

在圖書館中使用 external over public 會降低 gas 成本嗎?

  • April 21, 2022

我有一個圖書館

實用程序.sol

library Utils {
  struct UtilType {
     unit var1;
     bool var2;
  }

 function addExtra(UtilType storage state, uint extra) public {
   state.var1 += extra;
 }
}

注意庫中函式的public可見性。並且該功能的使用如下:addExtra``utils.sol

我的契約.sol

import "utils.sol"
contract MyContract {
  using Utils for UtilsType;
  UtilsType state;

 function foo(uint extra) public {
   state.addExtra(extra);
 }
}
  1. 將更public改為external減少myutils.sol外部函式呼叫成本並節省任何氣體?
  2. 如果是這樣,節省氣體是否僅由於uint變數而不是結構類型而發生,因為它是儲存記憶體?

將函式聲明為external而不是public根本不會影響 gas 使用,無論是在合約中還是在庫中。

在早期版本的 Solidity 中,只有外部函式可以接受calldata參數。公開一個函式會迫使你使用更昂貴的memory參數。這個限制在 Solidity 0.6.9 中被取消了。這可能是誤解最初的來源。使用外部函式可以降低通話成本,但這並不是因為它們的可見性。

除此之外,它們之間的選擇只影響分析(有些事情可能會被禁止),而不是程式碼生成。在這兩種情況下,您將獲得完全相同的字節碼。

例子

您可以自己檢查字節碼是否相同。

讓我們把這個簡單的庫放在一個名為的文件中lib.sol

library L {
   enum E {A, B, C}
   struct S { address[50] addresses; }

   function f(
       uint a,
       string memory b,
       bytes1[] calldata c,
       mapping(E => S[]) storage d,
       function() external e
   )
   public
   returns (
       uint,
       string memory,
       bytes1[] calldata,
       mapping(E => S[]) storage,
       function() external
   )
   {
       return (a, b, c, d, e);
   }
}

然後執行編譯器兩次,將可見性更改為external第二次執行之前:

solc lib.sol --bin --metadata-hash none > public.bin
sed -i s/public/external/ lib.sol
solc lib.sol --bin --metadata-hash none > external.bin
diff public.bin external.bin

即使沒有啟用優化器,輸出也是空的,這意味著絕對沒有區別。

在編譯器中實現

您可以檢查編譯器程式碼,以了解不只是這個簡單的範例具有這種行為方式。

對於外部/公共功能,您可能會在兩個地方有所不同:

請注意,在這兩種情況下,都沒有區分publicvs的條件external

調度檢查了一個介面函式列表,其中包括公共函式和外部函式。它由 建構ContractDefinition::interfaceFunctionList(),它遍歷合約中的所有函式並FunctionDefinition::isPartOfExternalInterface()用作過濾器。這反過來呼叫Declaration::isPublic(),儘管名稱如此,但它有一個>=可見性條件,因此它也匹配外部函式:

bool isPublic() const { return visibility() >= Visibility::Public; }

您可以更深入地了解身體是如何生成的,但您也不會在那裡找到任何特殊情況。

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