Despliegue De Web ÐApp Con Quorum+Angular+Python+Flask En Un VPS Con Ubuntu 16.04 [4]

Este artículo es la cuarta parte de una serie dedicada al desarrollo de una ÐApp en Quorum. El primer artículo está dedicado a la configuración de un nodo de Quorum, el segundo trata sobre Solidity, el lenguaje de programación utilizado en Ethereum para programar smart contracts y la tercera parte está dedicada a Python, el lenguaje usado para la parte back-end de la ÐApp. En esta cuarta entrega vamos a explicar el desarrollo de la parte front-end con TypeScript y Angular, junto con su posterior despliegue en IPFS.

Despliegue de web ÐApp con Quorum+Angular+Python+Flask en un VPS con Ubuntu 16.04
[1] [Quorum]
[2] [Solidity]
[3] [Python]
[4] [Angular]

TypeScript es un lenguaje de programación orientado a objetos y con tipado estático opcional. Es un superset de JavaScript que se transpila a este lenguaje.

Angular es un framework programado en TypeScript que facilita el desarrollo de aplicaciones web. Es totalmente distinto de su antecesor AngularJS.

IPFS (InterPlanetary File System) es un protocolo distribuido peer-to-peer que permite almacenar archivos, los cuales son identificados por un hash. En nuestro caso desplegaremos la parte front (HTML, CSS y JS) de nuestra Ðapp en IPFS.

Lo primero que haremos sera instalar Node.js:


curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - after sudo apt-get install -y nodejs

Posteriormente utilizaremos npm como gestor de paquetes:


apt-get install npm

Una vez de que hayamos seguido estos pasos, dentro del directorio raíz del proyecto ejecutaremos el siguiente comando, que hará que se instalen todas las dependencias que necesita la parte front de la ÐApp para funcionar:


$ npm install
npm WARN deprecated nodemailer@2.7.2: All versions below 4.0.1 of Nodemailer are deprecated. See https://nodemailer.com/status/
npm WARN deprecated socks@1.1.9: If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.0
npm WARN deprecated mailcomposer@4.0.1: This project is unmaintained
npm WARN deprecated node-uuid@1.4.8: Use uuid module instead
npm WARN deprecated buildmail@4.0.1: This project is unmaintained

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN @angular/animations@6.1.8 requires a peer of @angular/core@6.1.8 but none is installed. You must install peer dependencies yourself.
npm WARN bootstrap@4.1.3 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself.
npm WARN bootstrap@4.1.3 requires a peer of popper.js@^1.14.3 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

added 1214 packages in 184.247s

Si todo ha funcionado correctamente ejecutaremos el comando:


$ ng serve
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
                                                                                          
Date: 2018-09-24T20:39:51.567Z
Hash: 7323fb42d67392adde82
Time: 14204ms
chunk {main} main.js, main.js.map (main) 43 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 227 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 5.22 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 188 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 4.03 MB [initial] [rendered]
ℹ 「wdm」: Compiled successfully.

En el módulo principal se encuentran todas las dependencias necesarias para el funcionamiento del proyecto:

En el módulo core se encuentra el servicio DataService que es el encargado de realizar las operaciones básicas REST (GET, POST, PUT DELETE):

El siguiente módulo sería AppRoutingModule, que se encargaría de enrutamiento de la aplicación:

El controlador utiliza reactive forms para la construcción del formulario. Los métodos del controlador son los eventos desencadenados al pulsar sobre los distintos botones. La lógica que tiene cada uno de ellos básicamente consiste en recoger los datos escritos por el usuario en el formulario para después suscribirse a un observable que se encuentra en los servicios ContractsService y BooksService, que será el encargado de invocar al método correspondiente del DataService y emitir un resultado. Si el observable emite datos se muestra un mensaje por pantalla con información al usuario, en caso contrario se muestra un mensaje de error:

En el servicio ContractsService se encuentra el método de creación y despliegue del smart contract:
contracts.service.ts

• ContractsService
◦ compileContract no recibe parámetros y retorna un observable de tipo any
Por último, BooksService es donde se localizan los métodos observables que son los encargados de invocar a los distintos endpoints expuestos por el controlador flask-Python del back-end el cual enlaza con las funciones de los smart contracts de GiveLibAck:

• BooksService
◦ createBook recibe como parámetros el código ISBN y el nombre del libro, retorna un observable de tipo any
◦ getBooksByOwner no recibe parámetros y retorna un observable de tipo any
◦ lendBook recibe como parámetros la dirección a la que debe ser prestado y el tokenId, retorna un observable de tipo any
◦ returnBook recibe como parámetro el tokenId y retorna un observable de tipo any

Estos serían los pasos para usar la aplicación:

En primer lugar se despliega el contrato pulsando sobre el botón correspondiente:

En segundo lugar se crea un libro pasandole un ISBN y un nombre:

En tercer lugar se realiza la búqueda de los libros devolviendo la dirección del dueño del libro:

El siguiente paso sería prestar un libro donde se introduce en el campo correspondiente la dirección del destinatario del libro:

Por último, se producidiría la devolución del libro prestado:

Finalmente para desplegar la ÐApp en IPFS habría que ejecutar previamente el comando de inicialización:

ipfs init

Después desde Angular se genera la build:

$ ng build

Esto creará un directorio dist con el HTML, CSS y JS de la ÐApp.
Para desplegarlo se utiliza el comando:

$ ipfs add -r dist

Posteriormente la aplicación ya puede ser accedida a través de Infura en la URL correspondiente, en nuestro caso:
https://ipfs.infura.io/ipfs/QmRMcacKdbKAFyoejrQ3eHztT4LE8a9zSSDVGJVABWseii/