У меня есть несколько вопросов.
uint8, uint16, uint32, etc.
я прочитал это:Обычно от использования этих подтипов нет никакой пользы, потому что Solidity резервирует 256 бит памяти независимо от размера uint. Например, использование uint8 вместо uint (uint256) не сэкономит вам газа.
Итак, если я наберу непосредственно в контракте переменную состояния, что-то вроде этого:
uint8 test
Почему везде, где я его использую, потребление газа не будет меньше, чем uint32 test2
? Я спрашиваю, потому что с uint8 test1
, я использую меньше места для хранения.
// way1
struct Person {
uint8 test1;
uint32 test2;
uint8 test3;
}
// way2
struct Person {
uint8 test1;
uint8 test2;
uint32 test3;
}
Почему второй способ потребляет меньше газа, чем первый? Если мы посмотрим на обе структуры, то увидим, что они обе потребляют одинаковое количество памяти, но все же говорят, что way2 будет намного лучше для меньшего потребления газа. Почему ?
Это о том, как переменные упакованы вместе и о том, насколько умен компилятор (подсказка: не очень умен). Компилятор только пытается упаковать последующие переменные вместе, но он не может упаковать переменные, между которыми есть что-то еще.
В вашем первом случае все переменные могут поместиться в один 32-байтовый слот, но, если я не ошибаюсь, компилятор этого не делает, потому что они разных типов. Во втором случае первые две переменные имеют один и тот же тип и могут быть плотно упакованы внутри одного слота, что позволяет сэкономить газ.
Вы можете прочитать больше об упаковке переменных, например, здесь: https://fravoll.github.io/solidity-patterns/tight_variable_packing.html
Ника Курашвили
Лаури Пелтонен