Что такое EVM?

EVM — это среда выполнения для блокчейна Ethereum. Позволяет запускать код смарт-контракта путем компиляции в байт-код EVM.

Основы: Solidity → Байт-код → Opcode

Как вы знаете, код Solidity должен быть скомпилирован в байт-код перед развертыванием в сети Ethereum. Этот байт-код соответствует серии инструкций кода операции, которые интерпретирует EVM.

Исходный код: файл, написанный на языке программирования, таком как Java, Solidity.

Байт-код: скомпилирован из исходного кода и запущен на виртуальной машине, такой как JVM, EVM.

Машинный код: код, который может прочитать только операционная система. Байт-код преобразуется в машинный код и, наконец, выполняется.

Байт-код

Чтобы эффективно хранить коды операций, они кодируются в байт-код. Каждому коду операции выделяется байт (например, STOP - 0x00). Давайте посмотрим на следующий байт-код: 0x6001600101

Во время выполнения байт-код разбивается на байты (1 байт равен 2 шестнадцатеричным символам). Байты в диапазоне 0x60–0x7f (PUSH1-PUSH32) обрабатываются по-другому, потому что они включают данные push (которые необходимо присоединить к коду операции, а не рассматривать как отдельный код операции).

Первая инструкция - 0x60, которая переводится в PUSH1. Следовательно, мы знаем, что длина push-данных составляет 1 байт, и добавляем следующий байт в стек. Теперь в стеке 1 элемент, и мы можем перейти к следующей инструкции. Поскольку мы знаем, что 0x01 является частью инструкции PUSH, следующая инструкция, которую нам нужно выполнить, - это еще одна инструкция 0x60 (PUSH1) вместе с теми же данными. Теперь в стопке 2 одинаковых элемента. Последняя инструкция - 0x01, что переводится как ADD. Эта инструкция берет 2 элемента из стека и помещает сумму этих элементов в стек. Теперь в стеке один элемент: 0x02.

Коды операций

Можно разделить все коды операций на следующие категории:

  1. Коды операций управления стеком (POP, PUSH, DUP, SWAP);

  2. Арифметические операции / сравнение / побитовые коды операций (ADD, SUB, GT, LT, AND, OR);

  3. Коды операций окружающей среды (CALLER, CALLVALUE, NUMBER);

  4. Коды операций, управляющие памятью (MLOAD, MSTORE, MSTORE8, MSIZE);

  5. Коды операций управления памятью (SLOAD, SSTORE);

  6. Коды операций, относящиеся к счетчику программ (JUMP, JUMPI, PC, JUMPDEST);

  7. Коды операций остановки (STOP, RETURN, REVERT, INVALID, SELFDESTRUCT).

Архитектура EVM

EVM использует архитектуру на основе стека. Размер слова (то есть размер элемента данных в стеке) составляет 256 бит (32 байта). Это сделано для облегчения выполнения 256-битных вычислений Keccak-хэша и эллиптических кривых. Его модель памяти основана на байтовых массивах с адресной адресацией. Максимальная глубина стека - 1024. EVM также имеет независимую модель хранения; она похожа на память, но представляет собой не массив байтов, а массив слов, основанный на адресации по словам. Хранилище - это постоянное хранилище ключей и значений, которое поддерживается как часть состояния системы (постоянное хранилище в дереве Меркла). Все данные в памяти и хранилище будут инициализированы до 0. EVM не является стандартной структурой фон Неймана. Программный код хранится в независимом виртуальном ПЗУ, которое может взаимодействовать только с помощью определенных инструкций, а не в общедоступной памяти или хранилище.

Полезные ссылки: https://www.evm.codes/, https://ethervm.io/

Зачем нужен газ?

Плата за газ помогает поддерживать безопасность сети Ethereum. Требуя плату за каждое вычисление, выполняемое в сети, мы не позволяем злоумышленникам рассылать спам в сети. Чтобы избежать случайных или враждебных бесконечных циклов или других вычислительных потерь в коде, каждая транзакция должна устанавливать ограничение на количество вычислительных шагов выполнения кода, которое она может использовать. Основная единица вычислений - «газ».

Хотя транзакция включает лимит, любой газ, не использованный в транзакции, возвращается пользователю (т.е. возвращается max fee -  (base fee + tip)). 

Виды учётных записей Ethereum

Externally-owned — контролируется кем-либо, у кого есть private key.

Contract — смарт-контракт, развернутый в сети, управляемый кодом.

 Оба типа учетных записей имеют возможность:

  1. Получать, хранить и отправлять ETH и токены;

  2. Взаимодействовать с развернутыми смарт-контрактами.

Ключевые отличия

 Externally-owned:

  1. Создание учетной записи ничего не стоит;

  2. Может инициировать транзакции;

  3. Транзакции между Externally-owned могут быть только переводы ETH / токенов.

 Contract:

  1. Создание контракта требует затрат, потому что используется сетевое хранилище;

  2. Может отправлять транзакции только в ответ на полученные транзакции;

  3. Транзакции от Externally-owned учётной записи в Contract учетную запись могут запускать код, который может выполнять множество различных действий, таких как передача токенов или даже создание нового контракта. 

Создание учётной записи

EVM обрабатывает адреса длиной 160 бит.

Учетная запись состоит из криптографической пары ключей: public и private. Public key генерируется из private key с помощью алгоритма ECDSA.  

Публичный адрес Externally-owned учетной записи формируется следующим образом — берутся последние 20 байтов от Keccak-256(public key) и добавляется 0x в начало.  

Адрес Contract обычно указывается при развертывании контракта в блокчейне Ethereum. Адрес формируется из Externally-owned адреса создателя и количества транзакций, отправленных с этого адреса («nonce»). Последние 20 байтов от Keccak-256(RLP(Externall-owned; nonce)). 

Про RLP: https://eth.wiki/fundamentals/rlp

 Скрины формул из Ethereum Yellow Paper: https://ethereum.github.io/yellowpaper/paper.pdf

Что входит в каждый тип учётной записи

Каждая учетная запись состоит из balance, nonce, bytecode и stored data (storage). Однако между двумя типами учетных записей есть некоторые различия. Например, у External-owned поля bytecode и storage пусты, в то время как Contract хранит свой байт-код и корневой хэш Меркла всего дерева состояний. Более того, в то время как External-owned имеют соответствующий private key, Contract - нет. Действия Contract учетных записей контролируются кодом.

Комментарии (1)


  1. JekaMas
    14.04.2022 08:33
    +1

    Позволю поправить понятия и убрать маркетин

    EVM — это FSM, он же конечный автомат. Небольшая стэковая машинка на 1000-2000 строк кода.

    Газ нужен для решения проблемы остановки и, главное, чтобы поддерживать курс эфира.

    Контракт solidity - хранимая процедура базы данных.