Primeras aventuras en sway
Tags: spanish, webdev, sway, blockchain
Published: 2023-04-03 22:12:15



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/exce8lggftbv5f1u24y6.png)

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]( https://www.fuel.network/).

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](https://fuellabs.github.io/sway/v0.34.0/book/reference/), 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
```

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;
    }
}
```
**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xj2uxtwrmcp2h8zr9k1b.png)

_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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhqdvygjngl5uoz2u8ty.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m1cqrgv3inus1nzdgfc8.png)

---

**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j57spp1grzg8tnqhf0v4.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ih9v1z169niqp82crzmw.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tohc30g91efs5yy6enqs.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsxbp14p3dcdsv8ei9ra.png)

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": []
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ujw7og7e1znneow2mw3o.png)

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfwwns9ng3akd888iwgz.png)

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



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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ll91n4m42iowp5h8df7v.png)

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmx5mxpqc5zrtxazj3tv.png)



**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7rp2l6n8fkytu7q10sx.png)
En el archivo next.config.js se agrega lo siguiente: 

```
 experimental: {
    esmExternals: false,
  }
```

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