New to Rust? Grab our free Rust for Beginners eBook Get it free →
How to Use Mappings Inside Structs in Solidity

A mapping can live inside a Solidity struct when the struct stays in storage. That layout lets one record hold ordinary fields such as a name plus values keyed by addresses, but it also changes what you can copy or return from a function. I compiled the contract below with solc during this refresh, so the example starts from a contract artifact rather than a sketch.
The storage rule behind a mapping in a struct
A mapping is a key-to-value lookup that Solidity stores persistently. Unlike an array, it has no length and Solidity does not keep a list of its keys for you to loop through.
Solidity allows a mapping as a struct member, including a struct reached through another mapping. The restriction is the important part: mappings and structs that contain them belong in storage, not memory, because Solidity cannot create an independent in-memory copy of an unbounded key space. The Solidity Types documentation also limits public function parameters and returns to ABI-safe types.
Each Member can keep a different credit amount for every address because the state mapping supplies the storage location for the struct.
A working mapping-inside-struct contract
The contract below stores one Member for each caller, with a credits mapping owned by that record.

Read and write the nested mapping
setCredit reaches the record with members[msg.sender], then writes through credits[account]. An unset key reads as the value type’s default, which is 0 for uint256.
getMember takes a storage reference to the outer record and returns its name with one nested value. That result is compatible with the application binary interface (ABI).
What Solidity cannot return or copy
You cannot return a Member value that includes its mapping, and you should not expect a mapping-containing struct to behave like a normal memory object. A mapping has no enumerable key collection, so there is no complete value for the ABI encoder to serialize.
Expose a specific lookup, a scalar summary, or a separate key list when callers need enumeration. A key list adds storage and update work, so use it only when the contract must discover every key rather than inspect a known one.
Return a summary instead
getMember accepts the inner key as an input and returns only values that the ABI can encode.
When to use this layout
Use a mapping inside a struct when each parent record needs its own keyed collection. Membership flags, per-user balances, permissions, and per-project settings are common fits because the caller usually knows both the parent and inner key.
Choose a different layout when the contract must enumerate every entry on-chain or return the complete collection to a frontend. A separate array of keys can support enumeration, but validate how duplicate prevention and deletion affect gas before adding it.
Next step
Compile the contract, deploy it in a local test environment, then call setCredit and getMember with the same owner and account addresses. That small test verifies the storage path that matters: owner, Member record, and the nested mapping entry.
Can a Solidity struct contain a mapping?
Yes. A Solidity struct can contain a mapping when the struct is used in storage. The mapping cannot be copied into memory or returned as part of a struct through the ABI.
Why can I not return a struct with a mapping in Solidity?
A mapping has no enumerable key list and is storage-only. Solidity cannot serialize the complete mapping through the ABI, so return scalar fields or a lookup result instead.




