Una versión escrita de nuestro viaje por la integración NEAR
Empecemos por cuales serian los 3 pilares del Protocolo NEAR:
- Proof of Stake (Prueba de Participación)
- Sharded (Fragmentado, Fragmentación)
- WASM Smart Contracts (Contratos Inteligentes de WebAssembly)
Debido a que el consenso en una blockchain (cadena de bloques) de Proof of Stake se logra mediante el staking y no mediante el minado, Near tiene bloques rápidos de hasta 1 segundo de corta finalidad.
La blockchain al ser fragmentada significa que las llamadas entre contratos son asincrónicas (no debe ser confundido con sincrónicas como en Ethereum o Solana). Cuando se programan contratos en Near se necesita tener la mentalidad de trabajar con actores modelos (o microservicios, pero odio ese término). El requerimiento de asincronicidad es necesario para que los shards sean procesados en paralelo llevando a un mayor rendimiento de transacción. Las Blockchains dónde los contratos inteligentes no son fragmentados simplemente van a chocar contra un techo de escalabilidad, descargando al GPU o ASIC, (Aplicación Específica de Circuito Integrado, mientras sean sincrónicas) lo cual solamente demora horizontalmente la llegada de este techo y no permite llegar a escalabilidad exponencial.
Los contratos en NEAR tienen código WASM, por esto puedes desarrollar en cualquier lenguaje que pueda compilar en WASM. Actualmente AssemblyScript (subconjunto de TypeScript) y RUST son los más respaldados con herramientas de cadena decentes.
DESCARGO DE RESPONSABILIDAD: Esto te va a tomar MENOS de 30 minutos si puedes programar en TypeScript.
Construir una WebApp (Aplicación Web) en el Protocolo NEAR (la cual es exactamente donde accede Near) es muy fácil comparado con otras blockchains
Clonemos el ejemplo del contador aquí: https://github.com/near-examples/counter.
git clone https://github.com/near-examples/counter yarn
La parte principal de nuestro contrato incluye almacenamiento en cadena, control de inicio de sesión para el recibo generado, y funciones públicas exportadas. Las funciones que determinen almacenamiento deben ser llamadas de otra manera para que sean vistas (incluso sin cuenta NEAR).
Near soporta múltiples tipos de colecciones (que se describen a sí mismas) por medio del near-sdk-as.
Las principales que vas a necesitar:
- storage.getPrimitive — get/set
- persistentMap — set/get
- persistentUnorderedMap — set/get/query/length
No incluyo persistentVector ya que deberías intentar evitar usarlo, es muy sencillo quemar toneladas de gas iterando vectores, intenta usar conjuntos cuando sea posible.
Los valores por defecto para colecciones de persistentMap tienen que usar el sufijo !
let balance = myPersistentMap.get("myacc.near", u128.Zero)!
logging.log va a generar una salida de registro en tu recibo cuando invoques una función, esto es útil para control de flujo de lo que pasó, especialmente cuando los contratos se vuelven más complejos. Un ejemplo de un Minting Contract (contrato de minteo) legible por humano puede tener un mensaje de inicio de sesión de “alice.near has minted(ha minteado) 5.0 ZOD desde zod.near”
Lancemos nuestro contrato, para esto vamos a necesitar near-cli.
npm install near-cli -g
Y para lanzarlo vamos a crear una cuenta testnet de prueba. Las cuentas son contratos y solamente puedes tener 1 contrato por cuenta. Para crear multiples contratos necesitas utilizar sub cuentas, contract1.me.near, contract2.me.near
Lancemos e invoquemos la función getCounter
yarn build
ACC1=$(near dev-deploy out/main.wasm | sed 's/.*id: (.*), node.*/1/' | head -n 1)
near view --accountId $ACC1 $ACC1 getCounter '{}'
La salida es
View call: dev-1623290109414-64922580028342.getCounter({})
0
Incrementamos el contador
near call --accountId $ACC1 $ACC1 incrementCounter '{"value": 1}'
Miremos esta invocación en el explorador de bloques https://explorer.testnet.near.org/accounts/dev-1623290109414-64922580028342
Increíble.
Para visualizar una función podemos usar un curl pero necesitamos analizar gramaticalmente la salida de la línea de comando, en vez de ello es más simple utilizar un script de nodo rápido. No necesitamos siquiera una cuenta en Near.
node << EOF
const fetch = require('node-fetch');
async function go() {
const args_base64 = Buffer.from('{}').toString('base64')
const params = {account_id: "zodtv.near", method_name: "mint_status",
request_type: "call_function", finality: "final", "args_base64": args_base64}
const json_args = {jsonrpc: "2.0", id: "1", method: "query", params: params}
const fetch_args = {
method: "POST",
body: JSON.stringify(json_args),
headers: {
"Content-Type": "application/json"
}
}
const response = await fetch("https://rpc.mainnet.near.org", fetch_args);
const {result} = await response.json();
const mint_status = JSON.parse((new TextDecoder()).decode(new Uint8Array(result.result)))
console.log(mint_status)
}
go()
EOF
El siguiente snippet (Sección de código) utiliza RPC API https://docs.near.org/docs/api/rpc para consultar el estado del contrato mint zodtv.near
{
"total_minted": "3120000000000000000000000000",
"level": "0",
"near_price": "3000000000000000000000000",
"zod_price": "10000000000000000000000"
}
Near denomina hasta el 24, el yocto.
3_000_000_000_000__000_000_000_000
es 3.0
Con eso concluye la primera serie aquí, la próxima vamos a trabajar con una web frontend y correctamente obtener balance, estado y más.