5

I am reading the Solidity by example voting example. I am interested in the vote contract function:

function vote(uint proposal) {
    Voter sender = voters[msg.sender];
    require(!sender.voted);
    sender.voted = true;
    sender.vote = proposal;

    // If `proposal` is out of the range of the array,
    // this will throw automatically and revert all
    // changes.
    proposals[proposal].voteCount += sender.weight;
}

What happens if a transaction runs out of gas after the line sender.voted = true; but before the line proposals[proposal].voteCount += sender.weight;. In this case, it seems like the vote will be counted as made, but actually the voteCount will not be updated. Because of the require(!sender.voted); line, the voter cannot attempt to revote with a higher gas limit.

How are such out of gas situations handled in practice to guarantee atomicity of setting sender.voted and incrementing proposals[proposal].voteCount?

0
5

When a contract run into an error (bad jump, out-of-gas, or any other exception) it throw an error and the entire transaction is reverted.

The reason for reverting is that there is no safe way to continue execution, because an expected effect did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction (or at least call) without effect.

You can find more information about atomicity, throw and exceptions in the Doc

2
  • Does this include ETH transfers? i.e. let's say the 1st line in the function was msg.sender.transfer(1000); would that revert as well? – shaharsol Jun 21 '18 at 17:04
  • 1
    Yes it does include ETH transfers – Crema Jun 21 '18 at 20:10

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.