For example, I have two integers: one is uint128, another is uint64. I want to store those two integers by converting them to bytes24. And when I use them, parse the bytes24 to uint128 and uint64.
How do I do this?
Ethereum Stack Exchange is a question and answer site for users of Ethereum, the decentralized application platform and smart contract enabled blockchain. It only takes a minute to sign up.Sign up to join this community
Combining data from variables smaller than 32 bytes before storing is a good idea!
SSTORE is very expensive at 20 kilogas per EVM word (32 bytes). Luckily, Solidity will do this for you under the hood if you compile with
solc --optimize. See the "More Optimization" section of this article on the EVM for how that works. Might as well let the compiler do the work for you.
Transaction Data Cost
Sending in the parameters separately has its own gas cost. This shouldn't be top of your list of concerns, however: it only costs 68 gas per nonzero byte. That sounds like a lot for a full 32-byte uint, but if you are passing smaller values, they will have a lot of zeros (only priced at 4 gas per byte).
It turns out that you would only save 128 gas in transaction data costs by combining the fields, because you're only reducing the number of zeros you send, which are cheap. That saved gas does not even include the added cost of splitting the data again in Solidity. This is clearly not worth the effort, and probably has a net negative effect on gas costs.
Without combining the fields:
fieldA = 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF fieldB = 0x000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF transaction non-zero bytes = (128 + 64) / 8 = 24 transaction zero bytes = (128 + 192) / 8 = 40 gas cost for parameters = 68 * 24 + 4 * 40 = 1792
With combining the fields:
fieldC = 0x0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF transaction non-zero bytes = (128 + 64) / 8 = 24 transaction zero bytes = 64 / 8 = 8 gas cost for parameters = 68 * 24 + 4 * 8 = 1664