Sin gas y atomicidad

Estoy leyendo el ejemplo de votación Solidity by example. Estoy interesado en la votefunción de contrato:

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;
}

¿Qué sucede si una transacción se queda sin gas después de la línea sender.voted = true;pero antes de la línea proposals[proposal].voteCount += sender.weight;? En este caso, parece que la votación se contará como realizada, pero en realidad voteCountno se actualizará. Debido a la require(!sender.voted);línea, el votante no puede intentar volver a votar con un límite de gasolina más alto.

¿Cómo se manejan en la práctica tales situaciones de falta de gas para garantizar la atomicidad de la configuración sender.votedy el incremento proposals[proposal].voteCount?

Respuestas (1)

Cuando un contrato se encuentra con un error (mal salto, sin gasolina o cualquier otra excepción), arroja un error y se revierte toda la transacción.

El motivo de la reversión es que no existe una forma segura de continuar con la ejecución, porque no se produjo el efecto esperado. Debido a que queremos conservar la atomicidad de las transacciones, lo más seguro es revertir todos los cambios y hacer que la transacción completa (o al menos la llamada) no tenga efecto.

Puede encontrar más información sobre atomicidad, tiro y excepciones en el Doc

¿Esto incluye transferencias ETH? es decir, digamos que la primera línea en la función fue msg.sender.transfer(1000);¿eso también se revertiría?
Sí, incluye transferencias ETH.