contract Adder {
uint public a;
function add() public {
for (uint i; i < 100; i++) {
a += i;
}
}
}Почему в этом случае первый вызов функции
add стоит сильно больше газа (на 20к больше), чем последующие? И почему вот с таким кодом:contract Adder {
uint public a = 1; // a любой, но НЕ нулевой
function add() public {
for (uint i; i < 100; i++) {
a += i;
}
}
}вызовы стоят одинаково? Я и раньше замечал такую вещь, причём в разных средах. Ответ, на самом деле, очень простой: эта логика зашита прямо в EVM. Читаем документацию по опкодам:
* G(sset) — 20000 Paid for an SSTORE operation when the storage value is set to non-zero from zero
* G(sreset) — 2900 Paid for an SSTORE operation when the storage value’s zeroness remains unchanged or
is set to zero.
То есть переводя с русского на человеческий:
* Мы платим 20к газа, если сохраняем в переменную состояния новое НЕ нулевое значение, но только в том случае, если эта переменная хранила до этого ноль
* Но мы платим всего лишь 2900 газа, если в не-нулевую переменную мы сохраняем что-то ещё (или она была нулевой и осталась нулевой)
Отака история, малята.