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.
Contenidos
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.