Solidity

使用 uint將 uint(address) 映射到 uint

  • January 8, 2020

有什麼理由不使用

uint[2**160-1] addressIndex;

代替

mapping(address => uint) addressIndex;

?

更新:

下面的答案是指以下之間的區別:

  • 一種mapping(address => uint)
  • struct {address key; uint value;}元素數組

這不是這裡要問的。

我把它留在這裡是因為我覺得它仍然在這個問題的背景下有所貢獻……


我希望這張表能回答你的問題:

|----------------|---------|-------|
|                | Mapping | Array |
|----------------|---------|-------|
| Add an item    | O(1)    | O(1)  |
|----------------|---------|-------|
| Remove an item | O(1)    | O(n)  |
|----------------|---------|-------|
| Find an item   | O(1)    | O(n)  |
|----------------|---------|-------|

僅當給出以下任何限制時,才應在映射上選擇數組:

  1. 物品的順序很重要
  2. 映射的鍵不是由使用者提供的

它們大致相同。

您的固定大小的數組佈置了一個非常大的地址空間,其中每個可能的地址等價物都有一個插槽。這在邏輯上等同於mapping所做的,儘管佈局不同(參見下面伊斯梅爾的評論),因此天然氣成本略有不同。

為了可讀性,我會傾向於映射。Solidity 要求對慣用的、可讀的程式碼有強烈的偏好,因此有一個反對冗長的論點。

這個小例子對陣列有輕微的,幾乎微不足道的氣體效率優勢(故意刪除視圖以從 Remix 獲得一些氣體核算)。

pragma solidity 0.5.12;

contract ArrayMapping {

   uint[2**160-1] addressIndex;
   mapping(address => uint) mapped;

   function getArray(uint row) public returns (uint) { // <== 1128 gas
       return addressIndex[row];
   }

   function getMap(address a) public returns (uint) { // <== 1174 gas
       return mapped[a];
   }
}

如果有幫助,本教程會列出一些同時使用數組和映射的方法。https://medium.com/robhitchens/solidity-crud-part-1-824ffa69509a

或者,您可能對以下內容感興趣:Solidity 是否存在解決良好且簡單的儲存模式?

此外,您的意圖很明確,但是明確類型轉換以確保您的表達式執行您認為的操作可能是一個好主意。IIRC 對隱式轉換進行了更改,但為什麼不明確呢?

uint(uint(2)**uint(160)-uint(1)) addressIndex;

這是為了確保您不會陷入以下陷阱:Solidity 的指數運算符中的意外隱式轉換

希望能幫助到你。

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