¿Cuál es la diferencia entre una transacción y una llamada?

¿Cuál es la diferencia entre una transacción y una llamada? En algunas interfaces, puedo interactuar con contratos a través de llamadas o transacciones. ¿Cuál es la diferencia entre los dos, y los contratos también pueden hacer transacciones y llamadas?

NOTA para evitar confusiones: callen esta pregunta no se encuentra ni el código de operación EVM CALL ni Solidity <address>.call() , que realizan cambios en los estados del contrato, sino la API Web3.jsweb3.eth.call() , que no realiza ningún cambio de estado.

Respuestas (2)

Llamar

Una llamada es una invocación local de una función de contrato que no transmite ni publica nada en la cadena de bloques.

Es una operación de solo lectura y no consumirá Ether. Simula lo que sucedería en una transacción, pero descarta todos los cambios de estado cuando termina.

Es síncrono y el valor de retorno de la función de contrato se devuelve inmediatamente.

Su API web3.js es web3.eth.call y es lo que se usa para las funciones de Solidityviewpureconstant .

Su JSON-RPC subyacente es eth_call

Transacción

Una transacción se transmite a la red, los mineros la procesan y, si es válida, se publica en la cadena de bloques.

Es una operación de escritura que afectará a otras cuentas, actualizará el estado de la cadena de bloques y consumirá Ether (a menos que un minero lo acepte con un precio de gas de cero).

Es asíncrono, porque es posible que ningún minero incluya la transacción en un bloque (por ejemplo, el precio del gas para la transacción puede ser demasiado bajo). Dado que es asíncrono, el valor de retorno inmediato de una transacción es siempre el hash de la transacción. Para obtener el "valor de retorno" de una transacción a una función, se deben usar eventos (a menos que sea el caso 4 que se analiza a continuación). Para ethers.js, un ejemplo: ¿ escuchar eventos de contrato usando ethers.js?

Su API web3.js es web3.eth.sendTransaction y se utiliza si no se marca una función de Solidity constant.

Su JSON-RPC subyacente es eth_sendTransaction

sendTransaction se usará cuando se necesite un verbo, ya que es más claro que simplemente transacción.

Recomendación para llamar primero, luego enviar transacción

Dado que una transacción de envío cuesta Ether, es una buena práctica "probar las aguas" emitiendo una llamada primero, antes de la transacción de envío. Esta es una forma gratuita de depurar y estimar si habrá algún problema con la transacción de envío, por ejemplo, si se encontrará una excepción de falta de gas.

Esta "ejecución en seco" generalmente funciona bien, pero en algunos casos tenga en cuenta que la llamada es una estimación, por ejemplo, una función de contrato que devuelve el blockhash anterior, devolverá resultados diferentes según cuándo se realizó la llamada y cuándo se realiza la transacción. realmente minado.

Finalmente, tenga en cuenta que aunque una llamada no consume Ether, a veces puede ser necesario especificar la cantidad real de gas para la llamada : el gas predeterminado para llamadas en clientes como Geth, aún puede ser insuficiente y aún puede conducir a Out de Gasolina

Caso 4: ¿los contratos pueden crear transacciones?

Hay 4 casos de cómo se puede invocar una función de contrato.

Aquí están los 4 casos, y los primeros 3 se han tratado anteriormente :

  1. invocación directa de una función de contrato, originada con call

  2. invocación directa de una función de contrato, originada con sendTransaction

  3. invocación de contrato de una función de contrato, originada con call

4. invocación de contrato de una función de contrato, originada con sendTransaction

Aunque Case4 parece que un contrato "también puede hacer transacciones", porque está dentro de una transacción, la definición de una transacción son datos firmados por un actor externo. Por lo tanto Case4 no es una transacción.

Del Libro Amarillo :

Transacción : Un dato, firmado por un Actor Externo. Representa un Mensaje o un nuevo Objeto Autónomo. Las transacciones se registran en cada bloque de la cadena de bloques.

Anteriormente, se indicó que los eventos debían usarse para obtener el valor de retorno de una función de contrato, originada con sendTransaction. Eso pertenece y es cierto para el Caso 2. Para el Caso 4, el contrato obtiene el valor de retorno de una función de contrato directamente y puede usarlo. Así es como el Libro Amarillo lo dice en negrita:

Llamada de mensaje : El acto de pasar un mensaje de una cuenta a otra. Si la cuenta de destino está asociada con un Código EVM no vacío, entonces la VM se iniciará con el estado de dicho Objeto y se actuará sobre el Mensaje. Si el remitente del mensaje es un Objeto Autónomo, entonces la Llamada pasa cualquier dato devuelto por la operación de VM

Con estas definiciones del Libro Amarillo, se puede ver que Case4 es una llamada de mensaje dentro de una transacción (por lo tanto, cambios de estado), no hay transacciones anidadas y que una unidad de actividad en la cadena de bloques de Ethereum está dentro de una sola transacción . que puede contener varias llamadas de mensajes .

Actualización: dado que llamar a una función puede ser ambiguo (¿es un eth_call o un eth_sendTransaction?), hay una propuesta para eth_simulateTransaction .

¿Solo agregaría una aclaración/conclusión final sobre la posible ambigüedad entre una llamada web3 () y una llamada de mensaje () entre dos contratos? La sintaxis se vería muy similar y, por lo tanto, se podría ver que si un contrato llama a otro contrato, funciona de manera similar a una llamada web3, lo cual no es el caso. No lo simula en ese entorno. Produce cambios de estado.
Gracias, voté a favor y pude modificar el último párrafo.
Nomino esta respuesta como etiqueta wiki para invocación de contrato. Siéntase libre de revisar y contribuir con el wiki y el extracto .
¿Algo de esto cambia con la "Abstracción" que viene en Metropolis?
Veo un mensaje para una llamada de función de vista en Remix que dice "(El costo solo se aplica cuando se llama por un contrato)". Tengo una función de verificación de saldo de direcciones, que realiza una llamada a un contrato de token externo utilizando el balanceOfmétodo Erc20. Entonces, en este caso, mi contrato inteligente llama al contrato de token. ¿Esto costará gasolina como se indica, a pesar de que todo el proceso es de solo lectura?
@GViz Una transacción que invoca una función viewo purenunca requerirá el pago del gas. Tiene razón en que una forma simple de saberlo es que un proceso completo que es de solo lectura no costará gasolina. Tenga en cuenta que las funciones todavía utilizan gasview .
@eth gran punto, el gas se usa temporalmente, pero no se paga, cuando se ejecutan funciones de vista para evitar que se ejecuten rutinas arbitrariamente grandes (por ejemplo, bucles infinitos).
es calluna operación atómica? en otras palabras, si callfalla en algún lugar en el medio, ¿se revierte?
@ user1870400 eth_callno persiste nada: "retroceder" es su comportamiento predeterminado.
@eth, ¿cuándo se escriben (persisten) las actualizaciones de estado en el almacenamiento? según tengo entendido, al leer el código base, parece que las actualizaciones de estado se escriben en el almacenamiento cuando el bloque se agrega a Blockchain hasta entonces, es toda la memoria. ¿Es eso correcto?

La diferencia entre una llamada y una transacción es la siguiente:

  • Las transacciones son creadas por su cliente, firmadas y transmitidas a la red. Eventualmente alterarán el estado de la cadena de bloques, por ejemplo, mediante la manipulación de saldos o valores en contratos inteligentes.

  • Las llamadas son transacciones ejecutadas localmente en la máquina local del usuario, que es la única que evalúa el resultado. Estos son de sólo lectura y rápidos. No pueden cambiar la cadena de bloques de ninguna manera porque nunca se envían a la red. Algunos ejemplos "solo lectura/ejecución en seco/práctica".

Las llamadas son útiles para depurar contratos inteligentes, ya que no cuestan tarifas de transacción ni gas.

Busqué por un tiempo; esto finalmente me lo explicó (simplemente puse el constantmodificador en mi función y funcionó)