» » » Экономия газа в смарт-контрактах Ethereum

 

Экономия газа в смарт-контрактах Ethereum

Автор: admin от 1-02-2018, 10:50, посмотрело: 261

В Ethereum для выполнения каждой транзакции требуется определённое количество газа — специальной сущности. Существуют разные пути для снижения затрат. Часть из них уже реализована. Хочу начать с обсуждения вопроса оптимизации стоимости создания смарт-контракта.


Экономия газа в смарт-контрактах Ethereum


Как видите, можно заметно снизить расход газа, сокращая издержки. Прежде чем займёмся деталями давайте обсудим вопрос оптимизации программ.

функция очистки в проекте OpenSSL выглядела следующим образом:


Экономия газа в смарт-контрактах Ethereum


Конечно, проблема с функцией memset() является исключением из правил. Оптимизаторы генерируют корректный код, и обстоятельства использования могут привести к ошибкам. Но источником некорректного кода являются люди.


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


Если хотя бы один из параметров a или b чётный, то будет чётное количество итераций, поэтому возвращаемое значение будет 0.

Это импликация, поэтому при ложном условии следствие может быть любым. Возможна ли ситуация, когда и a, и b нечётные, но количество итераций будет чётным?


Ответ "да". Если значение или a, или b будет отрицательным, то вообще не будет ни одной итерации. Поэтому корректная ручная оптимизация приведёт к следующему коду:


Экономия газа в смарт-контрактах Ethereum


Виртуальная машина Ethereum


Виртуальная машина Ethereum (Ethereum Virtual Machine, EVM) — это основное "железо" платформы Ethereum. В упрощённом виде её архитектура представлена на следующей схеме:


Экономия газа в смарт-контрактах Ethereum


Можно выделить три типа памяти: балансы счетов (balances of accounts), код контрактов (code) и хранилища контрактов (storage). У каждого счёта (личного кошелька или контракта) есть свой собственный баланс в валюте Ethereum (ETH). Для каждого смарт-контракта хранится его код (исполняемая программа для EVM), а также собственная память для хранения переменных. Код контракта не меняется после создания.


Блокчейн Ethereum состоит из множества блоков в определённом порядке. Каждый блок — это набор транзакций и квитанций их выполнения (receipts). Состояние EVM (его память) полностью определяется всем набором предыдущих транзакций. Чтобы получить состояние EVM в момент N надо взять состояние EVM в момент N-1, после чего выполнить все транзакции из блока N. Поэтому, зная все транзакции блокчейна, мы можем определить состояние EVM на любой момент в прошлом. Процесс проиллюстрирован на следующей схеме:


Экономия газа в смарт-контрактах Ethereum


Отмечу, что если зафиксировать состояние EVM в момент M, то есть состояния EVM, которые будут недостижимы в будущем вне зависимости от выполняемых транзакций после блока M.


Рассмотрим два набора транзакций: T and U. Назову эти транзакции "равнозначные", если обработка транзакций T в блоке N приведёт EVM к "идентичному" состоянию, что и обработка U вместо T в том же самом блоке N. Ставлю в кавычки, поскольку допускается разница в балансе отправителя и майнера блока N из-за разницы в затратах газа между наборами транзакций T и U.


Все затраты времени и памяти включены в стоимость газа, поэтому основная цель оптимизации — это снижение затрат газа. Одним из подходов к оптимизации является поиск "равнозначных" транзакций с меньшими затратами газа. Речь идёт про удаление избыточного кода, но не изменении алгоритмов и т.п. Аналогично первому примеру с функцией calculate() выше.


Создание смарт-контрактов


Существует два разных вида транзакций. Сейчас собираюсь обсудить только транзакции создания смарт-контрактов. Транзакция создания контракта выполняет два основных действия в EVM: инициализирует хранилище контракта и сохраняет байт-код. Инициализация хранилища является результатом вызова конструктора контракта с параметрами миграции. Все другие методы контракта сохраняются в коде. Этот процесс изображён на следующей схеме:


Экономия газа в смарт-контрактах Ethereum


Вопрос оптимизации кода контракта оставим для будущих статей. Сегодня сосредоточимся на оптимизации кода развёртывания контракта.


Оптимизация кода развёртывания контракта


В предыдущем разделе мы обсудили, что есть очевидная цель оптимизации — минимизация потребления газа. Одновременно с этим необходимо убедиться, что оптимизированная транзакция "равнозначна" исходной.


Я использовал исходный байт-код развёртывания контрактов, доступный из блокчейна Ethereum. Для этой задачи исходного кода контрактов не требовалось. После этого выполнил трассировку выполнения развёртывания контракта и оставил только требуемый код. Процесс оптимизации кода развётывания можно представить следующим образом:


Экономия газа в смарт-контрактах Ethereum


Предыдущий пример упрощён, хотя используемый подход может быть применим и для более сложных транзакций.


Нижняя оценка


Выполнение каждой отдельной инструкции в EVM имеет свою стоимость в количестве газа. Хотя есть множество путей для достижения одинакового результата, но мы можем легко получить нижнюю оценку. Для этого достаточно просуммировать следующие числа:



  • Плата за данные кода развёртывания контракта;

  • Плата за создание контракта;

  • Количество различных переменных в хранилище, умноженное на стоимость оператора SSTORE;

  • Размер байт-кода контракта в словах, умноженный на стоимость записи в память и стоимость инструкции RETURN;

  • Количество событий, умноженное на соответствующую стоимость.


  • Данная нижняя оценка может быть использована в качестве основы и цели оптимизации.


    Здесь предполагал, что байт-код контракта будет копироваться из данных транзакции развёртывания. Ситуации генерации байт-кода "на лету" являются исключениями.


    Статистика и результаты


    Я сделал снимок блокчейна Ethereum на блоке №4841148. На этот момент в блокчейне было 119041944 транзакций, из которых только 1022020 транзакций по созданию контракта. Я сравнил входные данные этих транзакций и обнаружил 111806 уникальных кодов развёртывания контрактов.


    Экономия газа в смарт-контрактах Ethereum


    Каждый из уникальных кодов развёртывания запустил в Ganache CLI (бывший TestRPC) и получил квитанцию выполнения и байт-код контракта. Одновременно с этим выполнил наивную оптимизацию, а также посчитал нижнюю оценку. Оптимизированный код был протестирован на локальном блокчейне, после чего результаты сравнивались с исходным кодом. Процесс проиллюстрирован на следующей схеме:


    Экономия газа в смарт-контрактах Ethereum


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


    Для каждой обработанной транзакции получил три числа: исходные затраты на обработку, затраты для оптимизированной версии и нижнюю оценку. Все значения были посчитаны в текущей стоимости операций. Получились следующие результаты:


    Экономия газа в смарт-контрактах Ethereum


    Из таблицы можно увидеть, что даже наивная оптимизация позволяет сэкономить газ. К сожалению, количество не такое уж и большое. С другой стороны, в теории больше 10% газа может быть сэкономлено лишь для 10% контрактов. На практике с наивной оптимизацией мне удалось достичь экономии в 10% лишь для 0.3% контрактов.


    Учитывая все эти числа, мы можем вспомнить, что создание контракта — это единовременный процесс, поэтому могу заключить, что оптимизация развёртывания смарт-контрактов не является сейчас важным вопросом для Ethereum. Уверен, что ещё вернусь к этому вопросу в будущем, а сейчас есть ещё много интересных проблем оптимизации, связанных с байт-кодом самих контрактов.


    Человеческий фактор


    Небольшие ошибки могут перечеркнуть результаты всех предыдущих усилий. Например, 2131132 единиц газа было потрачено для транзакции transaction 0xdfa1..7fbb. Это на 23% больше газа, чем требовалось. Кто-то просто продублировал код развёртывания контракта перед отправкой. В итоге 6Кб данных вообще не использовались.


    Что дальше?


    Вопрос оптимизации при развёртывании смарт-контрактов появился в качестве побочного результата. Данная тема достаточно проста для понимания, поэтому решил с неё и начать.


    Продолжение следует...



    Источник: Хабрахабр

    Категория: Операционные системы » Android

    Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
    Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

    Добавление комментария

    Имя:*
    E-Mail:
    Комментарий:
    Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
    Введите два слова, показанных на изображении: *