[Ethereum] Is it reasonable to use uint128 or less to save space

evmoptimizationsolidity

As I understand EVM operates blocks of 256 bits. So uint256 is natural size for in memory calculations.

But I can't find in the documentation how it's applied to transactions and for storage.

I mean, is there any benefits of using:

function x(uint64 a, uint64 b)

instead of:

function x(uint a, uint b)

How much first transaction will take, and seconds? both will use 512 bits for data? or first 128 bits, second 512? maybe first will be 256 bit, as a minimal block length?

Same question for structs used in mapping values, say:

struct something {
  uint8 x, uint64 y
}

compared to:

struct something {
  uint x, uint y
}

Is there any storage optimization that EVM can use for the first struct?

Best Answer

In storage, variables are packed tightly, so your struct will fit in one word. See this page of the docs: http://solidity.readthedocs.io/en/latest/miscellaneous.html

For parameters, packing's less important since it's ephemeral data. Function arguments are always in memory: https://solidity.readthedocs.io/en/latest/frequently-asked-questions.html#what-is-the-memory-keyword-what-does-it-do

Another question though is the format of the transaction that goes over the wire. I'm having trouble finding the documentation for the format, but I did find a page saying that arguments are padded to 32 bytes in the ABI: https://github.com/ethereum/wiki/wiki/Solidity-Features

In any case it's definitely not a major cost difference. Looking at gas prices in the yellow paper, storing one word is 20,000 gas. Each nonzero byte of transaction data is just 68 gas. If each parameter is padded to 256 bits, then we'll have a bunch of zero bytes, and those only cost 4 gas. (Since zeros are cheaper I'm tempted to think these are packed, but I don't know for sure.)

Related Topic