web3.eth.estimateGas
y JSON-RPC estimaGas se puede usar para ver cuánto gas debe especificarse para una transacción, antes de elaborar la transacción.
Dado que es una estimación, ¿hay alguna limitación? ¿En qué casos se debe confiar menos en su uso, ya que puede producir una estimación que no es significativa o precisa?
estimaGas funciona simulando que la transacción realmente se incluyó en la cadena de bloques y luego devuelve la cantidad exacta de gas que se habría cobrado si esa operación simulada fuera real. En otras palabras, utiliza exactamente el mismo procedimiento que usaría un minero para calcular la tarifa real.
Dado este enfoque, un observador casual podría pensar que no hay limitaciones y que la estimación siempre será exactamente correcta. Desafortunadamente, estarían equivocados .
Imagine un contrato simple que verifica el hash de bloque más reciente y luego llama a otro contrato grande que consume mucha gasolina solo si el décimo bit en el hash de bloque es un 1. Si usa estimar Gas para medir el consumo de una transacción que llama a este contrato simple , su resultado dependerá completamente de si el bloque más reciente contenía un 1 en el décimo bit de su hash de bloque. Si se publica un nuevo bloque entre el momento en que llama a estimar Gas y el momento en que se incluye la transacción, su estimación tiene un 50 % de posibilidades de ser totalmente incorrecta . Esto puede parecer un ejemplo artificial, pero muchos contratos usan hash de bloque como fuente de entropía y cambian su comportamiento en función de cuál sea el hash. Así que esto es algo que definitivamente podría suceder en la naturaleza.
Pero se pone peor. ¿Qué sucede si el contrato que solicita su transacción cambia su comportamiento en función de las transacciones que se le envían? Ahora es posible que el consumo de gas sea diferente según el orden en que se enviaron las transacciones .
Por ejemplo, suponga que llamar a un contrato comúnmente llamado casi siempre cuesta solo unos pocos cientos de gasolina . Pero contiene una cláusula extraña en su código para que un mensaje firmado por una clave específica altere su comportamiento, haciendo que consuma millones de gasolina cada vez que se llama . La misma clave es entonces capaz de alterar el comportamiento de nuevo. Ahora el propietario de esa llave puede modificar a voluntad el consumo de gas del contrato. Si el propietario es un minero , podría usar este "contrato atrapado" para activar este comportamiento de desperdicio de gas al comienzo de cada bloque que calculan y desactivarlo al final. Siempre que nunca publiquen públicamente estas transacciones privadas, cada llamada de estimar Gas arrojará un valor bajo, mientras que cadala transacción enviada genuinamente costará millones de gasolina (que va directamente al bolsillo del minero). Con un diseño de contrato cuidadoso, ni siquiera tendrían que realizar los cálculos, porque saben cuál será el resultado. Y podrían ejecutar este "ataque de robo de tarifas" al azar , solo realizándolo ocasionalmente para que nadie se dé cuenta hasta que muchos usuarios hayan sido engañados.
Una vez más, este ejemplo es artificial. Pero el punto es que siempre debes considerar si un atacante tiene algo que ganar si haces una mala estimación . Si hay un vector posible, coloque código adicional en la parte de su aplicación para manejar la situación en la que su estimación es incorrecta. Una técnica simple que siempre debe usar es incluir un límite de gas sensato . De esa manera, hay al menos un límite superior de lo que puede hacer un atacante. Más allá de eso, recuerde que se llama llamada estimada de gas, no llamada máxima garantizada de gas, y sea razonable al confiar en ella.
tl;dr:
Si hay alguna forma de que las consecuencias de su transacción cambien dependiendo de cuándo o a quién se envíe, existe la posibilidad de que la estimación de Gas sea incorrecta en cantidades arbitrariamente grandes. Tome precauciones adicionales.
Una limitación que encontré, o al menos un aspecto digno de mención del método eth.estimateGas, es que solo funciona según lo previsto si la llamada real no arroja una excepción.
Esto bien puede ser un error en la versión actual de geth, pero lo que he encontrado es que una llamada a un método que arroja una excepción siempre arroja el mismo resultado de estimación de gas, que es un valor de 50000000 unidades de gas. A un precio de gasolina de 20000000000, mis llamadas estimadas de Gas arrojaban exactamente 1 éter, lo que parecía ser una cantidad enorme para una simple llamada que generaba una excepción.
Esto es un poco fastidioso, ya que no he encontrado una forma confiable de estimar el gas en transacciones que realmente lanzan una excepción (que consumen gas), pero al menos vale la pena saberlo ;-) Así que parece una buena idea de depurar.traceTransaction su transacción antes de estimar su consumo de gas para asegurarse de que no arrojará una excepción y no le dará una estimación de gas muy incorrecta.
Por cierto, este valor "50000000" parece ser el mismo que se usa para inicializar las variables relacionadas con el gas en el código fuente de la API go ( https://github.com/ethereum/go-ethereum/blob/master/eth/api .go ), lo que parece insinuar que esto es más un error que una característica ;-)
Una limitación (según mi propia observación, espero que alguien me corrija si no estoy entendiendo bien) es que incluso si estimateGas
las estimaciones son correctas, eso no le da el límite de gasolina que debe establecer al enviar su transacción.
El problema es que los reembolsos se acreditan solo al final de la transacción, por lo que si tiene una transacción que funciona y limpia algo de almacenamiento a medida que avanza, debe establecer un límite de gasolina lo suficientemente alto para hacer todo el trabajo sin el beneficio del reembolso.
ética
jeff coleman
ética
jeff coleman
ética
Nika Kurashvili
ética
viendo prorok