Solidity Contract Design – How to Remove Contract Storage with Instance Variables

contract-designcontract-developmentsolidity

Reading the Solidity docs:

delete a assigns the initial value for the type to a.

So, it just clears or resets the value of a variable (e.g., an integer to 0)?

I thought there was a way of removing things from storage, when it isn't needed?

Is it possible to have an instance variable that sometimes occupy bytes in storage, while at other times it takes no storage? If not, what mechanims can be used for this?

Best Answer

Setting a word of storage (i.e. all 32 bytes/256 bits) to zero is identical to removing it from storage completely: it will no longer form part of the blockchain state. You get a refund of 15000 gas for doing this (Appendix G, R_sclear in the Yellow Paper: "Refund given (added into refund counter) when the storage value is set to zero from non-zero").

Note that Solidity sometimes stores multiple smaller types within one storage word (e.g. up to eight uint32s). To remove the word from storage, all of the component variables need to be set to zero/deleted.

Examples

This results in just one storage word being persisted since x and y are packed into one word:

contract Foo {
    uint32 x=1;
    uint32 y=2;
    function bar () {}
}

After calling bar() in the following, you will have no storage persisted:

contract Foo {
    uint32 x=1;
    uint32 y=2;
    function bar () {
        delete x;
        delete y;
    }
}

After calling bar() in the following, you will again have no storage persisted. It is identical to the above.

contract Foo {
    uint32 x=1;
    uint32 y=2;
    function bar () {
        x = 0;
        y = 0;
    }
}

Function bar() in the following will leave the whole storage word persisted (no gas refund) since x and y share the word.

contract Foo {
    uint32 x=1;
    uint32 y=2;
    function bar () {
        delete x;
    }
}
Related Topic