Увеличить стоимость calldata, чтобы уменьшить максимальный размер блока.
Начну рассказывать из далека! Из-за растущего количество l2-блокчейнов, которые использовали calldata для хранения своих транзакций был внедрен EIP-4844: Shard Blob Transactions. Согласно этому стандарту для хранения данных был предоставлен специальный объект Blob, который в отличие от calldata, хранится ограниченный период времени для необходимой валидации данных.
И вот предлагается сделать использование calldata дороже, чем есть сейчас. Почему так?
▫️Что будет изменено?
Будет изменена схема расчета стоимости calldata. Для этого вводится новое понятие «минимальной стоимости calldata». Которое на первый взгляд неочевидно из формулы расчета.
Расчет газа по транзакции был достаточно простой.
tx.gasUsed = (
21000
+ STANDARD_TOKEN_COST * tokens_in_calldata
+ execution_gas_used
+ isContractCreation * (32000 + INITCODE_WORD_COST * words(calldata))
)
21000
Стандартная плата за вызов транзакции.
STANDARD_TOKEN_COST * tokens_in_calldata
Здесь заложено 4 газа за нулевой байт и 16 за ненулевой байт calldata.
STANDARD_TOKEN_COST = 4, tokens_in_calldata = zero_bytes_in_calldata + nonzero_bytes_in_calldata * 4
execution_gas_used
Использованный газ на выполнение того, что закодированно в calldata.
isContractCreation * (32000 + INITCODE_WORD_COST * words(calldata))
Эта часть отвечает за случай, когда создается новый контракт, в рамках этого стандарта нам это не важно.
Теперь новая формула расчета будет хитрее. Идем путем усложнения!🧑🦼
tx.gasUsed = (
21000
+
max(
STANDARD_TOKEN_COST * tokens_in_calldata
+ execution_gas_used
+ isContractCreation * (32000 + INITCODE_WORD_COST * words(calldata)),
TOTAL_COST_FLOOR_PER_TOKEN * tokens_in_calldata
)
)
Изменения не такие глобальные, 21000 газа остается за пределами изменений. Теперь будет браться максимальное значение между прошлым значением расчета и новой магической строчкой.
TOTAL_COST_FLOOR_PER_TOKEN * tokens_in_calldata
Где TOTAL_COST_FLOOR_PER_TOKEN - это константа, которая равняется 10 единицам газа. По сути, высчитанное значение, согласно этой строке, зависит от размера calldata. И именно эта строка определяет минимальную стоимость calldata.
▫️Нюанс
Это не просто изменение расчета стоимости calldata!🤔
Обычно в calldata передается закодированная функция и аргументы к ней для вызова на смарт-контракте. Содержимое calldata считается по газу, как 4 единицы за нулевой байт, 16 за ненулевой. Дальше добавляется газ за каждый опкод исполнения вызова, закодированного в calldata. Опускаем 21000 за вызов транзакции, это число постоянно.
Но не у роллапов, где в calldata передаются большие данные, отвечающие за их состояния!
Если использованного в транзакции газа недостаточно по сравнению с общим объемом загруженных данных, то она будет считаться транзакцией для хранения данных. То есть данных в calldata много, но газа на исполнение потреблено мало, тогда плата за calldata взимается в разы больше. И наоборот, обычная транзакция с вызовом функции mint() на токене будет взимать плату за calldata меньше.
И это видно по формулам. «Новая строчка» будет не только минимальным значением стоимости calldata. Если размер calldata большой, туда запихали огромное количество данных, то это будет дороже, нежели расчет стоимости по старой формуле.
▫️Обратная совместимость
Так как стандарт вводит новый способ расчета стоимости на газ, то всем кошелькам и нодам, использующим eth_estimateGas необходимо обновить формулу оценки газа согласно новой спецификации.
▫️Вывод
Отвечаю: Зачем делать calldata дороже?
На мой взгляд это корректировка экономической модели, которая будет стимулировать уменьшение использования calldata, что в свою очередь будет поощрять использование Blobs. Я наслышан, что в небольших объемах, роллапам до сих пор удобнее использовать calldata. Такая мысль в стандарте не озвучена, стандарт говорит, что он нацелен на уменьшение максимального размера блока.
#в_гостях_у_Pectra #павел_найданов