Introduccion
Seguramente algunos de ustedes saben qué es la cadena de bloques Ethereum (del inglés Ethereum), otros, por el contrario, ni siquiera tienen la más mínima idea al respecto. De una forma u otra, tanto el primero como el segundo escucharon algo sobre esta plataforma. Recientemente, muchos artículos en varias revistas grandes se han dedicado a este tema, sin embargo, para aquellas personas que han escuchado poco sobre Ethereum, todos los artículos sobre este tema parecen ser algo místico y completamente incomprensible. Entonces, ¿qué es esta plataforma? En resumen: Ethereum es una base de datos de acceso público con la capacidad de almacenar transacciones digitales por tiempo ilimitado. También es importante tener en cuenta que no se requieren sistemas de gestión de claves para mantener y proteger dicha base de datos. En cambio, esta plataforma funciona como un sistema de transacciones "indefensas", un marco en el que las personas pueden realizar transacciones entre pares, mientras que ninguna de las partes tiene ninguna obligación con la otra parte o con terceros.
No me sorprendería si entendieras poco. En realidad, el propósito de este artículo es explicar cómo funciona la cadena de bloques Ethereum a nivel técnico, sin recurrir a cálculos matemáticos complicados o fórmulas que son aterradoras en su tamaño. Incluso si no es un programador, tengo plena confianza en que este artículo lo ayudará a comprender los principios de la tecnología Ethereum. E incluso si algunas partes de este artículo están repletas de definiciones técnicas que pueden parecer demasiado complicadas para que las perciba, no debe desesperarse, porque su propósito es transmitirle una comprensión de esta plataforma en su conjunto, sin entrar en sutilezas técnicas y matemáticas.
Muchos de los temas cubiertos en este artículo están analizando esos conceptos básicos que probablemente haya encontrado más de una vez al leer papel amarillo (del "papel amarillo" en inglés es la especificación oficial de Ethereum). He agregado mis propias explicaciones y diagramas para que pueda descubrir esta tecnología lo más rápido posible. Bueno, para los más valientes y técnicamente expertos puedo aconsejar leer el papel amarillo Ethereum.
¡Empecemos!
¿Qué es blockchain?
Blockchain es un sistema transaccional de elemento único criptográficamente seguro con un estado común. No es la definición más fácil, ¿verdad? Dividamos cada componente de esta definición en partes separadas.
- "Criptográficamente seguro" significa que la seguridad de la criptomoneda es proporcionada por sofisticados algoritmos matemáticos que son casi imposibles de eludir. La protección creada con estos algoritmos es como un firewall: gracias a los algoritmos utilizados, eludir el sistema de seguridad es casi imposible (por ejemplo, es imposible crear transacciones falsas, destruir transacciones, etc.).
- "Sistema singleton transaccional" significa que solo hay un estado predeterminado del sistema, debido a lo cual ocurren todas las transacciones creadas en este sistema. En otras palabras, solo se proporciona un estado para un sistema dado, que es el único verdadero.
- “Con un estado común” significa que el estado especificado en el sistema es general y está abierto a todos.
Por lo tanto, la plataforma Ethereum implementa el paradigma blockchain anterior.
Paradigma de blockchain de Ethereum
La cadena de bloques Ethereum es esencialmente
un sistema de estado transaccional . En informática, un "sistema de estado" o "máquina de estado" es un sistema que procesa la información de entrada y, en función de este último, se convierte en un nuevo estado.

En la máquina de estado Ethereum, todos los procesos comienzan con el "estado inicial". Este estado es un análogo del estado cero en el que se encuentra la máquina hasta el momento en que las acciones relacionadas con las transacciones comienzan a ocurrir en su red. Cuando tales acciones comienzan a tener lugar, el estado inicial se reemplaza por el estado final, mientras que en cualquier momento el estado final refleja el estado actual de Ethereum.
Ethereum tiene millones de transacciones. Estas transacciones se agrupan en "bloques". Un bloque contiene una serie de transacciones, con cada bloque posterior conectado al anterior, lo que garantiza una especie de cadena de bloques.
Una transacción debe ser correcta para provocar su transición de un estado a otro.
Una transacción se considera correcta solo cuando ha pasado el proceso de verificación, la llamada "minería" . La minería es cuando un grupo de nodos (computadoras) consume sus recursos informáticos para crear un bloque de transacciones correctas.
Cualquier nodo en la red que se declare minero puede intentar crear y verificar un bloque de transacciones. Una experiencia común son los intentos de muchos mineros de crear y verificar simultáneamente un bloque de transacciones. Cada minero proporciona su propia "prueba" matemática cuando envía un bloque a la cadena de bloques, y esta prueba actúa como una especie de garantía: si la prueba existe, las transacciones en el bloque se consideran correctas.
El minero debe proporcionar su prueba matemática más rápido que cualquier otro competidor para que su bloque se agregue a la cadena de bloques principal. El proceso de verificación de cada bloque, que consiste en proporcionar al minero su prueba matemática, se denomina "prueba de trabajo".
El minero, que justifica el nuevo bloque, recibe una cierta recompensa por hacer este trabajo. ¿De qué tipo de recompensa estamos hablando? La cadena de bloques Ethereum utiliza un token digital incorporado, que se llama "ether" (del inglés ether - "ether"). Cada vez que un minero corrobora su bloque de transacciones, se crea una nueva ficha o un nuevo éter, y el minero recibe una recompensa por su creación.
Entonces, puede tener una pregunta muy lógica: ¿dónde está la garantía de que cada minero se adherirá a una sola cadena de bloques? ¿Cómo me aseguro de que otro equipo de mineros no decida crear su propia cadena de bloques?
Al comienzo de este artículo, ya citamos dicho concepto como un "sistema de transacción única con un estado común". Con base en esta definición, podemos concluir que no hay dos o más estados actuales correctos: es único en su clase. Por lo tanto, todos los que participan en el proceso de sustanciación de nuevos bloques deben aceptar esta afirmación como verdad. La presencia de varios estados (o cadenas) destruiría todo el sistema, porque sería imposible acordar cuál de los estados es el correcto. Por ejemplo, imagine que habría varias cadenas de bloques. Luego, en teoría, podría recolectar 10 monedas en una cadena, 20 monedas en la otra, 40 monedas en la tercera, etc. En este caso, sería imposible determinar qué cadena es la más "correcta".
Cada vez que se generan varias rutas, se produce una "bifurcación". A menudo, las ramas son muy indeseables porque violan la integridad del sistema y los usuarios tienen que elegir una de las cadenas posibles.

Para determinar cuál de las rutas posibles es correcta y evitar la formación de múltiples circuitos, Ethereum utiliza un método llamado
"protocolo GHOST" .
FANTASMA - "El subárbol observado más codicioso más codicioso"Trataré de explicar en palabras simples:
el protocolo GHOST anuncia que debemos elegir solo la ruta en la que se realizó el mayor número de cálculos . Para determinar esta ruta, puede usar el número del bloque que se determinó por última vez ("bloque de hoja"). Gracias a este enfoque, es posible determinar el número total de bloques en la ruta actual (excluyendo el bloque del estado inicial). Cuanto más alto es el bloque, más largo es el camino y más justificación deben proporcionar los mineros. En base a tales consideraciones, se acepta la única versión correcta para el estado actual.
Ahora que ya tiene una idea de qué es blockchain, le propongo tratar con los componentes principales que componen el sistema Ethereum:
- cuentas
- condicion
- remuneración del combustible
- transacciones
- bloques
- ejecución de transacciones
- minería
- justificación
Una pequeña digresión antes de comenzar: cuando nos referimos al hash X, significa el hash
KECCAK-256 usado en Ethereum.
Cuentas
El estado global global de la plataforma Ethereum consta de muchos objetos pequeños, cuentas que interactúan entre sí a través del paradigma de mensajería. Cada cuenta tiene un estado específico y una dirección de 20 bytes. La dirección en Ethereum es un identificador de 160 bits utilizado para identificar cualquiera de las cuentas.
Hay dos tipos de cuentas en total:
- Las cuentas externas se controlan mediante claves privadas. Sin embargo, dichos registros no tienen ningún código asociado con ellos.
- Las cuentas de contrato están controladas por un código especial especificado en el contrato y que tiene un código asociado con ellas.
Cuentas externas y contractuales
Veamos las principales diferencias entre cuentas externas y contractuales.
Para una cuenta externa, es posible enviar mensajes a otras cuentas externas, así como a otras cuentas contractuales . Para este propósito, es necesario crear y registrar una nueva transacción usando la clave privada. Un mensaje entre dos cuentas externas es solo un valor para transferir. Por otro lado, un mensaje enviado desde una cuenta externa a una cuenta de contrato implica la activación del código de la cuenta de contrato, y es posible realizar ciertas acciones (por ejemplo, usando este mensaje puede transferir tokens, escribir valores en la memoria integrada, crear tokens, ejecutar algunos informática, creación de nuevos contratos, etc.).
Al usar cuentas de contrato, a diferencia de las externas, es imposible iniciar nuevas transacciones por su cuenta . En cambio, utilizando cuentas de contrato, solo puede iniciar transacciones en respuesta a otras transacciones recibidas (por ejemplo, las recibidas de una cuenta externa o de otra cuenta de contrato). En más detalle sobre las llamadas entre cuentas contractuales, nos detendremos en la sección "Transacciones y mensajes".
Cada acción en la cadena de bloques Ethereum ocurre debido a transacciones iniciadas por cuentas controladas externamente.Estado de cuenta
El estado de cada una de las cuentas, independientemente de su tipo, puede tomar uno de los cuatro valores:
- nonce : si la cuenta corriente corresponde a una cuenta externa, el número recibido representa el número de transacciones que se enviaron desde la dirección de la cuenta. Si la cuenta es una cuenta de contrato, entonces el elemento nonce es el número de contratos creados en esta cuenta.
- saldo : el número total de wei comprados por esta cuenta. Por ejemplo, cada éter, que es la unidad de intercambio de Ethereum, contiene 10 ^ 18 wei - partes fraccionarias del éter.
- storageRoot : el hash del nodo raíz del árbol de prefijos del árbol Merkle (lo que será el árbol Merkle un poco más tarde). El árbol de Merkle codifica un hash del contenido de esta cuenta y, de forma predeterminada, está vacío.
- codeHash : un hash del código EVM (de la máquina virtual inglesa Ethereum; qué es lo que te contaré más adelante) de la cuenta. Para las cuentas contractuales, este campo es un código que se codifica y almacena como codeHash.
Estado general del sistema
Entonces, descubrimos que el estado global de Ethereum es una asignación de estados de cuenta a direcciones de cuenta. Esta asignación se almacena en la estructura de datos, el
árbol de prefijos de Merkle .
El árbol Merkle (o "Merkle trie") es un tipo de archivo binario que consta de un conjunto de nodos que incluyen:
- cierto número de nodos hoja, que se encuentran en la parte inferior del árbol que contiene los datos subyacentes;
- un conjunto de nodos intermedios, con cada nodo como un hash de sus dos nodos secundarios
- un nodo raíz, también formado por un hash de dos nodos secundarios, que representa la parte superior del árbol
Los datos ubicados en la parte inferior del árbol se crean dividiendo los datos que queremos guardar en fragmentos separados. Además, dichos fragmentos se colocan en cestas de almacenamiento de datos, después de lo cual se procesan con hash y se repite un proceso similar hasta que el número total de hashes sea igual a uno o al hash raíz.
Para cada valor almacenado dentro de este árbol, deberá ingresar una clave específica. Para obtener el valor correspondiente almacenado en los nodos hoja, debe obtener un comando de teclado: a qué cadena de nodos secundarios debe adherirse. En cuanto a Ethereum, el mapeo de la clave / valor requerido para el árbol de estado es entre direcciones y cuentas relacionadas, incluyendo balance, nonce, codeHash, así como storageRoot para cada cuenta, mientras que storageRoot es un árbol.
Una estructura similar del árbol de prefijos también se puede utilizar para almacenar transacciones y la página de aceptación de pagos. Si nos detenemos en esto con más detalle, cada bloque tiene un llamado "encabezado" o archivo de encabezado, que almacena el hash del nodo raíz de tres estructuras diferentes del árbol Merkle, que incluyen:
- Estado del árbol de prefijos
- Prefijo de transacciones de árbol
- Páginas de aceptación de pago para árbol de prefijos
La capacidad de almacenar eficazmente esta información en el árbol de prefijos de Merkle Ethereum es una solución increíblemente práctica para los llamados clientes delgados o nodos delgados. También debe tenerse en cuenta que el soporte de blockchain se proporciona a través de un conjunto de nodos. En palabras simples: en total hay dos tipos de nodos: completo y delgado.
Un nodo de archivo completo sincroniza la cadena de bloques cargando toda la cadena desde el bloque de estado inicial hasta el bloque actual que contiene el archivo de encabezado, y se ejecutan todas las transacciones ubicadas en él . Como regla general, los mineros almacenan el nodo de archivo completo, ya que sin este último no tendrán la oportunidad de participar en el proceso de minería. Además, también puede descargar un nodo completo, sin necesidad de completar cada transacción individual. También vale la pena señalar que cada nodo completo siempre contiene una cadena completa.
En el caso de que no sea necesario que el nodo realice cada transacción individual o solicite los datos acumulados, puede ser innecesario almacenar la cadena completa. Es en este caso que nos enfrentamos a un concepto como un nudo delgado. En
lugar de cargar y almacenar la cadena completa, así como la ejecución de todas las transacciones, los nodos delgados cargan solo la cadena de archivos de encabezado desde el bloque de estado inicial al encabezado actual, y no se realizan transacciones . Dado que los nodos delgados tienen acceso a los encabezados de bloque que contienen un hash de tres árboles de prefijos, pueden crear y recibir fácilmente las respuestas correspondientes con respecto a transacciones, eventos, saldo, etc.
El hash en el árbol de Merkle se extiende desde las ramas inferiores a las superiores, y si un atacante intenta reemplazar la transacción original con una falsa en la parte inferior del árbol de Merkle, esto conducirá a un cambio en el hash del nodo superior, y esto, a su vez, cambiará el hash del nodo ubicado encima de él y así sucesivamente, hasta que, en última instancia, esto conduce a un cambio en la raíz.
Cualquier nodo que requiera la verificación de cualquier parte de los datos utiliza la llamada "prueba de Merkle". Este último consiste en:
- Fragmento de datos a verificar
- Hash de raíz de árbol
- La llamada "rama": todos los hashes, desde el dato verificado hasta la raíz.
Cada usuario que lea dicha prueba puede verificar si el hashing para una rama en particular es apropiado en toda la sección del árbol, y también si este fragmento ocupa la posición correspondiente en este árbol.
Por lo tanto, podemos concluir que la ventaja de usar el árbol de prefijos de Merkle es que el nodo raíz de esta estructura depende criptográficamente de los datos almacenados en el árbol. Por lo tanto, el hash del nodo raíz se puede usar como un identificador seguro para estos datos. Debido al hecho de que el hash raíz de los árboles está incluido en el encabezado del bloque, así como su estado, transacciones e información sobre el recibo del pago, cualquiera de los nodos puede verificar esta o aquella parte del Ethereum sin la necesidad de almacenar todos los estados, que pueden tener un tamaño potencialmente ilimitado.
Combustible y recompensa
Uno de los puntos importantes en el sistema Ethereum es el proceso de pago.
Para cualquier cálculo que se realice como resultado de transacciones con transacciones dentro de la red Ethereum, se cobra una cierta tarifa . El valor nominal de este pago se llama "combustible" (del gas inglés).El combustible es una unidad de medida que se utiliza para determinar la cantidad de pago para un cálculo en particular. El precio del combustible es la cantidad de "éter" que puede gastar en cada unidad de combustible. Se mide el precio del combustible en gwei. Wei es la unidad más pequeña de éter, donde 1018 Wei es solo 1 éter. Un gwei es igual a 1,000,000,000 de Wei.Para cualquier transacción, el remitente debe establecer un límite de combustible , así como el precio del combustible. . – Wei, .
, 50 000 gwei, – 20 gwei. , 50 000 20 gwei = 1 000 000 000 000 000 Wei 0,001 .

, – , . , . , , , .
, , « » . , , , . , , , . : , , , , , ,
no será reembolsado al remitente ."¿Dónde exactamente estoy enviando combustible?" - usted pregunta Por lo tanto, todo el dinero gastado en la compra por parte del remitente del combustible se envía a la dirección del beneficiario, que en la mayoría de los casos es la dirección del minero . Dado que los mineros realizan liquidaciones y verificación de transacciones, son ellos quienes reciben las tarifas de combustible como recompensa.Como regla general, cuanto mayor sea el costo del combustible que el remitente desea pagar, mayor será el pago recibido por el minero como resultado de la transacción y, además, es más probable que el minero haga su elección a su favor. Por lo tanto, los mineros son libres de elegir qué transacciones desean validar y qué transacciones deben ignorar. A menudo, los mineros les dicen a los remitentes qué precio deben establecer para el combustible para que los primeros estén listos para completar las transacciones.Tarifa de uso de almacenamiento
, . 32 .
, , . , , , . , - , , .
?
,
, , . , , , . , (, -, , , ) - , , , , : , , .
, .Ethereum usa un lenguaje completo de Turing. En resumen: una máquina de Turing es una máquina que simula cualquier algoritmo informático. Para aquellos que escuchan por primera vez sobre una máquina Turing, les sugiero leer esto y esto . , – , , , . , , , , - . , .
, : « - ? ?» , , , …- .
, –
. , , , .
, , , .:
( , ).
, :
- nonce – , .
- gasPrice – Wei, , .
- gasLimit – , . , - .
- to – . , , , .
- value – Wei, . , , .
- v, r, s – , , .
- init – , . EVM-, . init . init , , , .
- data – () (data , ). , - , (, IP-).
, « », , – , – , . , – , .
, :
, , . . , – . , , , .
, , .,
gasLimit , (, - ). , , , , , , . , , , , .
Todas las transacciones se agrupan de alguna manera en "bloques". La cadena de bloques contiene varios de estos bloques interconectados.Dichos bloques consisten en:- bloque de encabezado
- información sobre la serie de transacciones incluidas en este bloque
- serie de otros encabezados de bloque para ommers actuales
¿Qué son los omemers?
, ( . «ommer»). – , . , , .
, , , ( 15 ), , , ( 10 ). . , , . « » (.. ).
Los Ommers fueron creados para que los mineros pudieran recibir una merecida recompensa por incluir bloques sin padres en la cadena principal. Los ommers, incluidos los mineros en la cadena principal, deben ser "válidos": ellos, ommers, deben ser descendientes en la sexta o anterior generación del bloque actual. Por ejemplo, después de la sexta generación, dichos descendientes no pueden incluirse en la cadena principal como bloques sin un padre: las transacciones posteriores pueden afectar negativamente el funcionamiento del sistema en su conjunto.Para los omemers, recibirás una recompensa menor que la inclusión de un bloque completo. Sin embargo, esto no debería restar valor a los intentos de los mineros de incluir dichos bloques sin un padre y recibir su merecida recompensa.Bloquear encabezados
, , , ?
– , :
- parentHash – ( , , )
- ommersHash –
- beneficiary – ,
- stateRoot – ( , , )
- transactionsRoot – , ,
- receiptsRoot – , ,
- logsBloom – ( ), ,
- difficulty –
- number – ( , ; )
- gasLimit –
- gasUsed – ,
- marca de tiempo - marca de tiempo para crear el bloque actual
- extraData : datos adicionales relacionados con el bloque actual
- mixHash : un hash que, en combinación con el elemento nonce, afirma que se realizan suficientes cálculos para el bloque actual
- nonce : un hash, que en combinación con el elemento mixHash afirma que se realizan suficientes cálculos para el bloque actual
Vale la pena señalar que cada encabezado de bloque contiene tres estructuras de árbol de prefijos para:- estado ( stateRoot )
- realización de transacciones ( transaccionesRoot )
- recibir información de pago ( recibosRoot )
Tales estructuras del árbol de prefijos no son más que el árbol de prefijos de Merfle, que ya hemos discutido anteriormente.Además, para esta definición, hay varios términos que probablemente debería encontrar interesantes.Revistas
La plataforma Ethereum proporciona la capacidad de mantener registros, cuyo propósito es registrar información sobre varias transacciones y mensajes. Además, también es posible que un contrato cree abiertamente una entrada en dicho diario utilizando el anuncio del "evento" que se registrará.Una entrada de diario incluye:- dirección de la cuenta de registrador
- Una serie de tareas que muestran varios eventos completados para la transacción actual
- cualquier dato que sea relevante para estos eventos
Las entradas de
registro se almacenan en el
filtro Bloom , lo que permite almacenar efectivamente una cantidad infinita de datos.
Obteniendo información de pago
Los registros almacenados en el encabezado provienen de la información contenida en el diario, que se relaciona con los datos de pago de la transacción (o cheque). Del mismo modo que recibe un cheque al comprar productos en una tienda, Ethereum crea un cheque similar para cada una de las transacciones. Y como probablemente ya haya adivinado, cada cheque contiene información sobre la transacción actual. El cheque incluye:
- número de bloque
- bloquear hash
- hash de transacción
- cantidad de combustible utilizado para la transacción actual
- la cantidad total de combustible que se utilizó para realizar la transacción actual para un bloque específico
- registros de transacciones generados por la transacción
- otra informacion
Dificultad de bloqueo
La complejidad del bloque es un concepto utilizado para garantizar la consistencia del tiempo necesario para validar los bloques. Para el bloque inicial, la complejidad es de 131.072 unidades. Para calcular la complejidad de cualquiera de los bloques, se utiliza una fórmula especial. En el caso de que la validación de uno de los bloques ocurriera más rápido que, por ejemplo, la validación del siguiente, el protocolo utilizado en Ethereum aumenta la complejidad de este último.
La complejidad del bloque también afecta el nonce-hash, cuya ejecución es necesaria durante la visualización del bloque, mientras que para este propósito, se utilizan algoritmos de verificación de seguridad.
La dependencia de un parámetro, la complejidad del bloque, en otro, nonce, se presenta en esta fórmula:
donde Hd es la complejidad del bloqueLa única forma de determinar el parámetro nonce que cumplirá la condición presentada por la fórmula es usar el algoritmo de comprobación de estado para encontrar todos sus valores posibles. El tiempo esperado para buscar todos los valores que coincidan con esta condición es la complejidad del bloque. Entonces podemos concluir: cuanto mayor es el valor de la complejidad del bloque, más difícil es encontrar el parámetro nonce y, por lo tanto, más difícil es validar el bloque, lo que, a su vez, aumenta el tiempo requerido para validar los bloques posteriores. Entonces,
basado en el valor obtenido durante la determinación de la complejidad del bloque, el protocolo utilizado determina cuánto tiempo se necesita para validar el bloque actual .
En el caso de que el tiempo requerido para validar el bloque sea menor al esperado, entonces el protocolo subestima la complejidad del bloque actual. Por lo tanto, el tiempo requerido para la validación de bloque se configura automáticamente para que coincida constantemente con los parámetros actuales (en promedio, dicho tiempo es de 15 segundos).
Transacción
Bueno, bueno, aquí llegamos quizás a la parte más compleja de los protocolos utilizados en Ethereum: las transacciones. Imaginemos que ha configurado una transacción en la red Ethereum. ¿Y qué crees que pasará con el estado de Ethereum durante tu transacción?
En primer lugar, cualquier transacción debe cumplir ciertos requisitos para que su ejecución no se cancele, a saber:
- Las transacciones deben cumplir con los requisitos de RLP. RLP es un prefijo de longitud recursiva (del prefijo de longitud recursiva en inglés), que es un formato de datos que se utiliza para codificar matrices incrustadas de datos binarios. El formato RLP se usa en Ethereum para organizar objetos.
- La presencia de una firma de transacción válida.
- La presencia de un valor nonce válido. Permítame recordarle que nonce es el número de transacciones enviadas desde la cuenta corriente. Para que este valor sea válido, debe coincidir con el valor nonce para la cuenta del remitente.
- El límite de combustible para una transacción debe ser igual o mayor que la cantidad especificada de combustible. La cantidad especificada de combustible incluye:
- Se requiere un valor predeterminado de 21,000 unidades de combustible para completar la transacción
- Cargo de combustible utilizado para enviar datos de transacción (4 unidades de combustible para cada byte de datos o código igual a cero, y 68 para cada byte de datos o código distinto de cero)
- 32,000 unidades adicionales de combustible si la transacción involucra la contratación
- El saldo de la cuenta corriente del remitente debe contener una cantidad suficiente de éter para cubrir el costo "anticipado" del combustible, que el remitente acuerda pagar. El costo anticipado del combustible se calcula de la siguiente manera: el límite del costo del combustible se multiplica por el costo del combustible para la transacción actual, como resultado de lo cual encontramos el costo máximo del combustible. Además, la cantidad total de combustible transportado desde el remitente al destinatario se agrega al costo máximo.

En caso de que haya cumplido todos los requisitos anteriores, continúe con el siguiente paso.
En primer lugar, el valor del costo anticipado del combustible se deduce de la cuenta del remitente, y el nonce del remitente se incrementa en 1. Después de eso, podemos calcular la cantidad restante de combustible mediante la siguiente fórmula:
restar la cantidad especificada de combustible de la cantidad total de combustible necesaria para realizar la transacción .
Después de eso, comienza la transacción. Durante la transacción actual en Ethereum, se produce el seguimiento de "subestado". La subenunciación es necesaria para registrar la información que se recopiló durante la transacción actual. Dicha información será necesaria inmediatamente después de la finalización de la transacción y contiene:
- Conjunto de autodestrucción : un conjunto de cuentas que se eliminarán cuando se complete la transacción
- Serie de registros : puntos de interrupción archivados e indexados necesarios para ejecutar código de máquina virtual.
- Saldo de reembolso : la cantidad que debe devolverse al remitente al finalizar la transacción. Ya mencioné anteriormente que usar el repositorio proporcionado por Ethereum cuesta una cierta cantidad de dinero, y este dinero se devuelve al remitente después de que deja de usar dicho repositorio. El sistema Ethereum almacena información sobre el uso de la tienda y el reembolso por su uso al remitente.
Después de eso, se realizan los diversos cálculos necesarios para la transacción.
Una vez que se han completado todos los pasos necesarios para la transacción (siempre que se hayan cumplido todos los requisitos anteriores), se completa el estado de la transacción y se calcula la cantidad de combustible no utilizado que debe devolverse al remitente.
Después de que se completa la transacción (exitosa) y se devuelve el combustible al remitente, ocurre lo siguiente:
- una cierta cantidad de éter utilizada para comprar combustible se envía al minero;
- el combustible utilizado para realizar la transacción se registra en el bloque para el cálculo del combustible (este bloque se utiliza para almacenar información sobre la cantidad total de combustible que se utilizó para realizar todas las transacciones en este bloque; además, dicho bloque se utiliza durante la validación;
- toda la información de la cuenta contenida en la sección del conjunto de autodestrucción se elimina.
Así que llegamos al final de este capítulo: aprendimos qué es un nuevo estado y por qué necesitamos un diario para realizar transacciones.
En el próximo capítulo, veremos más de cerca la diferencia entre las transacciones relacionadas con la creación de contratos y el envío de mensajes.
Crear contratos
Probablemente recuerde que solo hay dos tipos de cuentas en Ethereum: cuentas contractuales y cuentas externas. Cuando encuentre el término "transacciones de creación de contratos", debe tener en cuenta que el propósito de dicha transacción es crear una nueva cuenta de contrato.
Para crear una nueva cuenta de contrato, primero debemos declarar la dirección de la cuenta creada usando una fórmula especial. Después de eso, se crea una nueva cuenta. Para realizar esta operación, debe realizar una serie de acciones:
- poner cero a nonce
- ajustar el saldo de su cuenta igual al pago de la transacción (si el remitente está listo para enviar una cierta cantidad de éter como pago de la transacción)
- calcular la cantidad de pago que entra en el saldo de la cuenta creada desde la cuenta del remitente
- indicar que la bóveda ya no la usa
- configurar el hash de contrato como un hash de cadena vacío
En el momento en que comenzamos a crear una nueva cuenta, de hecho, ya la creamos utilizando el
código de inicio , que se envía automáticamente al comienzo de la transacción (olvidamos cuál es el código de inicio; consulte la sección "Transacciones y mensajes"). Hay varias opciones para el desarrollo de eventos durante la ejecución del código de inicio (por ejemplo, puede suceder: actualizar el repositorio de una cuenta, crear otra cuenta para el contrato actual, enviar un mensaje, etc.).
Después de que el sistema ejecuta el código diseñado para crear un nuevo contrato, el combustible ingresa al juego. No podrá realizar una transacción si requiere más combustible que el que está almacenado en su balance. En el caso de que, a pesar de esta restricción, intente realizar una transacción, recibirá un mensaje sobre la falta de combustible, después de lo cual el sistema se apagará automáticamente. Además, si la finalización de la transacción se debió a la falta de combustible, se lo transferirá a la etapa anterior a la transacción. Y lo más importante: al
receptor no se le reembolsará la cantidad de combustible que se gastó antes de que se descubriera su escasez .
Estas son las cosas ...
Sin embargo, si el remitente asignó una cierta cantidad de éter para la transacción actual, esta cantidad se devolverá incluso si la creación del contrato falló.
Si el código de inicialización fue exitoso, los fondos necesarios para crear el contrato deben ser aportados por el creador. Esta cantidad también incluye el costo de usar el almacenamiento, que en proporción directa aumenta con el tamaño del código creado para el contrato. En el caso de que el creador no tenga fondos suficientes para llevar a cabo esta operación, la transacción finaliza debido a la falta de combustible y las consecuencias serán las mismas que las anteriores.
Si todo salió bien y no recibimos un mensaje sobre la escasez de combustible, todo el combustible que no se utilizó para esta transacción se devuelve al remitente.
Victoria!
Mensajes
La operación para enviar un mensaje, en general, es bastante similar a la creación de un contrato, sin tener en cuenta algunas pequeñas diferencias.
Para realizar esta operación, no se requiere el uso de un código de inicio, ya que como resultado de su ejecución no se crea una nueva cuenta. Sin embargo, para dicha operación, es posible que necesite datos de entrada, pero solo si el destinatario transmitió dichos datos como resultado de la transacción. Después de la operación para enviar el mensaje, está disponible un nuevo bloque que contiene la información de salida, cuyo uso ocurre cuando se repite la operación.
Además de en el caso de la creación del contrato, si la operación para enviar un mensaje se interrumpió como resultado de la falta de combustible o una transacción no válida (por ejemplo, debido a un error de desbordamiento de pila, una dirección de salto no válida, un comando incorrecto), la cantidad de combustible utilizada para esta operación no se devuelve al iniciador llamar Por el contrario, todo el combustible no utilizado también se deduce de su saldo, y el estado del sistema vuelve al punto que precede a la operación de transferencia de saldo.
Hasta hace poco, en Ethereum no había forma de suspender o suspender transacciones sin perder el combustible que proporcionó para tal fin. Por ejemplo, puede imaginar una situación en la que inicia la creación de un contrato, cuya creación falló, porque el iniciador de la llamada no tenía derecho a realizar ninguna de las transacciones. Entonces, en la versión anterior de Ethereum, antes de actualizar la plataforma, en tal situación, se retiraría todo el combustible restante en su cuenta, mientras que el remitente tampoco habría recibido su combustible. Pero con el
lanzamiento de la actualización, Byzantium, tiene la oportunidad de suspender la ejecución de las operaciones de creación de contratos y devolver el sistema a su estado original sin perder el combustible restante en su cuenta . Por lo tanto, si una transacción sale como resultado de la suspensión de su ejecución, el combustible no utilizado se devuelve al remitente.
Modelo de ejecución
En las secciones anteriores, le conté cómo se ejecutan las transacciones. Ahora le sugiero que se ocupe de lo que sucede en la VM (de la Máquina virtual en inglés, una máquina virtual) en el momento de la transacción.
Parte del protocolo que realiza el procesamiento de transacciones en el sistema operativo Ethereum se llama Ethereum Virtual Machine (VME) .
VME es una máquina de Turing, como se mencionó anteriormente en este artículo. La única diferencia entre VME y una máquina Turing típica es que la primera requiere un "combustible" virtual para funcionar. Por lo tanto, todos los cálculos que se pueden realizar en el VME están de alguna manera limitados por la cantidad de "combustible" que circula en él, la máquina virtual.
Fuente: CMUAdemás, todas las características de la arquitectura de pila son inherentes a VME.
Una máquina apilada es una computadora que usa el algoritmo LIFO.
El tamaño de cualquier elemento de pila en VME es de 256 bits, y el tamaño máximo de pila alcanza 1024 bits.
Para VME, se proporciona una cierta cantidad de memoria, que no es constante. Los elementos se almacenan en forma de matrices de bytes con acceso a palabras.
También se proporciona un área de almacenamiento específica para VME. A diferencia de la cantidad de memoria, dicho almacenamiento (o área de almacenamiento) no cambia y es parte del estado del sistema. En VME, el código del programa se almacena en una
ROM virtual separada, cuyo acceso solo se puede obtener mediante instrucciones específicas. Desde este punto de vista, tal VME difiere de una
arquitectura típica de
von Neumann en la que el código del programa se almacena en la memoria de la computadora.
VME también tiene su propio lenguaje especial: código de bytes VME. Cuando un programador como usted o, por ejemplo, yo, escribimos un contrato inteligente que se ejecutará en el sistema Ethereum, esto generalmente ocurre con un lenguaje de alto nivel como Solidity. Después de escribir dicho código, lo compilamos en el código de bytes de VME para que VME pueda entender el comando que escribimos.
Procedemos directamente a la ejecución de operaciones.
Antes de realizar un cálculo específico, el procesador debe asegurarse de que la siguiente información sea válida y esté disponible:
- Estado del sistema
- Información sobre combustible suficiente para llevar a cabo la operación requerida.
- Dirección de la cuenta a la que pertenece el código ejecutable
- Dirección del remitente de la transacción: iniciador de la operación actual
- Dirección de la cuenta: el iniciador del código ejecutado (puede diferir de la dirección del remitente-iniciador)
- Información sobre la cantidad de combustible requerida para completar la transacción
- Entrada para operación
- La cantidad de Wei que debe enviarse a la cuenta de esta cuenta como resultado de la transacción actual
- Información de código de máquina ejecutable
- Información de encabezado de bloque para el bloque actual
- Profundidad del mensaje actual o creación del contrato
Inmediatamente antes del inicio del programa, la memoria del sistema está completamente vacía y el contador de comandos es cero.
PC: 0 STACK: [] MEM: [], STORAGE: {}
Luego, en VME, comienza una transacción recursiva: calcular el estado del sistema y el estado de la máquina para cada ciclo. El estado del sistema es el estado global de Ethereum. La condición de la máquina incluye:
- cantidad disponible de combustible;
- contador de comando;
- contenido de la memoria;
- número activo de palabras en la memoria;
- contenido de la pila
Los elementos de la pila se agregan o eliminan del borde izquierdo del fragmento de código.
Para cada ciclo, una parte determinada se toma de la cantidad restante de combustible, mientras se aumenta el contador de comando.
Hay tres opciones posibles para finalizar el ciclo:
- Las operaciones realizadas por la máquina alcanzan un estado excepcional (por ejemplo, debido a la falta de combustible virtual, instrucciones incorrectas, número insuficiente de elementos de la pila, valor del elemento de la pila que excede el tamaño de 1024 bits, asignación incorrecta de JUMP / JUMPI) y, por lo tanto, el proceso de ejecución de la operación se suspende.
- El flujo pasa al siguiente ciclo.
- Las operaciones realizadas por la máquina alcanzan su conclusión lógica (finalización del proceso)
Si los cálculos realizados por la máquina llegan a una conclusión lógica, y no a un estado excepcional, como resultado de esto, la máquina proporciona el estado resultante, así como información sobre el combustible restante y la producción resultante.
Estas son las cosas. Usted y yo acabamos de aprender la parte más compleja y confusa de Ethereum. No se preocupe si no comprende completamente algo: no necesita profundizar en cada pequeña cosa y comprender todos los procesos que tienen lugar en este sistema, bueno, a menos que realmente lo estudie completamente y trabaje a un nivel bastante profundo.
Diseño final del bloque
Finalmente, descubramos qué sucede con los bloques de transacciones durante su ejecución final.
La "ejecución final" puede ocurrir de dos maneras, dependiendo de si estamos creando un bloque o si ya se ha creado. En el caso de que solo creamos un bloque, el diseño final significa el proceso de extracción del bloque actual. Por otro lado, si ya se ha creado un bloque, dicha definición significa el proceso de validación del bloque actual. En los dos casos anteriores, se deben cumplir cuatro condiciones para el diseño final del bloque.
1) Validación (o, en el caso de la minería, determinación) de omemers: cada bloque omemer que está en el encabezado del bloque debe tener un encabezado de bloque válido y ser el sexto descendiente del bloque actual.
2) Validación de transacciones: el valor de gas utilizado para el bloque actual debe ser igual al valor de la cantidad total de combustible utilizado para llevar a cabo todas las transacciones enumeradas en este bloque.
3) Propósito del pago (solo en el caso de la minería): se asignan 5 unidades de éter al beneficiario para la minería de cada bloque (de acuerdo con la propuesta EIP-649, este pago se reducirá a 3 unidades de éter). Además, para cada ommer, al beneficiario del bloque actual se le asigna un pago en forma de 1/32 adicional del pago total para el bloque actual. Y el último: al beneficiario del bloque de ommers también se le asigna un pago en forma de una cierta cantidad, para la determinación de que hay una cifra especial.
4) Verificación de valores de estado y nonce: para llevar a cabo este procedimiento, debe asegurarse de que se completen todas las transacciones, así como cambiar los estados resultantes. Después de lo cual también deberá establecer un nuevo bloque después de que se haya enviado el pago de este bloque. El proceso de verificación ocurre al comparar el estado final con el estado del árbol de prefijos almacenado en el encabezado.
Prueba de minería
En la sección "Bloques", nos familiarizamos brevemente con un concepto como la complejidad de los bloques. El algoritmo, gracias al cual surgió el concepto de complejidad de bloque, se llama Prueba de trabajo (PoW).
El algoritmo PoW utilizado en el sistema Ethereum se llama Ethash (anteriormente, pero se llama Dagger-Hashimoto).
Este algoritmo tiene la siguiente forma:
donde m es mixHash; n es nonce; Hn: el título del nuevo bloque (nonce y mixHash no se incluyen aquí, ya que estos valores deben calcularse); Hn - nonce para el encabezado del bloque; d es el conjunto de datos DAG.En la sección "Bloques", también nos familiarizamos con los diversos valores proporcionados para el encabezado del bloque. Estos, como recordará, incluyen valores como mixHash y nonce. Déjame recordarte nuevamente:
- mixHash es un hash que, junto con un valor nonce, confirma que se han realizado suficientes cálculos para el bloque actual.
- nonce también es un hash que, junto con el valor mixHash, confirma que se han realizado suficientes cálculos para el bloque actual.
Por lo tanto, PoW es necesario para calcular los valores anteriores.
Explicar exactamente cómo se calculan mixHash y nonce utilizando la función PoW es una tarea bastante complicada y, de hecho, se puede dedicar un artículo completo a este punto. Pero en resumen, sucede lo siguiente:
El valor de "semilla" se calcula para cada uno de los bloques. Para contar cada una de las semillas, hay su propio "intervalo", con cada uno de los intervalos iguales a 30,000 bloques. Para cada intervalo, la semilla es un hash igual a una serie de ceros de 32 bytes. Para cada intervalo posterior, se proporciona un hash específico para la semilla anterior. Usando esta semilla, el nodo encuentra el valor del "hash" pseudoaleatorio.
Tal hash juega un papel muy importante, porque con su ayuda podemos entender mejor qué son los "nodos delgados", que se discutieron en artículos anteriores. El propósito de los nodos delgados es proporcionar la capacidad de algunos de los nodos para verificar efectivamente ciertas transacciones sin la necesidad de almacenar todo el conjunto de datos de blockchain. Un nodo delgado puede validar una transacción utilizando solo este hash. Esto se debe al hecho de que este hash puede volver a crear el bloque que necesita para la verificación.
Con este hash, el nodo puede crear un paquete de datos DAG en el que cada elemento depende de un pequeño número de pseudoelementos hash aleatorios. Cada minero novato primero debe crear su propio paquete de datos completo. Se almacena un paquete de datos por separado en el sistema para cada uno de los mineros, mientras que el volumen de dichos datos crece constantemente.
Por ejemplo, un minero puede tomar partes aleatorias de un paquete de datos y usarlas en una función matemática para hacer hash de esas partes para mixHash. Tal minero podrá establecer constantemente el valor de mixHash hasta que se reciban los datos iniciales en forma de un valor nonce. Cuando se cumple esta condición, dicho valor nonce se considerará válido y se puede agregar un bloque al circuito.
La minería como mecanismo de defensa.
En general, el propósito de PoW es probar criptográficamente que ciertos cálculos estaban destinados a obtener un resultado específico (valores nonce). Dio la casualidad de que
no hay otra forma de encontrar nonce, cuyo valor no exceda un cierto límite, excepto enumerando todas las opciones posibles, hasta encontrar la requerida . La distribución de salida para un hash de función utilizado constantemente ocurre de manera uniforme. Por lo tanto, sabemos con certeza que el tiempo
requerido para encontrar el valor nonce depende claramente del umbral de complejidad : cuanto mayor sea el umbral de complejidad, más tiempo llevará la búsqueda del valor nonce requerido. El algoritmo PoW representa el concepto de complejidad utilizado en esta cadena de bloques.
¿Qué significa blockchain seguro? La respuesta es bastante simple: una cadena de bloques segura es una cadena de bloques en la que absolutamente TODOS LOS USUARIOS confiarán. Como escribí anteriormente, si hay más de dos cadenas en la cadena de bloques, es lógico suponer que los usuarios no se sentirán seguros al trabajar con la cadena de bloques, ya que nadie puede decir con precisión cuál de las cadenas presentadas es válida.
Para esto, se utiliza el algoritmo PoW: asegura la unidad de la cadena en la cadena de bloques, evitando la creación de otras cadenas de bloques que pueden afectar el historial de transacciones (por ejemplo, crear transacciones falsas o eliminar o cambiar las existentes). Por lo tanto, para que un atacante pueda validar primero sus bloques, tendrá que determinar constantemente el valor de nonce y hacerlo más rápido que todos los demás usuarios de la red (espero que recuerden el protocolo GHOST que describí anteriormente). Por supuesto, para un atacante, este método no será factible, a menos que tenga a su disposición la mayoría de los recursos mineros de la red; este escenario se conoce como un
ataque del 51% .
La minería como medio de distribución de financiación.
Además del hecho de que el algoritmo PoW garantiza el funcionamiento seguro de la cadena de bloques, también distribuye la recompensa a aquellos usuarios cuyos cálculos se utilizaron para garantizar la seguridad. Ya escribí anteriormente que los mineros reciben una recompensa por extraer este o aquel bloque, así como:
- recompensa de 5 unidades de éter por el bloque "ganador" (pronto esta cifra debería caer a 3 unidades)
- costo del combustible consumido como resultado de una transacción en un bloque
- recompensa adicional por incluir ommers en el bloque
Para garantizar la coherencia en el funcionamiento del método PoW, que es necesario para garantizar la seguridad, y la distribución de recompensas, Ethereum se adhiere constantemente a dos principios, que se presentan a continuación:
- En primer lugar, atraer la mayor cantidad de usuarios posible para usar la plataforma. En otras palabras, el uso de esta plataforma no debería causar dificultades al usuario: no debe usar algoritmos muy complejos ni usar hardware desconocido. Además, el proceso de distribución de la remuneración también debe ser claro y simple para cualquiera que esté dispuesto a gastar algo de energía utilizada por su computadora para obtener varias unidades de éter apreciadas.
- En segundo lugar, para evitar la distribución desproporcionada de recompensas y otros recursos para cualquier nodo en particular: cualquier nodo para el que la distribución desproporcionada de recursos tendrá un gran impacto en la definición de la cadena de bloques canónica, que afecta negativamente la seguridad del sistema en su conjunto.
Por ejemplo, en el sistema Bitcoin, hay un problema con la implementación de los dos principios anteriores: su algoritmo PoW utiliza la función hash SHA256. El problema de este último es que su solución puede ser mucho más simple en el caso de usar hardware especial: ASIC.
Para evitar tales pinchazos en Ethereum, se utiliza un algoritmo PoW especial con memoria en serie (
Ethhash ). La estructura del algoritmo está construida de tal manera que para calcular el valor nonce, es necesario utilizar una gran cantidad de memoria y un gran ancho de banda de la conexión. Los requisitos para tener una gran cantidad de memoria significan que será muy difícil para una computadora con una cantidad normal de memoria calcular en paralelo varios valores nonce al mismo tiempo. En cuanto a los requisitos de alto rendimiento, incluso para una computadora ultrarrápida, detectar múltiples valores nonce al mismo tiempo será una tarea desalentadora. Por lo tanto, gracias a tales características de este sistema, se reduce la probabilidad de centralización de riesgos y, además, se crean condiciones más uniformes para la operación de varios nodos que realizan la verificación.
Por cierto, no hace mucho tiempo aprendí que Ethereum cambiará del algoritmo PoW a un cierto método llamado Prueba de participación (Prueba de participación). Este método solo es digno de un artículo separado para su revisión y discusión.
Conclusión
Bueno, aquí llegamos a la conclusión lógica de nuestro artículo.
De hecho, este artículo proporciona mucha reflexión. No debe preocuparse en absoluto por eso si ha dominado este artículo por segunda o tercera vez. Personalmente releí el papel amarillo y el papel blanco para Ethereum muchas veces antes de comenzar a profundizar en la esencia del asunto.
Realmente espero que este artículo te haya sido útil. Si encuentra algún error, le agradeceré que me lo cuente.
Fuentes:
github.com/ethereum/yellowpapermedium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369-
Servicio de promoción ICO n .
° 1 para reddit y bitcoin .