Let's consider the following completely useless code (tested in Remix):
// solium-disable linebreak-style
pragma solidity ^0.8.0;
contract MyContract
{
struct TestVars
{
uint8 a;
uint64 b;
uint64 c;
}
TestVars private vals;
constructor()
{
vals.a = 5;
vals.b = 6;
vals.c = 7;
}
function readValsStorage()
external
{
TestVars storage v = vals;
uint a = v.a;
uint b = v.b;
uint c = v.c;
}
function readValsMemory()
external
{
TestVars memory v = vals;
uint a = v.a;
uint b = v.b;
uint c = v.c;
}
}
The thing we are into is gas cost. It wonders me why storage is cheaper. I have read that each read from the contract storage costs gas. Also if you pack data into struct it behaves as one field unless you exceed the total size over 2^256.
So now my thougts come: if I read a, b, c from storage it will read 3 fields, so it will cause triple gas cost. It should be cheaper to read the entire struct to the memory as one field and grab variables.
But the result was opposite - the storage is cheaper. Why?