How do I store an array of objects per account?

I need to store an array of objects in one account, with non-fixed size, because I want to dynamically add objects to that array via instruction.
Is it possible?
If yes, where can I find some examples?

1 Like

Hi @nazar and welcome to the forum! :wave:

This very question was one the big hurdles I had to figure out while making my first Solana program. :slight_smile: Unfortunately I never really found any good examples and I had to figure it out myself. While I can tell you how I solved it, I don’t have a lot of great tutorial-like demo code.

Still, the way I solved it was by storing each item that there could be a dynamic number of in a separate account. Unfortunately, I don’t have much good examples, other than the little demo app I made here:

The interesting front-end code is here and the Solana program is here.

In my case I had to create calendar “time slots” that acted as reservations. There could be any number of different calendar reservations, no fixed number, so what I did was create a separate Solana account for every time slot. That time slot held things like the start time, the end time, whether or not the slot was reserved yet, and if it was, who reserved the slot.

In order for the frontend to list all the time slots for a specific user, I used the getProgramAccounts function from the web3.js API, and I passed it a filter that would filter on all accounts that had the owner set to the ID of the user I was looking for.

Let me know if you have any questions!

2 Likes

Hey, @zicklag, thank you for sharing the example.
That can be the case for us, however, we need to store a large amount of data, like 300k and with this approach, each item will need to have an account created to store that data item. And what did I see in docs is that for each account I need to pay rent, so I wonder won’t this be too expensive?

PS. Does this line in your repo actually pay for the rent when creating account?

1 Like

Oh, yeah, that sounds like a lot for storing directly on the blockchain. That would probably be really expensive. It looks like at the current price of SOL that would be $334 for two years of rent for 300k. If you pay two years of rent, the data will be permanent on the chain. The price of SOL is currently in a slump, though, so the price would probably be even higher ( in dollars ) as the market price of SOL goes up.

Yep. The minimum_balance function will calculate two years of rent so that the record will be permanently stored, without having to have it’s balance replenished over time as it gets charged rent.


Instead of storing that much data directly on the chain, though, I think you will have to use something like IPFS. I can explain more if you have any questions about IPFS, but essentially you would upload your data to IPFS, and then IPFS will give you a small hash that represents that data. You then store the hash on the blockchain to represent that account.

You’ll already know some of what I mention there, but you might also want to check out another one of my posts which mentions a little more about how you might design a full-blown app in Solana:

2 Likes

if we would go with storing that all data on IPFS, as I understood it would give only one hash for all the data that we can store on blockchain, but we need to have the ability to verify each record separately.
Then I think there is no difference btw those approaches, to store all data in blockchain or to store each record in IPFS and hash of each record in blockchain because we will end up storing all that 300k records in blockchain anyway. Is that correct or do I miss smth?

1 Like

I also had a thought to store the original data in a traditional database and only hashes of each record in the transactions. But what are the cons of this approach as compared to storing each record in the account?

1 Like
  • You would store each record in separately in IPFS and each would get it’s own hash.
  • You would store each record’s hash in a separate account on the blockchain
  • So instead of storing 300kb on the blockchain for each record, you would only store the size of the hash, which is like 64 bytes or something like that ( I can’t remember for sure the size of the hash ).

That way each record on the blockchain will link to the full data for the record on IPFS.

That’s essentially exactly what you’d be doing with IPFS. Storing only the hash of the record on the blockchain, so that you blockchain storage costs are minimum.

The disadvantage to doing this is that it doesn’t work for data that you need to perform some sort of on-chain verification for.

For instance, if you needed to store data on the blockchain that said how many likes that somebody got on a post, you would have to make sure that any user that likes a post, could only increase the like count by one. If you were just storing the hashes of an IPFS record on the blockchain, the blockchain has no way to go and read the data inside the IPFS object, so it can’t make sure that the user only adds one like to the like count.

So if you store data external to the blockchain, it has to be some kind of data that you can totally trust the user to set to whatever they want to. Things like the contents of a blog post, or an image or something would all make sense to store off the chain. Things that have strict rules that must be verified on-chain when changes are made, though, would have to be stored on the chain where the smart contract can get to it during the execution of a transaction.

1 Like

thank you so much,
Sorry I meant we are going to store 300 000 records with approximately 225.8 B for each document with its full size. But yeah, probably storing only the hash of that data will make more sense. Since we don’t need to perform any kind of on-chain operations, but only to verify the data integrity, that can be done by hash only.
And wouldn’t the price for rent of 300 000 accounts be too big?

1 Like

Oh, yeah, that’s even worse, because even if each hash was only 32 bytes for instance, that would still be thousands of dollars in rent for that many accounts.

Solana may reduce the rent fees sometime, maybe the release after the next, but I’m not sure about when that will be, and I’m not 100% it’s going to happen. There have been other people who said that the rent fees would just be too high that they can’t migrate to Solana.

Rent fees are only supposed to be enough to cover validator storage expenses, the issue is that rent is measured in SOL, and the price of SOL on the open market has fluctuated so much that now rent is much more expensive that it used to be. Eventually I think they plan on fixing this so that rent can be responsive to the price of SOL, but we’re not there yet.


I can’t think of much options that you have in this case. If you need to validate each record individually, you have to have a different account for each record. I don’t see a way around it without validating it off of the Solana chain in your own system, which pretty much makes it centralized and probably defeats your reason for using the blockchain in the first place.

I’m not sure what your use-case is, but my only thought is that the cost might be reasonable if, for example, you offloaded that initial setup fee to your users, assuming that each account was specific to a user or something like that. The fee for each user would probably be less than $0.30, which isn’t shocking, but I’m not sure if that fits your use-case.

1 Like

thanks for the response.
could you please describe how to calculate the rent for the 300 000 accounts?
I’ve seen the formulas in the doc, but it’s looking not clear for me.

1 Like

and talking about options, is another option to store each record’s hash inside the transaction a valid case?
then we wouldn’t have to use accounts and to pay for rent

1 Like

I use the solana rent command in the Solana CLI. It lets you pass the number of bytes your account will be and it tells you what the rent will be for that many bytes.

# 300000 accounts * 64 bytes ( assuming that's how many bytes a hash is ) = 19200000
$ solana rent 19200000
Rent per byte-year: 0.00000348 SOL
Rent per epoch: 0.365874729 SOL
Rent-exempt minimum: 133.63289088 SOL

That’s an interesting idea. Technically the transaction data is visible on the chain, because I can see the instruction data in the Solana explorer, but I don’t think it’s at all possible to access the data from past transactions inside of a Solana program.

So as far as I understand, “storing” the data in Solana transactions might work if you only ever needed to read the data off-chain, but not if you need to access those accounts in a smart contract.

2 Likes

I did a calculation of the approx price for a month’s storage of all that data, is that correct?

Rent per epoch: 0.365874729 SOL

Assuming one epoch now takes 2 days, we can calculate the approx price for a month:

0.365874729 * 15 = 5,488120935 SOL per month

Which is now with the current price of SOL ($157.59):

5,488120935 * $157.59 = $864,87 price per month
1 Like

@zicklag I just realized that our calculations probably are not correct, because solana rent command is calculating the rent per account with a given length

so instead of doing this solana rent 19200000, which will calculate the rent for the account with the length of 119200000, we should do this solana rent 64 and that would be the price for storing one account with the length of 64 bytes

that been said the calculation for the rent of one account per month:

âžś  ~ solana rent 64    
Rent per byte-year: 0.00000348 SOL
Rent per epoch: 0.000003658 SOL
Rent-exempt minimum: 0.00133632 SOL

0.000003658 * 15 (epochs in month) * $157.59 = $0,008 (rent of one account per month)

$0,008 * 300000 = $2400 (price for all our accounts)

1 Like

Good catch!

That looks about right, I made a NoteCalc note to make it easy to play with the values and double-check the math. ( You can follow the link and play with the note, too )

So in order to make the account storage permanent ( rent exempt ) for that many accounts, it looks like it would cost $63,177 total with SOL going at $157.59. But now SOL is going for $183.42 and that brings the total up to $73,532.

To see if there was any difference I added the price of one big account to the note, and it looks like one mega account is actually cheaper, not that it helps us, because we need them separate.

2 Likes

Thank you for making that cool note calc, awesome stuff!
Does rent exempt means that we need to have that sum ($63k) on our account and the account wouldn’t be charged? Pretty much like staking SOLs inside the account, right?

1 Like

I know, right! That tools is neat. :slight_smile:

Yeah, pretty much. When you create any Solana account, usually you will deposit 2 years worth of rent inside of that account, so that it will be persisted forever and never actually charged that rent.

If you deposit less than two years of rent, though, it will be charged and you will have to keep re-filling the SOL in that account or it will eventually have it’s SOL balance drop to zero and it will be deleted.

1 Like