Mapping
在乙太坊中如何檢查映射中的密鑰是否已經存在?
在這個文件的存在、完整性和所有權契約的證明中,為什麼
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
值為false
。uint
or類型的預設值為int
0。對於靜態大小的數組和bytes1
tobytes32
,每個單獨的元素將被初始化為其類型對應的預設值。最後,對於動態大小的數組bytes
和string
,預設值為空數組或字元串。因此,如果您有一個到結構的映射,那麼每個可能的鍵都指向“預設結構”。在您的情況下,這將是一個時間戳為 0 且所有者為
""
.映射可以看作是雜湊表,它被虛擬初始化,使得每個可能的鍵都存在,並映射到一個字節表示全為零的值:一個類型的預設值。
因此,如果您想檢查是否尚未設置映射,您可以檢查 if
files[fileHash].timestamp == 0
或 checkfiles[fileHash].owner.length == 0
。