Domina los Mappings en Solidity


En Solidity, los mappings son una de las estructuras de datos más potentes y útiles, especialmente diseñadas para almacenar datos de manera eficiente en la blockchain. Si estás empezando con Solidity, entender los
te dará una base sólida para manejar datos de manera estructurada y optimizada. ¡Veamos cómo funcionan!

¿Qué es un mapping?

En términos simples, un mapping es como un diccionario o tabla hash. Permite almacenar pares clave-valor, donde cada clave está asociada a un valor único. La clave puede ser cualquier tipo de dato básico (como address, uint, o bytes32), mientras que el valor puede ser cualquier tipo, incluyendo estructuras, arreglos y hasta otros mappings.

La sintaxis básica para declarar un mapping es:

mapping(KeyType => ValueType) public nombreDelMapping;
  • KeyType: El tipo de la clave, por ejemplo, address o uint.
  • ValueType: El tipo del valor asociado a cada clave, puede ser otro tipo de dato o una estructura.
  • nombreDelMapping: El nombre que le darás a tu mapping para usarlo en el contrato.
📰

Es recomendable dar nombres significativos a los valores dentro de un mapping, ya que esto facilita la comprensión de lo que representa cada par clave-valor.

Ejemplo sencillo: Un banco de tokens

Supongamos que quieres construir una aplicación de gestión de tokens. En este ejemplo, vamos a usar un mapping para almacenar el balance de tokens de cada usuario.

pragma solidity ^0.8.26;

contract BancoDeTokens {
    // Definimos el mapping
    mapping(address usuario => uint cantidad) public balances;

    // Función para depositar tokens
    function depositar(uint cantidad) public {
        balances[msg.sender] += cantidad;
    }

    // Función para consultar el balance
    function consultarBalance() public view returns (uint) {
        return balances[msg.sender];
    }
}

En este código:

  1. balances es un mapping que asocia cada address (la clave) con un uint (el valor) que representa el balance de tokens de ese usuario.
  2. La función depositar incrementa el balance del usuario que llama a la función.
  3. La función consultarBalance permite a un usuario ver su propio balance.

¿Qué ocurre si consultamos una clave inexistente?

Los mappings en Solidity tienen un comportamiento especial: si consultas una clave que nunca ha sido asignada, el mapping devuelve el valor por defecto del tipo de dato. En el caso de uint, devolverá 0.

Limitaciones de los mappings

  1. No son iterables: A diferencia de otros lenguajes, los mappings en Solidity no se pueden recorrer directamente. Si necesitas iterar sobre las claves o valores, tendrás que llevar un registro adicional en un arreglo o lista.

  2. No tienen tamaño: A diferencia de los arrays, no puedes obtener la cantidad de pares clave-valor almacenados en un mapping. Esto se debe a la forma en que Ethereum organiza los datos en la blockchain para ahorrar espacio.

Ejemplo avanzado: Mapping de mappings

En Solidity, también puedes crear mappings anidados, lo que significa que puedes tener un mapping de mappings. Esto es útil para escenarios complejos, como almacenar la autorización de un usuario para gestionar los tokens de otro.

// Definimos un mapping anidado
mapping(address duegno => mapping(address autorizado => uint cantidad)) public autorizaciones;

// Función para autorizar a otro usuario
function autorizar(address autorizado, uint cantidad) public {
  autorizaciones[msg.sender][autorizado] = cantidad;
}

// Consultar la autorización
function verAutorizacion(address duegno, address autorizado)
 public view returns (uint) {
  return autorizaciones[duegno][autorizado];
}

En este caso, autorizaciones es un mapping anidado, donde cada usuario (duegno) puede autorizar a otros (autorizado) para manejar una cantidad específica de tokens.

Conclusión

Los mappings son una herramienta poderosa en Solidity para estructurar y organizar datos. Aunque tienen algunas limitaciones, su capacidad de almacenar información de forma eficiente y su comportamiento con claves no inicializadas los convierten en una excelente opción para muchos casos de uso en contratos inteligentes. Al comprender cómo funcionan, estarás un paso más cerca de construir aplicaciones descentralizadas robustas y eficientes.