Solidity
如何返回嵌套了映射的結構數組?
這是程式碼。我想返回 Requests 數組。
pragma solidity >=0.8.4; contract Contract { struct Requests { string description; uint value; address recipient; bool complete; mapping(address => bool) sender; uint approvalCount; } Requests[] public requests; function createRequest(string memory d, uint v, address r) public { Requests storage newRequest = requests.push(); newRequest.description = d; newRequest.value = v; newRequest.recipient = r; newRequest.complete = false; newRequest.approvalCount = 0; newRequest.sender[msg.sender] = true; } }
不幸的是,這是不可能的。要了解原因,請查看映射是如何儲存的:
由於它們不可預測的大小,映射和動態大小的數組類型不能儲存在它們之前和之後的狀態變數“之間”。相反,根據上述規則,它們被認為僅佔用 32 個字節,並且它們包含的元素儲存在使用 Keccak-256 雜湊計算的不同儲存槽開始。
對於映射,插槽保持為空,但仍然需要確保即使有兩個彼此相鄰的映射,它們的內容最終位於不同的儲存位置。
對應於映射鍵的
k
值位於連接的位置,並且keccak256(h(k) . p)
是根據其類型應用於鍵的函式.``h
換句話說,映射值不儲存在單個位置,而是分佈在整個儲存中的隨機位置。此外,編譯器不儲存鍵,也不跟踪映射中已經存在的項目數,因此它甚至不知道要複製什麼。
這一直是個問題,這就是為什麼現在在
memory
結構中不允許映射的原因,因為實際上只會複製其他欄位並且會默默地跳過映射。它們仍然允許在storage
結構中使用,但存在相同的缺陷 - 編譯器為public
儲存變數生成的 getter 會靜默地跳過結構內的映射和數組。對於數組,解決方法是定義您自己的返回結構的函式。然後編譯器不會省略它。有了映射,問題就不同了,所以這還不夠。您必須將鍵儲存在某處,然後讓函式將鍵複製到一個新結構中,該結構有一個數組來代替映射。