Mapping

在乙太坊中如何檢查映射中的密鑰是否已經存在?

  • January 23, 2019

在這個文件的存在、完整性和所有權契約的證明中,為什麼files[fileHash].timestamp == 0要使用?為什麼要時間戳?

contract Proof

{
  struct FileDetails
  {
      uint timestamp;
      string owner;
  }

  mapping (string => FileDetails) files;
  event logFileAddedStatus(bool status, uint timestamp, string owner, string fileHash);


  //this is used to store the owner of file at the block timestamp
  function set(string owner, string fileHash)

  {

      //There is no proper way to check if a key already exists or not therefore we are checking for default value i.e., all bits are 0
      if(files[fileHash].timestamp == 0)

      {
          files[fileHash] = FileDetails(block.timestamp, owner);

          //we are triggering an event so that the frontend of our app knows that the file's existence and ownership details have been stored
          logFileAddedStatus(true, block.timestamp, owner, fileHash);
       }
else 
       {//this tells to the frontend that file's existence and ownership details couldn't be stored because the file's details had already been stored earlier
          logFileAddedStatus(false, block.timestamp, owner, fileHash);
       }           } 

  //this is used to get file information
  function get(string fileHash) returns (uint timestamp, string owner)
  {
      return (files[fileHash].timestamp, files[fileHash].owner);

  }
}

無法直接檢查映射中是否存在某些內容。在solidity中,一切都設置為它的“預設值”,直到它被改變。

這意味著每個整數都以 0 開頭,每個字元串以 a 開頭"",每個數組以 開頭[]。Solidity 沒有像其他語言那樣的“null”概念。

聲明的變數將具有一個初始預設值,其字節表示全為零。變數的“預設值”是任何類型的典型“零狀態”。例如,a 的預設bool值為falseuintor類型的預設值為int0。對於靜態大小的數組和bytes1to bytes32,每個單獨的元素將被初始化為其類型對應的預設值。最後,對於動態大小的數組bytesstring,預設值為空數組或字元串。

因此,如果您有一個到結構的映射,那麼每個可能的鍵都指向“預設結構”。在您的情況下,這將是一個時間戳為 0 且所有者為"".

映射可以看作是雜湊表,它被虛擬初始化,使得每個可能的鍵都存在,並映射到一個字節表示全為零的值:一個類型的預設值。

因此,如果您想檢查是否尚未設置映射,您可以檢查 iffiles[fileHash].timestamp == 0或 check files[fileHash].owner.length == 0

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