Web3 ha sido tendencia desde principios de 2022, al igual que los NFT explotaron el año pasado. Aún así, la noción de construir aplicaciones descentralizadas para casos de uso convencionales como Facebook, Instagram y Google ha sido una larga ambición de la comunidad criptográfica.
Sin embargo, mientras que algunas empresas de blockchain ya han desarrollado algunas DApps, la industria Web3 solo recientemente ha comenzado a ganar popularidad. En este artículo, crearemos un sistema de seguimiento de adopción para una tienda de mascotas en Ethereum desde cero.
Índice de contenido:
Resumen (TL;DR)
- Web3 ha sido tendencia desde principios de 2022, al igual que los NFT explotaron el año pasado.
- No se requiere experiencia previa en herramientas de solidez y desarrollo de blockchain como Ganache, Truffle, etc.
- Una DApp es una aplicación de software que opera en una red distribuida.
- Necesitamos instalar VS Code, NodeJS, Git, Truffle y Ganache.
- Después de eso, estableceremos nuestro entorno de desarrollo utilizando la Truffle Box, es decir, la tienda de mascotas.
- El siguiente paso es crear un contrato inteligente utilizando la solidez.
- Compilaremos el contrato inteligente usando el comando truffle compile y luego lo migraremos usando el comando truffle migrate.
- Crearemos un archivo TestAdoption.sol para probar nuestro contrato inteligente junto con el comando truffle test.
- Crearemos una interfaz de usuario con Web3.js y algún código existente en la caja de trufas.
- Por último, interactuaremos con nuestra DApp utilizando MetaMask y Ganache.
Planteamiento del problema
Tomemos el ejemplo de Pete. Pete es propietario de una tienda de mascotas en Nueva Delhi, India.
Como podemos ver, la tecnología Blockchain y la criptomoneda están ganando aceptación general. El 1 de febrero de 2022, la ministra de Finanzas, Nirmala Sitharaman, anunció que el Banco de la Reserva de la India emitiría una rupia digital utilizando la tecnología Blockchain a partir de 2022-23.
Este es un paso positivo en la dirección de la adopción de criptomonedas. Ahora India ha reconocido la tecnología Blockchain.
Así que Pete también está interesado en usar la tecnología Blockchain. Quiere usar la tecnología Blockchain para su tienda. Después de investigar un poco por su cuenta, Pete está fascinado con Ethereum Blockchain y la idea de los contratos inteligentes. Está interesado en usarlo para administrar las adopciones de mascotas de manera más eficiente. Su negocio puede acomodar hasta 16 mascotas en un momento dado. Ya tiene lista una base de datos de mascotas. Pete quiere que alguien cree una DApp para él.
El objetivo de la DApp es conectar una dirección de Ethereum con una mascota para ser adoptada.
Este es un ejemplo de cómo se ve una declaración de problema típica en un negocio de Blockchain. Ahora, pasemos al siguiente paso.
Prerrequisitos
Este artículo está destinado a personas que tienen una comprensión básica de Ethereum y Smart Contracts. Si no tiene conocimientos previos sobre Ethereum, comience desde aquí.
Un poco de experiencia en codificación de HTML y JavaScript ayudará a comprender fácilmente la lógica de codificación. Si alguien es nuevo en DApps o comienza su viaje de desarrollo web, puede seguir fácilmente este artículo. No se requiere experiencia previa en herramientas de solidez y desarrollo de blockchain como Ganache, Truffle, etc. Sin embargo, explicaremos cada paso a medida que avancemos.
Este artículo será útil para todos los novatos, y construiremos una DApp paso a paso. Ahora, pasemos al siguiente paso y entendamos qué es una DApp.
¿Qué es una DApp?
Una aplicación descentralizada es una aplicación de software que opera en una red distribuida. No está alojado en un servidor centralizado, sino en una red descentralizada peer-to-peer como IPFS. Para implementar o interactuar con una DApp, no es necesario revelar ninguna identificación del mundo real.
DApp = FrontEnd + BackEnd de contrato inteligente
El código backend está escrito principalmente en Solidity (o Vyper). Sin embargo, no existe un lenguaje específico para el código frontend. Ahora, pasemos al siguiente paso y entendamos cómo funcionan las DApps.
¿Cómo funcionan las DApps?
En el siguiente diagrama, podemos ver cómo funciona una DApp típica. Ahora profundicemos en este diagrama para entenderlo de una mejor manera.
- Navegador del cliente: Es un navegador normal escrito en HTML, CSS y JS.
- Web3.js: Es una colección de librerías que nos permiten interactuar con un nodo Ethereum local o remoto utilizando HTTP, IPC o WebSocket.
- Proveedor Web3: La red Ethereum contiene nodos, y todos los nodos comparten la misma copia de datos. Establecer un proveedor web3 en web3.js le dice a nuestro código desde qué nodo leeremos y escribiremos datos. Estamos utilizando Metamask en nuestra DApp para inyectar su proveedor web3 en el navegador.
- Máquina virtual Ethereum (EVM): Cada nodo Ethereum en la red tiene su implementación EVM y es responsable de ejecutar las mismas instrucciones de Contrato Inteligente a través de la red.
Instalación de dependencias
Hay algunos requisitos técnicos antes de comenzar a crear DApp. En esta sección, instalaremos todas las dependencias requeridas.
1. Instalación de VS Code
En primer lugar, necesitamos un IDE, es decir, un entorno de desarrollo integrado. Un IDE permite a los programadores simplificar el proceso de construcción de un programa informático. Aumenta la productividad de un programador al fusionar tareas típicas de desarrollo de software, como editar código fuente, crear ejecutables y depurar en un solo lugar.
Usaremos Visual Studio Code en nuestro artículo. Es un editor de código fuente ligero ideal para el uso diario con características como resaltado de sintaxis, coincidencia de corchetes, sangría automática, selección de cuadros, fragmentos, etc. Combina la facilidad de uso de un editor de código fuente con características avanzadas de desarrollo, como la finalización y depuración de código IntelliSense. Está disponible para macOS, Linux y Windows.
2. Instalación de NodeJS y npm
En segundo lugar, necesitamos un entorno de tiempo de ejecución. Usaremos NodeJS y npm. npm viene con NodeJS.
Node.js es un entorno de tiempo de ejecución de JavaScript que es de código abierto y multiplataforma. Es una herramienta muy utilizada para casi cualquier proyecto. Es una plataforma de lenguaje ligera, escalable y de código abierto que facilita la creación de aplicaciones a nivel corporativo. Npm contiene paquetes que utilizamos en nuestras aplicaciones para acelerar y mejorar el proceso de desarrollo.
3. Instalación de Git
En tercer lugar, necesitamos Git. Es un sistema de control de versiones distribuido gratuito y de código abierto diseñado para administrar todo con velocidad y eficiencia. Mantiene los cambios que hacemos en los archivos, por lo que tenemos un registro de lo que se ha hecho.
4. Instalación de trufa
En cuarto lugar, necesitamos trufa. Es un entorno de desarrollo de clase mundial, un marco de pruebas y una canalización de activos para blockchains basado en la Máquina Virtual Ethereum (EVM).
Para descargar Truffle, siga esta guía paso a paso.
- Paso 1: Abra VS Code.
- Paso 2: Haga clic en Terminal.
- Paso 3: Haga clic en Nuevo terminal.
- Paso 4: Pegue este comando en el terminal.
npm install -g truffle
- Paso 5: Para comprobar que Truffle está instalado correctamente, pega este comando en el terminal.
truffle version
5. Instalación de Ganache
Por último, necesitamos Ganache. Es una cadena de bloques local para el desarrollo rápido de aplicaciones Ethereum y Corda. Podemos usar Ganache a lo largo de todo el ciclo de desarrollo: desarrollo, implementación y prueba de DApps en un entorno seguro. Todas las versiones de Ganache están disponibles para Windows, Mac y Linux.
Ganache está disponible en dos modos: GUI y CLI. Ganache UI es una aplicación de escritorio compatible con Ethereum y Corda. Ganache CLI solo está disponible para el desarrollo de Ethereum.
En este artículo, usaremos Ganache CLI porque es simple y fácil de usar. Para descargar Ganache CLI, siga esta guía paso a paso.
- Paso 1: Abra VS Code.
- Paso 2: Haga clic en Terminal.
- Paso 3: Haga clic en Nuevo terminal.
- Paso 4: Pegue este comando en el terminal.
npm install ganache –global
- Paso 5: Para iniciar Ganache, pegue este comando en el terminal.
ganache
Ahora tenemos instaladas todas las dependencias. El siguiente paso es configurar y optimizar nuestro entorno de desarrollo.
Configuración del entorno de desarrollo
En esta sección, configuraremos nuestro entorno de desarrollo. Para configurar el entorno de desarrollo, siga esta guía paso a paso.
- Paso 1: Vaya a VS Code y cree una carpeta pet-shop-tutorial.
- Paso 2: Ahora haga clic derecho en pet-shop-tutorial y haga clic en Abrir en terminal integrado.
El equipo de Truffle ha creado Truffle Boxes. Estos son los repetitivos que contienen módulos útiles, contratos y bibliotecas de solidez, vistas front-end y mucho más.
- Paso 3: En este artículo, usaremos una Truffle Box, es decir, una tienda de mascotas, que incluye la estructura básica del proyecto y el código para la interfaz de usuario. Pegue este comando en el terminal.
truffle unbox pet-shop
Después de ejecutar el comando anterior, el comando descargará los archivos que podemos ver en la imagen de arriba.
- Método alternativo para el paso 3: Si alguien desea crear la interfaz de usuario desde cero pero quiere una trufa repetitiva. Pegue este comando en el terminal.
truffle init
- Paso 4: Instalaremos la extensión VS Code Solidity de Juan Blanco para escribir código Solidity en VS Code. Abra VS Code y vaya a Extensiones en la barra lateral derecha y haga clic en él. Busca Solidez y haz clic en Extensión, cuyo autor es Juan Blanco. Haga clic en Instalar.
Ahora nuestro entorno de desarrollo se ha creado con éxito. El siguiente paso es crear un contrato inteligente.
Creación de Smart Contract
En esta sección, crearemos un contrato inteligente para nuestra DApp. Esta lógica actuará como backend y almacenamiento para nuestra DApp. Para crear un contrato inteligente, siga esta guía paso a paso.
Paso 1: Vaya al directorio de contratos en la carpeta pet-shop-tutorial
Este directorio contendrá nuestro código de contrato inteligente escrito en solidez. Ahora Cree un nuevo archivo Adoption.sol.
Paso 2: Ahora, comenzaremos a escribir nuestro código de solidez
Pegue este código en el archivo Adoption.sol.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract Adoption {
}
Ahora, entenderemos el significado del código escrito anteriormente.
- SPDX-License-Identifier: GPL-3.0 : Solidity versión 0.6.8 ha introducido identificadores de licencia SPDX, lo que permite a los desarrolladores definir la licencia que utiliza el contrato. Los desarrolladores deben agregar esto en la parte superior. Si esto falta en el archivo de contrato, el compilador mostrará una advertencia. Además, si el archivo de contrato tiene varios identificadores de licencia, el compilador mostrará un error.
- > de solidez pragma=0,4,0 <0,9,0; : Este comando indica al compilador que el código fuente está escrito para las versiones 0.4.0 a 0.9.0 de Solidity. La palabra clave pragma se utiliza para habilitar las características y comprobaciones del compilador.
- contract Adoption {} : Este comando especifica la recopilación de código y datos en una dirección específica en la cadena de bloques de Ethereum.
Paso 3: Ahora, declararemos una variable para nuestro contrato inteligente
Pegue este código después de la adopción del contrato { en el archivo Adoption.sol.
address[16] public adopters;
Ahora, entenderemos el significado del código escrito anteriormente.
- address[16] : Esta declaración es una matriz de direcciones de Ethereum. Las matrices contienen un tipo y pueden tener una longitud fija o variable. En este caso, el tipo es dirección y la longitud es 16.
- público: Las funciones públicas son parte de la interfaz del contrato y se pueden llamar externa o internamente. Para las variables de estado público, se genera una función getter automática.
- adopters : Esta declaración es una variable que es un contenedor para almacenar valor.
Paso 4: Ahora, agregaremos la función adopt() a nuestro contrato inteligente
Necesitamos una función que permita a los usuarios realizar sus solicitudes de adopción. Así que crearemos una función adopt(). Pegue este código después de la declaración de variable en el archivo Adoption.sol.
// Adopting a pet
function adopt(uint256 petId) public returns (uint256) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
Ahora, entenderemos el significado del código escrito anteriormente.
- function adopt(uint256 petId) public returns (uint256) {} : Tenemos que especificar los parámetros de función y los tipos de salida en Solidity. En este caso, tomamos la entrada petId como un entero y la devolvemos como un entero. Para saber más sobre Funciones en Solidity, haga clic aquí.
- require(petId >= 0 && petId <= 15); : Estamos utilizando la función require() para comprobar si petID está dentro del rango. Como las matrices se indexan desde 0 en Solidity, estamos tomando el valor petID entre 0 y 15.
- adopters[petId] = msg.sender; : Si el ID se encuentra dentro del rango, la función agrega la dirección que realizó la llamada a la matriz de adoptantes. msg.sender denota la dirección de la persona o contrato inteligente que llamó a esta función.
- devolver petId; : Estamos devolviendo el petId como salida.
Paso 5: Ahora, agregaremos la función getAdopters() a nuestro contrato inteligente
Necesitamos una función para recuperar a los adoptantes. Esta función debería actualizar todos los estados de adopción de mascotas. Así que crearemos una función getAdopters(), que devuelve toda la matriz. Pegue este código después de la función adopt() en el archivo Adoption.sol.
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
Ahora, entenderemos el significado del código escrito anteriormente.
- function getAdopters() public view devuelve (address[16] memory) {} : La explicación de la declaración de función es similar al paso 4. La palabra clave view indica que la función no cambiará el estado del contrato. memory especifica la ubicación de datos de la variable.
- devolver adoptantes: Dado que ya hemos declarado la variable adoptantes en el paso 3. Podemos devolverlo.
Paso 6: Aquí está nuestro código de solidez completo
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract Adoption {
address[16] public adopters;
// Adopting a pet
function adopt(uint256 petId) public returns (uint256) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
}
Ahora nuestro contrato inteligente se ha creado con éxito. El siguiente paso es compilar el contrato inteligente.
Compilación de Smart Contract
En esta sección, compilaremos nuestro contrato inteligente. Ya que Solidity es un lenguaje compilado. Por lo tanto, debemos compilarlo en bytecode antes de que el EVM pueda ejecutarlo. Para compilar el contrato inteligente, siga esta guía paso a paso.
- Paso 1: Vaya a la carpeta pet-shop-tutorial de VS Code. Ahora haga clic derecho en él y haga clic en Abrir en la terminal integrada.
- Paso 2: Pegue este comando en el terminal. Este comando compilará todos los contratos en el directorio de contratos.
truffle compile
Después de ejecutar el comando anterior, veremos la salida como se muestra en la imagen de abajo.
Ahora nuestro contrato inteligente se ha compilado con éxito. El siguiente paso es migrar el contrato inteligente.
Migración de Smart Contract
En esta sección, migraremos nuestro contrato inteligente. Las migraciones son archivos JavaScript que ayudan a implementar contratos en la red Ethereum. Para migrar el contrato inteligente, siga esta guía paso a paso.
Paso 1: Vaya al directorio de migraciones en la carpeta pet-shop-tutorial.
Veremos que un archivo JavaScript ya está presente, es decir, 1 migración inicial.js. Este archivo controla la implementación del contrato inteligente Migrations.sol. Necesitamos un archivo similar para nuestro contrato Adoption.sol. Crearemos un nuevo archivo, es decir, 2_deploy_contracts.js, similar a nuestro 1_initial_migration.js. La parte de codificación será similar en ambos archivos. Los únicos cambios serán las funciones require() e deploy(). Aquí escribiremos Adopción en lugar de Migraciones. Pegue este código en el archivo 2_deploy_contracts.js.
var Adoption = artifacts.require(«Adoption»);
module.exports = function(deployer) {
de
Paso 2: Ahora es el momento de ejecutar Ganache.
Necesitamos tener una cadena de bloques operativa antes de migrar nuestro contrato inteligente a ella. Como se discutió anteriormente, usaremos Ganache CLI. También ahora necesitaremos dos terminales. El primero será para los comandos de Ganache, y el segundo será para los comandos de trufa. Así que tenemos que abrir nuestros terminales integrados dos veces. Para iniciar Ganache, pegue este comando en el terminal.
ganache
Este comando creará una cadena de bloques que operará localmente en el puerto 8545.
Paso 3: Ahora, cambiaremos el número de puerto
La principal diferencia entre Ganache GUI y CLI es que Ganache GUI se ejecuta en el puerto 7545, pero Ganache CLI se ejecuta en el puerto 8545. Así que ahora cambiaremos el número de puerto en el archivo truffle-config.js, que está presente en la parte inferior de la carpeta pet-shop-tutorial.
Paso 4: Ahora, es hora de migrar el contrato inteligente a la cadena de bloques
Pegue este comando en el terminal. Este comando migrará todos los contratos del directorio de migraciones.
truffle migrate
Después de ejecutar el comando anterior, veremos la salida como se muestra en la imagen de abajo.
Ahora, si volvemos a Ganache, podemos ver que el estado de la cadena de bloques ha cambiado. La cadena de bloques ahora muestra el bloque número 4. Anteriormente, era 0.
Ahora nuestro contrato inteligente ha migrado con éxito. El siguiente paso es probar el contrato inteligente.
Probar el contrato inteligente
En esta sección, probaremos nuestro contrato inteligente. Probar un contrato inteligente es esencial porque un error puede costar millones de dólares. Para probar el contrato inteligente, siga esta guía paso a paso.
Paso 1: Vaya al directorio de prueba en la carpeta pet-shop-tutorial
Este directorio contendrá código escrito en solidez para pruebas de contratos inteligentes. Ahora cree un nuevo archivo TestAdoption.sol. Pegue este código en el archivo TestAdoption.sol.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
import «truffle/Assert.sol»;
import «truffle/DeployedAddresses.sol»;
import «../contracts/Adoption.sol»;
contract TestAdoption {
Adoption adoption = Adoption(DeployedAddresses.Adoption());
uint expectedPetId = 8;
address expectedAdopter = address(this);
}
Ahora, entenderemos el significado del código escrito anteriormente.
- importar «trufa/Assert.sol»; : Estamos importando Assert.sol desde el directorio global de trufas. Nos da varias comprobaciones de aserción para usar en nuestras pruebas.
- importar «trufa/DeployedAddresses.sol»; : Estamos importando DeployedAddresses.sol desde el directorio global truffle. Truffle desplegará una nueva instancia del contrato que se está probando en la cadena de bloques cuando se ejecuten las pruebas. Este archivo obtiene la dirección del contrato implementado.
- importar «.. /contracts/Adoption.sol»; : Estamos importando Adoption.sol desde el directorio de contratos ya que este es el contrato inteligente en el que queremos realizar pruebas.
- Adopción adopción = Adopción(DeployedAddresses.Adoption()); : Este código contiene la dirección del contrato inteligente que se va a probar, es decir, el contrato de adopción.
- uint expectedPetId = 8; : Esta variable contiene el ID de mascota esperado, que el contrato TestAdoption utilizará para las pruebas.
- dirección expectedAdopter = dirección(esto); : Establecemos la dirección de adoptante esperada en esto, que recupera la dirección del contrato actual porque el contrato TestAdoption enviará la transacción al contrato de adopción.
Paso 2: Ahora, probaremos la función adopt()
Pegue este código después de la declaración de expectedPetId en el archivo TestAdoption.sol.
// Testing the adopt() function
function testUserCanAdoptPet() public {
uint returnedId = adoption.adopt(expectedPetId);
Assert.equal(returnedId, expectedPetId, «Adoption of the expected pet should match what is returned.»);
}
Ahora, entenderemos el significado del código escrito anteriormente.
- uint returnedId = adoption.adopt(expectedPetId); : Llamamos al contrato inteligente previamente declarado, es decir, contrato de adopción con el ID esperadoPetId.
- Assert.equal(returnedId, expectedPetId, «La adopción de la mascota esperada debe coincidir con lo que se devuelve.»); : Pasamos el valor real, es decir, returnedId, el valor esperado, es decir, expectedPetId y un mensaje de error que se imprime si la prueba falla en la función Assert.equal().
Paso 3: Ahora, probaremos la recuperación del dueño de una sola mascota
Pegue este código después de la función testUserCanAdoptPet() en el archivo TestAdoption.sol.
// Testing retrieval of a single pet’s owner
function testGetAdopterAddressByPetId() public {
address adopter = adoption.adopters(expectedPetId);
Assert.equal(adopter, expectedAdopter, «Owner of the expected pet should be this contract»);
}
Ahora, entenderemos el significado del código escrito anteriormente.
- address adopter = adoption.adopters(expectedPetId); Estamos obteniendo la dirección del adoptante almacenada por el contrato de adopción después de pasar elPetId esperado.
- Assert.equal(adopter, expectedAdopter, «El dueño de la mascota esperada debe ser este contrato»); Estamos pasando el valor real, el valor esperado y un mensaje de error que se imprime si la prueba produce un error en la función Assert.equal().
Paso 4: Ahora, probaremos la recuperación de todos los dueños de mascotas
Pegue este código después de la función testGetAdopterAddressByPetId() en el archivo TestAdoption.sol.
// Testing retrieval of all pet owners
function testGetAdopterAddressByPetIdInArray() public {
address[16] memory adopters = adoption.getAdopters();
Assert.equal(adopters[expectedPetId], expectedAdopter, «Owner of the expected pet should be this contract»);
}
Ahora, entenderemos el significado del código escrito anteriormente.
- address[16] adoptantes de memoria = adoption.getAdopters(); : Estamos almacenando a los adoptantes en la memoria en lugar del almacenamiento del contrato.
- Assert.equal(adopters[expectedPetId], expectedAdopter, «El dueño de la mascota esperada debe ser este contrato»); : Estamos pasando el valor real, el valor esperado y un mensaje de error que se imprime si la prueba da como resultado un error en la función Assert.equal().
Paso 5: Aquí está nuestro código de solidez completo
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
import «truffle/Assert.sol»;
import «truffle/DeployedAddresses.sol»;
import «../contracts/Adoption.sol»;
contract TestAdoption {
// The address of the adoption contract to be tested
Adoption adoption = Adoption(DeployedAddresses.Adoption());
// The id of the pet that will be used for testing
uint256 expectedPetId = 8;
// Testing the adopt() function
function testUserCanAdoptPet() public {
uint256 returnedId = adoption.adopt(expectedPetId);
Assert.equal(returnedId, expectedPetId, «Adoption of the expected pet should match what is returned.»);
}
// Testing retrieval of a single pet’s owner
function testGetAdopterAddressByPetId() public {
address adopter = adoption.adopters(expectedPetId);
Assert.equal(adopter, expectedAdopter, «Owner of the expected pet should be this contract»);
}
// Testing retrieval of all pet owners
function testGetAdopterAddressByPetIdInArray() public {
// Store adopters in memory rather than contract’s storage
address[16] memory adopters = adoption.getAdopters();
Assert.equal(adopters[expectedPetId], expectedAdopter, «Owner of the expected pet should be this contract»
);
}
// The expected owner of adopted pet is this contract
address expectedAdopter = address(this);
}
Paso 6: Ahora, es hora de probar el contrato inteligente
Pegue este comando en el terminal.
truffle test
Después de ejecutar el comando anterior, veremos la salida como se muestra en la imagen de abajo.
Ahora nuestro contrato inteligente se ha probado con éxito. El siguiente paso es crear una interfaz frontend para nuestra DApp.
Creación de una interfaz de usuario para smart contract
En esta sección, crearemos una interfaz de usuario. El código para el front-end de la DApp también está en la trufa de la tienda de mascotas. Está presente en el interior del directorio src. Solo agregaremos aquellas funciones que son exclusivas de Ethereum. Para crear una interfaz de usuario para un contrato inteligente, siga esta guía paso a paso.
Paso 1: Creación de instancias de web3
Vaya al archivo app.js en el directorio de prueba de la carpeta pet-shop-tutorial. Ahora, elimine el comentario de varias líneas de la función initWeb3() y pegue el código a continuación.
// {Part 1}
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.request({ method: «eth_requestAccounts» });;
} catch (error) {
// User denied account access…
console.error(«User denied account access»)
}
}
// {Part 2}
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// {Part 3}
else {
App.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:8545’);
}
web3 = new Web3(App.web3Provider);
Ahora, entenderemos el significado del código escrito anteriormente.
- Parte 1, es decir, si condición: Estamos comprobando si usamos navegadores DApp donde se inyecta un proveedor de ethereum en el objeto de la ventana. Lo usamos para crear nuestro objeto web3, pero también necesitamos solicitar acceso a las cuentas explícitamente con ethereum.enable().
- Parte 2, es decir, otra condición si: Si el objeto ethereum no existe, verificamos si hay una instancia web3 inyectada. Si existe, esto indica que estamos utilizando un navegador DApp más antiguo. Así que obtenemos su proveedor y lo usamos para crear nuestro objeto web3.
- Parte 3, es decir, otra condición: Si no hay una instancia web3 inyectada, creamos nuestro objeto web3 utilizando nuestro proveedor local.
Paso 2: Creación de instancias del contrato
Necesitamos crear instancias de nuestro contrato inteligente, para que web3 entienda dónde encontrarlo y cómo funciona. Ahora, elimine el comentario de varias líneas de la función initContract() y pegue el código a continuación.
$.getJSON(‘Adoption.json’, function(data) {
// Get the necessary contract artifact file and instantiate it with @truffle/contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
// Set the provider for our contract
App.contracts.Adoption.setProvider(App.web3Provider);
// Use our contract to retrieve and mark the adopted pets
return App.markAdopted();
});
Ahora, entenderemos el significado del código escrito anteriormente.
- var AdoptionArtifact = datos; : Estamos recuperando el archivo Artifact para nuestro contrato inteligente.
- App.contracts.Adoption = TruffleContract(AdoptionArtifact); : Ahora pasaremos el archivo Artifact a TruffleContract(), que crea una instancia del contrato con la que interactuar.
- App.contracts.Adoption.setProvider(App.web3Provider); : Estableceremos el proveedor web3 del contrato utilizando el valor App.web3Provider que almacenamos anteriormente al configurar web3.
- return App.markAdopted(); : Llamaremos a la función markAdopted() si las mascotas ya están adoptadas de una visita anterior.
Paso 3: Obtener las mascotas adoptadas y mejorar la interfaz de usuario
Ahora, elimine el comentario de varias líneas de la función markAdopted() y pegue el código a continuación.
// Part 1
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
return adoptionInstance.getAdopters.call();
// Part 2
}).then(function(adopters) {
for (i = 0; i < adopters.length; i++) {
if (adopters[i] !== ‘0x0000000000000000000000000000000000000000’) {
$(‘.panel-pet’).eq(i).find(‘button’).text(‘Success’).attr(‘disabled’, true);
}
}
}).catch(function(err) {
console.log(err.message);
});
Ahora, entenderemos el significado del código escrito anteriormente.
- Parte 1: Declararemos la variable adoptionInstance fuera de las llamadas del contrato inteligente para acceder a la instancia fácilmente después de recuperarla por primera vez. Después de esto, usaremos la función call(), que nos permite leer datos de la cadena de bloques sin una transacción.
- Parte 2: Después de llamar a la función getAdopters(), usaremos el bucle for para verificar si se almacena una dirección para cada mascota. Por último, comprobamos todos los errores posibles.
Paso 4: Manejo de la función adopt()
Ahora, elimine el comentario de varias líneas de la función handleAdopt y pegue el código a continuación.
// Part 1
var adoptionInstance;
web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
}
var account = accounts[0];
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
// Execute adopt as a transaction by sending account
return adoptionInstance.adopt(petId, {from: account});
}).then(function(result) {
// Part 2
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
});
Ahora, entenderemos el significado del código escrito anteriormente.
- Parte 1: Usaremos web3 para recuperar las cuentas de usuario. Después de la comprobación de errores, seleccionamos la primera cuenta en la devolución de llamada. Después de eso, obtendremos el contrato implementado y almacenaremos la instancia en adoptionInstance. Luego enviaremos una transacción en lugar de una llamada. Las transacciones requieren una dirección de origen y tienen un costo asociado. Enviamos la transacción ejecutando la función adopt() con petID y un objeto que contiene la dirección de la cuenta, es decir, la cuenta.
- Parte 2: El objeto de transacción es el resultado del envío de una transacción. Si no se producen problemas, ejecutamos nuestra función markAdopted() para sincronizar la interfaz de usuario con nuestros datos recién almacenados.
Paso 5: Aquí está el código completo del archivo .js la aplicación
App = {
web3Provider: null,
contracts: {},
init: async function() {
// Load pets.
$.getJSON(‘../pets.json’, function(data) {
var petsRow = $(‘#petsRow’);
var petTemplate = $(‘#petTemplate’);
for (i = 0; i < data.length; i ++) {
petTemplate.find(‘.panel-title’).text(data[i].name);
petTemplate.find(‘img’).attr(‘src’, data[i].picture);
petTemplate.find(‘.pet-breed’).text(data[i].breed);
petTemplate.find(‘.pet-age’).text(data[i].age);
petTemplate.find(‘.pet-location’).text(data[i].location);
petTemplate.find(‘.btn-adopt’).attr(‘data-id’, data[i].id);
petsRow.append(petTemplate.html());
}
});
return await App.initWeb3();
},
initWeb3: async function() {
// Modern dapp browsers…
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.request({ method: «eth_requestAccounts» });;
} catch (error) {
// User denied account access…
console.error(«User denied account access»)
}
}
// Legacy dapp browsers…
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:7545’);
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON(‘Adoption.json’, function(data) {
// Get the necessary contract artifact file and instantiate it with @truffle/contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
// Set the provider for our contract
App.contracts.Adoption.setProvider(App.web3Provider);
// Use our contract to retrieve and mark the adopted pets
return App.markAdopted();
});
return App.bindEvents();
},
bindEvents: function() {
$(document).on(‘click’, ‘.btn-adopt’, App.handleAdopt);
},
markAdopted: function() {
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
return adoptionInstance.getAdopters.call();
}).then(function(adopters) {
for (i = 0; i < adopters.length; i++) {
if (adopters[i] !== ‘0x0000000000000000000000000000000000000000’) {
$(‘.panel-pet’).eq(i).find(‘button’).text(‘Success’).attr(‘disabled’, true);
}
}
}).catch(function(err) {
console.log(err.message);
});
},
handleAdopt: function(event) {
event.preventDefault();
var petId = parseInt($(event.target).data(‘id’));
var adoptionInstance;
web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
}
var account = accounts[0];
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
// Execute adopt as a transaction by sending account
return adoptionInstance.adopt(petId, {from: account});
}).then(function(result) {
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
Ahora nuestra interfaz de usuario se ha creado con éxito. El siguiente paso es interactuar con DApp.
Interacción con DApp
Este es el paso final. En esta sección, interactuaremos con DApp. Para interactuar con la DApp, sigue esta guía paso a paso.
Paso 1: Instalación de MetaMask
MetaMask es una billetera criptográfica y una puerta de enlace Web3 a las DApps de blockchain. Actualmente está disponible como una extensión del navegador y una aplicación móvil en dispositivos Android e iOS. Para descargar MetaMask, siga esta guía paso a paso.
Paso 2: Agregar Ganache a MetaMask
Ahora, conectaremos MetaMask a la cadena de bloques creada por Ganache CLI. Haga clic en el icono que muestra Ethereum Mainnet. A continuación, veremos una opción para Añadir Red. Haga clic en el botón Agregar red.
Ahora, agregaremos los siguientes parámetros que se detallan a continuación y haremos clic en Guardar.
- Nombre: Ganache
- RPC-URL: http://127.0.0.1:8545
- ID de cadena: 1337
Después de guardar, veremos esta pantalla como se muestra a continuación. Cada cuenta creada por Ganache CLI recibe 1000 ether. Notaremos menos éter ya que se usó algo de gas cuando implementamos el contrato y ejecutamos las pruebas.
Paso 3: Ejecutar la DApp
Ahora es el momento de ejecutar nuestra DApp. Iremos a la segunda Terminal. Este comando iniciará un nuevo servidor web local y abrirá una nueva pestaña del navegador con nuestra DApp. Pegue este comando en el terminal.
npm run dev
Después de ejecutar el comando anterior, veremos la salida como se muestra en la imagen de abajo.
Paso 4: Uso de la DApp
- Ahora, es el momento de usar nuestra DApp. Adoptaremos a Gina. Haga clic en el botón Adoptar.
- Aparecerá una notificación de Metamask y verá una transacción. Ahora, haga clic en confirmar.
- Veremos una nueva notificación para la transacción confirmada.
- Ahora, si volvemos a la sección de actividad de la cartera MetaMask podemos ver una transacción.
- Si volvemos a nuestra DApp. Podemos ver que el botón de adopción ahora se cambia al éxito.
Conclusión
Hemos tratado de explicar todo desde cero de una manera paso a paso. Hemos dado explicaciones y razonamientos para cada paso. Estamos contentos por todos los que han leído este artículo y han creado esta DApp desde cero sin experiencia previa en el desarrollo de DApp. Crearemos una nueva y emocionante DApp desde cero en el próximo tutorial. Todos los créditos del código utilizado pertenecen a Truffle Documentation.
Preguntas formuladas con frequently
¿Cuáles son algunas DApps famosas?
CryptoMines, Bomb Crypto, Splinterlands y Axie Infinity son algunas DApps populares en el mercado.
¿Cómo gana dinero DApp?
Las DApps pueden ganar dinero a través del lanzamiento de una ICO, anuncios, tarifas de transacción, suscripciones, etc., y mucho más.
¿Tienen futuro las DApps?
Las DApps continuarán expandiéndose a un ritmo exponencial en el futuro. Aunque este proceso llevará tiempo, se proyecta que 2022 verá mejoras significativas y la propagación de la tecnología blockchain y sus aplicaciones.
¿Por qué Web3 es el futuro?
La privacidad es la mayor preocupación para los usuarios habituales en 2022. En Web3, los usuarios tendrán la propiedad completa de sus activos. A diferencia de ahora, donde los gigantes tecnológicos controlan la mayoría de las plataformas.
¿Dónde podemos encontrar DApps?
Podemos encontrar todas las DApps populares en DApp Radar. Es una de las mejores tiendas DApp disponibles en el mercado.