I am trying to manage strings on a smart contract. I know these strings will be 46 bytes long so I thought I could convert them into bytes and split them in two bytes32 arrays. Then I realized smaller bytes sizes exist, so I opted for two bytes23 arrays. Which one should I use?
2 Answers
It really depends on what you mean by “manage strings.”
Ideally you’d just keep things simple and use string
, but yes, if you’re going to be storing these strings on-chain, then it would be a huge waste to store as string
because for each 46-byte string you’d use 2 storage slots for the 46 bytes, and an extra storage slot to write the length 46
every time.
It really depends on what you plan to do with these strings. For example, if you’re going to store an array of these 46-byte strings, it would save you a lot of storage gas to pack them all after each other back to back. In this way e.g. 10 46-byte strings would occupy 10 × 46 bytes = 460 bytes ≈ 15 slots, rather than 10 × 64 bytes = 640 bytes = 20 slots.
-
Thanks for your answer. Basically, those strings are IPFS CIDs and they will be stored in an array of CID, a struct I created composed of two bytes23 object. My dapp flow is structured in rounds and each of these rounds will have its own array of CIDs. So if i am getting it right, as long as i store them one after the other it makes sense using smaller structure (bytes23 in this case), am i right? – Commented Mar 21 at 16:26
-
I read here that if a CID is 46 characters starting with "Qm", it's a base58-encoded CIDv0 which when converted to binary is simply a 34-byte chunk of data that always starts
0x1220…
, which means that you can store it in a singlebytes32
and avoid a lot of trouble. Just make sure you know what type of CID you are dealing with before you proceed further.– dwarduCommented Mar 21 at 16:40 -
To give a more general answer… as on-chain storage is expensive, you always want to be storing data using as little bytes as possible. So you should always deal with base256-encoded data (binary) rather than data that has been encoded with less symbols (e.g. base58) to be more human-friendly. Other than that, I suggest you search this forum as some related questions have already been answered.– dwarduCommented Mar 21 at 16:55
I would recommend to stay with the usual types until you have the requirement to optimize the contract.
Trying to optimize a contract without an specific purpose will only make it more difficult to read and make changes.