Solidity

在合約上設置白名單地址的 Gas Cost

  • January 21, 2022

我知道我們都有白名單的高gas成本問題。

我注意到有兩種方法可以在合約上設置白名單地址。

我想知道哪一個成本更低。

$$ approach 1 $$

function whitelistUsers(address[] calldata _users) public onlyOwner {
   delete whitelistedAddresses;
   whitelistedAddresses = _users;
 }

function isWhitelisted(address _user) public view returns (bool) {
   for (uint i = 0; i < whitelistedAddresses.length; i++) {
     if (whitelistedAddresses[i] == _user) {
         return true;
     }
   }
   return false;
 }

$$ approach2 $$

function getWhitelistState(address user) public view returns(bool) {
   return whitelistes[user];
 }
 function setWhitelistAddresses(address[] calldata addresses) external onlyOwner {
   for (uint8 i = 0; i < addresses.length; i++) 
     whitelisted[addresses[i]] = true;
   whitelistAccessCount += addresses.length;
 }

這在很大程度上取決於您的契約是如何使用的。

例如,如果您有一個自定義界面並希望所有互動都通過該界面完成,那麼使用p0pps.

在比較您的兩種方法時approach 2,無論如何都更便宜。

如果我們考慮設置白名單,那麼在區塊鏈上儲存一個數組將需要將數組的每個元素和數組的長度寫入區塊鏈(所以 n+1 寫入)。對於映射方法,您需要更新每個元素的值(所以 n 寫入)。

要讀取白名單的狀態,您需要在映射方法中準確讀取 1 個儲存槽,而在儲存數組時,您最壞的情況必須從儲存中讀取整個白名單(因此所有 n 個元素)。

映射方法的唯一缺點是跟踪白名單地址更加棘手,因為您不能只返回整個數組。另一種方法是使用連結列表:https ://hackernoon.com/a-linked-list-implementation-for-ethereum-deep-dive-oy9432pa

對您的程式碼的一般評論approach 2

whitelistAccessCount的並不總是正確的。如果您setWhitelistAddresses多次呼叫並且數組包含已列入白名單的地址,那麼您的計數將是錯誤的。

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