Глава 3. Виртуальная машина Ethereum (EVM)

Содержание страницы

Глава 3

Виртуальная машина Ethereum (EVM) – это глобальный компьютер, который может использовать любой человек за небольшую комиссию, выплачиваемую в эфире.

EVM (Ethereum Virtual Machine) – это единый глобальный 256-битный “компьютер”, в котором все транзакции хранятся локально на каждом узле сети и исполняются с относительной синхронностью. Это глобально доступная виртуальная машина, состоящая из множества отдельных компьютеров.

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

Если вам кажется экономически невыгодным существование целой EVM со всеми ее узлами, реплицирующими одинаковые транзакции и слепо поддерживающими одинаковое состояние между тысячами отдельных компьютеров, важно иметь надлежащее основание для сравнения с тем, как сегодня работают информационные технологии в области финансового обслуживания. EVM – это образец простоты и эффективности по сравнению с ними! Что еще более важно, вся эта работа не проводится впустую. На деле, как вы узнаете из этой главы, подтверждение результатов этой работы – это именно то, что в действительности защищает сеть.

Сеть центральных банков вчерашнего дня

Сегодня корпорации, страховщики, университеты и другие крупные учреждения тратят огромные суммы денег на создание и поддержание программных сервисов и IT-инфраструктуры для своих сотрудников и всех своих направлений бизнеса. Их различные притоки и оттоки средств регулируются крупными коммерческими банками, у которых есть своя собственная архитектура, политика, база кода, базы данных и уровни инфраструктуры. Конечно, все это работает поверх Fedwire (федеральной автоматизированной системы денежных переводов), которая является системой валовых расчетов в режиме реального времени (RTGS) Федерального Резерва.

Федеральный Резерв является центральным банком США. Fedwire используется всеми банками-членами Федерального Резерва для расчетов окончательных платежей в электронных долларах США. Любой аттестованный и действующий в юрисдикции штата банк может стать членом системы, купив в ней долю. Fedwire принадлежит и управляется непосредственно 12-ю федеральными резервными банками, и хотя она собирает взносы, работает она не ради извлечения прибыли.

Эта система обрабатывает немыслимые суммы долларов США – триллионы за триллионами. Она обладает некоторыми великолепными возможностями: есть система овердрафта, которая покрывает все существующие и утвержденные счета, и эта система признанно надежна, даже для перевода средств между континентами. Она функционирует в той или иной форме уже порядка ста лет.

Как вы можете представить, обеспечение безопасности и надежности программного обеспечения Fedwire чрезвычайно дорого обходится. Правда, стоимость построения и обслуживания уровней поверх RTGS еще выше, в силу ее требований безопасности. В конечном итоге эти расходы возлагаются на корпорации, которые пользуются услугами коммерческих банков, в виде комиссий. У этих компаний есть расходы на обслуживание своей собственной IT-инфраструктуры. В совокупности все это приводит к значительному повышению цен и комиссий для обычных потребителей.

Что из себя представляют виртуальные машины?

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

В целом можно сказать, что виртуальная машина – это эмуляция компьютерной системы при помощи другой компьютерной системы. Эти эмуляции основаны на тех же компьютерных архитектурах, что и объекты их эмуляции, но обычно они воспроизводят эту архитектуру на другом “железе”, не том, эмулировать которое они были предназначены. Виртуальные машины могут быть созданы программными средствами, аппаратными или использовать обе категории средств. В случае с Ethereum  используются обе. Чем обеспечивать защищенную работу сети из тысяч дискретных машин, как в системе Fedwire, Ethereum использует подход по обеспечению защищенной работы одной очень массивной машины, которая может охватить всю планету.

Как вы поймете из длинного списка клиентов Ethereum для различных операционных систем, EVM – это собирательная эмуляция, запущенная на тысячах машин, которые – на своем уровне – могут использовать любую из десятков версий Windows, Linux, ethOS и macOS (подробнее о ethOS в Главе 6).

Роль протокола Ethereum в банковской сфере

В рамках этой книги мы не постулируем гипотезу о том, подходят ли системы на основе блокчейна для использования суверенными центральными банками, или что эти системы совершенно точно являются заменой для центробанков. Более вероятно, что сами центральные банки начнут внедрять эту технологию. Коммерческие банки определенно заинтересованы в ней; вы найдете более подробную информацию о банках и предприятиях, вовлеченных в разработку контрактов Ethereum, в Главе 11.

Система Fedwire – это система расчетов с интерфейсом взаимодействия, разработанным под нужды банков с лицензией штатов и их операторов. К примеру, конечный пользователь розничного банка практически никак не взаимодействует с этой системой; работа с ним выполняется розничным банком.

Разработчики программного обеспечения расценивают Fedwire, как “платформу для банков”. Что выберет банк для построения поверх Fedwire (качество обслуживания, банковские онлайн-инструменты, физические традиционные филиалы, финансовые продукты, сопутствующие продажи) – это то, что выделит его из числа других банков в системе Fedwire.

Любой может создать банковскую платформу

Ethereum значительно более универсален. Он позволяет любому человеку поднимать сеть с таким же или даже лучшим уровнем обеспечения безопасности и надежности, чем у Fedwire, и с возможностью выполнения почти мгновенных защищенных трансферов ценности. И это лишь стартовая точка для Ethereum.

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

Но есть ли возможность масштабирования до скоростей и размеров Fedwire?

Ответ – да, есть,

Ethereum способен на это, но процесс займет несколько лет. Нет прямого или установленного предела ни для размеров блоков, ни для размеров транзакций. В Биткойн размер блока ограничен до 1Мб, что составляет примерно 7 транзакций в секунду. В Ethereum эти лимиты увеличиваются или уменьшаются в зависимости от спроса и пропускной способности сети.

Однако это не означает, что блоки могут быть неограниченного размера. Напомним, что единицы работы в сети Ethereum оцениваются в газе. Таким образом, более крупные, более сложные ethereum смарт контракты стоят больше газа для хранения и исполнения. Максимальное количество газа, которое может быть потрачено на блок, является переменной, но есть максимум. Теоретически, одна крупная транзакция может израсходовать весь лимит газа для одного блока. Но если будет поддерживаться постоянный спрос на большие лимиты газа, то система будет увеличивать лимит газа на блок с шагом в 0,09%. (Подробности о том, как это работает, можно прочитать в “Ethereum Yellow Paper” (формулы 40-42). На момент написания книги лимит газа для одного блока составлял 4,041,325 газа на блок.

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

Лаура Шин, автор и ведущая блокчейн-ориентированного подкаста Unchained, провела интервью с Адамом Людвином о блокчейн-стартапе из Сан-Франциско Chain в 2016 году и написала следующее:

  – Что касается владельцев сети в действующей системе, если вы идете в JPMorgan Chase Bank и кладете на депозит $50 наличными, Chase берет эти деньги, выпущенные Федеральным Резервом, на хранение в своей сети. Но Людвин сказал, представьте себе, что вместо банков, работающих в сети Fedwire, нынешняя система для электронной обработки платежей между банками-членами будет воссоздана на блокчейне, ключи от которого банки будут хранить для совершения переводов.

  – Это может затем привести к тому, что кастодианами для такой валюты будут становиться нефинансовые организации. “Для небольших сумм вам не нужен банк,” – сказал Людвин. – “Могут ли Google, Apple, Facebook хранить небольшие суммы цифровых денег? Меняет ли это модель того, кто может быть хранителем этих денег? Ответ – да.” Дополнительно, это может открыть новые возможности для peertopeer кредитования, уменьшая зависимость потребителей от банков в вопросах получения кредитов.

Что делает Виртуальная машина Ethereum (EVM)?

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

Как все это работает?

В EVM можно запускать произвольные программы (смарт-контракты, упомянутые в Главе 1), написанные на языке Solidity. Эти программы, получая определенные входные данные, всегда будут выполнять операцию вывода в том же порядке, с одинаковыми нижележащими изменениями состояния. Это делает программы на Solidity полностью детерминированными и гарантирует их исполнение, при условии, что вы достаточно заплатили за транзакцию; но мы поговорим о плате за газ чуть позже в этой главе, а в последующих мы дойдем до обучения solidity.

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

Как мы уже обсуждали, задача каждой ноды в EVM состоит в том, чтобы запускать одинаковый код, это часть протокола обработки блоков. Узлы обрабатывают блоки и запускают любой код, заключенный в транзакциях. Каждый узел делает это независимо; он не только сильно распараллелен, но и достаточно избыточен.

Несмотря на все внешние признаки, это эффективный способ балансировать глобальный реестр надежным образом. Важно помнить, насколько много денег, мощностей и человеческой энергии расходуется на каждый банк по всему миру, чтобы наладить его собственную уникальную IT-систему или набор из систем для каждого из его направлений деятельности. В банковской системе, базирующейся на Ethereum, все пользователи (корпорации или клиенты) получают прямой доступ к похожей на Fedwire системе бесплатно, имея возможность программировать транзакции. Поскольку протокол является свободным и опенсорсным, любой может запустить узел и подключиться к сети. К сожалению, последние разъяснения по системе Fedwire зачастую остаются без упоминания о криптовалютах, хотя это важный контекст в плане понимания преимуществ крупных публичных блокчейнов.

Вы можете найти актуальную, написанную сообществом, документацию проекта Ethereum в “Homestead Documentation Initiative”: http://ethdocs.org/en/latest

Эта документация создана не под редакцией фонда Ethereum, но она стала популярным ресурсом за счет понятного объяснения технических концепций.

За более глубокими техническими пояснениями и для просмотра предложений по улучшению Ethereum (“Ethereum Improvement Proposals”, EIPs), обратитесь к вики Ethereum по адресу.

На странице вики вы найдете “Ethereum White Paper”. Если после прочтения этой книги у вас останутся вопросы о том, как работает Ethereum, скорее всего ответ вы сможете найти либо в “White Paper”, либо в упомянутом ранее “Yellow Paper”, ссылку на который вы также сможете найти в вики Ethereum.

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

Глобальная одноэлементная машина

EVM – это транзакционная одноэлементная (“singleton”) машина с общим состоянием. В вычислительной сфере это означает, что она представляет собой один гигантский объект данных, а не то, чем она является физически: сеть дискретных машин-синглтонов, действующих по отдельности и в постоянной связи друг с другом. (Если вы непрограммист, то возможно, помните из Главы 1, что объект представляет собой небольшой фрагмент информации, которая отформатирована определенным образом, и которая содержит атрибуты, а также методы для чтения или изменения этих атрибутов).

Приложения для EVM называются смарт-контрактами

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

“Умные контракты”

Вместо того, чтобы утомлять вас этимологией словосочетания “смарт-контракт”, давайте проясним одно: в нашем контексте контракт относится к определенному виду контрактов – финансовому контракту, также известному в более разговорной речи, как дериватив или опцион. Финансовые контракты – это соглашения о покупке и продаже в определенный момент в будущем, обычно по установленной цене. В контексте Ethereum смарт-контракты – это соглашения между аккаунтами о передаче эфира (то есть,  платежа) при выполнении определенных условий.

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

EVM запускает байткод

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

Машины состояний

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

Цифровой vs. аналоговый

Фундаментальной идеей в концепции компьютера состояний является идея переключателя, который может находиться в двух состояниях: включен или выключен. Нули и единицы (общепринятый язык машин) используются для передачи состояний массивам метафорических переключателей, которым, условно говоря, задается определенная конфигурация для кодирования указанных букв, цифр или других символов клавиатуры. Все символы на клавиатуре (и не только) могут быть представлены всего восемью переключателями, поэтому память компьютеров кратна восьми. Например, код символа для запятой 0010 1100.

В компьютерном программировании буквы и цифры могут использоваться для написания машинных инструкций, в разговорной речи это называется кодом. Американская ученая и контр-адмирал флота США Грейс Хоппер (изображение 3-1) разработала первый компилятор, который автоматически транслировал человекочитаемый код в машинный код (типа байткода EVM), который является менее абстрактным и, следовательно, находится на один шаг ближе к нулям и единицам, о которых мы так много говорим.

Контр-адмирал Грейс Хоппер была одним из первых программистов, кто писал код для гарвардского компьютера Марк I в 1944 году.

Утверждения состояний (“statements“)

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

Утверждения могут вернуть значение “true” или “false”, и, в зависимости от кода, этот двоичный результат может привести к добавлению, удалению или изменению информации в одном из многочисленных адресов памяти компьютера. (Поскольку язык Solidity строго типизирован, в нем нет “псевдоправдивых” (“truthy”) и “псевдоложных” (“falsy”) утверждений, как в Javascript). Четкое различие между “true” и “false”, “да” и “нет”, “включен” и “выключен” – это то, что позволяет компьютерам безопасно принимать решения вместо людей.

Роль данных в состоянии

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

Важно различать атрибут и состояние. Состояние – это то, что может легко и предсказуемо меняться. Давайте используем пример с автомобилем.

Перекраска автомобиля – это тяжелая работа, но она может быть выполнена. Цвет краски является примером атрибута. В псевдокоде вы можете сказать следующее о машине:

bodyColor = red

В компьютерном программировании это называется парой ключ/значение. Ключ, bodyColor, имеет присвоенное ему значение, которое является red (“красный”). Чтобы изменить значение этого ключа, ваш код выполняет новое утверждение значения, чтобы оно стало иным:

bodyColor = green

И теперь ваша машина перекрашена. У нее новое значение цвета (“зеленый”).

Теперь, давайте предположим, что вы указали компьютеру, что цвет этого автомобиля будет часто меняться. Другими словами, вы делаете цвет автомобиля переменной. Что ж, можно сказать, что переменная (в данном случае, цвет) может иметь состояние, которое является изменяющимся значением. Но отдельное значение, такое как green (“зеленый”), не имеет состояния; green – это просто green.

Одометр представляет еще один пример переменной с изменяемым состоянием.

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

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

Как работают внутренности EVM

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

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

Если что-то пойдет не так – допустим, одна из этих инструкций не является возможной с математической точки зрения – состояние машины станет недопустимым, и программа закроется или остановится. Фактически, вся система может упасть.

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

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

К этому моменту мы легко прошли через столетие науки о вычислениях, чтобы добраться до EVM. Теперь мы начнем замедляться и посмотрим, как некоторые ее компоненты работают на практике.

EVM постоянно проверяет наличие транзакций

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

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

Создание общей машины, повествующей о том, что произошло

Транзакции, в силу вышесказанного, представляют собой некое подобие машинного повествования, хронику – допустимый в вычислительном отношении переход от одного состояния к другому. Как говорит Гевин Вуд в “Yellow Paper”:

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

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

Криптографическое хеширование

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

Что делают хеш-функции (или алгоритмы хеширования)

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

Примечание

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

Блоки: история изменения состояний

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

Все блоки, связанные воедино, включая первичный блок (“genesis block” – почетное название первого блока, добытого сетью после выхода в онлайн), называются блокчейном. В некоторых кругах вы услышите, что блокчейн называют распределенным реестром или технологией распределенного реестра (DLT).

Реестр – это точная формулировка, поскольку цепочка содержит каждую транзакцию в истории сети, что делает ее по сути гигантской бухгалтерской балансовой книгой. Однако большая часть так называемых цифровых реестров не используют доказательство выполнения работы (“Proof-of-work”) для защиты сети, как это делают Биткойн и Ethereum.

Суть времени блоков

В Биткойн один блок равен 10 минутам. Это так называемое время блока выводится из констант, жестко закодированных в схему выпуска Биткойн, в общей сложности 21 миллион монет будут выпущены с 2009 по 2024 год, а вознаграждение за майнинг уменьшается вдвое каждые четыре года.

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

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

Недостатки коротких блоков

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

Чтобы компенсировать это, майнерам, которые находят валидные, но не “выигрывающие” блоки, выплачивается неполное вознаграждение в качестве утешения. В Ethereum подобные блоки называются “дядями” (“Uncles”).

Что делает блок валидным, а что делает его “выигрывающим”, является темой Главы 6.

Чтобы посмотреть на полный протокол блоков Ethereum, посетите страницу.

А теперь, давайте продолжим наш обзор EVM.

Блокчейн из “соло-узлов”

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

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

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

Распределенная защита

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

Действительно, решение этой проблемы доказуемым и заслуживающим доверия образом является предназначением EVM, как и виртуальной машины Биткойн. Устойчивость и безопасность EVM достигаются большим количеством машин, добывающих блоки в сети, стимулом для которых является зарабатывание вознаграждения, номинированного в эфире или биткойнах. Мы быстро пройдемся по этой теме перед тем, как углубиться в полное разъяснение в Главе 6.

Роль майнинга в функции перехода состояний

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

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

.

Для каждой транзакции в блоке EVM выполняет следующее:

  1. Проверка транзакции на соответствие установленному формату. Имеет ли она правильный набор значений? Является ли сигнатура валидной? Соответствует ли значение nonce (счетчик транзакций) в транзакции значению nonce в аккаунте? Если чего-либо из этого не хватает – возвращается ошибка.
  2. Расчет комиссии за транзакцию путем умножения требуемого объема работы (обозначается как STARTGAS, как вы узнаете из таблицы 3-1) на цену газа. Затем с баланса аккаунта пользователя вычитается комиссия и увеличивается значение nonce отправителя (счетчик транзакций). Если в аккаунте недостаточно эфира, возвращается ошибка.
  1. Инициализация платежа за газ; с этого момента вычитается определенное количество газа за каждый обработанный байт в транзакции.
  2. Передача суммы транзакции – отправляемой суммы – на принимающий аккаунт. Если принимающий аккаунт еще не существует, он будет создан. (Офлайн-узлы Ethereum могут генерировать адреса, поэтому сеть может не знать об указанном адресе до тех пор, пока транзакция не состоится).

Если принимающий адрес является адресом контракта, запускается код этого контракта. Это продолжается до тех пор, пока код не завершит исполнение или не закончится платеж за газ.

  1. Если у отправляющего аккаунта недостаточно эфира для завершения транзакции, или закончился газ, все изменения из этой транзакции откатываются назад. В качестве предупреждения – комиссионные отчисления, которые по-прежнему отправляются майнеру и не возмещаются.
  2. Если транзакция выдает ошибку по любой другой причине, газ возмещается отправителю, а любые комиссии, связанные с использованным газом, отправляются майнеру.

Примечание

Данные из смарт-контракта исполняются на 4-ом шаге функции перехода состояний, как описано выше.

Таблица 3-1.

Стоимость типовых операций EVM.

Имя операции

Расход газа

Описание

step1Сумма по умолчанию за цикл исполнения
stop0Бесплатно
suicide0Бесплатно
sha320Хеш-функция SHA-3
sload20Берет из постоянного хранилища
sstore100Помещает в постоянное хранилище
balance20Запрос баланса аккаунта

 

create100Создание контракта
call20Инициализация read-only вызова
memory1Каждое дополнительное слово при расширении памяти
txdata5Каждый байт данных или кода для транзакции
transaction500Базовая плата за транзакцию
contract creation53,000Изменено в Homestead с 21000

 

Аренда времени в EVM

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

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

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

Верите или нет, но данное объяснение все еще представляет собой лишь поверхностный взгляд на внутреннее устройство EVM. Вы узнаете больше в Главах 5 и 6. А сейчас будет полезно разобраться с тем, что такое комиссии, какова их роль в исполнении транзакций, и каково их влияние на паттерны в разработке.

Привет, газ!

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

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

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

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

Примечание

Суммарное количество использованного газа, умноженное на цену газа, дает сумму комиссии, начисленную по отдельно взятой транзакции.

Почему газ так важен?

Расходы на газ гарантируют, что время вычисления в сети будет соответствующим образом оценено. Это работает по-другому в Биткойн, где комиссия основана на размере транзакции в килобайтах. Поскольку код Solidity может быть произвольно сложным, короткий фрагмент инструкций может генерировать большое количество вычислительной работы, тогда как длинный фрагмент может генерировать меньше работы. Вот почему комиссии в EVM основаны на объеме выполняемой работы, а не на размере транзакции.

Почему газ не оценивается в эфире?

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

Комиссия как мера регулирования

Как вы узнаете из Главы 7, такие сети, как Биткойн и Ethereum, используют экономические стимулы и антистимулы для того, чтобы делать определенные атаки на сеть нецелесообразными. Комиссии относятся к категории сдерживающих факторов.

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

Блоки, которые потребляют избыточное количество газа, представляют большую опасность для Ethereum. Их распространение по сети может занять много времени вследствие их огромного размера. Как система адаптируется к запросам пользователей, у которых могут иметься легитимные основания на использование крупных смарт-контрактов, станет понятно позже в этой главе, а также в Главе 6. Протокол помогает сокращать последние блоки при помощи различных методов, которые мы рассмотрим в Главе 6, и выставляет плавающее ограничение на операции, которое на текущий момент устанавливает 65536 операций за один блок.

Работа с газом

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

Особенности газа

Давайте рассмотрим некоторые детали работы с газом:

  • К сожалению, термин “газ” создает некоторую путаницу. Для каждой транзакции требуется значение STARTGAS. Это значение упоминается как gasLimit в “Yellow Paper” и часто просто как gas в Geth и Webjs
  • Каждая транзакция также требует от пользователя указания цены газа.
  • Сумма, заданная в STARTGAS, умноженная на цену газа, депонируется на время исполнения вашей транзакции.
  • Если цена газа, которую вы предлагаете за транзакцию, слишком низкая, узлы не будут обрабатывать транзакцию, и она будет оставаться в сети невыполненной.
  • Если ваша цена газа приемлема для сети, но расходы на газ выходят за пределы доступных средств на балансе вашего кошелька, то транзакция не будет исполнена и откатится назад; эта неудавшаяся транзакция записывается в блокчейн, и вы получаете возмещение за весь STARTGAS, не использованный в транзакции.
  • Использование чрезмерного STARTGAS не приводит к более быстрой обработке ваших транзакций, а в некоторых случаях может сделать ее менее привлекательной для майнеров.

Как газ связан с масштабируемостью системы

Если вы отправляете вычислительно сложный набор инструкций в EVM, единственным человеком, по которому это ударит, будете вы. Работа потратит ваш эфир и остановится, когда закончится эфир, выделенный вами для транзакции. Это не окажет никакого влияния на чужие транзакции. Невозможно затруднить работу EVM, не заплатив для этого очень много в форме комиссий за транзакции.

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

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

Аккаунты, транзакции и сообщения

Напомним из Главы 2, что в Ethereum есть два типа аккаунтов:

  • Внешние аккаунты
  • Аккаунты контрактов

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

Внешние аккаунты

Внешний аккаунт (EOA) также известен как аккаунт, контролируемый при помощи пары закрытых ключей, которые могут храниться человеком или на внешнем сервере.  Эти аккаунты не могут содержать код EVM. Характеристики EOA включают:

  • Содержит баланс эфира
  • Способен отправлять транзакции
  • Контролируется с помощью закрытых ключей аккаунта
  • Не связан ни с каким кодом
  • База данных ключ/значение, содержащаяся в каждом аккаунте, где ключи и значения являются 32-байтными строками

Аккаунты контрактов

Аккаунты контрактов не контролируются людьми. Они хранят инструкции и активируются внешними аккаунтами или другими аккаунтами контрактов. Аккаунты контрактов обладают следующими характеристиками:

  • Содержат баланс эфира
  • Хранят определенный код контракта в памяти
  • Могут быть приведены в действие людьми (отправляющими транзакцию) или другими контрактами, отправляющими сообщение
  • При исполнении могут выполнять сложные операции
  • Имеют свое собственное постоянное состояние и могут вызывать другие контракты
  • Не имеют владельца после включения в EVM
  • База данных ключ/значение, содержащаяся в каждом аккаунте, где ключи и значения являются 32-байтными строками

Транзакции и сообщения

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

Транзакция в EVM представляет собой криптографически подписанный пакет данных, хранящий сообщение (как описано ранее), в котором содержится указание для EVM, что нужно сделать – отправить эфир, создать новый контракт, запустить существующий контракт или выполнить определенные вычисления. Адреса контрактов могут быть получателями транзакций, как и пользователи с внешними аккаунтами. Вспомните обсуждение криптографически защищенной связи в Главе 2, когда мы говорили о зашифрованных коммуникациях: транзакция похожа на приватный обмен данными между двумя пользователями в незащищенной сети, которые, тем не менее, могут “отправлять” ценность (токены) друг другу.

Характеристики транзакций

Транзакции обладают следующими характеристиками:

  • Адрес получателя; если не указать адрес получателя (и прикрепить данные смарт-контракта) – это метод для загрузки новых смарт-контрактов. Как вы узнаете, будет возвращен адрес контракта, чтобы пользователь знал, как получить доступ к этому контракту в будущем.
  • Подпись, идентифицирующая отправителя
  • Поле значения, показывающее отправляемую сумму
  • Опциональное поле данных для сообщения (если транзакция отправляется на адрес контракта)
  • Значение STARTGAS,     указывающее    максимальное    количество    шагов вычислений, которые предоплачены
  • Значение GASPRICE, представляющее плату, которую отправитель готов заплатить за газ.

Характеристики сообщений

Сообщение представляет собой фрагмент данных, отправляемый одним контрактом другому контракту (никогда для или от человека). Сообщения – это виртуальные объекты, которые никогда не будут сериализованы и существуют только в EVM. Когда майнер получает вознаграждение в сети Ethereum, это реализуется с помощью сообщения, увеличивающего баланс адреса для получения платежей майнера; это не представляет собой транзакцию.

Сообщение отправляется, когда контракт запускается виртуальной машиной EVM, и это приводит к исполнению операционные коды CALL и DELEGATECALL. Вы узнаете об операционных кодах в следующем разделе этой главы.

Примечание

Поскольку сеть Ethereum не подключена к HTTP-сети, она не использует HTTP-методы. Вместо этого она использует коды операций, которые традиционно используются для передачи сообщений внутри одного локального хоста. Вот что имеется ввиду под характеристиками, включающими такую формулировку, как “единая глобальная машина”. Биткойн работает аналогичным образом.

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

Сообщение содержит следующие характеристики:

  • Адрес отправителя сообщения
  • Адрес получателя сообщения
  • Поле значения (указывается, сколько эфира отправляется, если вообще отправляется)
  • Опциональное поле данных (содержащее входные данные для контракта)
  • Значение STARTGAS,    ограничивающее   количество газа, которое может использовать сообщение

Оценка комиссионных отчислений в виде газа для операций

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

В таблице 3-1 показаны затраты на некоторые типовые операции EVM.

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

Операционные коды в EVM

Как вы узнаете, некоторые из этих операций можно назвать методами. Одна из самых запутанных вещей в парадигме блокчейна заключается в том, что она объединяет технические соглашения из нескольких областей науки о вычислениях и сетях. Одним из примеров является использование операционных кодов в Ethereum (и Биткойн). В таблице 3-2 показаны все коды операций, доступные для EVM, и соответствующие им функции.

Таблица 3-2.

Это полный список операционных кодов EVM.

0s: Остановка и арифметические операции
0x000x00Остановить исполнение
0x01ADDОперация сложения
0x02MULОперация умножения
0x03SUBОперация вычитания
0x04DIVОперация целочисленного деления
0x05SDIVЦелое число со знаком
0x06MODОстаток при целочисленном делении
0x07SMODОстаток при целочисленном делении со знаком
0x08ADDMODОстаток при целочисленном делении
0x09MULMODОстаток при целочисленном делении

 

0x0aEXPОперация возведения в степень
0x0bSIGNEXTENDРасширение длины с дополнением до двух (число со знаком в дополнительном коде)
10s: Сравнение и побитовые логические операции
0x10LTСравнение “меньше, чем”
0x11GTСравнение “больше, чем”
0x12SLTСравнение “меньше, чем” со знаком
0x13SGTСравнение “больше, чем” со знаком
0x14EQСравнение на равенство
0x15ISZEROПростой NOT оператор
0x16ANDПобитовая операция AND
0x17ORПобитовая операция OR
0x18XORПобитовая операция XOR
0x19NOTПобитовая операция NOT
0x1aBYTEВозвращение одного байта из слова
20s: SHA3
0x20SHA3Вычисление хеша Keccak-256
30s: Информация о сети
0x30ADDRESSПолучение адреса

 

текущего исполняемого аккаунта
0x31BALANCEПолучение баланса заданного аккаунта
0x32ORIGINПолучить адрес отправителя транзакции
0x33CALLERПолучить адрес отправителя вызова. Это адрес аккаунта, напрямую отвечающего за данное исполнение (прим. переводчика: за исключением delegatecall)
0x34CALLVALUEПолучить депонируемое значение (wei) текущей инструкции/транзакции, отвечающей за данное исполнение

(прим. переводчика: wei, отправляемые вместе с текущим вызовом)

0x35CALLDATALOADПолучить входные данные текущей среды
0x36CALLDATASIZEПолучить размер входных данных в текущей среде (прим. переводчика: размер данных вызова в байтах)
0x37CALLDATACOPYКопировать входные данные текущей среды в память. Относится к входным данным, передаваемым посредством команды вызова сообщения или транзакции
0x38CODESIZEПолучить размер кода, работающего в текущей среде

 

0x39CODECOPYКопировать код, работающий в текущей среде, в память
0x3aGASPRICEПолучить цену газа в текущей среде
0x3bEXTCODESIZEПолучить размер кода аккаунта
0x3cEXTCODECOPYКопировать код аккаунта в память
40s: Информация о блоке
0x40BLOCKHASHПолучить хеш одного из 256 последних завершенных блоков
0x41COINBASEПолучить адрес майнера, завершившего блок
0x42TIMESTAMPПолучить временную метку блока
0x43NUMBERПолучить номер блока
0x44DIFFICULTYПолучить сложность блока
0x45GASLIMITПолучить лимит газа для блока
50s: Стек, память, хранилище и операции потока
0x50POPУдалить элемент из стека
0x51MLOADЗагрузить слово из памяти
0x52MSTOREСохранить слово в память
0x53MSTORE8Сохранить байт в память

 

0x54SLOADЗагрузить слово из хранилища
0x55SSTOREСохранить слово в хранилище
0x56JUMPИзменение счетчика команд
0x57JUMPIУсловное изменение счетчика команд
0x58PCПолучение значения счетчика команд до инкрементирования
0x59MSIZEПолучить размер активной памяти в байтах
0x5aGASПолучить количество доступного газа, включая соответствующее понижение
0x5bJUMPDESTОтметить валидный пункт назначения для прыжков
60s and 70s: Push-операции
0x60PUSH1Разместить 1-байтовый элемент в стеке
0x61PUSH2Разместить 2-байтовый элемент в стеке
0x7fPUSH32Разместить

32-байтовый (машинное слово) элемент в стеке

80s: Операции дублирования
0x80DUP1Дублирование первого элемента стека
0x81DUP2Дублирование второго элемента стека

 

0x8fDUP16Дублирование шестнадцатого элемента стека
90s: Операции обмена
0x90SWAP1Заменить первый и второй элемент стека
0x91SWAP2Заменить первый и третий элемент стека
0x9fSWAP16Заменить первый и семнадцатый элемент стека
a0s: Операции с логами
0xa0LOG0Добавить запись лога без тем
0xa1LOG1Добавить запись лога с одной темой
0xa4LOG4Добавить запись лога с 4 темами
f0s: Системные операции
0xf0CREATEСоздать новый аккаунт со связанным кодом
0xf1CALLСообщение-вызов в аккаунт
0xf2CALLCODEСообщение-вызов в данный аккаунт с кодом альтернативного аккаунта
0xf3RETURNПрекратить исполнение, вернуть выходные данные
0xf4DELETECALLСообщение-вызов в данный аккаунт с кодом альтернативного аккаунта, но сохраняя текущие значения для отправителя и значения.

 

Прекратить исполнение; пометить для удаления
0xffSUICIDEПрекратить исполнение и зарегистрировать аккаунт для последующего удаления

 

В традиционной веб-разработке примерным эквивалентом операционного кода будет операция по протоколу HTTP, также известная как метод доступа по протоколу HTTP. К ним относятся GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE и CONNECT.

Эти методы надежны и хорошо известны.

В Ethereum и Биткойн все работает иначе. Поскольку сеть также является и глобальной машиной, “методы”, которые вы используете для совершения вызовов по сети, – это лишь машинный код, типа того, что используется внутри отдельного компьютера.

Итоги Главы 3

Эта глава составила более полное представление о EVM как о базе данных, и как вносятся изменения в ее состояние. Хотя обоснование архитектуры должно быть для вас теперь более понятным, многое еще предстоит обсудить. Если вы хотить прочитать дополнительную документацию о том, как EVM исполняет программы, вы найдете список ресурсов по адресу.

Также про тему EVM можно почитать дополнительно на Habr.

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

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

Инструкции, составляющие смарт-контракты, хранятся в байт-коде EVM. Но до того, как они компилируются в байт-код, они пишутся человеком на языке программирования Solidity. Этот язык является предметом следующей главы.

Примечания к Главе 3

  1. Forbes, “Central Banks Explore Blockchains: Why Digital Dollars, Pounds Or Yuan Could Be A Reality In 5 Years,” www.forbes.com/sites/laurashin/2016/10/12/central-banks-explore-blockchains-why-digital-dolla rs-pounds-or-yuan-could-be-a-reality-in-5-years/#5ef54e7176d8, 2016.
  2. Wikipedia, “Grace Hopper,” https://en.wikipedia.org/wiki/Grace_Hopper, 2016.
  3. Gavwood.com, “Ethereum: A Secure Decentralised Generalised Transaction Ledger”, http://gavwood.com/paper.pdf, 2016.
  4. Bitcoin Wiki, “Controlled Supply,” https://en.bitcoin.it/wiki/Controlled_supply, 2016.
  5. Google Code, “Diff-Match Patch,” https://code.google.com/p/google-diff-match-patch/, 2016.
  6. Ethereum White Paper, “Ethereum State Transition Function,” https://github.com/ethereum/wiki/wiki/White-Paper#ethereum-state-transition-function, 2016.
  7. GitHub, “Ethereum White Paper,” https://github.com/ethereum/wiki/wiki/White-Paper, 2016.
  8. ConsenSys Media, “Ethereum, Gas, Fuel and Fees,” https://media.consensys.net/ethereum-gas-fuel-and-fees-3333e17fe1dc#.ozbhydyz6, 2016.

Андрей Никитенко
Андрей Никитенко
Задать вопрос эксперту
Понравилась статья? Поделить с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Share via
Copy link