Ethereum virtual machine что это

Что такое виртуальная машина Эфириума и зачем она нужна?

Команда Эфириума создала виртуальную среду, которая позволяет смарт-контрактам взаимодействовать друг с другом. Эту среду стали называть виртуальной машиной Эфириума, Ethereum’s Virtual Machine или EVM. Разберёмся с ней.

EVM даёт смарт-контрактам дополнительную функциональность, не усложняя при этом их модель работы. Получается, это глобальный суперкомпьютер? Наверное, именно так можно описать виртуальную машину Эфириума. Она берёт на себя все транзакции, которые могли бы выполняться на вашем компьютере – например, отправка и принятие денег, документов или контрактов – и преобразует эту систему в глобальном масштабе.

Как работает виртуальная машина Эфириума

Биткоин – это базовый элемент того, что умеет блокчейн. У вас есть единица стоимости – BTC – и вы можете отправлять и получать фрагменты этого значения другим людям, а они – вам. Затем появился Эфириум и позволил людям создавать смарт-контракты и децентрализованные приложения Dapps, причём для этих целей также задействуется технология блокчейна. Узнать больше о смарт-контрактах можно в нашей подробной статье.

Следующим шагом стала разработка среды, в которой все эти смарт-контракты живут и взаимодействуют друг с другом. Именно тут в игру вступает виртуальная машина Эфириума (EVM). И эту систему лучше всего рассматривать как виртуальный компьютер на блокчейне, который превращает ваши идеи в код и воспроизводит его в глобальной сети Эфириума.

Примеры работы EVM Эфириума

Предположим, вы хотите создать механизм, который позволит вам и трём вашим соседям по квартире справедливо делать покупки для дома. Вы создаёте смарт-конракт в соответствии с этой необходимостью. И у вас есть несколько задач, которые смарт-контракт должен учитывать.

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

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

  • на товары для дома выделяется только 10 долларов в неделю;
  • покупки товаров должны совершаться только в одном определённом магазине;
  • необходимо убедиться, что товары из конкретного магазина были доставлены по указанному адресу.

Лондон. Источник: Твиттер

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

  • Человек А готов потратить всего 20 долларов;
  • человек Б готов отдать 40 долларов;
  • человек В может себе позволить внести только 10 долларов;
  • человек Д имеет право внести недостающую сумму и приобрести телевизор, если соблюдены все вышеуказанные условия.

Видите, как все эти контракты полагаются на все предыдущие контракты? Это и есть принцип работы виртуальной машины Эфириума. Это среда, в которой все эти контракты существуют, взаимодействуют и влияют друг на друга.

Это как мессенджер, только для смарт-контрактов.

В чём суть виртуальной машины Эфириума?

Помимо того, что она позволяет решить денежный вопрос с соседями по квартире? На самом деле, EMV умеет делать много полезных вещей.

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

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

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

Будущее виртуальной машины Эфириума

На самом деле, у виртуальной машины Эфириума всё только начинается, и ещё многое ждёт впереди. В будущем сложность, скорость и способность виртуальной машины будут только расти. Примерно тому, как развивалась компьютерная отрасль с появлением домашних персональных компьютеров. Поживём – увидим.

Виталик Бутерин. Источник: 2Биткоина

Читайте также:  Чем обусловлен рост инвестиций

В нашем крипточате ходлеров можно обсудить тему подробнее с профессионалами в отрасли.

Источник

Что такое виртуальная машина Ethereum (EVM) простыми словами

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

Что представляет собой EVM? Как работает машина на простых примерах и какие у нее возможности? Будем разбираться в этой статье!

Что такое виртуальная машина Ethereum?

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

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

  • Все члены семьи должны создать индивидуальные ETH-адреса;
  • Все должны ежемесячно вносить определенную сумму на общий смарт-контакт;
  • Никто из членов семьи не сможет единолично снять средства;
  • Средства могут быть использованы только с разрешением всех членов семьи;

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

  • На товары для кухни – 0.3 ETH;
  • На товары для ванной – 0.3 ETH;
  • На продукты питания – 1.4 ETH;

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

  • Мать – 0.5 ETH;
  • Отец -1.5 ETH;
  • Сын – 0.25 ETH;
  • Дочь – 0.25 ETH;

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

Простым словами, виртуальная машина Ethereum – это мессенджер и менеджер задач, только для смарт-контрактов.

Возможности виртуальной машины Ethereum

Помимо решения семейных вопросов, виртуальная машина Ethereum может делать многое. Например, составлять договора по страхованию или по возврату кредитных средств.

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

Все смарт-контракты создаются на следующих языках программирования:

  • Solidity – наиболее используемый язык у Ethereum-разработчиков. 80% смарт-контрактов создаются с помощью Solidity
  • Vyper – достойная альтернативна Solidity специально для смарт-контрактов
  • LLL – сложный в использовании язык, который используется только опытными разработчиками.
  • Serpent – практически аналог Python. Используется в основном энтузиастами.
  • Mutan – на текущий момент не используемый язык программирования.

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

Для выполнения абсолютно любых задач, EVM принимает программный код, конвертирует его в двоичный (0 и 1) и только после этого становится “двигателем” смарт-контрактов.

Резюмируем

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

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

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

Напомним, в 2018 году мы разобрали, что представляют смарт-контракты на блокчейне Ethereum.

Источник

Под капотом Ethereum Virtual Machine. Часть 1 — Solidity basics

В последнее время все чаще в новостях можно услышать слова «криптовалюта» и «блокчейн» и, как следствие, наблюдается приток большого количества заинтересованных этими технологиями людей, а вместе с этим и огромное количество новых продуктов. Зачастую, для реализации какой-то внутренней логики проекта или же для сбора средств используются «умные контракты» — особые программы, созданные на платформе Ethereum и живущие внутри его блокчейна. В сети уже существует достаточно материала, посвященного созданию простых смарт-контрактов и базовым принципам, однако практически нету описания работы виртуальной машины Ethereum (далее EVM) на более низком уровне, поэтому в этой серии статей я бы хотел разобрать работу EVM более детально.

Solidity — язык, созданный для разработки умных контрактов, существует относительно недавно — его разработка началась только в 2014 году и, как следствие, местами он »сыроват». В этой статье я начну с более общего описания работы EVM и некоторых отличительных особенностей solidity, которые нужны для понимая более низко-уровневой работы.

Читайте также:  Расчет коэффициента покрытия инвестиций по балансу

P.s Статья предпологает наличие некоторых базовых знаний о написании смарт-контрактов, а также о блокчейне Ethereum’a в целом, так что если вы слышите об этом в первый раз, то рекомендую сначала ознакомиться с основами, например, здесь:

Table of contents

Memory types

​ Перед тем, как начать погружаться в тонкости работы EVM, следует понять один из самых выжных моментов — где и как хранятся все данные. Это очень важно, т.к области памяти в EVM сильно отличаются своим устройством, и, как следствие, разнится не только стоимость чтения/записи данных, но и механизмы работы с ними.

Storage

​ Первый и самый дорогой тип памяти — это Storage. Каждый контракт обладает своей собственной storage памятью, где хранятся все глобальные переменные (state variables), состояние которых постоянно между вызовами функций. Её можно сравнить с жестким диском — после завершения выполнения текущего кода все запишется в блокчейн, и при следующем вызове контракта у нас будет доступ ко всем полученным ранее данным.

Структурно storage представляет из себя хранилище типа ключ-значение, где все ячейки имеют размер в 32 байта, что сильно напоминает хэш-таблицы, поэтому эта память сильно разрежена и мы не получим никакого преимущества от сохранения данных в двух соседних ячейках: хранение одной переменной в 1ой чейке и другой в 1000ой ячейке будет стоить столько же газа, как если бы мы хранили их в ячейках 1 и 2.

Как я уже говорил, этот тип памяти является самым дорогим — занять новую ячейку в storage стоит 20000 газа, изменить занятую — 5000 и прочесть — 200. Почему это так дорого? Причина проста — данные, сохранненные в storage контракта, будут записаны в блокчейн и останутся там навсегда.

Также, совсем несложно подсчитать максимальный объем информации, который можно сохранить в контракте: количество ячеек — 2^256, размер каждой — 32 байта, таким образом имеем 2^261 байт! По сути имеем некую машину Тьюринга — возможность рекурсивного вызова/прыжков и практически бесконечная память. Более чем достаточно, чтобы симулировать внутри еще один Ethereum, который будет симулировать Ethereum 🙂

Memory

​ Вторым типом памяти является Memory. Она намного дешевле чем storage, очищается между внешними (о типах функций можете прочитать в следующих главах) вызовами функций и используется для хранения временных данных: например аргументов, передаваемых в функции, локальных перемеменных и хранения значений return. Её можно сравнить с RAM — когда компьютер (в нашем случае EVM) выключается, ее содержимое стирается.

По внутреннему устройству memory представляет из себя байт-массив. Сначала она имеет нулевой размер, но может быть расширена 32-байтовыми порциями. В отличие от storage, memory непрерывна и поэтому хорошо упакована — намного дешевле хранить массив длины 2, хранящий 2 переменные, чем массив длины 1000, хранящий те же 2 переменные на концах и нули в середине.

Чтение и запись одного машинного слова (напомню, в EVM — это 256 бит) стоит всего 3 газа, а вот расширение памяти увеличивает свою стоимость в зависимости от текущего размера. Хранение некольких KB будет стоить недорого, однако уже 1 MB обойдется в миллионы газа, т.к цена растет квадратично.

Stack

​ Так как EVM имеет стэковую организацию, неудивительно, что последней областью памяти является stack — он используется для проведения всех вычислений EVM, а цена его использования аналогична memory. Он имеет максимальный размер в 1024 элемента по 256 бит, однако только верхние 16 элементов доступны для использования. Конечно, можно перемемещать элементы стэка в memory или storage, однако произвольный доступ невозможен без предварительного удаления верхушки стэка. Если стэк переполнить — выполнение контракта прервется, так что я советую оставить всю работу с ним компилятору 😉

Data location of complex types

​ В solidity работа со ‘сложными’ типами, такими как структуры и массивы, которые могут не уложиться в 256 бит, должна быть организована более тщательно. Так как их копирование может обходиться довольно дорого, мы должны задумываться о том, где их хранить: в memory (которая не постоянна) или же в storage (где хранятся все глобальные переменные). Для этого в solidity для массивов и структур существует дополнительный параметр — ‘местоположение данных’. В зависимости от контекста, этот параметр всегда имеет стандартное значение, однако он может быть изменен ключевыми словами storage и memory. Стандартным значением для аргументов функции является memory, для локальных переменных это storage (для простых типов это по-прежнему memory) и для глобальных переменных это всегда storage.

Существует также и третье местоположение — calldata. Данные, находящиеся там, неизменяемы, а работа с ними организована также, как в memory. Аргументы external функций всегда хранятся в calldata.

Местоположение данных также важно, потому что оно влияет на то, как работает оператор присвоения: присвоения между переменными в storage и memory всегда создают независимую копию, а вот присвоение локальной storage переменной только создаст ссылку, которая будет указывать на глобальную переменную. Присвоение типа memory — memory также не создает копии.

Читайте также:  Экономика описана потребительский расход 2300 инвестиции 700

Transactions and message calls

​ В Ethereum’е существует 2 вида аккаунтов, разделяющих одно и то же адресное пространство: External accounts — обычные аккаунты, контролируемые парами приватных-публичных ключей (или проще говоря аккаунты людей) и contract accounts — аккаунты, контролируемые кодом, хранящимся вместе с ними (смарт-контракты). Транзакция представляет из себя сообщение от одного аккаунта к другому (который может быть тем же самым, или же особым нулевым аккаунтом, смотрите ниже), содержащее какие-то данные (payload) и Ether.

С транзакциями между обычным аккаунтами все понятно — они всего-лишь передают значение. Когда целевым аккаунтом является нулевой аккаунт (с адресом 0), транзакция создает новый контракт, а его адрес формирует из адреса отправителя и его количества отправленных транзакций (‘nonce’ аккаунта). Payload такой транзакции интерпретируется EVM как байткод и выполняется, а вывод сохраняется как код контракта.

Если же целевым аккаунтом является contract account, выполняется код, находящийся в нем, а payload передается как входные данные. Самостоятельно отправлять тразакции contract account’ы не могут, однако можно запускать их в ответ на полученные (как от external account’ов, так и от других contract account’ов). Таким образом можно обеспечить взаимодействие контрактов друг с другом посредством внутренних транзакций (message calls). Внутренние транзакции идентичны обычным — они также имеют отправителя, получателя, Ether, gas и тд., а контракт может установить для них gas-limit при отправке. Единственное отличие от транзакций, созданных обычными аккаунтами, заключается в том, то живут они исключительно в среде исполнения Ethereum.

Visibility

В solidity существует 4 типа ‘видимости’ функций и переменных — external, public, internal и private, стандартом является public. Для глобальных переменных стандартом является internal, а external невозможен. Итак, рассмотрим все варианты:

  • External — функции этого типа являются частью интерфейса контракта, что значит они могут быть вызваны из других контрактов посредством message call. Вызванный контракт получит чистую копию memory и доступ к данным payload, которые будут расположены в отдельной секции — calldata. После завершения выполнения, возвращаемые данные будут размещены в заранее выделенном вызвавшим контрактом месте в memory. External функция не может быть вызвана изнутри контракта напрямую (то есть мы не можем использовать func() , однако все еще возможен такой вызов — this.func() ). В случае, когда на вход подается много данных, эти функции могут быть более эффективны, чем public (об этом я напишу ниже).
  • Internal — функции, а также глобальные переменные этого типа могут использоваться только внутри самого контракта, а также контрактов, унаследованных от этого. В отличие от external функций, первые не используют message calls, а работают посредством ‘прыжков’ по коду (инструкция JUMP). Благодаря этому, при вызове такой функции memory не очищается, что позволяет передавать по ссылке сложные типы, хранящиеся в memory (вспомните пример из главы Data location — tmpArr передается в функцию h по ссылке).
  • Public — public функции универсальны: они могут быть вызваны как внешне — то есть являются частью интерфейса контракта, так и изнутри контракта. Для public глобальных переменных автоматически генерируется специальная getter-функция — она имеет external видимость и возвращает значение переменной.
  • Private — private функции и переменные ничем не отличаются от internal, за исключением того, что они не видны в наследуемых контрактах.

Для наглядности рассмотрим небольшой пример.

Одним из самых частых вопросов является ‘зачем нужны external функции, если всегда можно использовать public’. На самом деле, не существует случая, когда external нельзя заменить на public, однако, как я уже писал, в некоторых случаях это более эффективно. Давайте рассмотрим на конкретном примере.

Выполнение public функции стоит 413 газа, в то время как вызов external версии только 281. Происходит это потому, что в public функции происходит копирование массива в memory, тогда как в external функции чтение идет напрямую из calldata. Выделение памяти, очевидно, дороже, чем чтение из calldata.

Причина того, что public функциям нужно копировать все аргументы в memory в том, что они могут быть вызваны еще и изнутри контракта, что представляет из себя абсолютно другой процесс — как я уже писал ранее, они работают посредством прыжков в коде, а массивы передаются через указатели на memory. Таким образом, когда компилятор генерирует код для internal функции, он ожидает увидеть аргументы в memory.

Для external функций, компилятору не нужно предоставлять внутренний доступ, поэтому он предоставляет доступ к чтению данных прямо из calldata, минуя шаг копирования в память.

Таким образом грамотный выбор типа ‘видимости’ служит не только для ограничения доступа к функциям, но и позволяет использовать их эффективнее.

Источник

Оцените статью