Saltar al contenido principal
Change page

Transacciones

Las transacciones son instrucciones firmadas criptográficamente desde cuentas. Una cuenta iniciará una transacción para actualizar el estado de la red Ethereum. La transacción más simple es transferir ETH de una cuenta a otra.

Requisitos previos

Para ayudarle a comprender mejor esta página, le recomendamos que primero lea Cuentas y nuestra introducción a Ethereum.

¿Qué es una transacción?

Una transacción de Ethereum se refiere a una acción iniciada por una cuenta de propiedad externa, en otras palabras, una cuenta administrada por un humano, no por un contrato. Por ejemplo, si Bob envía a Alice 1 ETH, la cuenta de Bob debe ser debitada y la de Alice debe ser acreditada. Esta acción que cambia el estado tiene lugar dentro de una transacción.

Diagram showing a transaction cause state change Diagrama adaptado de Ethereum EVM illustrated (opens in a new tab)

Las transacciones, que cambian el estado de la EVM, deben transmitirse a toda la red. Cualquier nodo puede transmitir una solicitud para que se ejecute una transacción en la EVM; después de que esto suceda, un validador ejecutará la transacción y propagará el cambio de estado resultante al resto de la red.

Las transacciones requieren una tarifa y deben incluirse en un bloque validado. Para simplificar esta descripción general, cubriremos las tarifas de gas y la validación en otra parte.

Una transacción enviada incluye la siguiente información:

  • from: la dirección del remitente, que firmará la transacción. Esta será una cuenta de propiedad externa, ya que las cuentas de contrato no pueden enviar transacciones.
  • to: la dirección receptora (si es una cuenta de propiedad externa, la transacción transferirá valor. Si es una cuenta de contrato, la transacción ejecutará el código del contrato).
  • signature: el identificador del remitente. Esto se genera cuando la clave privada del remitente firma la transacción y confirma que el remitente ha autorizado esta transacción.
  • nonce: un contador que se incrementa secuencialmente y que indica el número de transacción de la cuenta.
  • value: cantidad de ETH a transferir del remitente al destinatario (denominada en Wei, donde 1 ETH equivale a 1e+18 Wei).
  • input data: campo opcional para incluir datos arbitrarios.
  • gasLimit: la cantidad máxima de unidades de gas que puede consumir la transacción. La EVM especifica las unidades de gas requeridas por cada paso computacional.
  • maxPriorityFeePerGas: el precio máximo del gas consumido que se incluirá como tarifa de prioridad para el validador.
  • maxFeePerGas: la tarifa máxima por unidad de gas que se está dispuesto a pagar por la transacción (incluyendo baseFeePerGas y maxPriorityFeePerGas).

El gas es una referencia a la computación requerida para procesar la transacción por parte de un validador. Los usuarios tienen que pagar una tarifa por esta computación. El gasLimit y el maxPriorityFeePerGas determinan la tarifa de transacción máxima pagada al validador. Más sobre el gas.

El objeto de la transacción se verá un poco así:

Pero un objeto de transacción debe estar firmado usando la clave privada del remitente. Esto prueba que la transacción solo pudo provenir del remitente y no fue enviada de manera fraudulenta.

Un cliente de Ethereum como Geth manejará este proceso de firma.

Ejemplo de llamada JSON-RPC:

Ejemplo de respuesta:

Con el hash de la firma, se puede probar criptográficamente que la transacción provino del remitente y se envió a la red.

El campo de datos

La gran mayoría de las transacciones acceden a un contrato desde una cuenta de propiedad externa. La mayoría de los contratos están escritos en Solidity e interpretan su campo de datos de acuerdo con la .

Los primeros cuatro bytes especifican a qué función llamar, utilizando el hash del nombre y los argumentos de la función. A veces puede identificar la función a partir del selector utilizando esta base de datos (opens in a new tab).

El resto de los datos de llamada son los argumentos, codificados como se especifica en las especificaciones de la ABI (opens in a new tab).

Por ejemplo, echemos un vistazo a esta transacción (opens in a new tab). Use Click to see More para ver los datos de llamada.

El selector de función es 0xa9059cbb. Hay varias funciones conocidas con esta firma (opens in a new tab). En este caso, el código fuente del contrato (opens in a new tab) se ha subido a Etherscan, por lo que sabemos que la función es transfer(address,uint256).

El resto de los datos es:

0000000000000000000000004f6742badb049791cd9a37ea913f2bac38d01279
000000000000000000000000000000000000000000000000000000003b0559f4

Según las especificaciones de la ABI, los valores enteros (como las direcciones, que son enteros de 20 bytes) aparecen en la ABI como palabras de 32 bytes, rellenadas con ceros en la parte delantera. Por lo tanto, sabemos que la dirección to es 4f6742badb049791cd9a37ea913f2bac38d01279 (opens in a new tab). La value es 0x3b0559f4 = 990206452.

Descriptores de transacciones

Debido a que el campo de datos contiene bytes hexadecimales opacos, puede ser extremadamente difícil verificar qué acción realizará realmente una transacción. Esta vulnerabilidad de "firma a ciegas" se aborda mediante la firma clara (opens in a new tab) a través del uso de descriptores de transacciones (opens in a new tab) (definidos por ERC-7730).

La especificación ERC-7730 utiliza descriptores de transacciones (a menudo estructurados como archivos JSON) para enriquecer los datos que se encuentran en las ABI y los mensajes estructurados, como los datos de llamada de transacciones de la EVM, los mensajes EIP-712 y las operaciones de usuario EIP-4337. Los desarrolladores utilizan estos descriptores para mapear variables de transacciones específicas directamente en plantillas de formato, asegurando que los datos subyacentes sigan siendo legibles por máquina para las aplicaciones.

En el frontend, las billeteras utilizan este contexto de formato para traducir el código de bytes opaco en información clara y legible para los humanos. Al resolver automáticamente valores como direcciones de tokens en símbolos reconocidos, o cantidades en decimales, a los usuarios se les presenta un resumen en lenguaje sencillo de la intención exacta de la transacción (por ejemplo, 'Intercambiar 1000 USDC por al menos 0.25 WETH') antes de que firmen.

Tipos de transacciones

En Ethereum hay algunos tipos diferentes de transacciones:

  • Transacciones regulares: una transacción de una cuenta a otra.
  • Transacciones de despliegue de contratos: una transacción sin una dirección 'to' (para), donde el campo de datos se utiliza para el código del contrato.
  • Ejecución de un contrato: una transacción que interactúa con un contrato inteligente desplegado. En este caso, la dirección 'to' es la dirección del contrato inteligente.

Sobre el gas

Como se mencionó, las transacciones cuestan gas para ejecutarse. Las transacciones de transferencia simples requieren 21000 unidades de gas.

Entonces, para que Bob envíe a Alice 1 ETH a una baseFeePerGas de 190 Gwei y una maxPriorityFeePerGas de 10 Gwei, Bob tendrá que pagar la siguiente tarifa:

(190 + 10) * 21000 = 4,200,000 Gwei
--o--
0.0042 ETH

La cuenta de Bob será debitada con -1.0042 ETH (1 ETH para Alice + 0.0042 ETH en tarifas de gas).

La cuenta de Alice será acreditada con +1.0 ETH.

La tarifa base será quemada -0.00399 ETH.

El validador se queda con la tarifa de prioridad +0.000210 ETH.

Diagram showing how unused gas is refunded Diagrama adaptado de Ethereum EVM illustrated (opens in a new tab)

Cualquier gas no utilizado en una transacción se reembolsa a la cuenta del usuario.

Interacciones de contratos inteligentes

Se requiere gas para cualquier transacción que involucre un contrato inteligente.

Los contratos inteligentes también pueden contener funciones conocidas como funciones view (opens in a new tab) o pure (opens in a new tab), que no alteran el estado del contrato. Como tal, llamar a estas funciones desde una EOA (cuenta de propiedad externa) no requerirá ningún gas. La llamada RPC subyacente para este escenario es eth_call.

A diferencia de cuando se accede mediante eth_call, estas funciones view o pure también se llaman comúnmente de forma interna (es decir, desde el propio contrato o desde otro contrato), lo que sí cuesta gas.

Ciclo de vida de la transacción

Una vez que se ha enviado la transacción, sucede lo siguiente:

  1. Se genera criptográficamente un hash de transacción: 0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017
  2. Luego, la transacción se transmite a la red y se agrega a un pool de transacciones que consta de todas las demás transacciones pendientes de la red.
  3. Un validador debe elegir su transacción e incluirla en un bloque para verificar la transacción y considerarla "exitosa".
  4. A medida que pasa el tiempo, el bloque que contiene su transacción se actualizará a "justificado" y luego a "finalizado". Estas actualizaciones hacen que sea mucho más seguro que su transacción fue exitosa y nunca será alterada. Una vez que un bloque está "finalizado", solo podría cambiarse mediante un ataque a nivel de red que costaría muchos miles de millones de dólares.

Una demostración visual

Vea a Austin guiarle a través de las transacciones, el gas y la minería.

Transactions — ETH.BUILD

A demonstration of how Ethereum transactions work using the ETH.BUILD educational tool.

Ver con transcripción 

Sobre de transacción tipada

Ethereum originalmente tenía un formato para las transacciones. Cada transacción contenía un nonce, precio del gas, límite de gas, dirección de destino (to), valor, datos, v, r y s. Estos campos están codificados en RLP, para verse algo así:

RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])

Ethereum ha evolucionado para admitir múltiples tipos de transacciones para permitir que se implementen nuevas características como listas de acceso y EIP-1559 (opens in a new tab) sin afectar los formatos de transacciones heredados.

EIP-2718 (opens in a new tab) es lo que permite este comportamiento. Las transacciones se interpretan como:

TransactionType || TransactionPayload

Donde los campos se definen como:

  • TransactionType: un número entre 0 y 0x7f, para un total de 128 tipos de transacciones posibles.
  • TransactionPayload: una matriz de bytes arbitraria definida por el tipo de transacción.

Según el valor de TransactionType, una transacción se puede clasificar como:

  1. Transacciones de tipo 0 (heredadas): El formato de transacción original utilizado desde el lanzamiento de Ethereum. No incluyen características de EIP-1559 (opens in a new tab) como cálculos dinámicos de tarifas de gas o listas de acceso para contratos inteligentes. Las transacciones heredadas carecen de un prefijo específico que indique su tipo en su forma serializada, comenzando con el byte 0xf8 cuando se utiliza la codificación de Prefijo de Longitud Recursiva (RLP). El valor de TransactionType para estas transacciones es 0x0.

  2. Transacciones de tipo 1: Introducidas en EIP-2930 (opens in a new tab) como parte de la actualización Berlín de Ethereum, estas transacciones incluyen un parámetro accessList. Esta lista especifica las direcciones y las claves de almacenamiento a las que la transacción espera acceder, lo que ayuda a reducir potencialmente los costos de gas para transacciones complejas que involucran contratos inteligentes. Los cambios en el mercado de tarifas de EIP-1559 no se incluyen en las transacciones de tipo 1. Las transacciones de tipo 1 también incluyen un parámetro yParity, que puede ser 0x0 o 0x1, lo que indica la paridad del valor y de la firma secp256k1. Se identifican por comenzar con el byte 0x01, y su valor de TransactionType es 0x1.

  3. Transacciones de tipo 2, comúnmente conocidas como transacciones EIP-1559, son transacciones introducidas en EIP-1559 (opens in a new tab), en la actualización London de Ethereum. Se han convertido en el tipo de transacción estándar en la red Ethereum. Estas transacciones introducen un nuevo mecanismo de mercado de tarifas que mejora la previsibilidad al separar la tarifa de transacción en una tarifa base y una tarifa de prioridad. Comienzan con el byte 0x02 e incluyen campos como maxPriorityFeePerGas y maxFeePerGas. Las transacciones de tipo 2 son ahora las predeterminadas debido a su flexibilidad y eficiencia, especialmente favorecidas durante períodos de alta congestión de la red por su capacidad para ayudar a los usuarios a administrar las tarifas de transacción de manera más predecible. El valor de TransactionType para estas transacciones es 0x2.

  4. Transacciones de tipo 3 (blob) se introdujeron en EIP-4844 (opens in a new tab) como parte de la actualización Dencun de Ethereum. Estas transacciones están diseñadas para manejar datos "blob" (objetos binarios grandes) de manera más eficiente, beneficiando particularmente a los rollup de capa 2 (l2) al proporcionar una forma de publicar datos en la red Ethereum a un costo menor. Las transacciones blob incluyen campos adicionales como blobVersionedHashes, maxFeePerBlobGas y blobGasPrice. Comienzan con el byte 0x03, y su valor de TransactionType es 0x3. Las transacciones blob representan una mejora significativa en la disponibilidad de datos y las capacidades de escalado de Ethereum.

  5. Transacciones de tipo 4 se introdujeron en EIP-7702 (opens in a new tab) como parte de la actualización Pectra de Ethereum. Estas transacciones están diseñadas para ser compatibles con versiones futuras con la abstracción de cuentas. Permiten que las EOA se comporten temporalmente como cuentas de contrato inteligente sin comprometer su funcionalidad original. Incluyen un parámetro authorization_list, que especifica el contrato inteligente al que la EOA delega su autoridad. Después de la transacción, el campo de código de la EOA tendrá la dirección del contrato inteligente delegado.

Lecturas adicionales

¿Conoce algún recurso de la comunidad que le haya ayudado? ¡Edite esta página y agréguelo!