0
0
Blockchain / Solidityprogramming~15 mins

Structs in Blockchain / Solidity - Deep Dive

Choose your learning style9 modes available
Overview - Structs
What is it?
Structs are custom data types that group together related pieces of information under one name. They let you bundle different values, like numbers and text, into a single unit. In blockchain programming, structs help organize data clearly and efficiently. They are like blueprints for creating complex data objects.
Why it matters
Without structs, managing related data would be messy and error-prone, especially in blockchain where data integrity and clarity are crucial. Structs solve this by keeping related data together, making smart contracts easier to read, write, and maintain. Without them, contracts would be harder to understand and more likely to have bugs.
Where it fits
Before learning structs, you should understand basic data types like integers, strings, and arrays. After structs, you can learn about mappings and how to use structs with functions and storage in smart contracts. Structs are a foundation for building complex data models in blockchain programming.
Mental Model
Core Idea
A struct is like a labeled container that holds different pieces of related data together as one object.
Think of it like...
Imagine a struct as a filing folder where you keep related documents like a person's ID, address, and phone number all in one place. Instead of carrying each document separately, you carry the folder that groups them neatly.
┌───────────────┐
│   Struct:     │
│  Person       │
├───────────────┤
│ name: string  │
│ age: uint     │
│ wallet: addr  │
└───────────────┘
Build-Up - 7 Steps
1
FoundationBasic Struct Definition
🤔
Concept: How to define a struct with simple fields.
In blockchain smart contracts, you define a struct by naming it and listing its fields with types. For example: struct Person { string name; uint age; } This creates a new type called Person with two pieces of data: name and age.
Result
You get a new data type Person that can hold a name and age together.
Understanding how to define a struct is the first step to grouping related data logically.
2
FoundationCreating and Using Struct Instances
🤔
Concept: How to create and access data inside a struct instance.
Once you have a struct type, you can create variables of that type: Person alice = Person("Alice", 30); You can access fields with dot notation: string aliceName = alice.name; uint aliceAge = alice.age;
Result
You can store and retrieve grouped data easily using struct variables.
Knowing how to create and use struct instances lets you organize data in your contract clearly.
3
IntermediateStructs in Storage and Memory
🤔Before reading on: do you think structs behave the same in storage and memory? Commit to your answer.
Concept: Understanding the difference between storage and memory for structs in blockchain contracts.
Structs can be stored permanently on the blockchain (storage) or temporarily during function execution (memory). For example: Person storage p = people[id]; // persistent storage Person memory temp = Person("Bob", 25); // temporary memory Changes to storage structs persist, but memory structs disappear after the function ends.
Result
You learn when changes to structs are saved or temporary.
Knowing storage vs memory behavior prevents bugs where data changes unexpectedly vanish or persist.
4
IntermediateNested Structs and Arrays
🤔Before reading on: can structs contain other structs or arrays? Guess yes or no.
Concept: Structs can hold other structs or arrays to model complex data.
You can define structs inside structs or have arrays of structs: struct Address { string street; string city; } struct Person { string name; Address addr; uint[] scores; } This lets you build detailed data models.
Result
You can represent complex real-world data in your contracts.
Understanding nested structs unlocks powerful ways to organize multi-layered data.
5
AdvancedPassing Structs to Functions
🤔Before reading on: do you think structs are passed by value or reference to functions? Commit to your answer.
Concept: How structs behave when passed as function arguments affects data changes.
When you pass a struct to a function, it can be passed by value (copy) or by reference (pointer), depending on whether it's in memory or storage: function updatePerson(Person storage p) internal { p.age += 1; } function readPerson(Person memory p) internal view returns (uint) { return p.age; } Modifying storage structs inside functions changes the original data; modifying memory structs does not.
Result
You control whether functions modify original structs or just copies.
Knowing how structs are passed avoids unintended data changes or wasted gas.
6
AdvancedStructs and Gas Optimization
🤔
Concept: How struct design affects blockchain transaction costs.
Because blockchain storage is expensive, packing struct fields efficiently saves gas. For example, grouping smaller data types together can reduce storage slots: struct Packed { uint128 a; uint128 b; } versus struct Unpacked { uint128 a; uint256 b; } The packed struct uses less storage and costs less gas.
Result
You learn to design structs that save money on blockchain operations.
Understanding gas costs encourages writing efficient, cost-effective smart contracts.
7
ExpertStructs in Upgradeable Contracts
🤔Before reading on: do you think changing struct layouts in upgrades is safe? Commit to your answer.
Concept: How struct layout affects contract upgrades and storage compatibility.
In upgradeable contracts, changing struct fields or order can corrupt stored data. Developers must keep struct layouts consistent or use storage gaps: struct Data { uint a; uint b; uint[50] __gap; } This reserved space allows adding fields later without breaking storage layout.
Result
You understand the risks and techniques for safe contract upgrades involving structs.
Knowing struct layout rules prevents critical bugs and data loss in live blockchain systems.
Under the Hood
Structs are stored as contiguous blocks of data in blockchain storage, with each field occupying a slot or part of a slot depending on its size. When accessed, the blockchain runtime calculates the storage slot based on the struct's position and field offset. In memory, structs are copied as whole objects. This low-level layout affects gas costs and upgrade safety.
Why designed this way?
Structs were designed to group related data efficiently while fitting blockchain storage constraints. The fixed layout allows predictable storage access and gas estimation. Alternatives like separate variables would be harder to manage and more error-prone. The design balances clarity, efficiency, and upgradeability.
┌───────────────┐
│ Struct Storage│
├───────────────┤
│ Slot 0: name  │
│ Slot 1: age   │
│ Slot 2: wallet│
└───────────────┘

Access flow:
Caller -> Struct variable -> Field offset -> Storage slot -> Read/Write
Myth Busters - 4 Common Misconceptions
Quick: Do structs automatically save changes made inside functions? Commit yes or no.
Common Belief:Changes to structs inside any function automatically update the stored data.
Tap to reveal reality
Reality:Only structs passed by storage reference update stored data; structs in memory are copies and changes do not persist.
Why it matters:Assuming all changes persist can cause bugs where data seems to update but actually doesn't, leading to inconsistent contract state.
Quick: Can you reorder struct fields freely without issues? Commit yes or no.
Common Belief:You can reorder or add fields anywhere in a struct without affecting existing data.
Tap to reveal reality
Reality:Changing field order or inserting fields breaks storage layout and corrupts existing data in upgradeable contracts.
Why it matters:Ignoring this can cause irreversible data loss or contract malfunction after upgrades.
Quick: Are structs always cheaper than separate variables? Commit yes or no.
Common Belief:Using structs always reduces gas costs compared to separate variables.
Tap to reveal reality
Reality:Poorly designed structs with unoptimized field packing can increase gas costs compared to separate variables.
Why it matters:Assuming structs are always cheaper can lead to inefficient contracts and higher transaction fees.
Quick: Can structs contain dynamic arrays without extra care? Commit yes or no.
Common Belief:Structs can freely contain dynamic arrays without affecting storage or gas costs significantly.
Tap to reveal reality
Reality:Dynamic arrays inside structs add complexity and higher gas costs due to separate storage and resizing operations.
Why it matters:Ignoring this can cause unexpected high gas fees and contract complexity.
Expert Zone
1
Struct field order affects storage slot packing and gas efficiency, so ordering from smallest to largest types is optimal.
2
Using storage pointers to structs inside functions can save gas by avoiding unnecessary copies.
3
Reserved storage gaps in structs are essential for safe contract upgrades to maintain storage layout compatibility.
When NOT to use
Structs are not ideal when data is simple and accessed individually; in such cases, separate variables or mappings may be clearer. Also, avoid structs with large dynamic arrays if gas cost is a concern; consider external storage patterns instead.
Production Patterns
In production, structs are used to model entities like users, tokens, or orders. Developers combine structs with mappings for efficient lookups and use storage pointers in functions to optimize gas. Upgradeable contracts carefully manage struct layouts with reserved gaps to allow safe future changes.
Connections
Classes in Object-Oriented Programming
Structs are similar to classes but usually simpler and without methods.
Understanding structs helps grasp how data grouping works in many programming languages, bridging to object-oriented concepts.
Database Records
Structs resemble records or rows in a database table, grouping related fields.
Knowing structs clarifies how data is organized and stored both in code and databases, aiding data modeling skills.
Data Serialization
Structs must be serialized to store or transmit data efficiently on blockchain.
Understanding struct layout aids in grasping how data is packed and unpacked for network or storage operations.
Common Pitfalls
#1Modifying a struct passed as memory expecting changes to persist.
Wrong approach:function updateName(Person memory p) public { p.name = "NewName"; } // Caller expects p.name to change permanently
Correct approach:function updateName(Person storage p) internal { p.name = "NewName"; }
Root cause:Confusing memory (copy) and storage (reference) causes changes to be lost after function ends.
#2Reordering struct fields in an upgradeable contract causing data corruption.
Wrong approach:struct Person { uint age; string name; } // Changed order from original contract
Correct approach:struct Person { string name; uint age; uint[50] __gap; } // Keep original order and add gap for upgrades
Root cause:Not understanding storage layout and upgrade safety leads to broken contract state.
#3Using dynamic arrays inside structs without managing gas costs.
Wrong approach:struct Data { uint[] values; } // Large arrays cause high gas on writes
Correct approach:Use separate mappings or external storage for large dynamic data instead of arrays inside structs.
Root cause:Ignoring gas implications of dynamic arrays inside structs leads to expensive transactions.
Key Takeaways
Structs group related data into one named unit, making smart contracts clearer and easier to manage.
Understanding storage vs memory behavior of structs is crucial to avoid bugs and unexpected data loss.
Designing structs with field order and size in mind can save significant gas costs on the blockchain.
In upgradeable contracts, maintaining struct layout consistency is essential to prevent data corruption.
Structs connect programming concepts like classes and database records, helping organize complex data effectively.