Arrays en Solidity

Solidity

En este tutorial vamos a ver cómo crear y manipular Arrays en Solidity. Del mismo modo que ocurre en JavaScript o en PHP, los Arrays de solidity te permiten almacenar colecciones de elementos. Sin embargo, existe una diferencia, ya que los Arrays de Solidity solamente pueden contener elementos del mismo tipo. Por ejemplo, podrás crear un Array de enteros u otro de variables booleanas, pero no una Array que contenga tanto tipos enteros como booleanos.

Tipos de Arrays en Solidity

En Solidity existen dos tipos de Arrays, que básicamente se diferencian en la forma en la que se almacenan:

  • Storage arrays: Arrays que se almacenan en la blockchain. Es decir; que tras ejecutar el código de tu Smart Contract, el contenido de estos arrays se almacenará de forma persistente en la memoria de la blockchain.
  • Memory arrays: Arrays que se almacenan en memoria, de forma que sus valores solamente existen temporalmente mientras se ejecuta un Smart Contract o una función del Smart Contract, dependiendo del lugar en el que se definan.

Storage Arrays

Para declarar un storage array debes definir el tipo de datos que contendrá seguido de un corchete de apertura y otro de cierre y el identificador del Array. En el siguiente ejemplo declaramos un array de tipo uint al que llamamos miArray:

uint[] miArray;

Los storage arrays pueden ser de tamaño fijo o de tamaño dinámico. Si no especifiamos su tamaño a la hora de definirlos, como ocurre en el ejemplo anterior, estamos creando un array de tamaño dinámico, que es la opción por defecto. Sin embargo, es posible crear arrays de tamaño fijo especificando su tamaño entre corchetes a la hora de definirlos:

uint[2] miArray;

Sin embargo, la gran desventaja de los arrays de tamaño fijo es que perderás acceso al método push, que permite insertar elementos en array, tal y como veremos a continuación.

Memory Arrays

Los arrays definidos en memoria son siempre de tamaño fijo. La gran diferencia con los storage arrays consiste en que los memory arrays no se almacenan en la Blockchain al terminar la ejecución del código o de la función del Smart Contract, sino que desaparecerán.

Los memory arrays se suelen declarar en las funciones y no a nivel global del Smart Contract. Su declaración es algo compleja, ya que tendrás que indicar el tipo de valor que contendrán seguido de un corchete de apertura y otro de cierre, además de la sentencia memory y del identificador del array.

Luego tendrás que asignarle un valor mediante la sentencia new, seguido del tipo de dado que contiene el array, un corchete de apertura y otro de cierre y su tamaño entre paréntesis.

A continuación declaramos un array de 10 posiciones que contendrá valores de tipo uint:

uint[] memory miArray = new uint[](10);

A continuación vamos a ver cómo agregar elementos a un Array, cómo acceder a ellos, cómo actualizarlos y cómo eliminarlos.

Cómo agregar elementos a un Array

Primero explicaremos cómo agregar elementos a cada uno de los dos tipos que array que existen en Solidity.

Cómo agregar elementos a un Storage Array

Para agregar un elemento a un storage array usamos el método push, que es un método predefinido que se encuentra nativamente en los arrays de Solidity:

miArray.push(1); // Agregamos un elemento
miArray.push(12); // Agregamos otro elemento

Tal y como puedes ver, el método push se usa del mismo modo que su equivalente de JavaScript.

Cómo agregar elementos a un Memory Array

En este tipo de array no existe el método push, aunque conocemos por adelantado el número de posiciones que contienen. Por ello, bastará con indicar directamente el índice de la posición en la que queremos insertar un elemento.

En el siguiente ejemplo insertamos el número 10 en la primera posición del Array:

miArray[0] = 10; 

En este otro ejemplo insertamos el número 20 en la segunda posición del Array:

miArray[1] = 20;

Cómo leer elementos de un Array

A continuación, veremos cómo acceder a los elementos que hemos agregado a un Array. El método es exactamente el mismo para ambos tipos de Array.

Cómo leer elementos de un Storage Array

Para leer un elemento de un storage array en Solidity debes indicar el índice del elemento al que quieres acceder entre corchetes, al igual que en JavaScript. En el siguiente ejemplo accedemos al primer elemento de nuestro array:

miArray[0];

El primer elemento del array se encontrará en la posición 0, que es el valor con el que comienzan los índices en Solidity, al igual que ocurre con la gran mayoría de los lenguajes de programación. El segundo elemento se encontrará en la posición 1:

miArray[1];

Cómo leer elementos de un Memory Array

Podrás leer valores de un memory array siguiendo el mismo método seguido para los Storage Arrays. Es decir; indicando el índice del elemento al que quieres acceder entre corchetes. En el siguiente ejemplo accedemos al primer elemento de nuestro array:

miArray[0];

Recuerda que los índices comienzan por el valor 0. En este otro ejemplo accedemos al segundo valor del Array:

miArray[1];

Cómo actualizar elementos de un Array

A continuación, veremos cómo actualizar los elementos de un array.

Cómo actualizar elementos de un Storage Array

Para actualizar un elemento de un storage array en Solidity debes hacer referencia a la posición del array que quieres actualizar mediante su índice. Seguidamente basta con que le asignes un valor como si de una variable se tratase.

En el siguiente ejemplo actualizamos el contenido de la primera posición del array, asignándole el valor 4:

miArray[0] = 4;

Cómo actualizar elementos de un Memory Array

El método que usaremos para actualizar los elementos de un array almacenado en memoria será el mismo usado para los storage arrays. Tendrás que hacer referencia a la posición del array que quieres actualizar mediante su índice para luego asignarle un valor:

En el siguiente ejemplo actualizamos el contenido de la primera posición del array, asignándole el valor 30:

miArray[0] = 30;

Cómo borrar elementos de un Array

A continuación, veremos cómo borrar los elementos de un Array. Sin embargo, comenzaremos explicando que el borrado funciona de un modo algo diferente a otros lenguajes de programación.

Tras eliminar un elemento de un array, todavía podrás obtener un valor desde dicha posición. Dicho valor será el valor 0 en el caso de un array que contenga valores numéricos, ya que es el valor por defecto que contienen los arrays numéricos en Solidity. Si hubieses definido un Array de tipo booleano, tras eliminar un elemento y luego obtenerlo, obtendrías el valor false.  Esta es una gran diferencia entre Solidity y otros lenguages de programación, que devolverían null o undefined.

Cómo borrar elementos de un Storage Array

Para borrar un elemento de un Array debes usar la sentencia delete seguida del identificador del array y del índice entre corchetes que hace referencia a la posición del array que deseas eliminar. En el siguiente ejemplo eliminamos el segundo elemento del Array:

delete miArray[1];

Sin embargo, tras eliminar el elemento anterior, todavía podrás obtener el valor 0 desde dicha posición.

Cómo borrar elementos de un Memory Array

Para borrar elementos de un Array definido en memoria tendrás que usar la sentencia delete seguida del identificador del Array y de la posición a eliminar entre corchetes. En le siguiente ejemplo eliminamos el segundo elemento del Array:

delete miArray[1];

Sin embargo, tras eliminar el elemento anterior, todavía podrás obtener el valor 0 desde dicha posición.

Operaciones CRUD con Arrays en Solidity

Vamos a ver cómo crear una función que realice las operaciones CRUD que hemos visto tanto con un storage array como con un memory array.

Luego veremos algunas de las operaciones más comunes que realizarás con arrays en Solidity. Veremos cómo recorrer un Array, cómo pasárselo como valor a una función o cómo devolverlo desde una función.

Operaciones CRUD con Storage Arrays en Solidity

Vamos a ver un ejemplo completo de un Smart Contract en el que definimos un storage array para luego agregar elementos, leerlos, actualizarlos y eliminarlos:

pragma solidity ^0.8.13;

contract MiContrato
{
    uint[] miArray; // Definición

    function operaciones() external
    {
        miArray.push(10); // Insertamos un elemento
        miArray.push(20); // Insertamos otro elemento

        miArray[0]; // Leemos el primer elemento

        miArray[0] = 30; // Actualizamos el primer elemento

        delete miArray[1]; // Borramos el segundo elemento
    }
}

Operaciones CRUD con Memory Arrays en Solidity

Ahora veremos otro ejemplo de un Smart Contract en el que definimos un memory array para luego agregar elementos, leerlos, actualizarlos y eliminarlos:

pragma solidity ^0.8.13;

contract MiContrato
{
    function operaciones() external
    {
        uint[] memory miArray = new uint[](10); // Definición
    
        miArray[0] = 10; // Insertamos un elemento
        miArray[1] = 20; // Insertamos otro elemento

        miArray[0]; // Leemos el primer elemento

        miArray[0] = 3; // Actualizamos el primer elemento

        delete miArray[1]; // Borramos el segundo elemento
    }
}

Operaciones comunes con Arrays en Solidity

Ahora veremos algunas de las operaciones que usarás en tu día a día como desarrollador:

Cómo obtener el número de elementos de un Array

Para obtener el número total de elementos que contiene un Array puedes usar el método length. En el siguiente ejemplo, usamos el método length para conocer el número de elementos del array miArray, obteniendo 2 como resultado:

miArray.length; // 2

Cómo iterar los elementos de un Array

A continuación vamos a usar un bucle for para recorrer los elementos del Array. Si no sabes cómo usar un bucle for, puedes consultar el tutorial en el que explico los bucles de Solidity.

Primero debemos definir el bucle inicializando su contador con el valor 0. Luego especificamos la condición de parada, que se dará cuando el contador llegue al valor del número total de elementos que contiene el array, usando para ello el método length. Finalmente expecificamos la acción a realizar, incrementando el valor del contandor en una unidad.

En el siguiente ejemplo recorremos el Array miArray:

for (uint i = 0; i < miArray.length; i++) {
    miArray[i]; // Accedemos a la posición del contador
}

En el siguiente ejemplo recorremos el Array miArray, reemplazando el valor de todos sus elementos con el valor 2:

for (uint i = 0; i < miArray.length; i++) {
    miArray[i] = 2; // Actualizamos la posición del contador
}

Cómo pasar un Array como argumento de una función

Vamos a ver cómo aceptar un Array como parámetro de una función. Para ello vamos a declarar la función aceptaArray. Tendremos que especificar el tipo de los valores que contendrá el Array seguido dos corchetes, el método de almacenamiento del array y finalmente de su identificador.

Cuando se trata de una función externa, definida con el modificador external, tendremos que usar el tipo calladata:

funcion aceptaArray(uint[] calldata miArray) external
{
    // Código
}

Cuando se trate de una función pública o de una función interna, definidas mediante los modificadores public e internal respectivamente, tendremos que usar el tipo memory.

En el siguiente ejemplo definimos una función pública que acepta el array miArray como parámetro:

funcion aceptaArray(uint[] memory miArray) public
{
    // Código
}

En el siguiente ejemplo definimos una función interna que acepta el array miArray como parámetro:

funcion aceptaArray(uint[] memory miArray) internal
{
    // Código
}

Cómo devolver un Array como valor desde una función

Para devolver un array como valor desde una función, tendremos que especificar su tipo en la declaración de la función. Para ello tendremos que usar la sentencia returns seguida de la especificación del array entre paréntesis.

funcion devuelveArray() returns(uint[] memory)
{
    // Código
}o

Y esto ha sido todo. Espero que os haya servido de ayuda.


Avatar de Edu Lazaro

Edu Lázaro: Ingeniero técnico en informática, actualmente trabajo como desarrollador web y programador de videojuegos.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado esta guía. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirla en Twitter 😊

Si quieres conocer mis proyectos, sígueme en Twitter.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

“- Hey, Doc. No tenemos suficiente carretera para ir a 140/h km. - ¿Carretera? A donde vamos, no necesitaremos carreteras.”