Creación de redes Blockchain con Substrate

Creación de redes Blockchain con Substrate

Introducción

En este artículo presentamos una framework para desarrollar redes Blockchain de manera rápida, sencilla y customizada. No entraremos en una explicación exhaustiva de lo que es una red blockchain pero destacaremos algunas características.

¿Qué es una blockchain?

De forma básica, una blockchain es una estructura de datos donde los bloques de datos estan linkados formando una cadena ordenada. Los detalles específicos de una blockchain depende de la funcionalidad que ofrezca. A alto nivel, debe tener una serie de características:

Bloques

Cada bloque en una cadena de bloques tiene algunos datos que se pueden usar para generar un identificador único para ese bloque. Una parte de estos datos es el identificador único del bloque anterior, conocido como “bloque principal”. Dado que cada bloque tiene un puntero a su bloque padre, los bloques se pueden ordenar de forma determinista. Cualquier pequeño cambio en los datos de un bloque cambiará su ID único. Dado que el ID de este bloque cambió, el bloque que viene después (el “bloque secundario”) también cambiará. Esto significa que es fácil verificar que dos cadenas de bloques tengan exactamente los mismos datos simplemente verificando el identificador único del último bloque de la cadena.

Bloques

Porducción de bloques

Debido a estas propiedades, los sistemas blockchain se utilizan comúnmente para realizar un seguimiento de un libro mayor compartido (shared ledger). El contenido del libro mayor no se cambia cambiando un bloque existente, sino agregando nuevos bloques a la cadena de bloquesa través de lo que denominamos transacciones.

Una vez que se recopila un conjunto válido de transacciones, se colocan en el contenido de un bloque, y luego este bloque se coloca al final de la cadena. Este proceso de producción de bloques permite que el estado subyacente de la cadena de bloques cambie con el tiempo.

Transacciones

Nodos

Las redes blockchain están diseñadas para ser distribuidas y descentralizadas. Diferentes usuarios pueden hacer un seguimiento de las transacciones y el shared ledger sin intermediarios. Siguiendo las reglas anteriores, cada participante de este libro de contabilidad compartido puede ejecutar un nodo, que es un programa informático que sigue las reglas de la red blockchain y se conecta a otros nodos que hacen lo mismo, todo sin la necesidad de un servicio centralizado. Los sistemas blockchain son a menudo sistemas “abiertos”, lo que significa que cualquiera puede participar. Para prevenir contra actores malintencionados, se implementan mecanismos para incentivar el buen comportamiento mientras se castiga el mal comportamiento.

Para aprender más sobre redes blockchain podeis revisar estos videos: https://anders.com/blockchain/

Framework Substrate

Substrate es un framework open source, modular y extensible que se utiliza para crear redes Blockchain. Esta vinculado al desarrollo de parachains en la red Polkadot, pero puede usarse de forma independiente. En este caso, no profundizaremos en la arquitectura de red Polkadot, pero es dejamos esta introducción para que la conozcais. Básicamente se trata de una red que crea un entorno interoperable entre redes blockchain y permite el despliegue de parachains, que son redes blockchain especializadas y con un modelo de gestión propio. Polkadot se ha desarrollado usando Substrate y intenta proponer un modelo escalable y interoperable entre multitud de redes blockchain.

A la hora de afrontar la creación de una red blockchain debemos plantear qué necesitamos para crear una red Blockchain propia. Usaremos el framework Substrate que nos ofrece:

Arquitectura

  • Base de datos distribuida:

Uutilizado para hacer persistente el estado de la cadena de bloques. Usa un mecanismo sencillo de clave-valor, muy eficiente y no hace suposiciones sobre el contenido o la estructura de los datos. Técnicamente se implementa un Patricia Merkle tree (trie) modificado

  • Comunicación de red:

Capacidad que permite al cliente comunicarse con otros participantes de la red. Substrate utiliza la implementación de Rust de la pila de red libp2p para establecer la comunicacion entre pares

  • Cola de transacciones:

Las transacciones se recopilan y forman en bloques que finalmente definen cómo cambia el estado de la cadena de bloques. Sin embargo, el orden de estas transacciones puede afectar el estado final del shared ledger. Substrate le permite un control total sobre la dependencia y la gestión de colas de transacciones en la red.

  • Consenso:

La lógica que permite a los participantes de la red ponerse de acuerdo sobre el estado de la cadena de bloques. Substrate permite suministrar motores de consenso personalizados y también incluye varios mecanismos de consenso que se han construido sobre la base de la investigación de Web3 Foundation. Encontramos el desde el tradicional Proof of Work (PoW), Aura (Authority Round), y consenso de Plkadot consensus, que es único por el hecho que separa el proceso de producción de bloques (BASE) con el de finalización (GRANDPA)

Overview

Creación de blockchain con Substrate

Prerequisitos

Siguiendo el tutorial de Substrate crearemos el entorno de trabajo necesario para desplegar nuestro nodo Substrate. Nuestro entorno de pruebas se basa en una Debian 10.

  1. Dependencias
sudo apt update
# May prompt for location information
sudo apt install -y git clang curl libssl-dev llvm libudev-dev
  1. Entorno de desarrollo Rust

Realizaremos la instalación manual del entorno Rust.

# Install
curl https://sh.rustup.rs -sSf | sh

info: downloading installer

Welcome to Rust!

This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.

Rustup metadata and toolchains will be installed into the Rustup
home directory, located at:

  /developer/.rustup

This can be modified with the RUSTUP_HOME environment variable.

The Cargo home directory located at:

  /developer/.cargo

This can be modified with the CARGO_HOME environment variable.

The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:

  /developer/.cargo/bin

This path will then be added to your PATH environment variable by
modifying the profile files located at:

  /developer/.profile
  /developer/.bashrc

You can uninstall at any time with rustup self uninstall and
these changes will be reverted.

Current installation options:


   default host triple: x86_64-unknown-linux-gnu
     default toolchain: stable (default)
               profile: default
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
> 1

info: default host triple is x86_64-unknown-linux-gnu
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2021-06-17, rust version 1.53.0 (53cb7b09b 2021-06-17)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
  6.0 MiB /   6.0 MiB (100 %)   6.0 MiB/s in  1s ETA:  0s
info: installing component 'clippy'
info: installing component 'rust-docs'
 16.1 MiB /  16.1 MiB (100 %)   3.1 MiB/s in  4s ETA:  0s
info: installing component 'rust-std'
 25.3 MiB /  25.3 MiB (100 %)   6.3 MiB/s in  3s ETA:  0s
info: installing component 'rustc'
 48.4 MiB /  48.4 MiB (100 %)  10.6 MiB/s in  4s ETA:  0s
info: installing component 'rustfmt'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu installed - rustc 1.53.0 (53cb7b09b 2021-06-17)


Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).

To configure your current shell, run:
source $HOME/.cargo/env


# Configure
source ~/.cargo/env

Configuramos la última versión estable del entorno (toolchain) de Rust. La toolchain está formada de todas las herramientas necesarias para compilar una aplicación hecha en Rust. Incluye entre otras cosas:

  • El compilador, rustc
  • El gestor de dependencias y constructor, cargo
  • El generador de documentación, rustdoc
  • Librerías estandar para la plataforma
$ rustup default stable
info: using existing install for 'stable-x86_64-unknown-linux-gnu'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.53.0 (53cb7b09b 2021-06-17)

$ rustup update
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: checking for self-updates

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.53.0 (53cb7b09b 2021-06-17)

info: cleaning up downloads & tmp directories

$ rustup update nightly
info: syncing channel updates for 'nightly-x86_64-unknown-linux-gnu'
info: latest update on 2021-06-17, rust version 1.55.0-nightly (a85f584ae 2021-06-16)
info: downloading component 'cargo'
  6.0 MiB /   6.0 MiB (100 %)   4.0 MiB/s in  1s ETA:  0s
info: downloading component 'clippy'
info: downloading component 'rust-docs'
 16.7 MiB /  16.7 MiB (100 %)   4.3 MiB/s in  3s ETA:  0s
info: downloading component 'rust-std'
 22.0 MiB /  22.0 MiB (100 %)   4.1 MiB/s in  5s ETA:  0s
info: downloading component 'rustc'
 50.1 MiB /  50.1 MiB (100 %)   4.2 MiB/s in 11s ETA:  0s
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
 16.7 MiB /  16.7 MiB (100 %)   4.8 MiB/s in  3s ETA:  0s
info: installing component 'rust-std'
 22.0 MiB /  22.0 MiB (100 %)   9.8 MiB/s in  2s ETA:  0s
info: installing component 'rustc'
 50.1 MiB /  50.1 MiB (100 %)  11.3 MiB/s in  4s ETA:  0s
info: installing component 'rustfmt'

  nightly-x86_64-unknown-linux-gnu installed - rustc 1.55.0-nightly (a85f584ae 2021-06-16)

info: checking for self-updates


$ rustup target add wasm32-unknown-unknown --toolchain nightly
info: downloading component 'rust-std' for 'wasm32-unknown-unknown'
info: installing component 'rust-std' for 'wasm32-unknown-unknown'
 13.4 MiB /  13.4 MiB (100 %)  10.0 MiB/s in  1s ETA:  0s

En este punto, tenemos todo lo necesario para poder compilar nuestra primera Substrate Chain

Creación de nuestro nodo Substrate

Una vez tenemos los prerequisitos instalados, podemos utilizar Git para clonar el Substrate Developer Hub Node Template, que sirve de punto de partida para crear nuestro entorno en Susbtrate Lo descargamos y lo compilamos. El tiempo de compilación es considerable. En nuestro entorno de pruebas con 4Gb de RAM asignados, hemos tardado aproximadamente 55 minutos…

$ git clone -b v3.0.0+monthly-2021-05 --depth 1 https://github.com/substrate-developer-hub/substrate-node-template

#Compile the Node Template

$ cd substrate-node-template
$ cargo build --release

  Compiling sc-informant v0.9.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling sc-offchain v3.0.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling sc-finality-grandpa v0.9.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling sc-chain-spec v3.0.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling substrate-wasm-builder v4.0.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling node-template-runtime v3.0.0 (/home/root/devel/chain/substrate-node-template/runtime)
   Compiling rocksdb v0.16.0
   Compiling kvdb-rocksdb v0.11.1
   Compiling sc-client-db v0.9.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling sc-service v0.9.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling sc-cli v0.9.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
   Compiling frame-benchmarking-cli v3.0.0 (https://github.com/paritytech/substrate.git?tag=monthly-2021-05#70ef0afc)
    Finished release [optimized] target(s) in 54m 38s

Una vez finaliza la compiación de la plantilla del nodo, realizamos una prueba para ver su ejecución y comprobar que podemos iniciar correctamente el servicio. Para ejecutar un nodo temporal en modo desarrollo debemos ejecutar dentro la carpeta target: ./target/release/node-template –dev –tmp

Destacamos los flag:

    --dev , setup del nodo en modo developer
    --tmp , esto guarda todos los datos activos para el nodo (ckeys, blockchain database, networking info, ...) y se elimina tan pronto como finaliza correctamente su nodo (usando ctrl + c). Entonces, cada vez que comience con este comando, tendrá un estado inicial desde el que trabajar. Si se mata el nodo, / tmp se limpia automáticamente al reiniciar, y estos archivos se pueden eliminar manualmente si es necesario.
$ /devel/chain/substrate-node-template# target/release/node-template --dev --tmp
2021-06-17 23:01:47 Running in --dev mode, RPC CORS has been disabled.    
2021-06-17 23:01:47 Substrate Node    
2021-06-17 23:01:47 ✌️  version 3.0.0-12d56a7-x86_64-linux-gnu    
2021-06-17 23:01:47 ❤️  by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2021    
2021-06-17 23:01:47 📋 Chain specification: Development    
2021-06-17 23:01:47 🏷 Node name: plastic-trees-8355    
2021-06-17 23:01:47 👤 Role: AUTHORITY    
2021-06-17 23:01:47 💾 Database: RocksDb at /tmp/substrateA0LX14/chains/dev/db    
2021-06-17 23:01:47 ⛓  Native runtime: node-template-100 (node-template-1.tx1.au1)    
2021-06-17 23:01:47 🔨 Initializing Genesis block/state (state: 0x5b57…3fc4, header-hash: 0x406a…3b4f)    
2021-06-17 23:01:47 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.    
2021-06-17 23:01:47 ⏱  Loaded block-time = 6s from genesis on first-launch    
2021-06-17 23:01:47 Using default protocol ID "sup" because none is configured in the chain specs    
2021-06-17 23:01:47 🏷 Local node identity is: 12D3KooWQgSvdqLzxPz6HvshCrLExeCcKaGwH6PUasMUY8n1wGeg    
2021-06-17 23:01:47 📦 Highest known block at #0    
2021-06-17 23:01:47 〽️ Prometheus server started at 127.0.0.1:9615    
2021-06-17 23:01:47 Listening for new connections on 127.0.0.1:9944.    
2021-06-17 23:01:48 🙌 Starting consensus session on top of parent 0x406a6de78cba395e2c1de670230cc7cb16a097677480a57b9e3a650f368e3b4f    
2021-06-17 23:01:48 🎁 Prepared block for proposing at 1 [hash: 0x573d9c8d12ffdd578eac60d004d5a5af52734714e9f96b5d1776bb8f3ab2f20c; parent_hash: 0x406a…3b4f; extrinsics (1): [0x23ac…69ec]]    
2021-06-17 23:01:48 🔖 Pre-sealed block for proposal at 1. Hash now 0x6eaf0a37400480f672e179c5bd6e8ef0f9887d8db1459ab2c56cbf5c2fb79381, previously 0x573d9c8d12ffdd578eac60d004d5a5af52734714e9f96b5d1776bb8f3ab2f20c.    
2021-06-17 23:01:48 ✨ Imported #1 (0x6eaf…9381)    
2021-06-17 23:01:52 💤 Idle (0 peers), best: #1 (0x6eaf…9381), finalized #0 (0x406a…3b4f), ⬇ 0 ⬆ 0    
2021-06-17 23:01:54 🙌 Starting consensus session on top of parent 0x6eaf0a37400480f672e179c5bd6e8ef0f9887d8db1459ab2c56cbf5c2fb79381    
2021-06-17 23:01:54 🎁 Prepared block for proposing at 2 [hash: 0xa5a993522e3489862cef256be47688bc725ff5d5382047159608bfd940aecf21; parent_hash: 0x6eaf…9381; extrinsics (1): [0x8159…cc43]]    
2021-06-17 23:01:54 🔖 Pre-sealed block for proposal at 2. Hash now 0xb59ca468de44bab055d9124ecaee4d16a0053284a69d09144694f120ee149497, previously 0xa5a993522e3489862cef256be47688bc725ff5d5382047159608bfd940aecf21.    
2021-06-17 23:01:54 ✨ Imported #2 (0xb59c…9497)    
2021-06-17 23:01:57 💤 Idle (0 peers), best: #2 (0xb59c…9497), finalized #0 (0x406a…3b4f), ⬇ 0 ⬆ 0    
2021-06-17 23:02:00 🙌 Starting consensus session on top of parent 0xb59ca468de44bab055d9124ecaee4d16a0053284a69d09144694f120ee149497    
2021-06-17 23:02:00 🎁 Prepared block for proposing at 3 [hash: 0x0f1e55e0e140518ba10a74295d6a32371a73d4ff9bccf57dab8be9d8232836cf; parent_hash: 0xb59c…9497; extrinsics (1): [0xeec9…a5d3]]    
2021-06-17 23:02:00 🔖 Pre-sealed block for proposal at 3. Hash now 0xdc904d6b296790e481c1c5bf4231f1985bb378a58d8e563ae2516e9ff27cec5e, previously 0x0f1e55e0e140518ba10a74295d6a32371a73d4ff9bccf57dab8be9d8232836cf.    
2021-06-17 23:02:00 ✨ Imported #3 (0xdc90…ec5e)   
2021-06-17 23:03:32 💤 Idle (0 peers), best: #18 (0xb672…c9e2), finalized #16 (0x9831…e305), ⬇ 0 ⬆ 0    
2021-06-17 23:03:36 🙌 Starting consensus session on top of parent 0xb6727dec0148656d6c5541a3b3bfc3935a9060b30ecfd3d34ae6861ae0bbc9e2    
2021-06-17 23:03:36 🎁 Prepared block for proposing at 19 [hash: 0xa120887a6cb64d5ec567546d5a3b34ae1f5ba28731d092f1e62a12acf716e587; parent_hash: 0xb672…c9e2; extrinsics (1): [0x9768…8b89]]    
2021-06-17 23:03:36 🔖 Pre-sealed block for proposal at 19. Hash now 0xf0021b5622ff55c341ffa26c590f628cbe54273a2a55906864250ea43a7d66a7, previously 0xa120887a6cb64d5ec567546d5a3b34ae1f5ba28731d092f1e62a12acf716e587.    
2021-06-17 23:03:36 ✨ Imported #19 (0xf002…66a7)    
2021-06-17 23:03:37 💤 Idle (0 peers), best: #19 (0xf002…66a7), finalized #16 (0x9831…e305), ⬇ 0 ⬆ 0    
2021-06-17 23:03:42 🙌 Starting consensus session on top of parent 0xf0021b5622ff55c341ffa26c590f628cbe54273a2a55906864250ea43a7d66a7    
2021-06-17 23:03:42 🎁 Prepared block for proposing at 20 [hash: 0x4a935f0758ac23310cf260e1a0b7185f3e28ac974f0de4a60b568eee4ce08df9; parent_hash: 0xf002…66a7; extrinsics (1): [0xd9cd…ced4]]    
2021-06-17 23:03:42 🔖 Pre-sealed block for proposal at 20. Hash now 0x914e305921c46e59f84e76903b90b2e43fe4fbc17023bf8beccf629013b65a79, previously 0x4a935f0758ac23310cf260e1a0b7185f3e28ac974f0de4a60b568eee4ce08df9.    
2021-06-17 23:03:42 ✨ Imported #20 (0x914e…5a79)    
2021-06-17 23:03:42 💤 Idle (0 peers), best: #20 (0x914e…5a79), finalized #17 (0xc43a…b121), ⬇ 0 ⬆ 0    

Revisión básica de pruebas:

  • Crece el valor de finalized. Buscamos en el log mostrado en la consola y revisamos que el valor va aumentando.
2021-06-17 23:03:32 💤 Idle (0 peers), best: #18 (0xb672…c9e2), finalized #16 (0x9831…e305), ⬇ 0 ⬆ 0 
2021-06-17 23:03:42 💤 Idle (0 peers), best: #20 (0x914e…5a79), finalized #17 (0xc43a…b121), ⬇ 0 ⬆ 0  
  • Podemos ver la Base de Datos creada en /tmp
Database: RocksDb at /tmp/substrateA0LX14/chains/dev/db    
  • Revisamos el identificador del nodo. Buscamos el identificador del nodo en el log de la consola.
Local Node 2021-06-17 23:01:47 🏷 Local node identity is: 12D3KooWQgSvdqLzxPz6HvshCrLExeCcKaGwH6PUasMUY8n1wGeg    

Interactuar con nuestro nodo Substrate

Para interactuar con el nodo utilizaremos dos mecanismos diferentes:

  • La aplicación PolkadotJS
  • El template que propone Substrate para interactuar con el nodo

PolkadotJS

Para poder en prodcución una aplicación que utilizase nuestro nodo Substrate deberíamos proporcionar una interficie gráfica construida específicamente para gestionar la dApp. En entornos de prueba o para validar funcionalidades genéricas del nodo podemos usar la herramienta PolkadotJS

Pasos:

  1. Clonar el repositorio localmente, via git clone https://github.com/polkadot-js/apps
  2. Asegurar que tenemos una versión de Node.js instalada > 10.13
  3. Asegurar que tenemos una versión de Yarn instalada >= 1.10.1
  4. Instalar dependencias usando yarn
  5. Lanzar UI a través de yarn run, asegurando que nuestro nodo Substrate está operativo.
  6. Acceder a la UI via http://localhost:3000
$ git clone https://github.com/polkadot-js/apps/

Clonando en 'apps'...
remote: Enumerating objects: 323179, done.
remote: Counting objects: 100% (2229/2229), done.
remote: Compressing objects: 100% (407/407), done.
Recibiendo objetos:  46% (151376/323179), 765.47 MiB | 112.00 KiB/s   
remote: Total 323179 (delta 1947), reused 2070 (delta 1822), pack-reused 320950
Recibiendo objetos: 100% (323179/323179), 838.28 MiB | 1.23 MiB/s, listo.
Resolviendo deltas: 100% (292580/292580), listo.

$cd apps 
$yarn

➤ YN0013: │ zip-stream@npm:4.1.0 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ zwitch@npm:1.0.5 can't be found in the cache and will be fetched from the remote registry
➤ YN0066: │ typescript@patch:typescript@npm%3A4.3.2#~builtin<compat/typescript>::version=4.3.2&hash=34ad7d: Cannot apply hunk #2
➤ YN0000: └ Completed in 6m 24s
➤ YN0000: ┌ Link step
➤ YN0062: │ fsevents@patch:fsevents@npm%3A2.3.2#~builtin<compat/fsevents>::version=2.3.2&hash=1cc4b2 The platform linux is incompatible with this module, link skipped.
➤ YN0062: │ fsevents@patch:fsevents@npm%3A2.1.3#~builtin<compat/fsevents>::version=2.1.3&hash=1cc4b2 The platform linux is incompatible with this module, link skipped.
➤ YN0062: │ dmg-license@npm:1.0.9 The platform linux is incompatible with this module, link skipped.
➤ YN0062: │ iconv-corefoundation@npm:1.1.6 The platform linux is incompatible with this module, link skipped.

➤ YN0062: │ fsevents@patch:fsevents@npm%3A2.3.2#~builtin<compat/fsevents>::version=2.3.2&hash=1cc4b2 The platform linux is incompatible with this module, link skipped.
➤ YN0062: │ fsevents@patch:fsevents@npm%3A2.1.3#~builtin<compat/fsevents>::version=2.1.3&hash=1cc4b2 The platform linux is incompatible with this module, link skipped.
➤ YN0062: │ dmg-license@npm:1.0.9 The platform linux is incompatible with this module, link skipped.
➤ YN0062: │ iconv-corefoundation@npm:1.1.6 The platform linux is incompatible with this module, link skipped.
➤ YN0007: │ electron@npm:12.0.11 must be built because it never did before or the last one failed
➤ YN0007: │ highlight.js@npm:9.18.5 must be built because it never did before or the last one failed
➤ YN0007: │ core-js@npm:2.6.12 must be built because it never did before or the last one failed
➤ YN0007: │ secp256k1@npm:3.8.0 must be built because it never did before or the last one failed
➤ YN0007: │ @fortawesome/fontawesome-common-types@npm:0.2.35 must be built because it never did before or the last one failed
➤ YN0007: │ core-js@npm:3.8.1 must be built because it never did before or the last one failed
➤ YN0007: │ core-js-pure@npm:3.8.1 must be built because it never did before or the last one failed
➤ YN0007: │ bufferutil@npm:4.0.2 must be built because it never did before or the last one failed
➤ YN0007: │ utf-8-validate@npm:5.0.3 must be built because it never did before or the last one failed
➤ YN0007: │ node-hid@npm:2.1.1 must be built because it never did before or the last one failed
➤ YN0007: │ usb-detection@npm:4.10.0 must be built because it never did before or the last one failed
➤ YN0007: │ tiny-secp256k1@npm:1.1.6 must be built because it never did before or the last one failed
➤ YN0007: │ polkadot-apps@workspace:. must be built because it never did before or the last one failed
➤ YN0007: │ @fortawesome/fontawesome-svg-core@npm:1.2.35 must be built because it never did before or the last one failed
➤ YN0007: │ @fortawesome/free-solid-svg-icons@npm:5.15.3 must be built because it never did before or the last one failed
➤ YN0000: └ Completed in 2m 2s
➤ YN0000: Done with warnings in 8m 28s


$yarn start
$ polkadot-dev-clean-build 
<i> [webpack-dev-server] Project is running at http://[::]:3000/
<i> [webpack-dev-server] Content not from webpack is served from /home/developer/chain/apps/packages/apps/
.....
.....
<i> 8 modules
<i> webpack 5.38.1 compiled successfully in 147912 ms
<i> [webpack-dev-middleware] Compiled successfully.

Abrimos el navegador y accedemos, en nuestro caso, desde el propio host a http://localhost:3000.

Overview

En esta pantalla vemos la genereación de bloques, los eventos que se produczcan y un conjunto de menús que nos dan acceso a las herramientas de gestión básicas para interactuar con nuestro nodo.

Para asegura que estamos conectados con nuestro nodo local, podemos revisar la conexión:

Connection

Como se observa estamos conectados al nodo local. Podŕiamos cambiar de nodo y conectarnos a otras redes (parachain), incluso productivas de Polkadot o de Kusama.

Por defecto, el nodo de Substrate incorpora una serie de cuentas para realizar pruebas. Desde la propia interficie podemos revisar qué cuentas están en el nodo y cuanto balance tiene la cartera (wallet). Igualmente podemos probar de transferir fondos entre las cuentas y ver como se modifican estos balances.

Accounts

Ejemplo de aplicación para enviar fondos entre dos cuentas.

Balance

La interficie nos permite interactuar de manera directa con el nodo realizando diferentes llamadas y comprobando resultados. Esto es muy útil si se quiere verificar funcionalidades desarrolladas antes de ponerlas en producción. En el ejemplo, llamada para obtener información de una cuenta.

API

Otro caso de uso típico es la firma de contenido por parte de una cuenta del nodo. A través de la propia UI podemos acceder a esta funcionalidad.

Sign

En el menú Desarrollo, se despliegan múltiples funcionalidades para validar y interrogar al nodo y las diferentes funcionalidades que pueda integrar

Developer

Como observar, podemos interactuar de forma rápida y sencilla con nuestro nodo Substrate a través de la UI.

Para desarrollar nuestra propia UI podemos consultar la Polkadot-JS API Documentation

Front-End-Template

Otra forma de interactuar con nuestro nodo es creando una propia UI específica para gestionar la aplicación que vayamos a desarrollar. Substrate nos ofrece una plantilla para que tengamos un ejemplo de UI y cómo desarrollarla. Es lo que denominan Front-end-template, y necesita Yarn y Node.js.

Pasos:

  1. Clonar el repositorio localmente, via git clone https://github.com/substrate-developer-hub/substrate-front-end-template
  2. Asegurar que tenemos una versión de Node.js instalada > 10.13
  3. Asegurar que tenemos una versión de Yarn instalada >= 1.10.1
  4. Instalar dependencias usando yarn
  5. Lanzar UI a través de yarn run, asegurando que nuestro nodo Substrate está operativo.
  6. Acceder a la UI via http://localhost:8000
$git clone -b v3.0.0+monthly-2021-05 --depth 1 https://github.com/substrate-developer-hub/substrate-front-end-template

$cd substrate-front-end-template
$yarn install

YN0000: ┌ Resolution step
➤ YN0002: │ react-dev-utils@npm:11.0.4 doesn't provide typescript (p79ddf), requested by fork-ts-checker-webpack-plugin
➤ YN0002: │ react-dev-utils@npm:11.0.4 doesn't provide webpack (p2af19), requested by fork-ts-checker-webpack-plugin
➤ YN0000: │ Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code
➤ YN0000: └ Completed in 0s 650ms
➤ YN0000: ┌ Fetch step
➤ YN0013: │ yargs-parser@npm:13.1.2 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ yargs-parser@npm:18.1.3 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ yargs@npm:13.3.2 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ yargs@npm:15.4.1 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ yocto-queue@npm:0.1.0 can't be found in the cache and will be fetched from the remote registry
➤ YN0000: └ Completed in 1m 4s
➤ YN0000: ┌ Link step
➤ YN0062: │ fsevents@patch:fsevents@npm%3A2.3.2#builtin<compat/fsevents>::version=2.3.2&hash=11e9ea The platform linux is incompatible with this module, link skipped.
➤ YN0062: │ fsevents@patch:fsevents@npm%3A1.2.13#builtin<compat/fsevents>::version=1.2.13&hash=11e9ea The platform linux is incompatible with this module, link skipped.
➤ YN0007: │ core-js@npm:3.13.0 must be built because it never did before or the last one failed
➤ YN0007: │ core-js@npm:2.6.12 must be built because it never did before or the last one failed
➤ YN0007: │ bufferutil@npm:4.0.3 must be built because it never did before or the last one failed
➤ YN0007: │ utf-8-validate@npm:5.0.5 must be built because it never did before or the last one failed
➤ YN0007: │ node-hid@npm:2.1.1 must be built because it never did before or the last one failed
➤ YN0007: │ usb-detection@npm:4.10.0 must be built because it never did before or the last one failed
➤ YN0007: │ tiny-secp256k1@npm:1.1.6 must be built because it never did before or the last one failed
➤ YN0007: │ core-js-pure@npm:3.13.0 must be built because it never did before or the last one failed
➤ YN0007: │ ejs@npm:2.7.4 must be built because it never did before or the last one failed
➤ YN0000: └ Completed in 32s 404ms
➤ YN0000: Done with warnings in 1m 37s
# RUNNING

$ yarn start

Accedemos a través del navegador a la url local: http://localhost:8000

Template

Template

Para ver el funcionamiento podemos jugar haciendo una transferencia de fondos entre dos cuentas. En el visor de eventos aparecerá la transferencia

balances:Transfer:: (phase={"applyExtrinsic":1})-7
AccountId: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY, AccountId: 5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y, Balance: 1000000000000
Transfer succeeded. \[from, to, value\]

Resumen

  • Creación de nodo Substrate de Prueba
  • Creación de UI PolkadotJS
  • Creación de UI con plantilla

A partir de aquí, podemos ir desarrollando nuestras aplicaciones distribuidas. Algunas ideas para realizar:

  • Añadir nodos a nuestra red
  • Crear funcionalidad para notarizar eventos y a partir de aquí crear servicios de comunicación certificados y distribuidos
  • Evaluar funcionalidad NFT …

En próximos artículos iremos desarrollando algunos de estos puntos.


See also