WEB3DEV Español

Juan José Gouvêa
Juan José Gouvêa

Posted on

La Arquitectura de una Aplicación Web 3.0

Este artículo es una traducción del original, escrito por Preethi Kasireddy. La traducción fue hecha por Juan José Gouvêa.

La arquitectura de las aplicaciones Web 3.0 (o "DApps") es completamente diferente de la arquitectura de las aplicaciones Web 2.0.

Tomemos Medium, por ejemplo, un sitio web simple que permite a los usuarios publicar su propio contenido e interactuar con el contenido de otras personas.
Como una aplicación web 2.0, puede parecer simple, pero hay mucho en la arquitectura de Medium para que todo sea posible:

Primero, necesita un lugar para almacenar datos esenciales como usuarios, publicaciones, etiquetas, comentarios, me gusta, etc. Esto requiere una base de datos constantemente actualizada.

En segundo lugar, el código de back-end (escrito en un lenguaje como Node.js, Java o Python) debe definir la lógica comercial de Medium. Por ejemplo, ¿qué sucede cuando un nuevo usuario se registra, publica un nuevo artículo o comenta el artículo de otra persona?

En tercer lugar, el código de front-end (normalmente escrito en JavaScript, HTML y CSS) debe definir la lógica de la interfaz de usuario de Medium. Por ejemplo, ¿cómo se ve el sitio web y qué sucede cuando el usuario interactúa con cada elemento de la página?

Poniendo todo junto, cuando escribes un artículo en Medium, interactúas con tu front-end, que habla con tu back-end, que habla con tu base de datos. Todo este código está alojado en servidores centralizados y se envía a los usuarios a través de un navegador web. Este es un buen resumen de cómo funcionan la mayoría de las aplicaciones Web 2.0 en la actualidad.

web

Pero todo eso está cambiando.

La tecnología Blockchain ha desbloqueado una nueva y emocionante dirección para las aplicaciones Web 3.0. En este artículo, nos centraremos en lo que la blockchain de Ethereum trae a la mesa.

¿Qué hace que la Web 3.0 sea diferente?

A diferencia de las aplicaciones Web 2.0 como Medium, Web 3.0 elimina al intermediario. No hay una base de datos centralizada que almacena el estado de la aplicación, y no hay un servidor web centralizado donde resida la lógica de back-end.

En su lugar, puedes aprovechar la blockchain para crear aplicaciones en una máquina de estado descentralizada mantenida por nodos anónimos en Internet.

Por "máquina de estado" me refiero a una máquina que mantiene un estado de programa dado y estados futuros permitidos en esa máquina. Las Blockchains son máquinas de estado que se instancian con algún estado inicial y tienen reglas muy estrictas (es decir, un consenso) que definen cómo el estado puede hacer una transición.

Aún mejor, ninguna entidad controla esta máquina estatal descentralizada: todos en la red la mantienen colectivamente.

¿Qué pasa con un servidor back-end? En lugar de cómo se controlaba el back-end de Medium, en la Web 3.0 puedes escribir contratos inteligentes que definen la lógica de sus aplicaciones e implementarlas en la máquina de estado descentralizada. Esto significa que cualquier persona que desee crear una aplicación en la blockchain implementa su código en esa máquina de estado compartido.

¿Y el Front-End? Prácticamente sigue siendo el mismo, con algunas excepciones, que veremos más adelante.

Aquí está la arquitectura:

arquitectura web

Una mirada más cercana

Ahora profundicemos un poco más en lo que hace esto posible:

1) Blockchain

La Blockchain de Ethereum a menudo se presenta como una "computadora mundial". Esto se debe a que es una máquina de estado determinista y globalmente accesible mantenida por una red de nodos peer-to-peer. Los cambios de estado en esta máquina de estado están determinados ​​por las reglas de consenso que siguen los pares en la red.

Entonces, en otras palabras, está literalmente diseñada para ser una máquina de estado a la que cualquiera en el mundo puede acceder y también escribir. Como resultado, esta máquina no es propiedad de una sola entidad, sino de todos en la red.

Una cosa más que debes saber: los datos solo se pueden escribir en la blockchain de Ethereum; los datos existentes nunca se pueden actualizar o alterar.

2) Smart Contracts
Un contrato inteligente es un programa que ejecuta la blockchain de Ethereum y define la lógica detrás de los cambios de estado que ocurren en la misma. Los contratos inteligentes están escritos en lenguajes de alto nivel como Solidity o Vyper.

solidity

Dado que el código del contrato inteligente se almacena en la blockchain de Ethereum, cualquiera puede examinar la lógica de la aplicación de todos los contratos inteligentes en la red.

3) Máquina Virtual de Ethereum (EVM)

A continuación, tenemos la máquina virtual de Ethereum, que ejecuta la lógica definida en los contratos inteligentes y procesa los cambios de estado que ocurren en esta máquina de estado accesible globalmente.

La EVM no comprende lenguajes de alto nivel como Solidity y Vyper, que se utilizan para escribir contratos inteligentes. En su lugar, debe compilar el lenguaje de alto nivel en bytecode, que es lo que puede ejecutar EVM.

4) Front-End

Por último, tenemos el front-end. Como mencionamos anteriormente, define la lógica de la interfaz de usuario, pero el front-end también se comunica con la lógica de la aplicación definida en los contratos inteligentes.

La comunicación entre el front-end y los contratos inteligentes es un poco más complicada de lo que aparece en el diagrama anterior. Le daremos un vistazo más de cerca a esto más adelante.

¿Cómo se comunica el código front-end con los contratos inteligentes en Ethereum?

Queremos que nuestro front se comunique con nuestros contratos inteligentes para que puedan llamar funciones, pero recordemos que Ethereum es una red descentralizada. Cada nodo en la red Ethereum mantiene una copia de todos los estados en la máquina de estado Ethereum, incluidos el código y los datos asociados a cada contrato inteligente.
Cuando queremos interactuar con los datos y el código de una blockchain, necesitamos interactuar con uno de estos nodos. Esto se debe a que cualquier nodo puede transmitir una solicitud para que se ejecute una transacción en la EVM. Luego, un minero ejecutará la transacción y propagará el cambio de estado resultante al resto de la red.

Hay dos formas de transmitir una transacción:

  1. Configurando su propio nodo que ejecute el software de la blockchain de Ethereum

  2. Utilizando nodos proporcionados por servicios de terceros como Infura, Alchemy y Quicknode.

Si usas un servicio tercerizado, no tienes que lidiar con todos los dolores de cabeza que conlleva ejecutar un nodo completo. Después de todo, configurar un nuevo nodo Ethereum en tu propio servidor puede llevar días (hay una gran cantidad de datos para sincronizar; incluso podría ocupar más ancho de banda y almacenamiento de lo que puede manejar una computadora portátil normal).

Además, el costo del almacenamiento completo de la blockchain de Ethereum aumenta a medida que crece su DApp y necesita agregar más nodos para expandir su infraestructura. Por eso, a medida que su infraestructura se vuelve más compleja, necesitará más ingenieros de DevOps de tiempo completo. Ellos ayudarán a mantener la infraestructura para garantizar un tiempo de actividad confiable y tiempos de respuesta rápidos.

Todo esto para decir que evitar estos dolores de cabeza es la razón por la que muchas DApps optan por utilizar servicios como Infura o Alchemy para gestionar su infraestructura. Por supuesto, hay un pierde-gana, y esto crea un estrangulamiento centralizado, pero dejaremos este tema para otro día. ;)

Continuando, hablemos de los proveedores. Los nodos a los que te conectas cuando necesitas interactuar con la blockchain (ya sea que los configures tú mismo o uses los de terceros existentes) siempre se denominan "proveedores".

proveedores

Todo cliente de Ethereum (es decir, proveedor) implementa una especificación JSON-RPC. Esto garantiza que haya un conjunto uniforme de métodos cuando las aplicaciones front-end deseen interactuar con la blockchain. Si necesitas una introducción a JSON-RPC, es un protocolo de llamada a procedimiento remoto (RPC) simplificado y sin estado que define varias estructuras de datos y las reglas para su procesamiento. Es independiente del transporte, por lo que los conceptos se pueden usar dentro del mismo proceso, a través de sockets, a través de HTTP o en múltiples entornos de mensajería. Utiliza JSON (RFC 4627) como formato de datos.

Una vez que te conectas a la blockchain a través de un proveedor, puedes leer el estado almacenado en la blockchain. Pero, si deseas escribirle al estado, todavía hay una cosa más que debes hacer antes de poder enviar la transacción a la blockchain: "firmar" la transacción con tu clave privada.

Por ejemplo, imagina que tenemos una DApp que permite a los usuarios leer y publicar publicaciones de blog en la blockchain. Puedes tener un botón en el front-end que le permita a cualquiera ver las publicaciones escritas por un usuario específico. (Recuerda que leer la blockchain no requiere que el usuario firme una transacción).

Sin embargo, cuando un usuario quiere publicar un nuevo artículo en la cadena, nuestra DApp le pide al usuario que "firme" la transacción usando la clave privada; sólo entonces la DApp transmite la transacción a la blockchain. De lo contrario, los nodos no aceptarían la transacción.

Esta "firma" de transacciones es donde típicamente entra Metamask.

signer

Metamask es una herramienta que facilita que las aplicaciones manejen la gestión de claves y la firma de transacciones. Es muy sencillo. Metamask almacena las claves privadas del usuario en el navegador y cada vez que el front necesite la firma del usuario para la transacción, llama a Metamask.

Metamask también proporciona una conexión a la blockchain (como un "proveedor") ya que ya tiene una conexión a los nodos proporcionados por Infura, ya que la necesita para firmar transacciones. De esta forma, Metamask es a la vez proveedor y firmante. 🤯

Almacenamiento en Blockchain

Naturalmente, esta arquitectura tiene sentido si estás creando una aplicación en la que todos los contratos inteligentes y los datos viven completamente en la blockchain de Ethereum. Pero todos los que han creado aplicaciones en Ethereum saben que almacenar todo en la blockchain es muy costoso.

Ten en cuenta que con Ethereum, el usuario paga cada vez que agrega nuevos datos a la blockchain. Esto se debe a que agregar un estado a la máquina de estado descentralizada aumenta los costos para los nodos que mantienen esa máquina de estado.

Pedirle a los usuarios que paguen más para usar tu DApp cada vez que su transacción requiera agregar un nuevo estado, no es la mejor experiencia. Una forma de combatir esto es usar una solución de almacenamiento fuera de la cadena descentralizada como IPFS o Swarm.

IPFS es un sistema de archivos distribuido para almacenar y acceder a datos. Entonces, en lugar de almacenar datos en una base de datos centralizada, el sistema IPFS distribuye y almacena los datos en una red peer-to-peer. Esto facilita la recuperación cuando sea necesario.

IPFS también tiene una capa de incentivos llamada "Filecoin". Esta capa alienta a los nodos de todo el mundo a almacenar y recuperar estos datos. Puedes usar un proveedor como Infura (que te brinda un nodo IPFS) o Pinata (que te brinda un servicio fácil de usar donde puedes "fijar" tus archivos a IPFS, tomar el hash de IPFS y almacenarlo en la blockchain).

Swarm es similar al ser una red de almacenamiento descentralizado, pero hay una diferencia marcante. Si bien Filecoin es un sistema separado, el sistema de incentivos de Swarm está integrado y se aplica a través de contratos inteligentes en la blockchain de Ethereum para almacenar y recuperar datos.

Ahora, con IPFS o Swarm, la arquitectura de nuestra aplicación se ve así:

arquitectura actual

Los lectores perspicaces también pueden haber notado en el diagrama que el código de front-end no está almacenado en la blockchain. Podríamos alojar este código en AWS como lo haríamos normalmente en la Web 2.0, pero esto crea un estrangulamiento centralizado para tu DApp. ¿Qué pasa si AWS falla? ¿Qué pasa si se censura tu aplicación?

Por eso, si deseas crear una aplicación verdaderamente descentralizada, debes elegir alojar su front-end en una solución de almacenamiento descentralizado, tal como IPFS o Swarm.

Así que ahora, la arquitectura de nuestra aplicación se parecerá más a esto:

Arquitectura actualizada

Consultando la blockchain

Hasta ahora, hemos hablado de escribir en la blockchain mediante la firma de transacciones y luego enviar esas transacciones a la blockchain. Pero, ¿qué pasa con la lectura de datos de contratos inteligentes en la blockchain? Hay dos formas principales de hacer esto:

1) Eventos de Smart Contracts

Puedes usar la biblioteca Web3.js para consultar y escuchar eventos de contratos inteligentes. Puedes escuchar eventos específicos y especificar una devolución de llamada cada vez que se active el evento. Por ejemplo, si tienes un contrato inteligente que envía un flujo continuo de pago de la persona A a la persona B en cada bloque, entonces puedes emitir un evento cada vez que se realiza un nuevo pago a la persona B. Tu código front-end puede escuchar eventos activados por el contrato inteligente y realizar acciones específicas basadas en él.

2) El Graph

El enfoque anterior funciona, pero tiene algunas limitaciones. Por ejemplo, ¿qué sucede si implementas un contrato inteligente y luego te das cuenta de que necesita que se emita un evento que no se incluyó inicialmente? Desafortunadamente, tendrías que volver a implementar un nuevo contrato inteligente con este evento y datos. Además, el uso de devoluciones de llamada para manejar varias lógicas de interfaz de usuario se vuelve muy complejo rápidamente.

Aquí es donde entra “The Graph”.

The Graph es una solución de indexación off-chain que facilita la consulta de datos en la blockchain de Ethereum. The Graph te permite definir qué contrato inteligente se indexará, qué eventos y llamadas de funciones se escucharán y cómo convertir los eventos entrantes en entidades que tu lógica de front-end (o lo que sea que use la API) pueda consumir. Utiliza GraphQL como lenguaje de consulta, que a muchos ingenieros front-end les encanta debido a su expresividad en comparación con las REST API tradicionales.

Al indexar los datos de la blockchain, The Graph nos permite consultar los datos on-chain en la lógica de nuestra aplicación con baja latencia.

Ahora la arquitectura de tu DApp se ve así:

Arquitectura 3

Casi hemos terminado, pero falta un tema más importante: el dimensionamiento.

Escalando tu DApp

Como habrás escuchado, Ethereum no escala, al menos, hasta ahora...

Escala

Claramente, tenemos un problema aquí. Crear una DApp en Ethereum con altas tarifas de gas y bloques completos conduce a una UX muy mala. Afortunadamente, hay algunas soluciones en desarrollo.

Una solución de escalabilidad popular es Polygon, una solución de escala L2. En lugar de ejecutar transacciones en la blockchain principal, Polygon tiene "sidechains" que procesan y ejecutan transacciones. Una side-chain (cadena lateral) es una blockchain secundaria que interactúa con la cadena principal. De vez en cuando, la cadena lateral envía una agregación de tus bloques recientes a la cadena principal.

sidechain

Otros ejemplos de soluciones L2 son Optimistic Rollups y zkRollups. La idea aquí es similar: empaquetamos las transacciones fuera de la cadena mediante un contrato inteligente "rollup" y luego asignamos periódicamente estas transacciones en la cadena principal.

La idea general es: las soluciones L2 realizan la ejecución de transacciones (es decir, la parte lenta) off-chain, con solo datos de transacciones almacenados on-chain. Esto nos permite escalar la blockchain, ya que no tenemos que ejecutar todas las transacciones on-chain. Esto también hace que las transacciones sean más rápidas y económicas, e incluso pueden comunicarse con la blockchain principal de Ethereum cuando sea necesario.

Arquitectura completa

Juntando todo

Si todo esto te está dando vueltas en la cabeza, no estás solo. Reunir todas estas herramientas es complejo y puede resultar en una experiencia dolorosa para el desarrollador. Pero no te preocupes, estamos empezando a ver nuevos frameworks que realmente mejoran la experiencia de los desarrolladores.

Por ejemplo, Hardhat es un framework que facilita a los desarrolladores de Ethereum la creación, implementación y prueba de sus contratos inteligentes. Hardhat ofrece la "Hardhat Network", que los desarrolladores pueden usar para implementar sus contratos inteligentes en una red local, sin tener que lidiar con entornos en vivo. Aún mejor, ofrece un excelente ecosistema de plugins que facilita mucho la vida de los desarrolladores. Hardhat también proporciona la funcionalidad console.log(), similar a javascript, para fines de depuración.

Por supuesto, esto es solo el comienzo. Espero que sigamos viendo mejores herramientas para desarrolladores en el futuro.

Conclusión

La mayoría de las personas pasan meses descubriendo cómo funciona la cadena de herramientas. Entonces, si eres un nuevo desarrollador de DApps, espero que este artículo te haya ahorrado algo de tiempo. ¡Es hora de empezar a crear!

Si te interesa crear aplicaciones Web 3.0, registrate en nuestra próxima cohorte de DappCamp, donde aprenderás a crear e implementar tu primera Dapp en Ethereum.

Como siempre, si tienes alguna pregunta o encuentras algún error en este artículo, házmelo saber en los comentarios :)

Discussion (0)