Sin combustible al llamar al método de contrato: Browser Solidity y Metamask

Intentando llamar al método sendFundsToFriend() en el contrato de testnet https://testnet.etherscan.io/address/0xce8efd03766a309af57ddeb9c79f3e7cd23da0df (código de contrato en https://gist.github.com/anonymous/5bdc3d9032a8b3cb5cba7c7625afa4d7 ) Obtuve:

Warning! Error encountered during contract execution [Out of gas]

El resultado de tx dice:

Result: {
  "blockHash": "0x585ca866c5143090c7a82443269d55658a176a018b1ad90827ec70adc1ff66c8",
  "blockNumber": 465927,
  "contractAddress": null,
  "cumulativeGasUsed": 508930,
  "from": "0xe5f68950d479fab12797dabbe5a4b0d88ec7a722",
  "gasUsed": 58787,
  "logs": [],
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "root": "0x1289d7517d81fa8c4894c0cd97fd200ec4e9f0fecebba586435daca8e4e8f9ec",
  "to": "0xce8efd03766a309af57ddeb9c79f3e7cd23da0df",
  "transactionHash": "0x703d7657c093557d1cd42dfeb7b8d0d3b74e413d22e8009b26d7ac966c85d048",
  "transactionIndex": 3
}
Transaction cost: 58787 gas.

ingrese la descripción de la imagen aquí

Al enviar el tx, el límite de gas de transacción se establece en 3000000, el valor predeterminado de solidez del navegador.

Si el costo de tx es 58787 gas y el límite es 3000000, ¿por qué el error de falta de gas? ¿Alguna idea? ¡Gracias!

PD: Probé un tx similar desde un nodo geth en lugar de usar metamask+browser-solidity y funcionó bien:

https://testnet.etherscan.io/tx/0x56465b6594769578d9223ca902757780600dd2628074aedcf9635fb590b75bfa

Por lo tanto, estoy haciendo algo mal con la solidez del navegador al llamar al método de contrato, o podría ser algún tipo de error en este entorno...

Es cumulateGasUsed, debe verificarlo, 508930
Según ethereum.stackexchange.com/questions/3346/… el gas acumulativo tiene que ver con todos los txs en el mismo bloque. ¿Por qué debo pagar tarifas por todos los txs en el bloque?
Además, 3000000 es mayor que 508930
De hecho, el método sendFundsToFriend no es pagadero. Es el contrato el que envía sus propios fondos a un amigo, no el remitente. La cantidad debe ser 0.
@JuanIgnacioPérezSacristán: Perdón, tenías razón, acumulable es todas las transacciones
Es difícil ayudarte si no podemos ver el código del contrato. ¿Podría publicar la solidez relevante?

Respuestas (3)

Mi teoría, mirando las transacciones desplegadas, es que las transacciones fallidas fueron a una dirección inexistente (cero nonce, cero ETH antes), y las exitosas fueron a una dirección existente (aparentemente tenían transacciones en el pasado y ETH ya). El primero consumiría más gas, empujándolo más allá del límite de gas normal.

La forma de probar esto sería usar metamask+browser-solidity para enviar a una dirección que ya tuviera ETH. Si falla, entonces no es el caso. Si no falla, entonces esto es probablemente lo que sucedió.

Todavía puede ser un error en metamask, ya que calculó mal la cantidad de gas que proporcionar.

EDITAR:

Puede que haya encontrado la respuesta.

Comparar un geth exitoso con una metamáscara fallida (supongo) muestra que las transacciones sin procesar son en realidad diferentes. Sospecho que el cliente que envió la transacción fallida está formateando los campos de manera diferente, o simplemente con errores.

En este punto, presentaría un error con metamask. Está más allá de mi propia capacidad de depuración.

Desafortunadamente, tampoco funciona de esta manera: testnet.etherscan.io/tx/… En este caso, la dirección de destino es testnet.etherscan.io/address/… con varios txs anteriores y un saldo no nulo. Este mismo tx usando el nodo geth funciona bien desde un nodo geth => testnet.etherscan.io/tx/…
Mirando de cerca, parece que metamask envía exactamente suficiente gas, mientras que geth envía gas extra. No estoy seguro de por qué se rompería si tiene lo suficiente; hay una pequeña cantidad de posibilidades oscuras. (No creo que sea un problema de reembolso, ya que no hay eliminación de almacenamiento ni autodestrucciones).
gas enviado por metamask: 33787 en testnet.etherscan.io/tx/… 58787 en testnet.etherscan.io/tx/… y testnet.etherscan.io/tx/… mientras que geth envía 1000000 pero gasta solo 23263 => testnet. etherscan.io/tx/…
Todavía no puedo pensar que sea otra cosa que no tener suficiente gasolina, ya que las transacciones son idénticas por lo demás. El cliente que lo envió no debería importar, ya que son los mineros los que lo ejecutan.
¿¡O no!? Ver mi última edición.
Gracias Mateo. Un error con metamask es mi hipótesis también.

Al principio pensé que tal vez estábamos calculando mal el gas de alguna manera y fallando en las transacciones, ya que la mayoría de los tx fallidos tienen muy poco gas, pero en realidad, a veces, transacciones casi idénticas parecían tener éxito con menos gas, como este par: https://testnet. etherscan.io/tx/0x5dde4e0536756b380b34a6fed79bda50bbe274c25b07ac1812f0d816917b9fbd _

Una cosa que noté es que estos dos son en realidad contratos diferentes, por lo que no estoy seguro de cuál publicó el código fuente.

También vale la pena señalar que está utilizando algunos patrones para enviar que no se recomiendan en los documentos de Solidity: https://solidity.readthedocs.io/en/develop/security-considerations.html?highlight=send#sending-and -recibiendo-éter

Me doy cuenta de que algunas de las transacciones fallidas son para contratos, y esos son algunos de los momentos más peligrosos para usar la sendfunción, ya que esos contratos podrían quemar el gas.

Lo siento, pasé un tiempo en esto, no estoy seguro de haberlo encontrado.

Mi culpa. Hay dos versiones del contrato, pero la última es esta testnet.etherscan.io/address/… y es esta la que corresponde al código fuente.
Entonces, ¿debería usar un patrón de retiro en lugar de un patrón de envío?
Probablemente debería usar retirar en lugar de enviar, pero esto no responde por qué sucedió esto.

Estaba enfrentando el mismo problema con Remix + Ganache, cambié a otra red de prueba de Ethereum y no apareció el problema. Pruebe con alguna otra red de prueba.