BlockchainSmart ContractsSolidity16 min readUpdated

uint Array in Solidity: A Beginner Smart Contract Guide

By Mudassir Khan — Agentic AI Consultant & AI Systems Architect, Islamabad, Pakistan

Cover illustration for: uint Array in Solidity: A Beginner Smart Contract Guide

Section 01 · Definition

What is a uint array in Solidity?

A uint array is a list of whole numbers stored on the blockchain. Each number is non negative, each entry sits at a numbered position, and the list can grow over time.

Quick answer

What is a uint array? A uint array is an ordered collection where every entry is a non negative whole number. uint stands for unsigned integer. The default type is uint256, so the most common shape you will see in real contracts is uint256[]. You read by index, you write by push, and you check the size with .length.

The word uint is short for unsigned integer, which means a whole number that is always zero or above. The default size is 256 bits, so uint by itself is the same as uint256. When you put square brackets after a type, you turn it into an array of that type. So uint256[] is a list of unsigned integers.

Five indexed cells holding 85, 92, 73, 66, 80 with a sixth dashed cell labelled push, plus index numbers running from zero to five.
A uint256 array stores whole numbers in numbered slots. Every push appends a new slot at the end.

The mental model is a row of boxes. Each box holds one whole number. Each box has a number above it called the index, starting at zero. To look up the third box you write scores[2], because the third box sits at index two. To add a new box at the end you call scores.push(value).

Section 02 · Real use case

A simple real world example

A class teacher is recording exam scores on chain. Each score is a whole number from 0 to 100. The list grows every time a student submits.

The teacher needs three operations. Add a score after each submission. Read any score by its position. Know how many students have submitted so far. A uint array does all three with the smallest possible code surface.

Other places this same shape shows up: a counter contract that logs how long each task took in seconds, a game contract that records the highest dice roll in each round, or a treasury contract that stores every donation amount. None of those values can be negative, so a uint array is the right type.

Section 03 · Smart contract

A complete uint array smart contract

A small ScoreBook contract with one storage array and four functions. It is short enough to read in two minutes and complete enough to deploy in Remix.

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

contract ScoreBook {
    // 1. The storage array. Lives forever inside the contract.
    uint256[] public scores;

    // 2. Add a new score to the end of the list.
    function addScore(uint256 value) external {
        scores.push(value);
    }

    // 3. Read a single score by its index.
    function getScore(uint256 i) external view returns (uint256) {
        require(i < scores.length, "index out of range");
        return scores[i];
    }

    // 4. Return how many scores are stored.
    function totalScores() external view returns (uint256) {
        return scores.length;
    }
}

You can paste this into Remix at remix.ethereum.org, compile with the 0.8.20 compiler, deploy to the JavaScript VM, and interact with all four functions in the deploy panel. No wallet needed for the local tests.

Section 04 · Line by line

What every important line does

Walk through the contract one block at a time so the syntax stops feeling foreign.

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

The first line is a license tag. Solidity expects every file to declare one. MIT is the safe default for tutorial code. The second line tells the compiler which version of Solidity to use. The caret means any 0.8.x version that is at least 0.8.20.

solidity
uint256[] public scores;

This is the array declaration. The type uint256[] says the array holds unsigned 256 bit integers. The keyword public tells the compiler to generate a free getter that lets anyone read scores(i) from outside the contract. Storage arrays start empty unless you initialise them.

solidity
function addScore(uint256 value) external {
    scores.push(value);
}

The keyword external means this function is callable from outside the contract. scores.push(value) appends the new number at the end and grows the array length by one. There is no return value because the change is recorded in storage.

solidity
function getScore(uint256 i) external view returns (uint256) {
    require(i < scores.length, "index out of range");
    return scores[i];
}

The keyword view says the function reads state but does not change it, so calling it is free off chain. The require line guards the index before the lookup. If a caller passes an index that is too large the transaction reverts with the helpful message instead of failing silently. Inside the bounds, returning scores[i] hands the value back.

solidity
function totalScores() external view returns (uint256) {
    return scores.length;
}

Every Solidity array has a built in length property. It returns the number of items currently stored. Reading it is cheap and it never throws.

Section 05 · Reading and writing

Add data, get data, count items

Three operations cover the entire beginner surface area. The figure groups them so you can refer back later.

Three labelled cards titled write, read, and length showing the matching Solidity code lines for adding a score, reading a score, and counting the array.
The three core operations on a uint array. Write with push, read with index, count with length.

Adding data uses scores.push(85). The function takes one argument, places it at the new last position, and increases the length by one. A second push appends another value. There is no insertAt, no append range, no copy from another array.

Reading data uses bracket lookup. The first score is scores[0], the second is scores[1], and so on. If you want the most recent score you can use scores[scores.length - 1], but only when the array is not empty. Reading an out of range index reverts the call.

Counting items uses scores.length. It is not a function, so you do not put parentheses after it. The result is a uint256 that you can compare, assign, or pass into another function.

Section 06 · Methods

Add the array methods to ScoreBook, one function at a time

The ScoreBook contract from Section 03 only has push, indexed read, and length. Here are four more methods every beginner should know, added one function at a time so you can paste them into the same contract and try them in Remix as you go.

Start with the ScoreBook contract you already have. Each function below goes right after the existing ones inside the contract body. None of them needs a for loop, and each one teaches a distinct rule of Solidity array storage.

Function 1. Remove the last score with pop

solidity
function dropLast() external {
    require(scores.length > 0, "empty");
    scores.pop();
}

scores.pop() drops the last entry and shrinks the length by one. The require guard is critical: calling pop on a zero length array triggers a panic and the transaction reverts. Add the guard whenever the array can be empty at call time.

Function 2. Reset one slot with delete by index

solidity
function clearScore(uint256 i) external {
    require(i < scores.length, "out of range");
    delete scores[i];
}

delete scores[i] writes the type default into the targeted slot. For a uint the default is zero, so the call sets that entry to zero without changing the array length. Reading the slot afterwards returns zero, and the array still has the same number of items as before.

Function 3. Wipe the entire array with delete on the variable

solidity
function clearAll() external {
    delete scores;
}

delete scores on the whole array resets every slot to zero and sets the length back to zero in one line. Solidity does this in a single storage operation without iterating slot by slot. After the call, every indexed read goes out of range, and the next push starts a fresh list from index zero.

Function 4. Overwrite a slot with direct assignment

solidity
function updateScore(uint256 i, uint256 value) external {
    require(i < scores.length, "out of range");
    scores[i] = value;
}

Bracket assignment writes a new value into the slot at the given index. The bounds check stops the call early when the index is past the end. The length does not change because the slot already existed.

After adding the four functions, your ScoreBook contract now covers all five basic array operations: push, pop, delete by index, delete on the variable, and bracket assignment. Compile in Remix, redeploy, and try each new function from the deploy panel.

pop and delete are not the same thing

pop actually removes the last item and changes the length. delete scores[i] only resets that one slot to the default value, which is zero for a uint, and leaves the length unchanged. delete scores resets every slot to zero and sets the length back to zero. Pick pop when you want to shrink, pick delete when you want to reset.

Section 07 · Removal

Function 5. Remove any item with swap and pop

When you need to drop an item from the middle of a uint array and you do not care about preserving the order, the swap and pop pattern does it in constant time. Two writes and a pop, no iteration over the array.

The trick: move the last item into the slot you want to drop, then call pop. The targeted entry disappears, the last entry takes its place, and the length shrinks by one. The remaining items stay valid uint256 values, but their order is no longer the same as before. That trade off is the price of removing in O(1).

solidity
function removeAt(uint256 i) external {
    uint256 last = scores.length - 1;
    require(i <= last, "out of range");

    if (i != last) {
        scores[i] = scores[last];
    }
    scores.pop();
}

The if (i != last) guard skips a tiny self assignment when the caller asks for the last slot. When the function returns, the length is one less than before and the previous last entry sits at the position that was removed. For most beginner contracts, where the order of scores is not part of the public contract, this is the pattern you reach for. The hub guide on arrays in Solidity covers what to do when order matters and the swap is not enough.

Section 08 · More patterns

Return the whole array, build memory arrays, declare fixed length

Three more patterns added one at a time. The first goes onto ScoreBook as Function 6. The other two are reference patterns you will reuse in other contracts.

Function 6. Return the whole array as one value

Returning the whole array works when the array is small and the function is marked as a view. The return type uses the memory location keyword because the caller receives a fresh copy, not a pointer into storage. Add this function next to the rest in ScoreBook.

solidity
function allScores() external view returns (uint256[] memory) {
    return scores;
}

Pattern 1. Build a temporary memory array

Memory arrays let you build a temporary list inside a function without touching storage. The size is fixed at the moment you create them with new, so you cannot push or pop on a memory array. Set the entries by index after creation. This pattern lives on its own; it does not extend ScoreBook because the function is pure.

solidity
function buildBatch() external pure returns (uint256[] memory) {
    uint256[] memory batch = new uint256[](3);
    batch[0] = 10;
    batch[1] = 20;
    batch[2] = 30;
    return batch;
}

Pattern 2. Declare a fixed length storage array

Fixed length storage arrays declare the size inside the brackets. You cannot push or pop on a fixed length array because the size never changes. Every slot starts at zero and you write into the slots by index. This is a separate state variable on its own contract, not an extension of the dynamic ScoreBook array.

solidity
// Five slot uint array baked into storage.
uint256[5] public topFive;

function setTop(uint256 i, uint256 value) external {
    require(i < 5, "out of range");
    topFive[i] = value;
}

You cannot resize a dynamic storage array by writing to length

In Solidity 0.5 you could shrink an array with scores.length = newLen. That assignment was removed in 0.6 and any modern compiler rejects it. To grow an array, push. To shrink it, pop or delete. For a fully fresh array, run delete scores. The length property is read only in every current Solidity version.

Section 09 · Final contract

The complete ScoreBook with all six methods together

The original ScoreBook from Section 03 plus the six methods you have added function by function. One paste ready file you can drop into Remix and try every operation in a single session.

The contract below is the full version. The first three functions are the originals: push wrapped as addScore, indexed read wrapped as getScore, and the length read wrapped as totalScores. The remaining six are the additions you walked through in Sections 06 to 08.

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

contract ScoreBook {
    uint256[] public scores;

    // Append a new score.
    function addScore(uint256 value) external {
        scores.push(value);
    }

    // Read a single score by index.
    function getScore(uint256 i) external view returns (uint256) {
        require(i < scores.length, "out of range");
        return scores[i];
    }

    // Return how many scores are stored.
    function totalScores() external view returns (uint256) {
        return scores.length;
    }

    // Function 1. Remove the most recent score with pop.
    function dropLast() external {
        require(scores.length > 0, "empty");
        scores.pop();
    }

    // Function 2. Reset one slot to zero with delete by index.
    function clearScore(uint256 i) external {
        require(i < scores.length, "out of range");
        delete scores[i];
    }

    // Function 3. Wipe the whole list with delete on the variable.
    function clearAll() external {
        delete scores;
    }

    // Function 4. Overwrite a score with direct assignment.
    function updateScore(uint256 i, uint256 value) external {
        require(i < scores.length, "out of range");
        scores[i] = value;
    }

    // Function 5. Remove any score with swap and pop.
    function removeAt(uint256 i) external {
        uint256 last = scores.length - 1;
        require(i <= last, "out of range");
        if (i != last) {
            scores[i] = scores[last];
        }
        scores.pop();
    }

    // Function 6. Return the whole array as memory.
    function allScores() external view returns (uint256[] memory) {
        return scores;
    }
}

Open Remix, paste the contract, compile with the 0.8.20 compiler, and redeploy to the JavaScript VM. The deploy panel now lists nine callable buttons. Push three or four values with addScore, try removeAt(1), watch allScores reflect the new shape, then call clearAll and see the length drop to zero. Every method you have learnt in this post lives in this single file.

Section 10 · Beginner mistakes

Five mistakes new Solidity developers make with uint arrays

Pushing a negative number

A uint array cannot hold negatives. The line scores.push(-5) does not compile. If your domain has negatives, switch to int256[] instead.

Reading an out of range index

scores[scores.length] reverts because indexes go from 0 up to length minus 1. Always check the bound, or use a require, before indexing user provided positions.

Forgetting that delete keeps the slot

delete scores[2] sets that slot to zero but leaves the length unchanged. The array still has the same number of items, the third one just becomes zero. Use pop or swap and pop to actually remove an item.

Calling length like a function

It is scores.length, not scores.length(). Adding parentheses gives a compile error. The same is true for the addresses and string equivalents.

Returning the whole array on a huge dataset

A view that returns scores works in tests and reverts on production wallets when the list grows. For beginner contracts this is fine. For production, paginate the read by accepting a start index and a count.

Section 11 · Practice task

Try this on your own

A small extension that locks in the read, write, and length operations. Try to ship it without copying from the contract above.

Build a Highscore contract

Add a uint256[] scores array and a uint256 highest state variable that tracks the largest score seen so far. submitScore(uint256 value) pushes the value and updates highest if the new value is greater. getScore(uint256 i) returns one entry with a bounds check. clearScore(uint256 i) resets a slot with delete by index. removeAt(uint256 i) removes any entry with swap and pop. clearAll() wipes both the array and the highest tracker with delete. Bonus: emit a NewHighScore event whenever highest changes so off chain code can react.

Deploy the contract in Remix, push three or four values, and confirm highest reflects the largest one. Then call removeAt on the index that held the largest value and observe that highest is now stale. That stale value is the lesson: when you track aggregates next to an array, every method that touches the array has to update the aggregate too. Compare your version to the ScoreBook above and notice which lines you needed to add.

Section 13 · FAQ

Frequently asked questions

What is a uint array in Solidity in simple words?

A uint array is a list of whole numbers that cannot be negative. Each number sits at a numbered position called an index, and the first index is zero. The most common shape is uint256[], which holds 256 bit unsigned integers and is what you will see in almost every real contract.

How do I add a value to a uint array?

Call .push on the array with the value as the argument, for example scores.push(85). The new value lands at the end of the list and the length grows by one. push works only on dynamic storage arrays, not on fixed length ones declared with a number inside the brackets.

How do I read a value from a uint array?

Use square brackets with the index, for example scores[0] returns the first value. Indexes start at zero, so the last value is at scores[scores.length minus one]. Reading an index that is greater than or equal to the length reverts the transaction with a panic error.

How do I check the length of a Solidity uint array?

Read the length property with no parentheses, like scores.length. It returns a uint256 that tells you how many items are currently in the array. The read is free in a view function and never throws, even when the array is empty.

Can a uint array store negative numbers?

No. uint stands for unsigned integer, so a uint array cannot hold negative values. If you need negatives use int256[] instead, which is covered in the int array post in this beginner series. Trying to push a negative literal into a uint array is a compile error.

What is the difference between uint and uint256 in an array?

There is no difference. The keyword uint is an alias for uint256, so uint[] and uint256[] declare the same array type. Most style guides recommend writing uint256 explicitly because it makes the bit width visible to anyone reading the code.

How do I remove the last value from a uint array?

Call .pop on the array, for example scores.pop(). The function removes the last entry and shrinks the length by one. pop reverts the transaction when the array is empty, so guard the call with require(scores.length > 0, ...) whenever the array can be empty at call time.

What does the delete keyword do on a uint array?

delete on a single slot like delete scores[2] resets that slot to zero and leaves the length unchanged. delete on the whole array like delete scores resets every slot to zero and sets the length to zero. delete never frees the storage slot itself; it just writes the default value in place.

How do I remove an item from the middle of a uint array without a loop?

Use the swap and pop pattern. Copy the last entry into the slot you want to remove with scores[i] = scores[scores.length - 1], then call scores.pop(). The targeted entry disappears in constant time. The trade off is that the order of the remaining items is no longer the same as before.

Can I change the length of a Solidity uint array directly?

No. Solidity 0.5 allowed scores.length = newLen, but the assignment was removed in 0.6 and the modern compiler rejects it. Grow the array with push, shrink it with pop or delete, and reset it fully with delete scores. The length property is read only in every current Solidity version.

Written by Mudassir Khan

Agentic AI consultant and AI systems architect based in Islamabad, Pakistan. CEO of Cube A Cloud. 38+ agentic AI launches delivered for global founders and CTOs.

View agentic AI consulting serviceSee ChainTrust case study

Related service

Agentic AI Consulting

See scope & pricing →

Related case study

ChainTrust Compliance Engine

Read case study →

More on this topic

Need an AI systems architect?

Book a 30-minute architecture call. I will sketch the high-level design for your use case and give you an honest view of the trade-offs.

Book a strategy call →