Аккаунты, транзакции, газ и лимит газа на блок в сети Эфириум

Перевод на русский язык замечательной статьи от Hudson Jameson

Свои дополнения буду выделять курсивом.

Эта статья призвана помочь людям понять базовую механику работы аккаунтов, транзакций, газа и роль майнеров в выборе размера блока в сети Эфириум. Исправления приветствуются :)

Что такое аккаунты?

EOA и аккаунты-контракты

Существует два вида аккаунтов в сети Эфириум:

  • Externally Owned Accounts (внешний аккаунт)
  • Аккаунт-контракт

Это различие станет более абстрактным в грядущем обновлении “Метрополис”

Внешний аккаунт (EOA)

Аккаунт с внешним контролем:

  • имеет свой баланс эфира,
  • может отправлять транзакции (обычная пересылка эфира, либо запуск кода контракта),
  • контролируется приватными ключами,
  • не имеет привязанного к себе кода.

Аккаунт-контракт

Контракт:

  • имеет свой баланс эфира,
  • имеет привязанный к себе код,
  • выполнение кода инициируется транзакциями с EOA или сообщениями (вызовами), полученными из других контрактов.
  • когда запущен — выполняет операции произвольной сложности (Тьюринг-полные) — манипулирует своим собственным внутренним хранилищем, т.е. может иметь свое собственное перманентное состояние — может вызывать другие контракты

Все движения в блокчейне Эфириума приводятся в действие транзакциями из аккаунтов. Каждый раз, когда аккаунт-контракт получает транзакцию, его код запускается в соответствии с заложенными инструкциями и входными параметрами, полученными как часть транзакции. Код контракта выполняется Виртуальной Машиной Эфириума (EVM) на каждой ноде*, участвующей в сети, что является частью их работы по верификации нового блока.

*О значении нод в сети рекомендую посмотреть вот это видео с переводом выступления Andreas Antonopoulos, там идет речь о биткоине, но принцип в любом случае очень похожий.

Что такое транзакции и сообщения?

Транзакции

Термин “транзакция” в Эфириуме означает подписанный* пакет данных, который хранит сообщение, которое нужно отправить из внешнего аккаунта (EOA) другому аккаунту на блокчейне.

Транзакция содержит:

  • получателя сообщения,
  • подпись, определяющую отправителя и доказывающую его намерение отправить это сообщение через блокчейн получателю,
  • полеVALUE (стоимость) - Количество wei* которое необходимо переслать от отправителя к получателю (может быть нулевым)
    *кошельки, как правило, для удобства скрывают от нас значение в wei и показывают значение сразу в эфире,
  • необязательное поле DATA, которое может содержать сообщение, отправляемое в контракт,
  • значение GASLIMIT, определяющее максимальное количество вычислительных операций, допустимое в рамках конкретной транзакции,
  • значение GASPRICE, определяющее комиссию, которую отправитель готов заплатить за единицу газа. Одна единица газа соответствует запуску одной атомарной (неделимой) инструкции (другими словами — вычислительной операции).

Сообщения

Контракты имеют возможность посылать “сообщения” другим контрактам. Сообщения — это виртуальные объекты, которые никогда не сериализуются и существуют только в среде исполнения Эфириума. Их можно рассматривать как вызовы функций.

Сообщение содержит:

  • отправителя сообщения (неявно, т.к. оно приходит из контракта, а не с внешнего аккаунта).
  • получателя сообщения,
  • полеVALUE - количество wei отправляемое вместе с сообщением на адрес контракта,
  • необязательное поле DATA, что и есть фактические входные данные для контракта,
  • значение GASLIMIT, ограничивающее максимальное количество газа, которое может использовать выполнение кода, вызванное этим сообщением.

Сообщение очень похожи на транзакции, за исключением того, что они создаются контрактом, а не внешним аккаунтом. Сообщение создается когда контракт, который выполняет код в настоящее время, запускает операциюCALL или DELEGATECALL, которая создает и запускает сообщение. Сообщения так же часто называют “внутренними транзакциями” (“internal transactions” — вы можете увидеть такую закладку у любого адреса в etherscan, например тут). Как и транзакции, сообщения приводят к тому, что учетная запись получателя запускает свой код. Таким образом, контракты могут взаимодействовать с другими контрактами точно так же, как это делают внешние аккаунты. Очень часто люди используют термин “транзакция”, когда имеют в виду “сообщение”, так что этот термин постепенно уходит из употребления.

Что такое газ?

Эфириум использует среду исполнения на блокчейне, которая называется Виртуальной Машиной Эфириума (Ethereum Virtual Machine — EVM). Каждая нода, участвующая в сети, запускает EVM, как часть протокола верификации блоков. Они проходят через все транзакции в блоке, который они верифицируют, и запускают код, вызванный транзакциями, внутри EVM. Каждая полная нода* в сети проводит одинаковые вычисления и хранит одинаковые значения. Факт того, что запуск контрактов дублируется среди всех нод, делает контракты весьма дорогими, что в свою очередь создает стимул не использовать блокчейн для вычислений, которые можно провести вне его. Для каждой операции существует своя цена, которая выражена в единицах газа. Каждая операция, которую может использовать контракт, требует определенного количества газа. Здесь можно посмотреть устаревший список количества газа, требуемого для разных операций.

Газ и стоимость транзакции

Каждая транзакция требует включать в себя значение лимита газа (gas limit, так же иногда называют startGas) и комиссии, которую вы готовы заплатить за единицу газа. У майнеров есть выбор включить ли транзакцию в блок и забрать себе комиссию или не включать. На текущий момент все транзакции рано или поздно включаются в блок, но величина комиссии за транзакцию влияет на то, как быстро транзакция будет включена в блок. Если общее количество газа, используемое операциями, вызванными транзакцией, включая первоначальное сообщение и последующие сообщения (которые могли быть вызваны первоначальным сообщением), меньше или равны лимиту газа — тогда транзакция успешно проходит. Если общее количество газа превосходит лимит газа — тогда все произошедшие изменения обнуляются, но транзакция все равно будет считаться валидной и комиссия может быть списана майнером. Блокчейн покажет, что была попытка провести транзакцию, но не было предоставлено достаточное количество газа и все изменения, которые произошли во время вычисления этой транзакции, были отменены. Если газа было использовано меньше лимита — весь избыточный газ возвратится отправителю в виде Эфира. Поскольку предварительная оценка затрат газа только приблизительная — многие пользователи ставят заведомо высокий лимит газа, чтобы быть уверенным, что транзакция будет принята. Это нормально, т.к. весь неиспользованный газ будет возвращен*. 
*Однако не стоит ставить чрезмерно большой лимит газа — если он будет превышать лимит газа на блок, то транзакция будет отвергнута майнерами. Так же не стоит ставить чрезмерно высокий лимит газа во время ICO — если вы вдруг отправите тразнакцию до или после ICO — транзакция вернет ошибку и будет использован весь лимит газа (что может обойтись вам в десятки, а то и сотни долларов при том, что вы даже не попадете в нужное вам ICO)

Подсчет затрат на транзакцию

Затраты эфира на транзакцию зависят от двух факторов:

  • gasUsed: общее количество газа, затраченное на транзакцию
  • gasPrice: цена (в эфире) за одну единицу газа, которая определена в транзакии

Общие затраты= gasUsed * gasPrice

gasUsed (использованный газ)

Каждой операции в EVM присвоено определенное количество газа ею потребляемое. gasUsed — это сумма всего газа за все проведенные в транзакции операции.

Для подсчета используемого газа существует estimateGas API, который можно использовать, но с некоторыми оговорками.

gasPrice (цена газа)

Пользователь создает и подписывает транзакцию, и каждый пользователь может определить какую цену газа он готов заплатить (она даже может быть нулевой). Однако, Эфириум клиенты (Homestead) имеют цену газа по умолчанию 0.02e12 wei (20 Gwei). Т.к. майнеры стараются оптимизировать свои доходы и большинство транзакций отправляются с ценой газа в 20 Gwei, будет тяжело убедить майнеров принимать транзакции с меньшей (или нулевой) ценой газа*

*Я слегка изменил перевод, т.к. информация в статье была устаревшей (0.05e12 wei), к тому же, на самом деле, вполне можно посылать транзакции с ценой газа в 2 Gwei, если вы готовы подождать 1–3 минуты вместо нескольких секунд.

Пример с ценой транзакции

С разрешения я одолжу этот пример и аналогию у замечательной команды MyEtherWallet. Пожалуйста прочитайте их прекрасно написанный гайд по газу. Так же у них есть страница с отличными утилитами, которая, в том числе, позволяет вам конвертировать эфир в субединицы (wei, Gwei и т.п.).

Вы можете представлять лимит газа как количество литров/галлонов/единиц топлива для машины. Вы можете представлять цену газа как стоимость за литр/галлон/единицу топлива.

Если брать машину, то цена будет $2.50 (цена) за галлон (единицу). В Эфириме это 20 Gwei (цена) за газ (единицу). Чтобы заполнить весь бензобак понадобится 10 галлонов по $2.50 = $25. Если брать Эфириум, то 21000 газа по 20Gwei = 0.00042 ETH.

Следовательно, общая комиссия за транзакцию будет 0.00042 Эфира.

Отправка токенов, как правило, требует от ~50000 до ~100000 газа, так что общая комиссия за транзакцию увеличивается до 0.001 ETH — 0.002 ETH.

Что такое “лимит газа на блок”?

Лимит газа на блок — это максимально допустимое количество газа в блоке для определения того, как много транзакций может поместиться в блок. Например, у нас есть 5 транзакций и каждая транзакция имеет лимит газа в 10, 20, 30, 40 и 50. Если лимит газа на блок — 100, то первые 4 транзакции могут поместиться в блок. Майнеры решают какие транзакции поместить в блок. Кто-то из майнеров может попробовать поместить последние 2 транзакции в блок (50+40), и останется место только для первой транзакции (10). Если попытаться включить транзакцию, которая использует больше газа, чем текущий лимит газа на блок — она будет отвергнута сетью и ваш Эфириум клиент выдаст вам сообщение “Транзакция превышает лимит газа на блок”. Пример взят из этого поста на Ethereum StackExchange.

Согласно ethstats.net, лимит газа на блок на момент написания статьи составляет 4,712,357 газа, что говорит о том, что примерно 224 транзакции с лимитом газа в 21000 могут поместиться в 1 блок (в среднем новый блок производится каждые 15–20 секунд). Протокол позволяет майнеру блока регулировать лимит газа на блок на 1/1024 (0.0976%) в любом направлении.

Кто решает какой будет лимит газа на блок?

Майнеры. Отдельно от регулируемого протокола, стратегия с минимальным лимитом газа в 4,712,388 стоит по умолчанию в большинстве клиентов. Майнеры могут изменить это, но многие этого не делают и оставляют настройки по умолчанию.

Как изменяется лимит газа на блок?

Майнеры сети Эфириум используют майнинговые программы, такие как ethminer, которые подсоединяются к geth или Parity. geth и Parity имеют настройки, которые майнеры могут изменить. Настройки командной строки для майнинга в geth есть тут, а для Parity тут.

Что такое “DoS” в сети Эфириум?

Недавно было очень много комментариев по поводу замедления работы сети Эфириум, забивания её транзакциями и невозможностью её использования. Эти комментарии описывают замедление как “DoS” сети Эфириум. Инцидент отказа в обслуживании (Denial of Service) в сети Эфириум происходит, когда блоки постоянно заполнены и существует много транзакций со статусом “в ожидании”. Как мы знаем, майнеры могут выбрать какую транзакцию включить в блок исходя комиссии, прикрепленной к транзакции. Когда в очереди сотни тысяч транзакций (или, техническим языком, в пуле транзакций), это может вызывать нестандартные часовые задержки. Инциденты с DDoS (Distributed Denial of Service, Распределённый отказ от обслуживания) могут быть как и злонамеренными, так и нет.

Злонамеренный DoS

Осенью предыдущего года Эфириум был атакован неизвестным лицом или группой через так называемую транзакционную спам-атаку. Атака была описана в этом посте:

Атакующий совершил DoS атаку постоянно вызывая определенный код в смарт контракте, который был сложен для вычисления клиентами (нодами и майнерами), но очень дешев для добавления в сеть.

Во время атаки майнеров попросили уменьшить лимит газа на блок до 1.5 миллионов и потом до 2 миллионов в другом случае. Были и другие случаи, когда майнеров просили уменьшить лимит газа на блок во время атак на сеть.

Не злонамеренный DoS

Подобные инциденты происходят когда в сети так много транзакций “в очереди”, что требуется необыкновенно много времени для их обработки. Недавно популярность некоторых ICO вызвала перегрузку сети транзакциями. Ребята из Infura написали пост о технических деталях подобных инцидентов.

Почему лимит газа на блок не изменяется даже если блоки постоянно полные?

Основная причина: майнеры не используют возможности адаптивного лимита газа.

В протоколе Эфириума есть встроенный механизм, через который майнеры могут голосовать за лимит газа, так что вместимость может быть увеличена без хард форка. Изначально этот механизм сочетался со стандартной стратегией, когда майнеры голосовали за лимит газа, который составляет минимум 4.7 миллиона, но может достичь 150% от недавнего (экспоненциальная скользящая 1024 блоков) среднего используемого лимита газа, если требуемое количество выше, позволяя увеличивать вместимость вместе с возрастающим спросом, в то время как всё еще существует потолок для защиты от спама.

Как описано в части “Злонамеренный DoS” выше, несколько раз в прошлом майнерам было предложено изменить их стандартные настройки лимита газа на блок, чтобы помочь удержать атаку пока не будет выпущен новый патч. Проблема в том, что некоторый майнинговые пулы никогда не меняли свои настройки обратно, даже когда атаки утихли. Примерно месяц назад майнеров попросили изменить настройки лимита и цены газа чтобы повторно ввести возможность адаптивного лимита газа, т.к. последние ICO очень быстно заполняли блоки и вызывали задержки в работе сети Эфириума.

ETH Gas Station* — это отличный ресурс для тех, кто ищет актуальную информацию о том, как майнинговые пулы голосуют за лимит газа на блок.

*Там же можно смотреть актуальную информацию о текущей минимально-безопасной цене газа (на момент написания это всего-лишь 0.7 Gwei или примерно $0.003 за обычную транзакцию с лимитом газа 21000!)

Мои другие обучающие статьи о блокчейне, а так же мысли по проходящим ICO можно найти в телеграмм канале https://t.me/intelligent_crypto_investor