¿Por qué necesito especificar un límite de gas más alto que el gas estimado?

Si una llamada de contrato previsiblemente requiere que se procesen 41043 de gas según lo estimado por estimateGas, ¿por qué necesito especificar un límite de gas de ~70000 para que se procese?

Respuestas (3)

Creo que, en algunos casos, el gas usado acumulativo no es exacto debido al gasto de gas o al reembolso de gas. Si en algún momento el contrato supera el gasLimit, fallará con una excepción Out of Gas. Si se emite un reembolso más adelante en el contrato, reducirá la gasolina acumulada aunque supere lo que usted cree que es el "límite de gasolina" durante la ejecución del contrato.

Veamos a Etherdice como ejemplo.

  • El contrato tenía datos almacenados

  • Cada vez que un usuario enviaba una transacción al contrato, el contrato eliminaría el artículo más antiguo almacenado

  • Sin embargo, dado que el contrato solo reembolsa al final de la transacción, todos los fondos quedaron atrapados en el contrato debido a que se quedó sin gasolina.

Entonces, antes de que un usuario envíe una transacción, digamos que el combustible es 100,000. Después de que el usuario envía la transacción, el gas es 100.000. Durante el contrato, en un momento determinado, "necesita" 200.000. Y en el momento en que llega a ese límite, se queda sin gasolina y listo.

En el caso de etherdice, en realidad fue peor porque estaba alcanzando el límite global de 3141592 que existía antes de Homestead.

gracias por tu respuesta. Esto tiene mucho sentido, pero creo que no estoy haciendo ninguna operación con un precio de gasolina negativo : una llamada externa y algunas escrituras de almacenamiento (donde se sobrescribe el valor).
No debe considerar el Gas Usado acumulativo, es la cantidad acumulada de Gas Usado dentro del bloque actual. Mire varios tx en varios bloques, este valor subirá o bajará 'aleatoriamente', por lo que no puede usarlo para establecer su límite de gas (a menos que solo haya su tx en el bloque).

tu no

Puede especificar el gas exactamente y debería funcionar bien. El único inconveniente es que si cambia el estado del contrato que está ejecutando y requeriría más gas del que proporciona incluso una sola unidad, perderá todo el gas proporcionado y la transacción se revertirá.

La lógica del contrato no debería ser un problema (el uso de gas es constante), lo que significa que el gas usado acumulativo es estable. Es por eso que me pregunto, si se especifica 70k gasLimit, todo está bien (pero solo se usan 40k), y si especifico 50k, se gasta todo el gas y no se procesa tx.
@Ales Parece que se está quedando sin combustible, por lo que es posible que deba depurar con el EVM o, más simple, verificar un explorador de blockchain que simule el EVM: ethereum.stackexchange.com/q/1179/42
@eth sí, eso parece más probable ya que gasLimit==acumulativeGasUsed para estos txs. Pero me gustaría entender la razón de esto.
Una posible explicación: a medida que los mineros ejecutan operaciones por contrato, a veces (por ejemplo, para llamadas externas) estiman cuánto gas se necesitaría para la operación (y tal vez agreguen algún margen de seguridad), verifican si hay suficiente gas y solo entonces proceden con dicho operación si hay suficiente gas disponible. Si esto es cierto, gasLimit siempre debe ser mayor que la cantidad de gas que realmente se requiere y se usará al final.
Ah, este es un muy buen punto. Creo que estimaGas no tuvo en cuenta los reembolsos (es decir, libera algo de espacio de almacenamiento), lo que podría causar que subestime el requisito real. Consulte github.com/ethereum/go-ethereum/issues/2395
En realidad, acabo de revisar el código y ya se solucionó hace un tiempo. Entonces, aunque aún no está en la rama estable, en desarrollo debería funcionar bien. Por favor informe si no es para usted.
Bueno, entiendo que no deberíamos, pero tengo un contraejemplo. Mire lo siguiente: testnet.etherscan.io/tx/… Paso 325k y todo está bien porque la llamada necesita 323161. Ahora exactamente la misma llamada pero paso 324k gas en su lugar. Para el registro 324k > 323161 :) testnet.etherscan.io/tx/… y este último falla.

Aquí hay consejos generales, seguidos de una síntesis de las otras respuestas y comentarios para explicar esta situación particular.

Consejos generales

Pregunta específica

La conclusión parece ser:

  • OP estaba realizando algunas escrituras de almacenamiento (donde se sobrescribe el valor)
  • Las pocas escrituras de almacenamiento en realidad conducen a un reembolso de gasolina
  • OP estaba usando una rama estable de Geth
  • La sucursal estable de Geth tiene un error que subestimaba el gas ya que Geth lo normalizó para incluir reembolsos de gas, en lugar de informar el gas máximo consumido durante la transacción.
  • Por lo tanto, la transacción se estaba quedando sin gas y necesitaba un límite de gas más alto para ser procesada

Geth v1.4 o la developsucursal tiene la solución para estimar Gas. Tenga en cuenta que, aunque estimateGases práctico de usar, aún no será correcto para todos los escenarios posibles.