Transacciones
Última edición: @llucC(opens in a new tab), 16 de julio 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 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 arbitrariosgasLimit
: 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 debaseFeePerGas
ymaxPriorityFeePerGas
)
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 todoCopiar
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 todoCopiar
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 todoCopiar
Transacción en bruto
es la transacción firmada en Prefijo de longitud recursiva (RLP) formulario codificado- la propiedad
tx
es la transaccion firmada en formato JSON
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:
10000000000000000000000004f6742badb049791cd9a37ea913f2bac38d012792000000000000000000000000000000000000000000000000000000003b0559f4
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 gwei2--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
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.
Interacciones con contratos inteligentes
Se requiere gas para cualquier transacción que involucre un contrato inteligente.
Los contratos inteligentes también pueden presentar funciones conocidas como view
(opens in a new tab) o pure
(opens in a new tab), que no afectan el estado del contrato. Como tal, invocar estas funciones desde una EOA no requerirá gas. La llamada RPC subyacente para este escenario es eth_call
.
A diferencia de cuando se accede usando eth_call
, estas funciones view
o pure
también se llaman comúnmente de forma interna (es decir, desde el contrato en sí o de otro contrato), lo que sí cuesta gas.
Ciclo de vida de la transacción
Una vez enviada la transacción ocurre lo siguiente:
- Se genera criptográficamente un hash de transacción:
0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017
- 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.
- Un validador debe elegir su transacción e incluirla en un bloque para verificarla antes de considerarla «satisfactoria».
- 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.
Según el valor TransactionType
, una transacción se puede clasificar como:
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 es0x0
.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 direcciones y claves de almacenamiento a las que la transacción espera acceder, ayudando a reducir potencialmente los costos de gas para transacciones complejas que involucren 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ámetroyParity
, que puede ser0x0
o0x1
, lo que indica la igualdad del valor y de la firma secp256k1. Se identifican comenzando con el byte0x01
, y su valor TransactionType es0x1
.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 separando la tarifa de transacción en una tarifa base y una tarifa prioritaria. Comienzan con el byte
0x02
e incluyen campos comomaxPriorityFeePerGas
ymaxFeePerGas
. Las transacciones de Tipo 2 son ahora las predeterminadas debido a su flexibilidad y eficiencia, especialmente favorecidas durante los períodos de alta congestión de la red por su capacidad para ayudar a los usuarios a gestionar las tarifas de transacción de manera más predecible. El valor de TransactionType para estas transacciones es0x2
.
Más información
¿Conoces algún recurso en la comunidad que te haya servido de ayuda? Edita esta página y añádelo.