2

I have a simple contract that deletes the last element of the array:

pragma solidity^0.4.11;

contract GasRefundTest {

    uint[] myArray = [1, 2];

    function deleteLastElem() public returns(bytes32) {
        myArray.length--;
    }
}

Transaction cost for calling deleteLastElem() is 17182 gas.

When I change it to:

pragma solidity^0.4.11;

contract GasRefundTest {

    uint[] myArray = [1, 2];

    function deleteLastElem() public returns(bytes32) {
        delete myArray[1];
        myArray.length--;
    }
}

the transaction cost becomes 22480 gas.

I thought deleting storage slots should result in gas refund, instead I see gas increase.

Can anyone explain what's going on here.

  • Seems like the best way to answer this question is to go low-level and describe both processes in details (bytecode or opcodes). – Roman Frolov Feb 11 '18 at 22:12
  • I agree. Looking into bytecode or assembly would help clarify things – medvedev1088 Feb 12 '18 at 8:05
2

Reducing the size of a dynamic-size array already zeroes out the elements that were "removed."

So the version of your code that first does a delete myArray[1] is just doing an extra write to storage that's about to be done anyway.

Fun things to try:

// This doesn't take more gas depending on how big you make the array.
myArray.length = 3; // or 300 or 3000

myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
...
// This takes more gas the more elements you're removing, because it has to zero
// out more positions in storage.
myArray.length = 9; // vs. 1

EDIT

I should point out that this last example is a bit confusing. The gas refund does kick in there, but it's limited to half the consumed gas.

  • Thank you for the answer. Please explain about why 17k gas is impossible. I saw in the comments you mention that gas paid should be at least 21k however I didn't find this mentioned anywhere in the yellowpaper or sources. From what I understand without the refund the transaction would cost 21k + 5k + 5k =~31k (intrinsic gas + setting length + setting last elem to 0). Half of that is 15.5k. After refunding this amount consumed gas becomes 15500. Round about what remix shows. – medvedev1088 Feb 12 '18 at 7:33
  • In my previous comment I meant 15.5k cap which is greater than 15k so the 15k will be refunded, totalling to 16k. – medvedev1088 Feb 12 '18 at 7:40
  • 1
    @medvedev1088 I'm looking for a source, but I can't find it in the Yellow Paper either. Perhaps I'm mistaken. – user19510 Feb 12 '18 at 7:45
  • 1
    @medvedev1088 You are correct. The only limit on refunds is half the consumed gas, so consuming less than 21000 gas is possible. (I observed actual transactions on mainnet with less than 21000 gas consumed.) – user19510 Feb 12 '18 at 7:49
  • 1
    Also, I agree that this should be mentioned in the documentation. I had to experiment to find out which operation did the zeroing. (I assumed one would have to.) Given that all storage is implicitly initialized to zero, though, it makes sense that it's shortening the array that has to do the work. (Most of the time, it would be a waste to zero storage during array expansion.) – user19510 Feb 12 '18 at 8:25
1

To explain at the high level, you are doing 2 operations instead of 1, hence it requires more gas. All the code you write is compiled to low-level Ethereum Virtual Machine (EVM) commands, which then are interpreted by it. For each such command there is a particular gas price defined, look at this.

Now, in the second case, you use delete. From the docs,

delete a assigns the initial value for the type to a

It is important to note that delete a really behaves like an assignment to a, i.e. it stores a new object in a.

So you are putting 0 there first, before decreasing the length of an array. Purely for the sake of interest, you may try to use myArray[1] = 0; instead and see how this affects the gas used.

  • From the original question: "I thought deleting storage slots should result in gas refund, instead I see gas increase." See my answer for why this isn't the case here. – user19510 Feb 11 '18 at 21:48
  • @smarx, I saw your answer and basically we are talking about the same. – ZitRo Feb 11 '18 at 21:49
  • I don't think the confusion was about why doing two things costs more than one. It was why the gas refund isn't reducing the gas price. – user19510 Feb 11 '18 at 21:52
  • @smarx, it was, and my answer clarifies that as well as yours, isn't it? – ZitRo Feb 11 '18 at 21:53
  • I'm completely confused now. I'm not sure if I'm misunderstanding your answer or you're misunderstanding mine. – user19510 Feb 11 '18 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.