I'm currently working on a marketplace demo for the consensys bootcamp, you can find my entire code here.
Stores inside the marketplace (which are structs) are stored inside a mapping and the keys pointing to the stores are stored in an array. I have a function that removes a store and I wanted to test gas usage.
I have 2 different approaches:
- the first one just deletes the item id array and sets a bool flag to false
- the second approach just uses the delete keyword to delete the struct
.
/// @notice removes an existing store
/// @dev only callable by store owners, requires store to be active
/// @param _storeID ID of store to be removed
/// @return true on success, false on failure
function removeStore(bytes32 _storeID) public onlyStoreOwner returns(bool) {
// storage pointers to store and store id list
Store storage store = stores[msg.sender][_storeID];
bytes32[] storage storeIdList = storeIdLists[msg.sender];
// store has to be active in order to be removed
require(store.active, "store currently not active");
// copy last index of store id list to index of to be removed store and delete last item of array
storeIdList[store.index] = storeIdList[storeIdList.length-1];
storeIdList.length--;
// remove items from store
store.itemIdList.length = 0;
store.active = false;
emit RemovedStore(msg.sender, _storeID);
return true;
}
function removeStore2(bytes32 _storeID) public onlyStoreOwner returns(bool) {
// storage pointers to store and store id list
Store storage store = stores[msg.sender][_storeID];
bytes32[] storage storeIdList = storeIdLists[msg.sender];
// store has to be active in order to be removed
require(store.active, "store currently not active");
// copy last index of store id list to index of to be removed store and delete last item of array
storeIdList[store.index] = storeIdList[storeIdList.length-1];
storeIdList.length--;
// remove items from store
delete stores[msg.sender][_storeID];
emit RemovedStore(msg.sender, _storeID);
return true;
}
when I test the gas usage of both functions I generate a new store with the name "test" and the description "test". The item id list is empty and the bool flag gets set to true.
the removeStore function has a transaction cost of 26641 gas
as expected, the bool flag is set to false, everything else stays.
now the removeStore2 function has a transaction cost of 37230 gas
again, everything gets deleted as expected
Now to my question:
why does the second function consume more gas? the delete keyword sets 2 more non-zero storages to zero. shouldn't there be a gas refund? The transactions were tested with ganache-cli and the remix javascript vm.