Solidity tutorial: returning structs from public functions
In the current version of Solidity (0.4.13, as of this writing), it’s impossible to return a struct from a public function. For example, if you attempt to compile the following code, you will get two errors, one for each function that tries to do so:
You can open this Gist in browser-solidity with the following link: http://ethereum.github.io/browser-solidity/#gist=03f9e536d033f81fe2a2df7a74a17ddf&version=soljson-v0.4.13+commit.fb4cb1a.js
As you’ll see, the compiler complains about both functions, getBryn
and getPerson
:
TypeError: Internal type is not allowed for public or external functions.
Confirmed, it’s impossible to return structs.
However, if you’ve been coding in Solidity for a while, you might notice that the following works perfectly well:
Because the mapping
is public, Solidity automatically generates a getter for this function. That’s odd, because the getter would have to return a Person
struct, right? Let’s dig in a little bit deeper.
Let’s deploy the above contract and run the following Javascript code:
Okay, so what’s going on here?
Shouldn’t the compiler complain when we ask it to generate a getter for a mapping
that returns a Person
struct?
As it turns out, solc is smart enough to handle this case for us. Notice the return value from the invocation of project.people('0xdeadbeef')
. It’s an array, which is how Solidity tuples are returned to Javascript land. Alright, so we know that the getter is not returning a struct, per se, but rather a tuple. This is a big clue!
When the compiler generates a getter for a mapping
or an array where the element is a struct, it does something like the following:
As you can see, the getter simply breaks the struct down into a tuple. No internal types (like structs) are exposed. As a result, we get the functionality we desired with no compiler error. We simply have to be careful about the ordering of struct fields—if the order changes, we’ll have to change any code that interacts with this getter, since the order of the tuple values will change as well.
Knowing this, we can take a cue from Solidity’s implementation of this mapping
getter when writing our own functions that return structs.
Returning arrays of structs
Sometimes we might need to return an array of structs to the caller. However, if we take the naïve approach, we’ll once again run into the same limitation—we can’t expose internal types.
We learned above that we can “destructure” a struct and return it as a tuple. To return an array of structs, we will do the same thing. Each value in the returned tuple will represent a field in the struct. But because we’re trying to return many structs (and therefore, many values for each field), each field in the tuple will be an array.
Check out the following code to get a better sense of how this might look:
Getting data back in this format is, admittedly, a pain to deal with on the frontend. Depending on your frontend data model, you may very well have to write functions to “rebuild” these structs from the data you receive. I’ve thrown together a quick example to show you how you might go about doing that:
Note that struct “destructuring” is (hopefully) a temporary workaround. Solidity’s behavior is expected to change at some point in the future, making this a bit more seamless.
Find me around the web:
- Twitter: https://twitter.com/brynbellomy
- Github: https://github.com/brynbellomy
- LinkedIn: https://www.linkedin.com/in/bryn-bellomy
Join Coinmonks Telegram Channel and Youtube Channel get daily Crypto News
Also, Read
- Crypto Telegram Signals | Crypto Trading Bot
- Copy Trading | Crypto Tax Software
- Grid Trading | Crypto Hardware Wallet
- Best Crypto Exchange | Best Crypto Exchange in India
- Best Crypto APIs for Developers
- Best Crypto Lending Platform
- An ultimate guide to Leveraged Token
- Best VPNs for Crypto Trading
- Best Crypto Analytics or On-Chain Data | Bexplus Review
- 10 Biggest NFT MarketPlaces to Mint a Collection
- AscendEx Staking | Bot Ocean Review | Best Bitcoin Wallets
- Bitget Review | Gemini vs BlockFi | OKEx Futures Trading