Cree un chat descentralizado utilizando JavaScript y Rust (ensamblaje web)

Cree e implemente su propio chat descentralizado en solo cien líneas de código usando Wavelet.

Por lo tanto, el equivalente de un servidor de API HTTP NodeJS y una base de datos MySQL en este tutorial sería un contrato inteligente Rust y Wavelet (nuestra cadena de bloques).

Comencemos a construir un contrato inteligente para nuestro chat Dapp. Si aún no lo ha hecho, debe instalar Rust, junto con un backend del compilador WebAssembly para Rust, que puede instalarse ejecutando el siguiente comando:

❯ agregar objetivo de eliminación de datos wasm32-desconocido-desconocido

Inmediatamente después, proceda a crear su primer proyecto de Rust ejecutando el siguiente comando y dedique un poco de tiempo a buscar la forma de instalar dependencias / bibliotecas de terceros en su proyecto de Rust.

❯ carga nuevo –lib chat; cd chat

Las dependencias para la creación de contratos inteligentes de Wavelet están disponibles en el repositorio de paquetes de Rust crates.io aquí y aquí.

Debes tener tu archivo de configuración del proyecto Cargo.toml mira algo como esto:

Ahora que estamos todos configurados, permítame darle una explicación: aquí está el código fuente de nuestro contrato descentralizado de chat inteligente.

73 líneas de código. Eso es bastante (podría hacerse más pequeño tbh). Para explicar un poco lo que está pasando aquí:

El contrato inteligente expone dos funciones a las que nuestra interfaz puede llamar: get_messages ()y enviar_mensaje (msg: cadena).

los Cuerda param para enviar mensaje(…) se lee usando el param.read () función al declarar el entrada variable. Para obtener más detalles sobre cómo se especifican las entradas en los contratos inteligentes, haga clic aquí.

Los registros de chat se almacenan en un VecDeque (una cola de dos extremos donde puede empujar elementos al frente de la cola o al final de la cola), que se inicializa en en eso().

Cada registro de chat contiene un ID de remitente y un mensaje. La ID del remitente es una clave pública criptográfica de la persona que envió el mensaje de chat.

Llama enviar mensaje(…) para colocar un registro de chat en la cola de registros. Los mensajes de chat vacíos no están permitidos, y los mensajes de chat pueden tener un máximo de 240 caracteres.

La cola de registros tiene una capacidad máxima de 50 entradas de registro de chat. Si la cola está llena cuando se inserta un nuevo registro de chat en la cola, la cola elimina el mensaje más antiguo usando logs.pop_front (). Esta lógica se maneja en el prune_old_messages () función.

Puedes llamar get_messages () para obtener una versión fácil de leer de un chatlog. Los ID del remitente se imprimen como una cadena hexadecimal y se concatenan con el contenido del mensaje del remitente.

Entonces un ¡Iniciar sesión!() macro se utiliza para que el contrato inteligente proporcione a su interfaz todos los mensajes de chat disponibles de get_messages ().

Ahora construyamos nuestro contrato inteligente utilizando la herramienta de carga de Rust:

❯ construcción de carga – lanzamiento – objetivo wasm32-desconocido-desconocido

… y si todo va bien, en la carpeta target / wasm32-unknown-unknown / release, verá un archivo chat.wasm.

Ese es su contrato inteligente, listo para ser implementado en la cadena de bloques de Wavelet.

Necesitamos acceso a una red de blockchain de Wavelet para implementar nuestro contrato de chat inteligente.

No temas, organizamos uno para que pruebes tus contratos inteligentes. Dirígete a https://lens.perlin.net/ y te enfrentarás con esta pantalla de inicio de sesión.

Genere una nueva clave privada, guarde su clave privada, cargue una clave privada previamente guardada; luego proceder a iniciar sesión.

En caso de que no sepa qué es una clave privada, considérela como su contraseña. Asociada a su clave privada es una clave pública, que puede considerar como su nombre de usuario.

En un blockchain, existe el concepto de cuentas. Usted registra una cuenta generando una nueva clave privada que está asociada de manera única a una clave pública (que también llamamos una dirección de billetera).

Mientras no entregues tu clave privada, será muy difícil para un hacker robar tu cuenta. Así que mantenga su clave privada segura. Es lo que le da acceso a lo que puede considerar su identidad pública / nombre de usuario.

Proceder a Iniciar sesióny accederás a tu cuenta de Wavelet. Tomar nota de la Dirección del monedero En la parte superior izquierda, siendo su clave pública.

Felicidades Acaba de registrar su primera billetera / cuenta Wavelet.

Para un poco de fondo:

Cada cuenta tiene PERLs, o lo que algunos de ustedes pueden saber como una moneda virtual / criptomoneda.

Por lo tanto, puede pensar en su cuenta como una cartera que contiene PERLs (de ahí que la clave pública sea lo que llamamos una dirección de billetera).

La razón por la que tenemos esta moneda es porque no hay almuerzo gratis: los nodos que soportan la red Wavelet (en este caso, el que hospedamos) están dispuestos a hospedar / mantener vivo su contrato inteligente a cambio de algunos PERL.

La forma en que esto funciona es que cada vez que alguien llama enviar mensaje(…) en su contrato, deben pagar algunos PERL a la red de Wavelet.

Afortunadamente, proporcionamos una forma fácil para que usted o sus amigos obtengan algunos PERL de prueba en la red que hemos alojado para que pueda probar su aplicación de chat.

Para obtener algunos PERL, hemos configurado un servidor Discord al que puede unirse aquí. En el servidor en el canal # wavelet-faucet, escriba:

$ reclamación (su clave pública / dirección de billetera aquí)

Un robot enviaría 300,000 PERL a la dirección de su billetera proporcionada. Escriba el mensaje un par de veces más, hasta que tenga alrededor de 500,000 PERLs, y debería estar listo.

Dirigirse a la Desarrollador página en la pantalla, presione el botón 75% en el Límite de gas cuadro, y subir tu archivo chat.wasm allí.

Después de hacer clic en el botón "75%" después de alcanzar 500,000 PERLs de Discord.

Espera unos segundos y deberías ver tu ID de contrato inteligente. Asegúrese de anotarlo / guardarlo para más tarde, ya que lo necesitaremos para interactuar con nuestro contrato inteligente en nuestra interfaz.

Asegúrese de anotar su ID de contrato inteligente.

Y así, con solo presionar un botón, nuestro contrato inteligente ya está disponible. Trabajemos ahora en una interfaz para mejorar nuestra aplicación de chat descentralizada.

No recomendaré ningún framework en particular como React o Vue o Svelte, ni te enseñaré a diseñar tu aplicación; es totalmente de usted. En esta sección, analizaré los conocimientos básicos que necesita para conectar el diseño de su sitio web a Wavelet.

Para comenzar, cada nodo de Wavelet en la red aloja una API HTTP a la que podemos conectarnos para interactuar con / consultar información del libro mayor.

El punto final de la API, en particular para la red que alojamos para todos ustedes, que usó para registrar su cuenta y desplegar su contrato inteligente, es el siguiente enlace: https://testnet.perlin.net

Proporcionamos un cliente de JavaScript agradable y sencillo para interactuar con una API HTTP de nodos Wavelet, que funciona tanto en la web como en NodeJS.

En npm es wavelet-client, con el código fuente para que sea un solo archivo ubicado en Github aquí: https://github.com/perlin-network/wavelet-client-js

Ahora, asumiendo que tiene configurado el soporte async / await, podemos configurar wavelet-client de la siguiente manera:

Simplemente, lo que hace este código es dejarnos:

conéctese a la red de Wavelet, cargue nuestro monedero proporcionando nuestra clave privada para que podamos pagar los honorarios de uso de nuestro contrato inteligente y construya una instancia de contrato que proporcione métodos para ayudarnos a interactuar con nuestro contrato inteligente.

Antes de continuar, una cosa a tener en cuenta es que de los dos métodos de contrato inteligentes que definimos:

solo uno de ellos modifica el blockchain para insertar un nuevo registro de chat, mientras que el otro solo consulta el blockchain para recuperar todos los registros de chat realizados hasta el momento.

Es bueno saber que:

Los únicos métodos de contrato inteligentes por los que tiene que pagar los PERL de los nodos para ejecutar son los que modifican la cadena de bloques.

Así, como ejemplo, la get_messages () Se puede llamar a la función sin incurrir en ningún costo de PERL para su cuenta. Puedes llamarlo así:

Desde el código anterior, puede que se pregunte de inmediato: ¿qué es esto adicional? JSBI.BigInt (0) parámetro proporcionado?

Al llamar a un contrato inteligente, además de pasar parámetros de entrada, también puede enviar simultáneamente al contrato algunos de sus PERL.

Una razón por la que querría esta funcionalidad es porque, por ejemplo, podría hacer que ciertos métodos de contrato inteligentes solo se ejecuten si se deben enviar 500 PERL al contrato de antemano.

En este caso, no queremos enviar a nuestro contrato inteligente ningún PERL (solo estamos haciendo una aplicación de chat) al invocar get_messages (); por lo que simplemente establecemos la cantidad de PERL para enviar al contrato a cero.

Ahora, después de ejecutar el código anterior, debería ver lo siguiente en la consola de su navegador: {"result": null, "logs": ()}

Para explicar los resultados de la consola, qué ¡Iniciar sesión!(…) La macro, que usamos en la construcción de nuestro contrato inteligente, es colocar los registros como cadenas en la matriz de "registros".

Por otro lado, el objeto "resultado" está configurado para ser el resultado / error devuelto por su función de contrato inteligente.

Por lo tanto, como todavía no hemos enviado ningún mensaje de chat, la matriz de "registros" está vacía y el objeto "resultado" es nulo.

Sólo después de que llamemos enviar mensaje Un par de veces y volver a llamar get_messages ¿Veremos entonces nuestros mensajes en la matriz de "registros"?

Cavando un poco más, debería estar interesado en saber cómo contrato.prueba Funciona, lo que hace detrás de escena es:

descargue la última memoria de sus contratos inteligentes desde el nodo al que está conectado, cargue el código de contratos inteligentes y la memoria en la máquina virtual de su navegador, y ejecute localmente get_messages () Función y devuelve todos los registros y resultados impresos.

Ahora, hablemos de llamar al enviar_mensaje (msg: cadena) función. Como puede adivinar, llamar a esta función modifica la cadena de bloques al colocar el mensaje deseado en la cadena de bloques y, por lo tanto, cuesta los PERL.

La forma en que puede llamarse con el cliente Wavelet JS es bastante similar al código para get_messages ():

Todo es igual, excepto que usted pasa su billetera como primer parámetro, y especifica su mensaje como un parámetro de entrada codificado como un objeto así:

{escriba: "cadena", valor: "¡Su mensaje de chat aquí!"}

Solo para publicarlo, si alguna vez realiza una función de contrato inteligente fuera del alcance de este tutorial que solicita múltiples parámetros, puede pasar múltiples parámetros de entrada como una lista variada a la contrato.call funciona como tal:

Ahora, al igual que lo extraño JSBI.BigInt (0) pasado, usted podría preguntarse cuál es el segundo JSBI.BigInt (250000) pasado en es para.

Para asegurarse de no gastar demasiado PERLs ejecutando accidentalmente su función, puede establecer un límite a la cantidad de PERLs que puede intentar gastar en la ejecución de su función de contrato inteligente.

En este caso, lo que el código anterior denota es que su llamada a enviar mensaje() a lo sumo gastaría 250,000 PERLs.

La tarifa de PERL explícita que paga por la ejecución de una cláusula de contrato inteligente modificadora se calcula en función de cuántas instrucciones tiene que ejecutar su contrato inteligente para ejecutar completamente el método de contrato inteligente que desea.

Como pro-tip, intencionalmente proporcioné el límite de tarifa de 250,000 porque parece que la tarifa de límite superior para el envío de mensajes que noté mientras estaba haciendo pruebas es de 250,000 PERLs.

Puede encontrar más detalles sobre la estructura de tarifas cuando se trata de ejecutar métodos de contrato inteligentes aquí.

El último bit que quizás sería bueno tener es actualizar automáticamente los registros de chat cuando se agreguen nuevos registros de chat a la cadena de bloques.

Las actualizaciones se agrupan y luego se publican juntas dentro de Wavelet en lo que se llama una "ronda de consenso". Por lo tanto, cada vez que la cadena de bloques se modifica, después de uno o dos segundos, una "ronda de consenso" finaliza / pasa.

Podemos usar el cliente Wavelet JS para escuchar cuándo finaliza una ronda, descargar la última memoria de contrato inteligente actualizada y volver a ejecutar get_messages () para recopilar los últimos registros de chat con los que podemos actualizar nuestra interfaz con like:

En el código anterior, lo que está sucediendo es que el fetchAndPopulateMemoryPages () La función se llama cada vez que termina una ronda de consenso. La función descarga los últimos datos de memoria de sus contratos inteligentes.

Lo que sigue a continuación es una sola llamada a get_messages (), proporcionándole los últimos registros y resultados que se imprimen directamente en la consola de su navegador.

Así que con todos estos componentes diferentes, ahora tiene una aplicación de chat descentralizada con un espléndido backend y un frontend (con suerte espléndido).

Con suerte, después de un poco de limpieza, se ve algo como esto:

Ingrese su ID de contratos de chat en su interfaz de usuario que hicimos para que usted pueda chatear con sus amigos en https://perlin-network.github.io/decentralized-chat :).

Si no lo hace, de cualquier manera:

Enhorabuena, acaba de hacer su primera, escalable y segura. ¡Wavelet Dapp!

Configuración cero, cero claves API, cero dolores de cabeza de implementación, cero devops y cero preocupaciones sobre la necesidad de administrar una capa de datos escalable, costosa y resistente.

Hay mucho más que explorar, como una gran cantidad de funcionalidades adicionales proporcionadas por el cliente Wavelet JS, junto con un extenso conjunto de documentación para Wavelet ubicada en https://wavelet.perlin.net.

Ahora, para el lector escéptico, podría señalar: todo este tiempo, estábamos trabajando en la parte superior de una red de Wavelet que en Perlin hemos alojado para la comunidad.

En respuesta, siempre puede enrollar su propia red personal de Wavelet para alojar de forma privada su propia cantidad de Dapps, e incluso hacer que sus amigos se queden con algunas computadoras adicionales que tienen para que puedan contribuir a alojar sus Dapps a cambio de algunos PERL.

Sin embargo, estaremos alojando una red pública y abierta una vez que Wavelet esté completamente estabilizado y se descentralizará por completo. Más noticias vendrán sobre esto en el futuro.

Como nota al margen, lo que se ve en términos de los honorarios por invocar contratos inteligentes que alcanzan los 250,000 PERL no es representativo de lo costoso que serán los contratos inteligentes cuando Wavelet esté completamente descentralizado y abierto al público.

Nuestra idea es que las tarifas de invocación del método de contrato inteligente se sitúen en un rango de menos de un valor de centavos de dólar estadounidense (con respecto a cierta cantidad de PERL) cuando Wavelet se abre al público.

Las tarifas ridículas que ves por el momento no son representativas de cómo serán realmente las tarifas cuando desarrolles con Wavelet una vez que esté totalmente abierta y descentralizada públicamente.

Para dejar de lado algunas notas, lo que personalmente me parece más emocionante es que a pesar de esta conversación descentralizada que hicimos que es increíblemente simple, tiene implicaciones útiles y significativas dadas las numerosas agendas políticas presentes en nuestro mundo actual.

Extendiendo este tutorial un poco más lejos, es bastante sencillo para uno crear su propio Twitter descentralizado, red social, tienda minorista, programador de contenedores, base de datos de valores clave, Redis. De manera realista, sea cual sea el servicio o la plataforma que tenga en mente, podría imaginar que se descentralizaría.

Todo esto solo habiendo sido posible gracias a Wavelet.

Si necesita ayuda, está interesado en saber más o está atascado en cualquier parte del tutorial, no dude en comunicarse conmigo y con nuestro equipo de Perlin en nuestra Discordia aquí.

El código fuente para el tutorial completo está disponible aquí: https://github.com/perlin-network/decentralized-chat

’Hasta la próxima,
Kenta Iwasaki