Dominando Web 3.0 con Waves -Módulo #6

Kolin Platform
Dominando Web3.0 con Waves
10 min readJul 23, 2019

Módulo #6 Lanzamiento de su propia aplicación Web3.0 “Coupon Bazaar”

¡Hola! Estamos en el curso en linea “Dominando Web3.0 con Waves”. Modulo 6 y Final!

En este módulo, hablaremos de:

6.1 Oráculos

6.2 Obteniendo datos desde la cuenta de la API de nodo

6.3 Firmar y publicar transacciones utilizando Waves Keeper

6.4 dApp Web 3.0 Multi-Dominio

Las cadenas de bloques no tienen acceso directo a los datos del mundo exterior. Las blockchains no pueden recuperar, por ejemplo, información como las tasas de cambio de moneda, los pronosticos meteorológicos o los precios del mercado de valores directamente desde Internet.

Los oráculos están aquí para ayudar siendo las interfaces que conectan una cadena de bloques con el mundo exterior.

Un oráculo es un agente, un humano, un grupo de personas o un programa de computadora que envía datos desde el mundo exterior a la cadena de bloques (oráculo de entrada). Los oráculos también se pueden utilizar dentro de contratos inteligentes.

Hay muchos tipos diferentes de oráculos en función de las necesidades de los desarrolladores de dApp y las fuentes de datos. Básicamente, es cualquier información del mundo “exterior” que se registre en la cadena de bloques.

La plataforma Waves permite a los usuarios emitir sus propios oráculos y actuar como un portador de datos, una conexión confiable entre las API web y sus dApps. Los oráculos te permiten escribir datos en la cadena de bloques de acuerdo a ciertas reglas predeterminadas.

Basados en las herramientas provistas, algunos usuarios podrian describir sus protocolos y crear Oráculos, mientras que otros podrian encontrar fácilmente los Oráculos ya creados y construir DApps utilizando estos protocolos.

Link: https://oracles.wavesexplorer.com/

Docs: https://docs.wavesplatform.com/en/waves-oracles/about-waves-oracles.html

Pasos para crear un Oráculo

  1. Cree una cuenta de Waves o use el método GenerateAddress para obtener una nueva dirección junto con las claves públicas y privadas (una dirección puede crear un oráculo). El proveedor también puede usar una cuenta y claves ya existentes.
  2. Instale Waves Keeper para una fácil autorización.
  3. Abra Waves Oracles y eliga crear un Oraculo. Debe ser autorizado por Waves Keeper.
  4. Llene la información del proveedor de datos, cree una especificación y envíe la transacción (data transaction).
  5. Su tarjeta de Oráculo ha sido creada! Ahora su Oráculo tiene una tarjeta pública, que le dirá a otros usuarios qué tipo de datos y en qué formato su Oráculo transferirá informacion desde fuera de la cadena a la cadena de bloques. A continuación, comience a enviar transacciones en cualquier formato conveniente compatible con el protocolo Waves.

Fuente: https://docs.wavesplatform.com/en/waves-oracles/about-waves-oracles.html

Task: cree su propio oráculo y agregue aquí los datos de key-value registrados en la cuenta del oráculo

Como puede observar, un ORACLE es solo una cuenta donde se registran datos estandarizados para ser luego utilizados en otras aplicaciones digitales o activos inteligentes.

Además de la estandarización del Oracle, puede agregar más lógica sobre esta cuenta de Oracle … incluso convertirla en una cuenta dApp con cierta lógica.

Estamos construyendo un mercado descentralizado Web3.0 de cupones : “Coupon Bazaar”. Cada cupón es un activo digital que representa un descuento especial proporcionado por un proveedor.

¿Qué pasa si nuestro proveedor no acepta sus cupones emitidos? A los clientes no les gustará eso y enviarán informes a algún oráculo “verificador”.

Este oráculo puede cambiar el estado del proveedor a VERIFICADO (VERIFIED) o en LISTA NEGRA (BLACKLISTED).

Por lo tanto, ahora nuestro CouponBazaar rechazará cualquier artículo nuevo subido por los proveedores presentes en la Lista Negra (BLACKLISTED).

Por favor cree dos dApps:

1. Oracle-Verifier

2. CouponBazaar utilizando el código del paso anterior e intente agregar un nuevo elemento.

Ponga aquí los datos key — value de la aplicación de CouponBazaar:

Consejo: Oracle-Verifier no ha marcado una cuenta aún como BLACKLISTED o VERIFIED.

Por favor, crea dos dApps:

1. Oracle-Verifier

2. CouponBazaar utilizando el código del paso anterior. Establezca el estado en VERIFICADO usando Oracle-Verifier para algunas cuentas. Intente agregar un nuevo elemento desde una cuenta VERIFICADA.

Ponga aquí los datos key-value de la aplicación de cupón de bazar:

Estamos construyendo un mercado de cupones descentralizado de Web3.0: “Coupon Bazaar”. Los usuarios están buscando descuentos por bienes y servicios que pueden comprar por un pequeño precio en el mercado.

Como puede ver, no hay ningún servidor con una base de datos controlando nuestros artículos/cupones. Todo se almacena en la cadena de bloques en el almacenamiento key-value de la cuenta dApp.

¿Cómo se puede recuperar la matriz de elementos (datos de la cuenta) desde la cadena de bloques para luego ser enviada al entorno JavaScript del cliente?

Ya hemos comenzado a experimentar con el paquete @waves-transaction en módulos anteriores.

Hay muchas funciones API muy útiles para interactuar con el nodo de la blockchain. Echemos un vistazo a la nodeInteraction:

https://github.com/wavesplatform/waves-transactions/blob/master/src/nodeInteraction.ts

Probablemente, ya hayas notado que las cadenas de bloques tienen un valor especial llamado “height”, lo que representa el número de bloques extraídos desde el primer bloque “génesis”. Este valor se utiliza a menudo como una medida de “tiempo” dentro de los contratos inteligentes.

Para obtener la height actual de la blockchain puedes usar:

export declare const currentHeight: (apiBase: string) => Promise<number>;

Para recuperar todos los registros del estado actual de la dApp se puede utilizar:

export declare function accountData(address: string, nodeUrl: string): Promise<Record<string, IDataEntry>>;

También es posible probar y experimentar con los datos de la dApp en la consola del IDE:

export declare function accountDataByKey(key: string, address: string, nodeUrl: string): Promise<IDataEntry>;

P.D.: Si no estás usando JS, puedes usar la API de Nodo directamente: https://nodes.wavesplatform.com/api-docs/index.html#!/addresses/getData_1

Por ejemplo, si está intentando obtener solo datos específicos desde el almacenamiento de la dApp. Usted es libre de definir esta solicitud en forma de un patrón de expresión regular (RegEx):

async _accountDataPattern(matches) {
return await axios.get(`addresses/data/${this.dal.dApp}?matches=${matches}`, {
baseURL: this.nodeUrl,
validateStatus
})
.then(process400)
.then(x => x.data);
}

donde

this.nodeUrl = process.env.APP_NODE_URL || 'https://testnodes.wavesnodes.com';

y el PATTERN puede ser generado desde la lista de keys requeridas ([ “key1”, “key2”, …, “key3” ]).

/**
* Get node data by multiple keys
* @param {string[]} keys
* @returns {Promise<null|string | number | boolean>}
*/
async nodeFetchKeys(keys) {
const regexpKeys = keys.map(key => _escapeRegExp(key));
const regexp = new RegExp('^(' + regexpKeys.join('|') + ')$');
const data = await this.nodeFetchPattern(regexp);
return keys.map(key => data[key] || null);
}

En Web3.0, quienes controlan las SEED controla todas las actividades correspondientes a la CUENTA: transacciones, datos, activos digitales, interacción con los Contratos Inteligentes. Por lo tanto, una SEED debe estar bien protegida y, al mismo tiempo, ser fácil de usar por parte de los clientes.

Waves Keeper es una extensión del navegador que permite a los usuarios administrar sus cuentas (claves) e interactuar de forma segura y sin problemas con los servicios web habilitados para Waves y dApps.

Ya hemos instalado y configurado Waves Keeper en nuestra aplicación Web3.0 en el Módulo 1.

Waves Keeper podría usarse para la firma y publicación de transacciones.

WavesKeeper.signAndPublishTransaction(tx).then((data) => {
// published tx result
}).catch((error) => {
//processing errors
});

Para “sign & publish” (firmar y publicar) una invokeTransaction (invocacion de transaccion) tenemos que crear un objeto tx con los campos adecuados:

let tx = {
type: 16,
data: {
fee: {
assetId: "WAVES",
tokens: "0.005"
},
dApp: "3NBB3iv7YDRsD8xxxxxxV5eTcsfqh3j2mvF",
call:{
function:"additem",
args:[
{type: "string", value: itemId},
{type: "integer", value: 2},
]},
payment: [{tokens: 1, asset: "WAVES"}]
}

ATENCIÓN:

Utilizando una sintaxis similar a la del dinero para los pagos (PAYMENT), esto deberia verse como a continuacion:

{ tokens: 1, assetId: “WAVES” } or

{ coins: 100000000, assetId: “WAVES” } or

{ amount: 100000000, assetId: null }

En ambos mensajes, se indica el mismo precio de 1 WAVES. Puede convertir monedas fácilmente en tokens y viceversa, si sabe en qué activo está indicado el precio y ha recibido la precisión del token = monedas / (10 ** precisión). Si el campo contiene otros tipos distintos a MoneyLike, por ejemplo, string / MoneyLike, la suma se indica como un número en monedas.

Para saber más sobre la API de Waves Keeper lea la documentación:

https://docs.wavesplatform.com/en/waves-api-and-sdk/waves-keeper-api.html

En las páginas del navegador que operan bajo HTTP / HTTPS (no en las páginas locales con file: // protocol) con la extensión Waves Keeper instalada, los objetos globales de Waves Keeper están disponibles, con los siguientes métodos:

  • auth
  • publicState
  • signAndPublishCancelOrder
  • signAndPublishOrder
  • signAndPublishTransaction
  • signCancelOrder
  • signOrder
  • signTransaction
  • signRequest
  • signTransactionPackage
  • on

Todos los métodos, excepto “on” operan de forma asíncrona y devuelven promesas.

A veces tenemos situaciones donde:

1. Tenemos que firmar varias transacciones y publicarlas más tarde pero al mismo tiempo.

En el caso de las transacciones del proveedor: (1) Emitir nuevos tokens: cupones; (2) Agregar Tx de invocación de nuevo elemento: enviar cupones a la cuenta dApp.

2. tenemos que firmar un lote de transacciones al mismo tiempo, pero las publicaremos por separado dependiendo de ciertas condiciones (desencadenantes)

Es el caso para que los clientes voten “a favor” o “en contra” del proveedor: (1) commit tx, (2) reveal tx

Las transacciones que se han firmado, pero que aún no se han publicado, son válidas para su publicación dentro de aprox. 1,5 horas.

Para firmar un lote de transacciones sin publicar usaremos:

let txIssueSigned = await WavesKeeper.signTransaction(txIssue);let txAddItemSigned = await WavesKeeper.signTransaction(txAddItem);

y luego de forma sincronizada llamar(broadcast):

let resultIssue = await nodeInteraction.broadcast(JSON.parse(txIssueSigned), nodeUrl);let resultAddItem = await nodeInteraction.broadcast(JSON.parse(txAddItemSigned), nodeUrl);

ATTENTION: 1 — JSON.parse(…) es requerido aqui. 2 — Puede generar tx.id antes de firmarlo o publicarlo. (ver docs).

o

let txCommitSigned = await WavesKeeper.signTransaction(txCommit);let txRevealSigned = await WavesKeeper.signTransaction(txReveal);

y luego llamar publish commit tx. Guardando “reveal tx” en el almacenamiento local del navegador (localStorage). Extrayendo “reveal tx” de localStorage y transmítiendolo a la cadena de bloques después de que todos los votantes terminen sus pasos de confirmación.

¡Ahora puede desarrollar cualquier lógica de “pipelines” con transacciones dentro del código JS del navegador!

Lo último con respecto a Waves Keeper que vamos a discutir en este módulo: ¿Cómo reconocer a los usuarios que ya se han registrado en su dApp?

Por ejemplo, veamos la página de perfil del proveedor en el CouponBazaar.

Para hacer eso utilizaremos:

WavesKeeper.publicState()
then(state => {
console.log(state); //displaying the result in the console
/*...processing data */
}).catch(error => {
console.error(error); // displaying the result in the console
/*...processing errors */
})

Las direcciones para los usuarios actuales son ingresados en: state.account.address

Desde el Módulo 2, sabemos que hay algunas diferencias entre Web2.0 (antigua) y Web3.0 (nueva) en términos de arquitecturas técnicas.

Los servicios web tradicionales tienen partes de “servidor” y “cliente”. Cuando un usuario abre la página en su navegador, el servidor responde el contenido de una página web estática, HTML, recursos (como imágenes y fuentes) y código JavaScript.

Cuando un usuario interactúa con los componentes de UI de la página web, por ejemplo, botones y formularios, el código JavaScript crea nuevas solicitudes al servidor para obtener más datos que mostrar o escribe datos en la base de datos del servidor.

Después de procesar esta solicitud, el servidor devuelve una respuesta como un formato de datos de key-value JSON. Un navegador utiliza estos datos para cambiar el estado y la vista de la aplicación del cliente.

La Web3.0 funciona de una manera diferente. Por supuesto, la aplicación Web3.0 también requiere del código HTML más JavaScript para poder ejecutarse en el navegador. Entonces, para hacer eso, todavía es necesario el servidor con el código de la UI.

Cuando un usuario interactúa con la UI, se crea una solicitud de “Lectura”. Esta solicitud es procesada por la aplicación de nodos de la DLT/Blockchain. La principal diferencia aquí es que cualquiera puede leer estos datos. Es público al menos en las DLT/BLockchain mas populares.

Lo más importante es saber: cómo escribir información nueva en la red blockchain. Aquí necesitamos los términos de transacción y firma digital.

Todas las actualizaciones en la red de blockchain deben implementarse enviando una transacción, por lo tanto, se requiere la firma digital del iniciador de la transacción.

Como puede ver, la única razón para tener un servidor es simplemente alojar el código JavaScript + HTML para la aplicación del navegador.

Por lo tanto, significa que podemos usar una cuenta dApp con un lado “backend” para muchos sitios web diferentes, con diferentes dominios, código JS + HTML y activos tales como imágenes, gifs, etc.

¡Te deseamos mucha suerte con tus increíbles dApps!

¡Disfruta de la Web3.0!

Felicitaciones, has terminado el curso “Dominando Web3.0 con Waves”

--

--

Kolin Platform
Dominando Web3.0 con Waves

Kolin is an acronym of "Konscienco Lingvo" which in Esperanto means "Conscious Language". https://kolinplatform.com