Solidity – How to Properly Delete Array Elements in Smart Contracts

contract-deploymentcontract-designsolidity

I am working on a contract that lets player place wagers against one another.

I have a struct which looks like this that holds all the wagers

struct Wager {
        address player1;
        address player2:
        uint amount;
    }
 Wager[] public wagers;

after a wager is set an a winner declared I wanted to remove the wager from this array since it is no longer needed and I have no interest in having a history of wagers. I'm also unsure of the effect of this array growing very large in size if there are lots of continuous wagers being made.

Does anyone know of the proper mechanism for removing elements from an array for a case like this?

Thank help is appreciated! Thank You!

Best Answer

There is more too this than meets the eye.

First, there is no way to truly delete since the transaction that created the element and the previous states of the chain will forever remain part of immutible history.

Second, although it will help reduce chain bloat by marking the storage as useless (in the present state), the delete operation is in fact unavoidably a write to the state which costs gas to execute.

Third, logically deleting an element doesn't reorganize the list. It merely creates a void in the midst of the list, roughly like [a,b,c, nothing, e,f,g]. This _might) create logical problems in or around the contract.

A reorganization is possible in the case of an unordered list. This is done by moving the last element in the list into the slot to delete and then reducing the length of the array. This only works with "unordered" lists because it relies on shuffling the order of the elements. https://medium.com/@robhitchens/solidity-crud-part-2-ed8d8b4f74ec

You may find that either leaving the elements in place or reorganizing around mappings is actually a better data structure. You can also consider a soft delete which admittedly does nothing to reduce chain bloat.

Have a look over here for a mapped struct with delete pattern. Are there well-solved and simple storage patterns for Solidity?

Hope it helps.

UPDATE:

Thanks, smarx, for jumping in. Now, I'm curious!

Is it wrong to think delete is always a net costly operation?

pragma solidity ^0.4.20;

contract Refunds {

    mapping(uint => bool) public data;

    function setIt() public {
        data[1] = true;
    }

    function deleteIt() public {  // net cost ~ 5000 gas
        delete data[1];
    }
} 
Related Topic