Salta el contingut
Logo esquerra

SESSIÓ 1 - UD2.1: INTRODUCCIÓ A SOLIDITY

Setmana 1 (20-26 abril) - 2 hores


FITXA TÈCNICA

Dada Valor
Unitat UD2 - Smart Contracts
Tema Introducció a Solidity i primer contracte
Durada 2 hores
Nivell Inicial
Eines Remix IDE, MetaMask (només visualització)

OBJECTIUS D'APRENENTATGE

Al finalitzar aquesta sessió, l'alumnat serà capaç de:

  1. ✅ Comprendre què és un smart contract i per a què serveix
  2. ✅ Identificar l'estructura bàsica d'un contracte Solidity
  3. ✅ Utilitzar Remix IDE per escriure i compilar codi
  4. ✅ Declarar variables d'estat amb tipus adequats
  5. ✅ Crear funcions bàsiques de lectura i escriptura
  6. ✅ Desplegar un contracte a JavaScript VM i interactuar-hi

TEMPORITZACIÓ DE LA SESSIÓ

Temps Activitat Metodologia
0-15 min Presentació i objectius Exposició
15-45 min Teoria: Smart contracts i Solidity Exposició + exemples
45-60 min Configuració de Remix IDE Demostració
60-105 min Pràctica guiada: Primer contracte Codificació conjunta
105-120 min Exercici: Calculadora bàsica Pràctica individual

MATERIAL TEÒRIC

1. Què és un Smart Contract?

Definició: Un smart contract és un programa informàtic que s'executa automàticament quan es compleixen condicions predefinides. S'emmagatzema a la blockchain i és: - Immutable: No es pot modificar un cop desplegat - Transparent: Tothom pot veure el codi - Descentralitzat: S'executa en tots els nodes - Determinista: Sempre produeix el mateix resultat

Analogia:

Contracte tradicional:    Smart Contract:
┌─────────────────┐      ┌─────────────────┐
│   Notari        │      │   Blockchain    │
│   Paper         │  →   │   Codi          │
│   Confiança     │      │   Automàtic     │
└─────────────────┘      └─────────────────┘

2. Estructura d'un Contracte Solidity

// 1. Versió del compilador
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

// 2. Declaració del contracte
contract NomDelContract {

    // 3. Variables d'estat (emmagatzemades permanentment)
    uint256 public variablePublica;
    string private variablePrivada;

    // 4. Constructor (s'executa una vegada al desplegar)
    constructor() {
        variablePublica = 100;
    }

    // 5. Funcions
    function nomFuncio() public {
        // Codi de la funció
    }
}

3. Tipus de Dades Bàsics

Tipus Descripció Exemple
uint256 Nombre enter sense signe (0 a 2²⁵⁶-1) uint256 edat = 25;
int256 Nombre enter amb signe int256 temperatura = -5;
bool Boolean (true/false) bool actiu = true;
address Adreça Ethereum (20 bytes) address propietari = 0x...;
string Text de longitud variable string memory nom = "Alice";
bytes32 Dades binàries fixades (32 bytes) bytes32 hash = 0x...;

4. Visibilitat de Funcions

Modificador Accés des de Ús típic
public Dins i fora del contracte Funcions principals
private Només dins del contracte Lògica interna
internal Contracte i derivats Funcions per herència
external Només des de fora Funcions per altres contracts

5. Modificadors d'Estat

Modificador Gas Descripció
view Gratis (lectura) Llegeix variables, no les modifica
pure Gratis (càlcul) No llegeix ni modifica estat
(cap) Paga gas Pot modificar l'estat

PRÀCTICA GUIADA PAS A PAS

EXERCICI 1: El Teu Primer Contracte

Objectiu: Crear un contracte que emmagatzemi i mostri un missatge.

Pas 1: Accedir a Remix IDE

  1. Obre el navegador i ves a: https://remix.ethereum.org
  2. Tanca qualsevol tutorial que aparegui
  3. A la barra lateral esquerra, fes clic a FILE EXPLORERS
  4. Fes clic a Create New File 📄
  5. Anomena el fitxer: 01_HolaBlockchain.sol

Pas 2: Escriure el Codi

Copia i enganxa aquest codi:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract HolaBlockchain {

    // Variable d'estat per emmagatzemar el missatge
    string private missatge;

    // Constructor: s'executa al desplegar
    constructor() {
        missatge = "Hola Blockchain!";
    }

    // Funció per obtenir el missatge (lectura - gratis)
    function obtenirMissatge() public view returns (string memory) {
        return missatge;
    }

    // Funció per actualitzar el missatge (escriptura - paga gas)
    function actualitzarMissatge(string memory nouMissatge) public {
        missatge = nouMissatge;
    }

    // Funció per obtenir el propietari del contracte
    function obtenirPropietari() public view returns (address) {
        return msg.sender;
    }
}
2020260327174143
2020260327174057

Pas 3: Compilar el Contracte

  1. Fes clic a la icona SOLIDITY COMPILER (barra lateral esquerra)
  2. Assegura't que la versió és 0.8.20 o superior
  3. Fes clic a Compile 01_HolaBlockchain.sol
  4. Si tot va bé, veuràs un ✅ verd

Possible error i solució:

Error: Source file requires different compiler version
Solució: Canvia la versió al dropdown o modifica pragma solidity

2020260327174254

Pas 4: Desplegar a JavaScript VM

  1. Fes clic a DEPLOY & RUN TRANSACTIONS (barra lateral)
  2. A ENVIRONMENT, selecciona Remix VM (Cancun)
  3. Assegura't que CONTRACT mostra 01_HolaBlockchain
  4. Fes clic a Deploy (botó taronja)
  5. A sota, a Deployed Contracts, veuràs el teu contracte
2020260327184039

Pas 5: Interactuar amb el Contracte

2020260327184635

Abans de poder interactuar, hem de seleccionar el contracte que acabam de desplegar i ens apareixeran les funcions implementades al codi

2020260327184809

Lectura (gratis):

  1. Fes clic a obtenirMissatge (botó blau)
  2. Veure la resposta a sota: "Hola Blockchain!"
  3. Fes clic a obtenirPropietari → veuràs una adreça
2020260327184956

Escriptura (simulat - no paga gas real):

  1. A actualitzarMissatge, escriu: "El meu primer smart contract"
  2. Fes clic a transact
  3. Ara torna a clicar obtenirMissatge → veuràs el nou missatge!

Observa

🔵 Botons blaus = lectura (view/pure) → gratis

2020260327185031
🟠 Botons taronges = escriptura → pagarien gas en xarxa real
2020260327185046


EXERCICI 2: Contracte de Dades Personals

Objectiu: Crear un contracte que emmagatzemi múltiples dades.

Codi Base:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract DadesPersonals {

    // Variables d'estat
    string public nom;
    uint256 public edat;
    address public propietari;
    bool public verificat;

    // Constructor amb paràmetres
    constructor(string memory _nom, uint256 _edat) {
        nom = _nom;
        edat = _edat;
        propietari = msg.sender;
        verificat = false;
    }

    // Funció per verificar les dades
    function verificar() public {
        verificat = true;
    }

    // Funció per actualitzar l'edat
    function actualitzarEdat(uint256 novaEdat) public {
        require(novaEdat > 0, "L'edat ha de ser major que 0");
        require(novaEdat < 150, "L'edat no pot ser tan alta");
        edat = novaEdat;
    }

    // Funció per obtenir totes les dades
    function obtenirDadesCompletes() public view returns (
        string memory,
        uint256,
        address,
        bool
    ) {
        return (nom, edat, propietari, verificat);
    }

    // Funció pure per calcular anys fins als 100
    function anysFins100() public view returns (uint256) {
        if (edat >= 100) {
            return 0;
        }
        return 100 - edat;
    }
}

Proves a Realitzar:

  1. Desplegar amb paràmetres:
    • Nom: "Tofol Verdera"
    • Edat: 28
Intenta fer-ho sense mirar la indicació

2020260327185505

  1. Consultar dades:

    • nom()"Tofol Verdera"
    • edat()28
    • propietari() → la teva adreça
    • verificat()false
  2. Actualitzar:

    • verificar() → torna a consultar verificat()true
    • actualitzarEdat(29) → consulta edat()29
  3. Funcions avançades:

    • obtenirDadesCompletes() → veure totes les dades juntes
    • anysFins100()71 (si té 29 anys)

EXERCICI PROPOSAT: CALCULADORA BÀSICA

Enunciat:

Crea un contracte anomenat CalculadoraBasica que tingui:

Requisits obligatoris:

  1. Variables d'estat:

    • ultimResultat (uint256) → emmagatzema l'últim resultat
    • historialOperacions (uint256) → compta quantes operacions s'han fet
  2. Funcions:

    • sumar(uint256 a, uint256 b) → retorna la suma
    • restar(uint256 a, uint256 b) → retorna la resta (amb validació)
    • multiplicar(uint256 a, uint256 b) → retorna el producte
    • obtenirUltimResultat() → retorna ultimResultat
    • obtenirHistorial() → retorna historialOperacions
    • resetear() → posa a 0 ultimResultat i historialOperacions
  3. Validacions:

    • A restar, utilitza require per assegurar que a >= b
    • Missatge d'error: "No es permeten resultats negatius"
  4. Actualitzacions:

    • Cada funció ha d'actualitzar ultimResultat
    • Cada funció ha d'incrementar historialOperacions en 1

Template per començar:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract CalculadoraBasica {

    uint256 public ultimResultat;
    uint256 public historialOperacions;

    // COMPLETA AQUÍ LES FUNCIONS

}

Solució:

Fes clic per veure la solució proposada
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract CalculadoraBasica {

     uint256 public ultimResultat;
     uint256 public historialOperacions;

     function sumar(uint256 a, uint256 b) public returns (uint256) {
         ultimResultat = a + b;
         historialOperacions++;
         return ultimResultat;
     }

     function restar(uint256 a, uint256 b) public returns (uint256) {
         require(a = b, "No es permeten resultats negatius");
         ultimResultat = a - b;
         historialOperacions++;
         return ultimResultat;
     }

     function multiplicar(uint256 a, uint256 b) public returns (uint256) {
         ultimResultat = a * b;
         historialOperacions++;
         return ultimResultat;
     }

     function obtenirUltimResultat() public view returns (uint256) {
         return ultimResultat;
     }

     function obtenirHistorial() public view returns (uint256) {
         return historialOperacions;
     }

     function resetear() public {
         ultimResultat = 0;
         historialOperacions = 0;
     }
}

Proves recomanades:

1. sumar(10, 5) → 15
2. ultimResultat → 15
3. historialOperacions → 1
4. restar(20, 8) → 12
5. historialOperacions → 2
6. multiplicar(4, 3) → 12
7. restar(5, 10) → Error: "No es permeten resultats negatius"
8. resetear()
9. ultimResultat → 0
10. historialOperacions → 0


EXERCICI EXTRA (Opcional)

Contracte de Comptador amb Límits:

Crea un contracte que:

  • Tingui un comptador que comenci a 0
  • Permeti incrementar en 1
  • Permeti decrementar en 1
  • Tingui un límit màxim (ex: 100)
  • Tingui un límit mínim (ex: 0)
  • No permeti superar els límits
  • Tingui una funció per obtenir el percentatge respecte al màxim

MATERIALS DE SUPORT

Cheat Sheet Solidity Bàsic:

// ESTRUCTURA BÀSICA
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract NomContract {
    // VARIABLES
    uint256 public numero;          // Enter sense signe
    int256 public enterNegatiu;     // Enter amb signe
    bool public esCert;             // Boolean
    address public propietari;      // Adreça
    string public text;             // Text

    // CONSTRUCTOR
    constructor() {
        propietari = msg.sender;
    }

    // FUNCIONS DE LECTURA (gratis)
    function obtenirDades() public view returns (uint256) {
        return numero;
    }

    // FUNCIONS DE CÀLCUL (gratis)
    function calcular(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    // FUNCIONS D'ESCRIPTURA (paga gas)
    function actualitzar(uint256 nouValor) public {
        require(nouValor > 0, "Valor invalid");
        numero = nouValor;
    }
}

Errors Comuns i Solucions:

Error Causa Solució
Source file requires different compiler version Versió incorrecta Canvia pragma solidity o la versió al compilador
Function declared pure but reads state Funció pure accedeix a variables Canvia a view
Invalid type for argument Tipus de dada incorrecte Revisa els tipus dels paràmetres
DeclarationError: Identifier not found Variable no declarada Declara la variable abans d'usar-la

Enllaços Útils:

  • 📘 Documentació Solidity: https://docs.soliditylang.org
  • 🎮 Remix IDE: https://remix.ethereum.org
  • 📚 Solidity by Example: https://solidity-by-example.org
  • 💬 Comunitat Ethereum: https://ethereum.org/community

QÜESTIONARI DE REPÀS

Respon abans de la propera sessió:

  1. Quina diferència hi ha entre view i pure?
  2. Per què les funcions view i pure no consumeixen gas quan es criden externament?
  3. Què fa msg.sender?
  4. Quin tipus de dada utilitzaries per emmagatzemar:
    • L'edat d'una persona?
    • El nom d'un usuari?
    • Una adreça de wallet?
    • Si un usuari ha votat (sí/no)?
  5. Què passa si intentes restar 10 - 20 amb uint256?
  6. Per a què serveix require()?
  7. Quina és la diferència entre public i private?
Solucions
  1. view pot llegir variables d'estat, pure no llegeix ni modifica estat
  2. Perquè no modifiquen la blockchain, només fan càlculs locals
  3. Retorna l'adreça de qui ha cridat la funció
  4. uint256 o uint8, string memory, address, bool
  5. Donaria error (underflow) o revertiria (Solidity 0.8+)
  6. Per validar condicions i revertir la transacció si no es compleixen
  7. public és accessible des de dins i fora, private només des del contracte