VOOZH about

URL: https://blog.logrocket.com/ultimate-guide-data-types-solidity/

⇱ The ultimate guide to data types in Solidity - LogRocket Blog


2022-04-25
2235
#blockchain#web3
Teresa Amanwachi
104962
👁 Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

Solidity is a high-level, object-oriented programming language that is used to write smart contracts and build DApps. It also supports inheritance, libraries, and sophisticated user-defined types.

👁 Solidity Logo Over Colorful Background

Solidity is statically typed, so the data type for each variable must be specified at compile time. The variables can only accept the data type for which they were designed by the developer and cannot be altered dynamically.

The differences between data types in Solidity and those of other programming languages are subtle, but significant enough that many developers find this topic to be confusing.

Like other programming languages, Solidity classifies data into different types. But, Solidity is somewhat unique in that it has several elementary types that can be combined to form complex types.

This article is designed to be a comprehensive guide to Solidity data types — both value types and reference types. Having a clear understanding of data types in Solidity is essential for building smart contacts.

Jump ahead:

🚀 Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

Solidity value types

A value type stores its data directly in the memory it owns. Variables of this type are duplicated whenever they appear in functions or assignments. A value type will maintain an independent copy of any duplicated variables. Therefore, a change in the value of a duplicated variable will not affect the original variable.

There are several value types in Solidity: signed integers, unsigned integers, Boolean, addresses, enums, and bytes.

Signed integers

A signed integer, declared with the int keyword, is a value data type that can be used to store either positive or negative values in smart contracts.

int is an abbreviation for int256, which has a range of -2 ** 255 to 2 ** 255 - 1. This value type takes up to 32B by default, but we can make it smaller by specifying the number of bits in steps of 8. For example: int8, int16, int32, etc.

Here’s an example of a signed integer in Solidity:

pragma solidity ^0.5.10

// example of int value type in solidity

contract SampleInts }

 { int = -168; }

Unsigned integers

An unsigned integer, declared with the uint keyword, is a value data type that must be non-negative; that is, its value is greater than or equal to zero.

uint is an abbreviation for uint256. Just like signed integers, this value data type takes up to 32B by default. Again, we can make it smaller by specifying the number of bits in steps of 8. For example: uint8, uint16, uint32, etc.

These integers are restricted to a range based on their size. For example, uint8 has a range of 0 to 2 ** 8 -1, and uint256 has a range of 0 to 2 **256 - 1.

Here’s an example of an unsigned integer in Solidity:

pragma solidity ^0.5.10

// example of uint value type in solidity

Contract SampleUints }

 uint public u16 = 1890;
 uint public myUint u = 256;

}

Boolean

The bool value data type is used in Solidity to illustrate cases that have binary results. A bool has two fixed values: true or false, with false being the default. This data type only takes up 1B of storage.

Solidity supports all standard Boolean operators, such as:

  • != (inequality)
  • == (equality)
  • ! (logical negation)
  • && (logical conjunction, “AND”)
  • || (logical disjunction, “OR”)

It is essential to understand that you cannot translate the bool data type into integers in Solidity like you would with other programming languages. Also, in Solidity any assignments to other Boolean variables creates a new copy of the variable.

Here’s an example showing how a bool data type is declared and assigned a value in Solidity:

pragma solidity ^0.5.10

// example of a bool value type in solidity

Contract SampleBool } 

 bool public IsVerified = False;
 bool public IsSent = True;

}

These variables can be modified and applied in both incoming and outgoing parameters within smart contracts.


Over 200k developers use LogRocket to create better digital experiences

👁 Image
Learn more →

Addresses

An address value type is specifically designed to hold up to 20B, or 160 bits, which is the size of an Ethereum address.

Solidity actually offers two address value types: address and address payable. The difference between the two is that address payable can send and transfer Ether.

We can use an address to acquire a balance using the .balance method and to transfer a balance using the .transfer method.

Here’s an example of an address data type in Solidity:

pragma solidity ^0.5.10

// example of an address value type in solidity

Contract SampleAddress } 
 address public myAddress =
0xb794f5ea0ba39494ce839613fffba74279579268;

}

Enums

Enums, or enumeration, values in Solidity consist of user-defined data types. This data type is used explicitly for constant values, such as the names of integral constants, making a smart contract easier to read and maintain. Enums can help reduce the incidence of bugs in your code.

Enums limit a variable to a few predefined values and each copy maintains its value.

Options are represented by integer values beginning with zero; you can also specify a default value for the enum.

Here’s an example declaring an enum named food_classes consisting of six constant values: carb, protein, fats-oils, water, vitamin, and minerals:

pragma solidity ^0.5.10
// example of an enum value type in solidity
Contract SampleEnum } 

 enum < food_classes > }
 carb, protein, fats-oils, water, vitamin, and minerals;
}

It’s important to note that DApps do not recognize an enum within a smart contract. An integer value that corresponds to the enum constant must be provided.

Bytes

In Solidity, byte refers to 8-bit signed integers. Everything in memory is stored in bits with binary values 0 and 1.


More great articles from LogRocket:


The bytes value type in Solidity is a dynamically sized byte array. It is provided for storing information in binary format. Since the array is dynamic, its length can grow or shrink.

To reflect this, Solidity provides a wide range — from bytes1 to bytes32. The data type bytes1 represents one byte, while bytes32 represents 32B. 0 x 00 is the default value for byte. This value is used to prepare the default value.

Here are some examples of the bytes data type in Solidity:

pragma solidity ^0.5.10

// example of a byte data type in hexadecimal format in solidity

Contract SampleByte }

 bytes1 uu = 0 x 45;

}
pragma solidity ^0.5.10

// example of a byte data type in integer values decimal format in solidity

Contract SampleByte } 

 bytes1 pp = 12;

}
pragma solidity ^0.5.10

// example of a byte data type in -ve int values in decimal format in solidity

Contract SampleByte } 

 bytes1 ff = -62;
}
pragma solidity ^0.5.10

// example of a byte data type in character values in solidity

Contract SampleByte } 

 bytes1 ee = 'd'
}

Solidity reference types

Solidity reference types differ from value types in that they do not store values directly on their own. Instead, reference types store (or “reference”) the address of the data’s location and do not directly share the data.

Reference data types must be handled cautiously since they deal with storage locations. Data location affects the amount of gas used in a transaction and therefore can negatively impact smart contract development performance.

When using reference types, reference variables point a user to the location of value storage, and these can take up more than 32B of memory in size.

Two separate variables can refer to the exact location, and any change in one variable can affect the other. Several variables that point to the same address can be used to effect a change in a reference data type.

There are several reference data types in Solidity: fixed-sized arrays, dynamic-sized arrays, array members, byte arrays, string arrays, structs, and mapping.

Arrays

Arrays are a group of variables of the same data type, with each variable having a unique index. Array size can be fixed or dynamic.

Arrays data structures are dependent on other data types. They keep these data in storage and simplify the process of repetition, storage, and search for variables or a subset of variables within a group.

We can retrieve a requested variable by using the unique index location.

Here’s an example of an array in Solidity:

pragma solidity ^0.5.10

// code illustration of array in solidity

Contract SampleArray } 

 uint [10] = MyIntArray ;
}

Fixed-size arrays

Fixed-size arrays have a predefined size when they are declared.

Here’s an example of a fixed-size array in Solidity:

pragma solidity ^0.5.10

// code illustration of fixed-size array in solidity

Contract SampleFixedSizeArray }

uint[6] arrayName;

}

In Solidity, we cannot use the new keyword with a fixed-size array. Instead, the array’s data variables must be initialized inline, like so:

pragma solidity ^0.5.10

// code illustration of fixed-size array in solidity
Contract SampleFixedSizeArray }
uint [6] age = [ unit (60), 70, 80, 90, 100, 110] ;

They may also be initialized inline with a function:

pragma solidity ^0.5.10

// code illustration of fixed-size array in solidity

Contract SampleFixedSizeArray }
uint [6] age ;
age = [ unit (60), 7, 8, 9, 10, 11] ;

Dynamic-size arrays

Dynamic arrays do not have a predefined size when they are declared. Instead, their size is determined at run time.

Here’s an example of a dynamic-size array in Solidity:

pragma solidity ^0.5.10

// code illustration of fixed-size array in solidity

Contract SampleDynamicSizeArray }

int[] arrayName; 

We can initialize a dynamic array either inline or by using the new keyword like so:

pragma solidity ^0.5.10

// code illustration of dynamic-size array in solidity

Contract SampleDynamicSizeArray }

 int[5] englishMarks = [uint(50), 60,70,80,90];
 int[] scienceMarks = new int[](5);

Array members

Array members have the following properties:

  • Length: deals with the number of elements; it is used to count the number of elements in an array

After they are built, storage arrays have a fixed length. It can, however, be dynamic and determined by runtime parameters. The length of dynamically sized arrays is set to adjust their size.

  • Push: a member of dynamic storage arrays used to add an element to the array at the last position
  • Pop: a member that removes elements from the end of a dynamic array of bytes and storage (not strings)

Here’s an example of array members in Solidity:

pragma solidity ^0.5.10

// code illustration of array members in solidity

int[] public array ;
 int length = array length; // get the length of the array
 array push(u); // Append to array 

 array pop(); // Remove last element from array

Now let’s learn about two special arrays provided in Solidity: the byte array and the string array.

Byte arrays

A Solidity byte array is a dynamic array that can hold any number of bytes. This differs from the bytes value type we discussed earlier, which can take 32B for each variable. A byte array holds all of the bytes together tightly.

The byte array can be used in the following ways:

  • declare a state element with initial length size
  • divide into code lines that are similar to the arrays previously discussed
  • assign values directly and have values pushed into it
  • provide a read/write length property

Here’s an example of a byte array in Solidity:

pragma solidity ^0.5.10

// code illustration of byte array in solidity
 
Contract SampleBytesArray {

// as a state variable
 bytes simBytes = riBytes (2)

// as divided code lines 
 bytes simBytes ;
 simBytes = riBytes (8)

// with directly assigned values
 simBytes = " Lorem Modi " ;

// with values pushed into it
 simBytes. push ( byte(10) ) 

// as read/write length property
 simBytes. length = 5; // setting bytes length to 5 bytes

String arrays

String arrays are dynamic, like byte arrays, but they have unique constraints. For example, string does not have an index so it lacks array members such as length, push, and pop. If three is a need to perform any of these functions, string variables should be converted to bytes first, and then converted back to strings after the operation

They can be composed of characters within a single or double quote.

Here’s an example of a string array in Solidity. Note that the strings are declared and the values are assigned directly:

pragma solidity ^0.5.10

// code illustration of a string array in solidity

Contract SampleString
 String name = ' Lorem Modi " ;

// convert back to bytes
 Bytes ByteName = bytes ( name ) ;

Structs

The struct reference type in Solidity refers to a new (or custom) data type. You can use the struct keyword to define a structure, made up of multiple variables, which can be both value type and reference type.

In most cases, struct is used to represent a record.

It’s important to note that because structs must be finite in size, they cannot contain members of their type. This is not to say that struct cannot contain struct; for example, struct A can contain struct B, but struct A cannot contain struct A.

Here’s an example of a struct data type in Solidity:

pragma solidity ^0.5.10
// code illustration of string array in solidity

Contract SampleStruct

struct patient {
 string name;
 string age;
 uint16 gender;
 }

Mapping

In Solidity, mapping functions similarly to a hashtable or dictionary in other programming languages.

Mapping is the most frequently used reference type in Solidity. Mapping types are used to store data in the form of key-value pairs, where the key can be any of the inbuilt data types except for reference types, and the value can be any type.

The mapping function can retrieve stored data using the supplied key.

Because Solidity mapping only provides an option for one data storage location, this data type is permitted for state elements.

The mapping type is declared using the mapping keyword followed by data types for both key and value, separated by the => notation.

Here’s an example of a mapping type in Solidity:

pragma solidity ^0.5.10
// code illustration of mapping type in solidity
Contract SampleMap 
 
mapping (unit => address) Variables;

Conclusion

In this guide, we covered the relation and application of Solidity value types and reference types in smart contract development.

I hope this was a helpful tutorial on what is ostensibly a complex topic for many developers.

Enjoy your Solidity development journey!

Join organizations like Bitso and Coinsquare that use LogRocket to proactively monitor their Web3 apps

Client-side issues that impact users’ ability to activate and transact in your apps can drastically affect your bottom line. If you’re interested in monitoring UX issues, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

👁 LogRocket Dashboard Free Trial Banner

LogRocket lets you replay user sessions, eliminating guesswork around why bugs happen by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks.

LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.

Modernize how you debug web and mobile apps — start monitoring for free.

👁 Image
👁 Image
👁 Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

Debug Next.js apps with AI agents and next-browser

Learn how next-browser gives AI agents runtime context for debugging Next.js apps, including React props, hydration, PPR, forms, and performance.

👁 Image
Emmanuel John
Jun 17, 2026 ⋅ 9 min read

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

👁 Image
Chizaram Ken
Jun 16, 2026 ⋅ 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.

👁 Image
Ikeh Akinyemi
Jun 12, 2026 ⋅ 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo — with email/password login, Google OAuth, session persistence, and protected routes.

👁 Image
Chinwike Maduabuchi
Jun 9, 2026 ⋅ 13 min read
View all posts

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now