Cuentas, Transacciones, Gas y límites de Gas en los bloques de Ethereum

Este artículo se propone ayudar a las personas a entender algunos de los mecanismos básicos que se encuentran detrás de las cuentas, transacciones, gas y el rol que ocupan los miners a la hora de determinar el tamaño de los bloques en Ethereum. Cualquier corrección es bienvenida! :)

¿Qué son las cuentas?

EOA vs cuentas contrato

Hay dos tipos de cuentas en Ethereum

  • Cuentas Externas (Externally Owned Accounts)
  • Cuentas Contrato

Las diferencias entre ambas se van a encontrar en el abstracto de la próxima actualización de Metrópolis(english)

Cuentas Externas (EOAs)

Una cuenta controlada externamente

  • tiene un balance de ether
  • puede enviar transacciones (transferencia de ether o desencadena códigos de contrato)
  • es controlada por Private Keys o llaves privadas
  • no tiene código asociado

Cuentas Contrato

Un contrato

  • tiene un balance de ether
  • tiene un código asociado
  • la ejecución del código es desencadenada por transacciones o mensajes (llamados) recibidos de otros contratos.
  • cuando es ejecutada- realiza operaciones de una complejidad arbitraria (completo en Turing)- manipula su propia resistencia de almacenamiento, por ejemplo: puede tener su propio estado permanente- puede llamar a otros contratos

Todas las acciones en la cadena de bloques de Ethereum se ponen en movimiento gracias a las transacciones realizadas por las cuentas. Cada vez que una cuenta contrato recibe una transacción, su código es ejecutado de acuerdo a lo instruido por los parámetros internos enviados como parte de la transacción. El código del contrato es ejecutado por Ethereum Virtual Machine (Máquina Virtual de Ethereum) en cada nodo participante de la red, como parte de su verificación de los nuevos bloques.

¿Qué son las transacciones y los mensajes?

El término “transacción” es utilizado en Ethereum para referirse a los paquetes de datos firmados que contienen un mensaje enviado desde una cuenta externa a otra cuenta en la cadena de bloques.

Las transacciones contienen:

  • el receptor del mensaje
  • la firma identificatoria de quien lo envía y aprobando la intención de mandar el mensaje por medio de la cadena de bloques hacia el receptor.
  • el campo VALUE — la cantidad de wei que se debe transferir del emisor al receptor,
  • un campo opcional de datos, que puede contener el mensaje enviado al contrato,
  • un valor GASLIMIT que representa el número de la cantidad máxima de pasos computacionales que se le permite la ejecución de la transacción realizar
  • un valor GASPRICE que representa la tarifa que quien envía el mensaje está dispuesto a pagar por gas. Una unidad de gas corresponde a la ejecución de una instrucción atómica, por ejemplo: un paso computacional.

Mensajes

Los contratos tienen la capacidad de enviar “mensajes” a otros contratos.
Los mensajes son objetos virtuales que nunca son serializados y existen solamente en el ambiente de ejecución de Ethereum. Pueden ser concebidos por medio de la función llamada.

Un mensaje contiene:

  • el emisor del mensaje (implícito)
  • el receptor del mensaje
  • el campo VALUE — la cantidad de wei que se debe transferir junto al mensaje a la dirección del contrato,
  • un campo opcional de datos, que son los datos para el contrato
  • un valor GASLIMIT que representa el número de la cantidad máxima de gas que el código de ejecución desencadenado por el mensaje puede utilizar.

Esencialmente, un mensaje es como una transacción, excepto que es producido por un contrato y no por un actor externo. Un mensaje es producido cuando un contrato que se encuentra ejecutando código, ejecuta los códigos operacionales CALL o DELEGATECALL que producen y ejecutan un mensaje. Los mensajes pueden ser llamados en ocasiones “transacciones internas”. Como una transacción, un mensaje llega a la cuenta receptora con su propio código. En consecuencia, los contratos pueden tener relaciones con otros contratos del mismo modo en el que actores externos pueden. Muchas veces, las personas utilizan el término transacción cuando se refieren a un mensaje, así que es posible que este término sea eliminado por concenso de la comunidad por falta de uso.

¿Qué es Gas?

Ethereum implementa un ambiente de ejecución en la cadena de bloques llamado Ethereum Virtual Machine (EVM). Cada nodo participante de la red ejecuta el EVM como parte del protocolo de verificación del bloque. Va por las transacciones listadas en el bloque que se está verificando y ejecutan el código desencadenado por la transacción en el EVM. Cada uno de los nodos completos en la red realizan los mismos cálculos y almacenan los mismos valores. El hecho que la ejecución de los contratos son replicados redundantemente entre cada nodo, naturalmente los hace más costosos, lo que generalmente crea un incentivo de no utilizar la cadena de bloques para cálculos que pueden ser realizados fuera de la misma. Por cada operación ejecutada habrá un costo específico, expresado en un número de unidades de gas. Cada operación que un contrato puede utilizar a su favor, tiene un valor asociado de gas. Aquí hay una lista no actualizada de los costos de gas por código de operaciones (opcode).

Gas y costos de Transacciones

A cada transacción se le requiere incluir un límite de gas (a veces llamadostartGas) y una tarifa que está dispuesta a pagar por gas. Los mineros o miners tienen la opción de incluir la transacción y recolectar la tarifa o no. En la realidad, hoy todas las transacciones son eventualmente levantadas por los miners, pero la cantidad de tarifas de transacciones que un usuario elige enviar, afecta cuánto tiempo tomará hasta que la transacción sea minada o mined. Si el total de gas utilizado por los pasos computacionales generados por la transacción, incluyendo el mensaje original y todos los sub-mensajes que sean desencadenados, es menor o igual al límite de gas, entonces la transacción será procesada. Si el total de gas excede el gas limit, entonces todos los cambios son revertidos, excepto que la transacción todavía sea válida y la tarifa pueda ser recolectada por el miner. La cadena de bloques muestra que una transacción intentó ser realizada, pero no tenía gas suficiente y todas las operaciones del contrato fueron revertidas. Todo exceso de gas no utilizado por la ejecución de la transacción es reembolsado al emisor en Ether. Dado que los costos de gas estimados son sólo aproximados, muchos usuarios pagan gas de más para garantizarse que su transacción será aceptada. Esto no es un problema porque cada exceso de gas será reembolsado a la misma persona.

Gastos estimados de transacción

El costo total de una transacción está basado en 2 factores

  • gasUsed: el total de gas que es consumido por la transacción
  • gasPrice: el precio (en Ether) de una unidad de gas especificada en la transacción

Costo total= gasUsed * gasPrice

Gas utilizado (gasUsed)

A cada operación en el EVM se le asignó un número de cuánto gas llega a consumir. gasUsed es la suma de todo el gas por todas las operaciones ejecutadas.

Para estimar gasUsed, hay un API de gas estimado (estimateGas) que puede ser utilizado pero con algunas advertencias (en inglés)

Precio Gas (gasPrice)

Un usuario construye y firma una transacción, y cada usuario puede especificar cualquier gasPrice que deseen, que puede ser hasta cero. De cualquier manera, los clientes de Ethereum que comenzaron en Frontier tenían un gasPrice por defecto de 0.05e12 wei. Como los miners se optimizan para su ganancia, si la mayoría de las transacciones son enviadas con un gasPrice de 0.05e12 wei, sería difícil de convencer a un miner de aceptar una transacción que especificó menor, o cero, gasPrice .

Ejemplos de costos de transacciones

Con permiso, tomo prestado este ejemplo y analogía del genial grupo de MyEtherWallet. Por favor, visiten su estupendamente escrita guía sobre gas aquí (en inglés). También tiene una página excelente de utilidades que te permiten convertir cantidades de ether a subunidades.

Podés pensar en el límite de gas como la cantidad de litros/galones/unidades de gas para un auto. Podés pensar en el precio del gas como el costo de esos litros/galones/unidades de gas.

Con un auto, es $2.50 (precio) por galón (unidad). Con Ethereum, es 20 GWEI (precio) por gas (unidad). Para llenar tu “tanque”, te tomaría- 10 galones a $2.50= $25- 21000 unidades de gas a 20 GWEI= 0.00042 ETH.

Entonces, la tarifa por TX será de 0.00042 Ether.

Enviando tokens, típicamente tomará alrededor de 50000 gas a 100000 gas, así que el total de tarifa por TX se incrementará a 0.001 ETH -0.002 ETH.

¿Qué es “Block Gas Limit” o “Límite de Gas por Bloque”?

Los límites de gas por bloque son la máxima cantidad de gas permitido en un bloque para determinar cuántas transacciones pueden ingresar en el mismo. Por ejemplo, digamos que tenemos 5 transacciones donde cada transacción tiene un límite de 10, 20, 30, 40 y 50. Si el limite de gas del bloque es 100, entonces las primeras cuatro transacciones pueden entrar en el bloque. Los miners deciden qué transacciones incluirán en un bloque. Un miner diferente podría intentar incluir las últimas dos transacciones del bloque (50+40), y sólo tendría espacio para incluir la primer transacción (10). Si intentas incluir una transacción que utilice más gas de lo que el límite del bloque permite, será rechazada por la red y tu cliente de Ethereum enviará el mensaje “La transacción excede el límite de gas por bloque”. Los créditos par este ejemplo son para el post de Ethereum StackExchange por “ethers” (en inglés).

El límite de gas por bloque es actualmente 4,712, 357 gas al momento de escribir este artículo de acuerdo a ethstats.net, siendo esto alrededor de 224 transacciones que cada una contiene un límite de transacción de 21000 pueden entrar en 1 bloque (que es producido normalmente cada 15–20 segundos). El protocolo permite que el miner de un bloque ajuste el límite de gas por bloque por un factor de 1/1024 (0.0976%) en cada dirección.

¿Quién decide el límite de gas por bloque?

Miners en la red deciden cuál es el límite de gas por bloque. Separado del protocolo ajustable, el límite de gas por bloque es una estrategia por defecto utilizada por los miners de un mínimo límite de gas por bloque de 4,712,388 para la mayoría de los clientes. Los miners pueden elegir cambiarlos, pero muchos de ellos no lo hacen y lo dejan por defecto.

¿Cómo se cambia el límite de gas por bloque?

Los miners en Ethereum utilizan un programa de mina, como ethminer, que conecta a geth o a un nodo Parity cliente de Ethereum. geth y Parity tienen opciones que los miners tienen la posibilidad de cambiar. Las opciones de la linea de comandos de geth están listadas aquí y las de Parity están aquí.

¿Qué es un “DoS” de la red Ethereum?

Recientemente ha habido muchos comentarios sobre la red de Ethereum siendo más lenta, estando saturada o poco usual. Estos comentarios describen esta ralentización como un “DoS” de la red Ethereum. Una negación del servicio (denial of service = DoS) incidente en la red de Ethereum sucede cuando hay bloques llenos y transacciones pendientes. Recuerden que los miners son los que pueden decidir incluir transacciones basados en la tarifa de transacción que las mismas traigan consigo. Si hay cientos de miles de transacciones en espera (o como se conocen técnicamente hablando, una transaction pool) puede causar una demora inusual de horas para las transacciones. Incidentes DDos pueden ser maliciosos o no-maliciosos.

DoS maliciosos

El otoño pasado, Ethereum fue atacado por una persona o un grupo en lo que se llama un ataque de spam de transacciones. El ataque está descripto en este post (en inglés):

El atacante realizó un ataque DoS por repetitivamente llamar a ciertos códigos de operación (opcodes) en los contratos inteligentes que son computacionalmente difíciles para procesar por nuestros clientes, pero muy baratos para adherir a la red.

Durante el ataque, los se les pidió a los miners bajar el límite de gas por bloque a 1.5 millones y luego a 2 millones en otra instancia. Ha habido otras instancias donde se les ha pedido a los miners bajar los límites de gas de bloques durante a ataques en la red.

DoS no maliciosos

Los incidentes de DoS no maliciosos son simplemente cuando la red tiene demasiadas transacciones pendientes, al punto de que toma un tiempo más largo que el usual procesar una transacción. Recientemente la popularidad y proliferación de los eventos de distribución de tokens (u ofertas iniciales de moneda (ICOs) o venta de tokens) han causado que la red se haya respaldado con transacciones. Los chicos de Infura escribieron un blog sobre los detalles técnicos (en inglés)

¿Por qué no se cambia el límite de gas por bloque aunque los bloques estén llenos?

Razón primaria: los miners no están utilizando el feature de límite de gas adaptativo.

El protocolo de Ethereum tiene un mecanismo intrínseco donde los miners pueden votar el límite de gas, de modo que la capacidad puede ser incrementada sin necesidad de coordinar un hard fork. Originalmente, este mecanismo fue realizado a la par con una estrategia por defecto, donde los miners podían votar por un límite de gas que fuera por lo menos 4.7 millones, pero el cual podría utilizar el 150% del reciente (movimiento exponencial de bloque-1024) gas normalmente usado si la cantidad es mayor, permitiendo aumentar orgánicamente la capacidad y creciendo la demanda mientras todavía incluye un tope por propósitos anti-spam.

Como es descripto en la previamente mencionada sección “DoS maliciosos”, hubo múltiples momentos en el pasado donde se les sugirió a los miners cambiar sus ajustes para poder utilizar la configuración que les permite elegir un límite de gas por bloque que no fuera el por defecto, con intención de ayudar a desalentar ataques hasta que se realicen los arreglos. El problema es que algunas mining pools nunca cambiaron sus ajustes luego de que los ataques se calmaron. Alrededor de un mes atrás, se les pidió a los miners cambiar los ajustes de gas limit y gas price para presentar un nuevo feature de límite de gas adaptado, ya que las recientes ventas de token estaba llenando bloques muy rápido y causando una congestión en la cadena de bloques de transacciones.

ETH Gas Station es un excelente recurso para las personas que están buscando información sobre cuáles son los límites de gas que las mining pools están votando.

¿Qué tienen que hacer los miners para arreglar esto?

Los miners pueden ajustar sus configuraciones en su geth or cliente Parity para re- habilitar sus límites de gas adaptado. Nota: Los valores de abajo fueron tomados de este post de Reddit y pueden ser ajustados a mucho más, como es explicado en este post de Reddit.

Geth

Ajuste sugerido

--gasprice 4000000000 --targetgaslimit 4712388

Explicación

--targetgaslimit Target gas limit limita el tope artificial del piso de gas para que los bloques minen (por defecto: “4712388”) --gasprice El precio mínimo de gas aceptado por minar una transacción (por defecto: “20000000000”). Note: gasprice está listado en wei.

Parity

Ajuste sugerido

--gas-floor-target 4712388 --gas-cap 9000000 --gasprice 4000000000

Explicación

--gas-floor-target Cantidad de gas por bloque objetivo cuando se sella un nuevo bloque (por defecto: 4700000).

--gas-cap Una tapa o cap a cuánto más se va a aumentar el límite de gas por bloque de acuerdo al volumen de transacción (por defecto: 6283184).

--gasprice Cantidad mínima de Wei por GAS a ser paga por una transacción para que sea aceptada en el proceso de minar. Note: gasprice es listado en wei. Note 2: --gasprice es una “Legacy Option/Opción de legado”

Otras opciones de minar

Por favor, visitá CLI páginas de opciones para geth y Parity y ver la lista completa de opciones que los miners pueden usar para ajustar sus configuraciones de manera óptima.

Recursos y lecturas para expandir

Artículo original en Inglés por Hudson Jameson (hudsonjameson.com)