Solidity

Solidity:我如何應用刪除來完成儲存參考一個電話?

  • April 7, 2017

定義:

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]]; 
}

但是再次嘗試設計具有已知生命週期的原子操作,而不必依賴昂貴且混亂的批量清理。

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