Arrays are a fundamental data structure in programming, and Solidity is no exception. In Solidity, there are several types of arrays available, including dynamic arrays, fixed-size arrays, and multi-dimensional arrays.
- Dynamic Arrays
- Fixed Arrays
- Multi-Dimensional Arrays
- Solidity Array Functions
- Using Arrays In Solidity
Dynamic Arrays
Dynamic arrays are the most common type of array in Solidity. These are arrays whose length can be changed during runtime. To declare a dynamic array, we use the square bracket notation without specifying a length
uint[] exampleArray;
exampleArray.push(1337);
To add an element to a dynamic array, we use the push function which in this example adds the value 1337 to the end of the exampleArray array.
Fixed Arrays
Fixed-size arrays have a predetermined length that cannot be changed during runtime. To declare a fixed-size array, we use the square bracket notation with a length
uint[4] public anotherArray; // [0,0,0,0]
anotherArray[2] = 123; // [0,0,123,0]
In this example we define a fixed array called anotherArray and set it to have a four unsigned integers.
Multi-Dimensional Arrays
Multi-dimensional arrays are arrays that have more than one dimension. To declare a multi-dimensional array, we use the square bracket notation with multiple lengths
uint[3][3] mdArray;
mdArray[1][2] = 888;
This two-dimensional array is essentially an array of arrays. Each element in the multi-dimensional array is itself an array, which can contain multiple unsigned integer elements. To access an element in a two-dimensional array, we need to specify two indices: one for the row and one for the column.
Solidity Array Functions
Solidity provides several built-in functions to manipulate arrays. Here are some of the most commonly used array functions in Solidity:
- push This function is used to add an element to the end of an array. For example, myArray.push(5) would add the value 5 to the end of the array myArray.
- pop This function is used to remove and return the last element of an array. For example, myArray.pop() would remove and return the last element of myArray.
- length This function is used to get the number of elements in an array. For example, myArray.length would return the number of elements in myArray.
- delete This function is used to remove an element from an array. It takes one argument, which is the index of the element to remove. For example, delete myArray[3] would remove the element at index 3 of myArray.
- slice This function is used to create a new array from a portion of an existing array. It takes two arguments, which are the starting and ending indices of the portion of the array to include in the new array. For example, myNewArray = myArray.slice(1, 4) would create a new array myNewArray that contains elements 1, 2, and 3 of myArray.
- concat This function is used to concatenate two arrays into a new array. It takes one argument, which is the array to concatenate with the original array. For example, myNewArray = myArray.concat([6, 7, 8]) would create a new array myNewArray that contains all of the elements of myArray followed by the elements 6, 7, and 8.
- sort This function is used to sort the elements of an array in ascending order. For example, myArray.sort() would sort the elements of myArray in ascending order.
Using Arrays In Solidity
It is important to note that arrays in Solidity can have significant gas costs, especially when dealing with large arrays or complex operations. Therefore, it is essential to carefully consider the use of arrays and optimize their usage wherever possible to ensure the efficiency and effectiveness of smart contract code.
One common issue is to use a for loop to iterate over a dynamic array which can grow to large and eventually exceed the gas limit causing the smart contract to be rendered useless.
Here is some example code from the Solidity snippet repo on Github:
https://github.com/jamesbachini/Solidity-Snippets/blob/main/contracts/Arrays.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
contract Arrays {
uint[] public myArray = [2,4,6,8,10,12];
uint[4] public myFixedArray = [3,5,1,8];
uint[][] public nestedArray;
function arrayPush(uint _newNumber) public {
myArray.push(_newNumber);
}
function arrayLoop() public view {
for (uint i=0; i<myArray.length; i++) { // unbounded loop DoS warning
// do something with myArray[i]
}
}
function arrayLength() public view returns(uint) {
return myArray.length;
}
function deleteByIndex(uint _i) public {
for (uint i = _i; i < myArray.length - 1; ++i) {
myArray[i] = myArray[i+1];
}
myArray.pop();
}
}