DEV Community

Cover image for Primeras aventuras en sway
Sergio Martinez Marin
Sergio Martinez Marin

Posted on

Primeras aventuras en sway

Image description

Hola a todos:

Después de pasar por mi primera hackathon en modalidad física, me llevo muchas alegrías de ver una plataforma que promete mucho. Esta plataforma se llama Fuel.

Para no hechar una historia larga, se trata de una blockchain modular y está especializada en la capa de ejecución, esto quiere decir que esta capa de ejecución es una alternativa a todas las L2 que hay en sistemas etherum y puede estar en otras blockchain :)

Fuel network maneja su propia maquina virtual y lenguaje, y esto es algo positivo ya que solidity no ha podido dar avances más agresivos en su evolución como lenguaje por cuidar la retrocompatibilidad.

El lenguaje se llama sway, inspirado en Rust, diría que muy similar a rust, lo cual es tendencia ahora en las nuevas generaciones de soluciones de blockchain con todos sus beneficios y complejidades que esto implica.


A continuación vamos a realizar nuestro primer ejercicio paso a paso, desde un contrato básico, hasta llevarlo a interactuar con una interfaz web.

Antes que todo este tutorial se basa en este código
código fuente original:

https://github.com/FuelLabs/quickstart

La instalación:

funciona para cualquier solución linux compatible, Linux, mac y Windows( bajo wsl2)
Se baja y ejecuta esta instrucción

curl --proto '=https' --tlsv1.2 -sSf https://install.fuel.network/fuelup-init.sh | sh
Enter fullscreen mode Exit fullscreen mode

Instrucciones completas acá:

https://install.fuel.network/master/installation/index.html

creamos un directorio, y dentro de este directorio ejecutamos la siguiente instrucción

forc new countersm

entramos al directorio countersm/src y cambiamos el código de main.sw por el siguiente código:

contract;

storage {
    counter: u64 = 0,
}

abi Counter {
    #[storage(read, write)]
    fn increment();

    #[storage(read)]
    fn count() -> u64;
}

impl Counter for Contract {
    #[storage(read)]
    fn count() -> u64 {
        storage.counter
    }

    #[storage(read, write)]
    fn increment() {
        storage.counter = storage.counter + 1;
    }
}
Enter fullscreen mode Exit fullscreen mode

Storage
Estructuras "globales" y de acceso a todo el contrato.

abixxx
Definiciones genéricas de todas las funciones

impl xxx for Contract
Implementación del abi

Que nos obliguen a tener una estructura clara, nos da orden en el código :)

Nota: para el diario transcurrir, se recomienda editar el código con VS-code más la extensión de sway

Image description

En este caso,estoy corriendo el vs-code en windows y todo el sway en ubuntu 22.04 LTS desde WSL 🤓

Esta extensión nos advierte si tenemos algún error en nuestra codificación.

Una vez tenemos el código, en la consola de linux o mac compilamos el programa.

forc compile

Una vez tenemos listo nuestro código vamos a desplegarlo, pero........vamos a desplegarlo localmente, esto con el fin de tener una experiencia más agradable.

fuel-core run --ip 127.0.0.1 --port 4000

Image description

Acá tenemos billeteras generadas con fondos, entonces nos ahorramos crear la billetera y ponerle fondos, esto es muy útil cuando estamos haciendo desarrollos internos, luego si desplegamos en la testnet.

Como paso final de la parte de contratos vamos a deplegar el contrato en la red local ubicados dentro de la carpeta raiz de los contratos
forc deploy --unsigned

Image description


Creando la aplicación web
Como es una aplicación react, debemos tener instalado nodejs

https://nodejs.org/en

Nota:
Se intentó crear la aplicación web por NextJS, por Deno, o simplemente en consola, pero explota por un error en una libreria
https://www.npmjs.com/package/elliptic , la cual no permite hacer el uso de import o exports.

Para tener la interacción web-fuelnetwork, se usa la librería fuels, que es de typescript.

En este ejercicio vamos a usar vite, ya que no se recomienda usar create-react-app.

npm create vite@latest
React
Typescript+SWC

Image description

Image description

Image description

Ahora vamos al directorio web y ejecutamos npm install e instalamos la libería de fuels
npm install fuels


Después de instalar la libería fuels, vamos a mirar que al compilar con forc build se generó el abi en estructura json.

El código abi está generado en la siguiente carpeta

Image description

Si abrimos el archivo countersm-abi.json, vemos lo siguiente

{
  "types": [
    {
      "typeId": 0,
      "type": "()",
      "components": [],
      "typeParameters": null
    },
    {
      "typeId": 1,
      "type": "u64",
      "components": null,
      "typeParameters": null
    }
  ],
  "functions": [
    {
      "inputs": [],
      "name": "count",
      "output": {
        "name": "",
        "type": 1,
        "typeArguments": null
      },
      "attributes": [
        {
          "name": "storage",
          "arguments": [
            "read"
          ]
        }
      ]
    },
    {
      "inputs": [],
      "name": "increment",
      "output": {
        "name": "",
        "type": 0,
        "typeArguments": null
      },
      "attributes": [
        {
          "name": "storage",
          "arguments": [
            "read",
            "write"
          ]
        }
      ]
    }
  ],
  "loggedTypes": [],
  "messagesTypes": [],
  "configurables": []
Enter fullscreen mode Exit fullscreen mode

Nos ubicamos dentro de la carpeta web y ejecutamos el siguiente comando:

npx fuels typegen -i ../countersm/out/debug/*-abi.json -o ./src/types --contract

Con esto dejamos el abi listo para usar en web, pasamos el json a algo typescript!

Image description

En visual studio code, vamos modificar el archivo app.tsx y alteramos la funcionalidad del botón.

Image description

ponemos el siguiente código, lo que es contrato y llave secreta se cambia a sus datos respectivos.


import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import { useEffect, useState } from "react";
import "./App.css";
//Liberria para cargar la wallet
import { Wallet } from "fuels";
// Import the contract factory -- you can find the name in index.ts.
// You can also do command + space and the compiler will suggest the correct name.
//Generado npx fuels typegen -i ../countersm/out/debug/*-abi.json -o ./src/types --contract
import { CountersmAbi__factory } from "./types/factories/CountersmAbi__factory";

// The address of the contract deployed the Fuel testnet
//dato obtenido al desplegar el contrato localmente forc deploy --unsigned
const CONTRACT_ID =
  "0x3edb96c23766b8504caaff042994efa18460e7ba27f60191394a6bcf5be8d7d8";

//the private key from createWallet.js
//billetera generada al ejecutar el nodo localmente en memoria fuel-core run --ip 127.0.0.1 --port 4000
const WALLET_SECRET =
  "0x37fa81c84ccd547c30c176b118d5cb892bdb113e8e80141f266519422ef9eefd";

// Create a Wallet from given secretKey in this case
// The one we configured at the chainConfig.json
//el segundo parámetro es el provider, en este caso es local
const wallet = Wallet.fromPrivateKey(
  WALLET_SECRET, "http://127.0.01:4000/graphql"
);

// Connects out Contract instance to the deployed contract
// address using the given wallet.
const contract = CountersmAbi__factory.connect(CONTRACT_ID, wallet);


function App() {
  const [count, setCount] = useState(0)

  //función que hace incrementa en 1 y luego trae el valor de la blockchain local!! :)
  async function fuel_power(){
    await contract.functions.increment().txParams({ gasPrice: 1 }).call();
    const { value } = await contract.functions.count().get();
    setCount(Number(value));
  }

  return (
    <div className="App">
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://reactjs.org" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={fuel_power}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </div>
  )
}

export default App



Enter fullscreen mode Exit fullscreen mode

Finalmente activamos el vite
npm run dev
y abrimos el navegador en el puerto 5173
http://localhost:5173

Image description

Cómo es local, la interacción blockchain es a la velocidad del rayo :)

Image description

Felicitaciones!!
Tu primera implementación real y con interacción web

Repositorio github:
https://github.com/sergiotechx/counterReactFuel

Actualización

Un miembro de Fuel me indicó donde está el foro de la comunidad y allí ya resolvieron el problema con NEXTJS y funciona!

Image description
En el archivo next.config.js se agrega lo siguiente:

 experimental: {
    esmExternals: false,
  }
Enter fullscreen mode Exit fullscreen mode

https://forum.fuel.network/t/running-fuels-on-nextjs/1132

Top comments (0)