Как блокчейн Ethereum побуждает пользователей очищать хранилище
5 апреля 2023 г.Знаете ли вы, что EVM имеет функцию вознаграждения пользователей возвратом газа за очистку сетевого хранилища, занятого контрактными данными? Давайте узнаем больше об этом. После лондонского форка произошли некоторые изменения, но чтобы лучше понять это, мы рассмотрим сценарий до лондонского обновления, а затем мы увидим изменения, предложенные в лондонском обновлении.
Но прежде чем приступить к возмещению, мы должны получить некоторое представление о потреблении газа для хранения; это упростит понимание расчетов газа.
Я скопировал некоторые объемы газа непосредственно из бумаги Ethereum Yellow, давайте посмотрим, что это такое:
1. Gcoldsload — 2100 Стоимость доступа к холодному хранилищу.
2. Gsset — 20 000 Оплачивается за операцию SSTORE, когда значение хранилища задано ненулевым с нуля.
3. Gsreset — 2900 Оплачивается за операцию SSTORE, когда нулевое значение хранилища остается неизменным или установлено равным нулю.
4. Rsclear — 15 000 Возврат предоставляется (добавляется в счетчик возврата), когда значение хранилища установлено равным нулю с отличного от нуля.
Давайте быстро разберемся в этом:
1. Gcoldsload — вы должны платить каждый раз, когда получаете доступ к любой переменной хранилища в первый раз в функции, второй или последующий раз это стоит 100 газа. em>
2. Gsset – платите каждый раз, когда вы устанавливаете для любой переменной значение от нуля до отличного от нуля (от false до true в случай булов). Проще говоря, вы меняете значение по умолчанию, и теперь узлы должны отслеживать этот слот.
3. Gsreset — платите каждый раз, когда вы устанавливаете ненулевое значение на ненулевое или нулевое значение.
4. Rsclear — Каждый раз, когда вы устанавливаете какое-либо значение на значение по умолчанию, вы получаете возмещение.< /p>
Запомните эти моменты, прежде чем мы начнем
- Всякий раз, когда мы устанавливаем любое значение от ненулевого до ненулевого или от ненулевого до нуля, мы в совокупности говорим, что потребляемый газ равен 5000, добавляя Gcoldsload < em>и Gsreset.
- Каждая транзакция потребляет весь соответствующий газ во время выполнения, а возврат средств рассчитывается в самом конце транзакции.
- К каждой транзакции прилагается начальный газ, равный 21 000. Этот газ расходуется валидатором, чтобы определить, действительна транзакция или нет. 21 000 добавляется к каждой транзакции, и мы не можем это контролировать, поэтому каждая транзакция потребляет 21 000 плюс газ, необходимый для данных функции.
- Приведенные ниже расчеты газа неявно включают 21 000 газа.
Возврат работает всякий раз, когда вы устанавливаете значение по умолчанию. Для uint это ноль; для логического значения — false и т. д. Для простоты понимания я приведу примеры uint.
Перед лондонской развилкой
EVM возвращает газ пользователю в двух случаях. Во-первых, если вы вызываете функцию selfdestruct
, 24 000
газа возмещается из общего количества потребленного газа. Это было просто, и говорить не о чем, так как функция возврата газа для selfdestruct
была удалена в EIP-3529, а недавно метод selfdestruct
также устарел.
Во-вторых, если вы установите для любой переменной значение по умолчанию, вы получите возмещение в размере 15 000. Почему это происходит? Установка значения по умолчанию означает, что вы очищаете хранилище, поскольку узлам не нужно отслеживать тот конкретный слот хранилища, который вы только что очистили.
Это скриншот бумаги Ethereum Yellow, в которой указана сумма возмещения.
Но есть правильный способ расчета стоимости бензина для возмещения.
Вот ссылка из журнала Ethereum Yellow.
Механизм: возврат средств осуществляется в конце любой транзакции и ограничивается максимальным числом. Это максимальное количество составляет половину всего использованного газа.
Давайте разберемся на примере uint. Что происходит, когда мы устанавливаем любое ненулевое значение uint равным нулю?
Предположим, вы устанавливаете единственную переменную uint в нулевое значение в транзакции, поэтому общий применимый возврат средств будет 15 000
, но общий расход газа в этой транзакции составляет 24 000
, половина из которых составляет 12 000
, теперь 12 000
становится максимальным количеством газа, которое можно вернуть, что означает, что транзакция теперь будет стоить вам24 000 — MAXIMUM_GAS_REFUNDABLE = 24000–12000 = 12000< /код> газ.
Хотя мы рассчитывали вернуть 15 000
газа, лимит был ограничен 12 000
, что уменьшило сумму до 12 000
. Что, если наша транзакция потребляет 40 000
газа? В этом случае половина 40 000
составляет 20 000
, что больше, чем 15 000
, поэтому мы получим возмещение в размере 15 000
. газ.
Это было в случае, когда вы устанавливаете только одну переменную uint в ноль, что произойдет, если мы установим в ноль несколько переменных uint? Например:
contract {
uint256 count = 1;
uint256 count2 = 2;
uint256 count3 = 3;
uint256 count4 = 3;
uint256 count5 = 3;
uint256 count6 = 5;
uint256 count7 = 6;
uint256 count8 = 6;
function setTOzero() external {
count = 0;
count2 = 0;
count3 = 0;
count4 = 0;
count5 = 0;
count6 = 0;
count7 = 0;
count8 = 0;
}
}
//Transaction cost will be 21000+ execution cost
//execution cost = 8 * (Gcoldsload +Gsreset) = 8 * 5000 = 40000
// Transaction cost = 21000 + 40000 = 61000
Какой бы ни была стоимость вашей транзакции, она составляет EXECUTION_COST+ 21 000
. Теперь возврат рассчитывается на основе того, сколько переменных вы устанавливаете по умолчанию. В этом случае мы устанавливаем 8 переменных uint равными нулю, поэтому возвращаемая сумма считается равной 15 000 * 8 = 120 000
.
Подождите, если это сумма возврата, то сколько газа потребляет наша транзакция? Когда вы подсчитаете количество потребляемого газа, вы получите примерно 61 000
. Что произойдет, если 120 000
газа будет возмещено по транзакции на 61 000
? Платить за транзакцию будет майнер, поэтому был введен механизм ограничения.
Согласно формуле, максимальный газ, подлежащий возврату, составит 61000/2 = 30500
. Таким образом, расход газа составит 61000–30500 = 30500
вместо 61000–1 20 000
. Теперь я думаю, что вам это довольно ясно, но этот метод больше не действует после лондонского обновления.
Если вы хотите проверить это, вы можете переключиться на берлинскую версию VM в Remix IDE и посмотреть, как все работает.
Теперь давайте посмотрим, что изменилось в лондонском обновлении.
Обновление после Лондона
Эти цифры изменились после появления EIP-3529 в Лондонском обновлении. Сумма возврата газа теперь уменьшена до 4800
, а максимальная сумма, которую можно вернуть, теперь составляет одну пятую часть потребленного газа. Давайте разбираться с тем же подходом, что и раньше.
В первом случае, если мы устанавливаем только одну переменную в ноль, транзакция потребляет 26 000
. когда мы замечаем правило максимального количества газа в EIP-3529, оно говорит TOTAL_GAS_CONSUMED, деленное на 5, что в нашем случае 26 000/5
равняется 5 200
, что означает, что мы имели право на максимальный возврат 5200
в этой транзакции, но, как указано в EIP-3529, сумма возврата составляет 4800
. На этот раз нам возвращается 4800
, а транзакция стоит 21400 газа
(немного дополнительного газа).
Давайте возьмем второй случай, когда мы устанавливали 8 переменных равными нулю. Расход газа по-прежнему составляет 61 000
. Говоря о возмещении, мы ожидаем, что общий возврат составит 4800 * 8 = 38 400
, то есть ожидаемое потребление составит 61000–38400 = 22600
.
Но когда вы выполните эту транзакцию, вы заметите, что потребляемый газ составляет 49 000
. Теперь вы понимаете, что максимальное количество газа, подлежащего возмещению, ограничено до 61 000/5 = 12 200
, что означает, что общая сумма транзакции составит 61 000–12 200 ~ 49 000
.< /p>
Вы можете подумать, что привело к тому, что компенсация за газ стала ниже при обновлении Лондона. Посмотрите на причины, которые я скопировал с официального сайта EIP:
Возврат газа для _SSTORE_
и _SELFDESTRUCT_
изначально был введен, чтобы побудить разработчиков приложений писать приложения, которые практикуют “ хорошая государственная гигиена», очищая слоты для хранения и контракты, которые больше не нужны. Однако преимущества этого метода оказались намного ниже, чем предполагалось, а возмещение расходов на газ имело несколько неожиданных пагубных последствий:
* Возврат средств приводит к созданию GasToken. GasToken имеет преимущества в перемещении газового пространства из периодов с низкой оплатой в периоды с высокой оплатой, но у него также есть недостатки для сети, особенно в увеличении размера штата (поскольку слоты состояний эффективно используются в качестве «батареи» для экономии газа) и неэффективно блокирует использование газа блокчейна * Возвраты увеличивают дисперсию размера блока. Теоретическое максимальное количество фактического газа, потребляемого в блоке, почти в два раза превышает бумажный лимит газа (поскольку возвраты добавляют пространство газа для последующих транзакций в блоке, хотя возвраты ограничены 50% газа, использованного транзакцией). Это не фатально, но все же нежелательно, особенно с учетом того, что возмещение может быть использовано для поддержания двойных всплесков использования гораздо дольше, чем EIP-1559.
Теперь вам должна быть ясна концепция возврата газа. Чем больше вы будете играть с этим на ремиксе, тем больше вы будете понимать расчеты. Почему бы не попробовать выполнить некоторые реальные функции, поскольку те, что я написал выше, являются просто примерами? Можно попробовать посмотреть расход газа в реальных контрактах типа передаточной функции ERC20, когда баланс вот-вот обнулится. Дайте мне знать, что вы обнаружите в ходе этих экспериментов.
Есть вопросы по этой теме? Спросите меня в любое время в Twitter, LinkedIn или telegram.
:::информация Также опубликовано здесь.
:::
Оригинал