Uso de gas no determinista de la misma función

Ambiente

Truffle v4.1.8 node 10.0.0 pragma solidity ^0.4.21;

Asunto

Estoy llamando a la claimRefundfunción en mi contrato inteligente usando metamask. Al llamar a la función con un límite de gas de 37081 a un precio de gas de 20 gwei , la transacción gasta 36924 de gas y se revierte con EVM Revert.

Si cambio los parámetros a un límite de gas de 58080 a un precio de gas de 20 gwei , la transacción pasa gastando 24721 de gas.

El código se muestra a continuación:

   /**
   * @param investor Investor address
   */
  function refund(address investor) public {
    require(state == State.Refunding);
    uint256 depositedValue = deposited[investor];
    deposited[investor] = 0;
    investor.transfer(depositedValue);
    emit Refunded(investor, depositedValue);
  }
  }


  function claimRefund() public {
    require(isFinalized);
    require(!goalReached());

    vault.refund(msg.sender);
  }

Pregunta

¿Cómo es posible que la misma llamada resulte en una cantidad diferente de gas gastado? Además, ¿cómo puede fallar una función después de gastar más gasolina y pasar después de gastar menos gasolina?

Mostrar el código para goalReached()también ayudaría.
¿Estás probando contra ganache o alguna otra red de prueba como ropsten? ¿Qué versión del compilador estás usando? Hubo un error en solc que provocó un comportamiento extraño al estimar el uso de gas github.com/ethereum/solidity/issues/3687 y este reddit.com/r/ethdev/comments/82p78k/… .

Respuestas (1)

El problema es que la cantidad de gasolina que necesita suministrar a veces es mayor que la cantidad que realmente se deduce.

Esto sucede porque cuando borra el almacenamiento, como lo hace cuando elimina el saldo de deposited[investor], esto provoca un reembolso de gas que se restará de su gas total deducido. Sin embargo, este reembolso no se acredita hasta el final de la transacción, por lo que no se puede utilizar para pagar los pasos que siguen, en este caso su transferllamada y su Refundedevento.