Ir al contenido principal
Change page

Transacciones

Última edición: @llucC(opens in a new tab), 9 de enero de 2024

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

Requisitos previos

Para ayudarle a comprender mejor esta página, le recomendamos leer primero la sección sobre Cuentas, así como nuestra introducción a Ethereum.

¿Qué es una transacción?

Una transacción de Ethereum hace referencia a una acción iniciada por una cuenta de titularidad externa, en otras palabras, una cuenta administrada por una persona, no un contrato. Por ejemplo, si Bob le envía 1 ETH a Alice, este debe adeudarse de la cuenta de Bob y acreditarse en la cuenta de Alice. Esta acción según la que se modifica el estado de la red tiene lugar en una transacción.

Diagrama que muestra cómo una transacción provoca cambios de estado Diagrama adaptado de Ethereum EVM ilustrado(opens in a new tab)

Las transacciones, que modifican el estado de la EVM, se deben transmitir 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 este resumen, abarcaremos las comisiones de gas y el minado por separado.

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

  • desde: la dirección del remitente, que firmará la transacción. Esta será una cuenta de titularidad externa, ya que las cuentas contractuales no pueden enviar transacciones.
  • a: la dirección de recepción (si es una cuenta de propiedad externa, la transacción transferirá valor. Si se trata de un contrato, la transacción ejecutará el código del contrato).
  • Firma: identificador del remitente. 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.
  • Valor: cantidad de ETH a transferir del remitente al destinatario (denominada en WEI, donde 1ETH equivale a 1e+18wei).
  • datos de entrada: campo opcional para incluir datos arbitrarios
  • gasLimit: cantidad máxima de unidades de gas que puede consumir la transacción. LaEVMespecifica las unidades de gas necesarias para cada paso de cálculo.
  • maxPriorityFeePerGas: cantidad máxima de gas consumido que se incluirá como propina al validador.
  • maxFeePerGas: máxima comision por unidad de gas destinada al pago por la transacción (exclusiva de baseFeePerGas y maxPriorityFeePerGas)

El gas es una referencia al cálculo necesario para que el validador procese la transacción. Los usuarios tienen que pagar una tarifa por ese cálculo. Los valores gasLimit y maxPriorityFeePerGas determinan la tarifa por transacción máxima que se le paga al validador. Mas información sobre el gas.

El objeto de la transacción se verá de la siguiente forma:

1{
2 from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8",
3 to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a",
4 gasLimit: "21000",
5 maxFeePerGas: "300",
6 maxPriorityFeePerGas: "10",
7 nonce: "0",
8 value: "10000000000"
9}
Mostrar todo
Copiar

Es necesario firmar este objeto mediante la clave privada del emisor. De esta forma, se demuestra que la transacción solo pudo haberla enviado el emisor y que no se envió de forma fraudulenta.

Un cliente de Ethereum como Geth gestionará el proceso de firma.

Ejemplo de una llamada JSON-RPC:

1{
2 "id": 2,
3 "jsonrpc": "2.0",
4 "method": "account_signTransaction",
5 "params": [
6 {
7 "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db",
8 "gas": "0x55555",
9 "maxFeePerGas": "0x1234",
10 "maxPriorityFeePerGas": "0x1234",
11 "input": "0xabcd",
12 "nonce": "0x0",
13 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
14 "value": "0x1234"
15 }
16 ]
17}
Mostrar todo
Copiar

Ejemplo de respuesta:

1{
2 "jsonrpc": "2.0",
3 "id": 2,
4 "result": {
5 "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
6 "tx": {
7 "nonce": "0x0",
8 "maxFeePerGas": "0x1234",
9 "maxPriorityFeePerGas": "0x1234",
10 "gas": "0x55555",
11 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
12 "value": "0x1234",
13 "input": "0xabcd",
14 "v": "0x26",
15 "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e",
16 "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
17 "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"
18 }
19 }
20}
Mostrar todo
Copiar

Mediante el hash de la firma, se puede demostrar criptográficamente que la transacción proviene del emisor y que se envió a la red.

El campo de datos

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

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

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

Por ejemplo, veamos esta transacción(opens in a new tab). Use Clic para ver más 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 sido subido a Etherscan, así que sabemos que la función es transferencia (dirección,uint256).

El resto de los datos es:

10000000000000000000000004f6742badb049791cd9a37ea913f2bac38d01279
2000000000000000000000000000000000000000000000000000000003b0559f4

De acuerdo con las especificaciones ABI, valores enteros (como direcciones, que son enteros de 20 bytes) aparecen en el ABI como palabras de 32 bytes, agregadas con ceros en el frente. Así que sabemos que la dirección a es 4f6742badb049791cd9a37ea913f2bac38d01279(opens in a new tab). El valor es 0x3b0559f4 = 990206452.

Tipos de transacciones

En Ethereum hay algunos tipos diferentes de transacciones:

  • Transacciones regulares: una transacción desde una cartera a otra.
  • Transacciones de despliegue de contratos: una transacción sin la dirección «a», donde el campo de datos se usa para el código de contrato.
  • Ejecución de un contrato: una transacción que interactúa con un contrato inteligente desplegado. En este caso, la dirección «a» es la dirección de contrato inteligente.

Sobre el gas

Tal y como se ha mencionado, las transacciones necesitan gas para ejecutarse. Las transacciones de transferencia simple requieren 21.000 unidades de gas.

De modo que, para que Bob pueda enviar a Alice 1 ETH con un coste de baseFeePerGas de 190 gwei y de maxPriorityFeePerGas de 10 gwei, Bob tendrá que pagar la siguiente tarifa:

1(190 + 10) * 21000 = 4,200,000 gwei
2--o--
30,0042 ETH

En la cuenta de Bobs se cargará-1,0042 ETH (1 ETH por Alice + 0,0042 ETH en tasas de gas)

A la cuenta de Alice se añadirán +1,0 ETH

La tarifa base que se consumirá será de 0,00399 ETH

El validador se queda con una propina de +0,000210 ETH

También se necesita gas para cualquier interacción del contrato inteligente.

Diagrama que muestra la devolución del gas no utilizado. Diagrama adaptado de Ethereum EVM ilustrado(opens in a new tab)

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

Ciclo de vida de la transacción

Una vez enviada la transacción ocurre 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 añade a un grupo de transacciones que consta de todas las demás transacciones que estan pendientes en la red.
  3. Un validador debe elegir su transacción e incluirla en un bloque para verificarla antes de considerarla «satisfactoria».
  4. A medida que pasa el tiempo, el bloque que contiene su transacción se actualizará a «justificado» y luego a «finalizado». Estas actualizaciones agudizan la certeza de que su transacción se complete satisfactoriamente y nunca se altere. Una vez que el bloque está «finalizado», este sólo podrá cambiarse mediante un ataque a escala de red que costaría miles de millones de dólares.

Una demostración visual

Observe a Austin mientras le guía por las transacciones, el gas y la minería.

Typed Transaction Envelope

Inicialmente, Ethereum tenía un formato único para las transacciones. Cada transacción contenía un nonce, un precio de gas, un límite de gas, una dirección, un importe, datos, v, r y s. Estos campos se codifican en RLP, para tener un aspecto similar a este:

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

Ethereum ha mejorado y ahora es compatible con múltiples tipos de transacciones, lo que permite que se implementen nuevas características como listas de acceso y EIP-1559(opens in a new tab) sin afectar los formatos de transacción antiguos.

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

Tipo de transacción || Cargaútiltransacción

Donde los campos indican:

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

Más información

¿Conoce algún recurso de la comunidad que le haya servido de ayuda? Edite esta página y añádalo.

¿Le ha resultado útil este artículo?