Solidity:我如何應用刪除來完成儲存參考一個電話?
定義:
mapping(address => data) clusterContract; struct data { //defined inside a Library. mapping(address => Library.Struct[]) my_status; } data list; clusterContract[id] = list;
用法:
clusterContract[msg.sender].my_status[id].push( Library.Struct({ status: status_ })); delete clusterContract[msg.sender].my_status; //<=error occurs.
發生錯誤:
Error: Unary operator delete cannot be applied to type mapping(address => struct ReceiptLib.Status storage ref[] storage ref) E delete clusterContract[msg.sender].my_status;
另一方面:
delete clusterContract[msg.sender].my_status[id]
工作。=> 是否
delete clusterContract[msg.sender]
也刪除(初始化為 0)完整數組my_status
?**$$ Q $$**我如何申請
delete
完整的儲存參考$$ $$? 還是我需要迭代 ref$$ $$(跟踪ID)並如範例所示一一應用刪除? 例子:
for(int i=0;i<storedIDs.size();i++) delete clusterContract[msg.sender].my_status[storedIDs[i]];
感謝您寶貴的時間和幫助。
刪除數據確實會釋放客戶端使用的狀態空間,
State Tree Pruning
並且應該在不再需要時盡可能進行。然而,映射不能簡單地在單個操作中刪除,因為合約本身不知道數據在狀態地址中的位置。為此,它需要提供密鑰才能刪除單獨映射的元素。
uint[]
bytes
可以在一次操作中刪除無界數組,例如etc,solidity
但是,EVM 必須迭代地逐個刪除每個插槽。必須注意不要讓此類數組變得太大,因為未來的批量刪除操作可能會耗盡塊氣體限制並破壞您的合約。這裡的教訓是你的垃圾收集也應該被設計成原子的。儲存新數據的成本為每個插槽 20000,而覆蓋數據的成本僅為 5000。刪除數據也每個插槽花費 5000,但在通話結束時會返回每個插槽 15000 的 gas 退款。
Rob 的建議是使用數組的良好做法,因為您只需將其設置
length
為 0 即可重用重新初始化的儲存。但是,您使用的不是數組,而是映射,這是另一回事。所以,從你的程式碼片段……
struct data { //defined inside a Library. mapping(address => Library.Struct[]) my_status; } mapping(address => data) clusterContract; data list; clusterContract[id] = list; ... clusterContract[msg.sender].my_status[id].push( Library.Struct({ status: status_ }));
當你嘗試:
delete clusterContract[msg.sender].my_status; //<=error occurs.
您試圖一次性刪除整個映射,因為
.mystatus
定義為:mapping(address => Library.Struct[]) my_status;
但是不能刪除映射本身,只能刪除它的元素。
特別是在處理結構映射時,我會編寫解構函式來清理它們。所以像:
function destroy(id) internal { delete clusterContract[msg.sender].my_status[storedIDs[id]]; }
但是再次嘗試設計具有已知生命週期的原子操作,而不必依賴昂貴且混亂的批量清理。