EVM-функционал на Solana: введение

Марина Гурьева, CEO Neon Labs, рассказала про особенности запуска EVM в сети Solana на EVM-Compatible Meetup в Тбилиси. Мы сделали краткий конспект, из которого можно узнать: чем отличаются Solana и Ethereum; как происходят транзакции в Solana пошагово; как запустить Ethereum dApp на Solana; как работает Neon EVM. Приятного чтения! ✨

read in english >>>

О Neon Labs

Neon Labs занимается разработкой Neon EVM c декабря 2020 года. Перед Neon стоит нетривиальная задача — портировать EVM на Solana. Планируем запуститься на майннете Solana в конце ноября или в начале декабря. В Solana Devnet эта версия работает с апреля, проводим тестирования dApp с Ethereum — деплоим их в наше решение. В докладе расскажу, как именно мы решили «поженить» Solana и Ethereum.

Чем отличаются блокчейны

alt_text

Представим две галактики. Одна из них знакома нам, мы в ней прямо сейчас находимся. А вторая — находится в 100 млн световых лет от созвездия Рыбы, она устроена и выглядит совсем иначе. Наглядно видно, что галактики бывают разными. Точно так же различаются и блокчейн-системы: Solana и Ethereum — кардинально разные. Они отличаются и архитектурно, и с точки зрения технической реализации. На Solana, например, доступно параллельное выполнение транзакций, но при этом существуют ограничения на количество инструкций в рамках одной транзакции — чего нет в Ethereum.

Из чего состоит Solana

alt_text

На слайде классическая программа Solana. Существует два типа аккаунтов: data account и program account. Они отличаются флагом, который позволяет маркировать программы. Программы — это те программы, с которыми вы имели дело, если занимались когда-то операционными системами.

Структура программы достаточно простая:

  • адрес (у адреса есть Program Derived Address, который не имеет ключей и выбирается в пределах эллиптической кривой и отдается под управление программы);
  • лампорты (lamports, единицы измерения внутри Solana);
  • rent epoch (время списания лампортов). Нужно держать достаточное количество лампортов, чтобы Solana не удалила случайно программу;
  • владелец;
  • data (родной машиной для Solana является Berkley Packer Filter (BPF), поэтому там содержится BPF bytecode);
  • флаг, маркирующий программу.

Это базовая структура. Программный код EVM, де-факто, представляет собой смарт-контракт на Solana. То есть — это нативный смарт-контракт для Solana и может быть запущен на ней.

Как выглядит программа в Neon EVM

alt_text

Из каких элементов состоит Neon EVM:

  • программа: Neon EVM
  • владелец программы: Neon DAO, которое начнет работать после запуска в майннете;
  • BPF bytecode data + Ethereum Virtual Machine. EVM позволит добиться выполнения контрактов Ethereum, которые попали в Solana;
  • выставлен флаг на то, что это — программа;
  • три типа аккаунтов: простой аккаунт соответствует аккаунту пользователя в Ethereum (в поле «данные» собрана информация про аккаунты, релевантная с точки зрения аккаунта: address, nonce, balance etc.); Neon contract соответствует смарт-контрактам Ethereum (данные, релевантные любому смарт-контракту Ethereum — EVM bytecode);
  • Neon contract data — данные, которые ассоциируются с предыдущим контрактом.

Как проходят транзакции Neon внутри Solana

alt_text

NEON EVM — смарт-контракт на Solana и имеет дело поэтому с транзакциями этой сети в первую очередь. Наша задача сформировалась таким образом: получив на входе «эфироподобную» NEON-транзакцию каким-то образом превратить ее в «солановскую» транзакцию.

Транзакция NEON, запакованная в транзакцию Solana:

  • стандартная структура транзакции Solana: заголовок, account list, program index, data, подписи и так далее.
  • Для Solana поле «account list» — критичное поле, поскольку параллелизация выполнения возможна только при блокировке аккаунтов, задействованных в той или иной транзакции. То есть, Solana блокирует аккаунты, которые в этом списке указаны и дальше может выполнять параллельно вычисления для тех аккаунтов, которых нет в списке.
  • Есть программный индекс (program index), который указывает на NEON EVM.
  • data — «эфироподобная» транзакция с nonce, gasPrice, gasLimit, value etc.

Как запустить Ethereum dApp на Solana

alt_text

  • Допустим, контракт уже задеплоен и это, например, Uniswap.
  • Пользователь приходит в Neon через привычный ему инструмент, например, Metamask.
  • Он запускает транзакцию через Metamask, де-факто, транзакцию Neon.
  • Эта транзакция после подписи отправляется не на ноду Solana, а на специальный сервер Neon proxy с Neon RPC endpoint.
  • После этого она выходит «упакованная» в транзакцию Solana и попадает на Solana RPC endpoint.
  • Дальше идет вызов на Neon EVM-программу.

Как включить все аккаунты в транзакцию Solana

alt_text

Как известно, в Ethereum нет такого свойства. Поэтому задача Neon Proxy эмулировать выполнение транзакции, чтобы достать список аккаунтов, вовлеченных в выполнение транзакции. Когда транзакция Neon попадает в прокси, идет ончейн-вызов на EVM и происходит эмуляция для доступа к данным о задействованных аккаунтах. Далее транзакция посылается на Solana RPC endpoint.

Как происходит параллельное выполнение

alt_text

Никакой дополнительно магии нет — на ноды Solana поступают транзакции Solana и каждая «солановская» нода вызывает Neon EVM смарт-контракт. Собственно, это стандартный для Solana способ экзекуции транзакции в параллели. Происходит проверка на блокировку аккаунтов, и если множество блокируемых аккаунтов не совпадает, то транзакции выполняются в параллели.

Как выполнить длинные транзакции Ethereum в Solana

alt_text

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

Нам пришлось применить итеративное выполнение — делать бэк транзакций и выполнять их шаг за шагом, чтобы финализировать одну транзакцию Neon.

  • Neon Proxy эмулирует и запускает транзакцию.
  • Она, в виде «солановской» транзакции попадает на ноды Solana, запускается Neon EVM. Читаются аккаунты.
  • Сохраняется EVM state в специальном аккаунте Neon state, который нам тоже пришлось специально создать
  • Посылается receipt, что транзакция Neon не завершена. Это критично, потому что, когда прокси получается такой receipt он запускает продолжение транзакции.
  • Восстанавливается EVM state из аккаунта Neon state. Совершаются новые действия и снова идет сохранения.
  • Итерации продолжаются до тех пор, пока транзакция не будет выполнена полностью.
  • Последняя часть транзакции важна потому, что измененные аккаунты сохраняются в Solana state.
  • Совершается разблокировка заблокированных аккаунтов.
  • Посылается Receipt с информацией об успешном или неуспешном выполнении транзакции.

Как обеспечить атомарность больших транзакций в Solana

alt_text

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

Все, что я сказала выше — мы уже реализовали. Но в идеальном мире нам хотелось бы выполнять в параллели «эфироподобные» транзакции с одними теми же контрактами Solana. Например, контрактами ERC20, которые поддерживаются USDT, USDC и т.д., они часто используются. В том методе, который я описала, нам нужно их заблокировать, поэтому все ERC20-транзакции будут выполняться не в параллели, а друг за другом.

alt_text

Мы придумали способ под названием Optimistic Parallel Execution. Он красив с точки зрения реализации и позволяет сделать экзекуцию контрактов параллельной, даже при обращении к одним и тем же контрактам.

  • Когда у параметра появляются значения, сохраняются параметры, на каком шаге они появились.
  • Дальше проверяется, произошло ли изменение того или иного значения параметра на каком-то шаге или нет.
  • И в случае, если есть изменение значения на каком-то шаге какого-то параметра, то идет возврат за шаг до того, когда первый раз был прочитан этот параметр. То есть, по изменению мы понимаем, что в параллели была реализована транзакция, которая изменила параметр. То есть так транзакция, которая находится на исполнении, должна быть выполнена еще раз с того момента, когда параметр был впервые зафиксирован.
  • Промежуточные изменения записываются в Neon state и запись происходит в Solana state на последнем шаге.

Читайте также

Больше мероприятний