Техническая документация об Ethereum
Эта вводная статья была опубликована в 2014 году основателем Ethereum Виталиком Бутериным, до запуска проекта в 2015 году. Стоит отметить, что Ethereum, как и многие проекты с открытым исходным кодом, со временем эволюционировал.
Несмотря на то что этой статье уже несколько лет, мы не удаляем ее, потому что она продолжает служить полезным источником, содержащим точную информацию об Ethereum и его видении. Чтобы узнать о нововведениях в Ethereum и о внесении изменений в протокол, рекомендуем ознакомиться с этим руководством.
Платформа следующего поколения для смарт-контрактов и децентрализованных приложений
Создание биткоина в 2009 году Сатоши Накамото часто называется радикальной разработкой в деньгах и валюте, являясь первым примером цифрового актива, который одновременно не имеет основы или внутренней ценности(opens in a new tab) и не имеет централизованного эмитента или контроллера. Тем не менее другой, возможно, более важной, частью эксперимента является базовая технология блокчейн как инструмент распределенного консенсуса, и внимание быстро начинает смещаться к этому аспекту биткоина. Часто упоминаемые альтернативные приложения технологии блокчейн включают использование цифровых активов на блокчейне для представления пользовательских валют и финансовых инструментов (цветных монет(opens in a new tab)), право собственности на лежащее в основе физическое устройство (смарт-объект(opens in a new tab)), невзаимозаменяемые активы, такие как доменные имена (Namecoin(opens in a new tab)), а также более сложные приложения, в которых цифровые активы напрямую контролируются частью кода, реализующей произвольные правила (смарт-контракты(opens in a new tab)) или даже основанные на блокчейне децентрализованные автономные организации(opens in a new tab) (DAO). То, что Ethereum планирует предоставить — это блокчейн со встроенным полным по Тьюрингу языком программирования, который может быть использован для создания контрактов, которые можно использовать для кодирования произвольных функций перехода состояния, позволяя пользователям создавать любые из систем, описанных выше, как и многие другие, которые мы еще даже не придумали, просто записав логику в нескольких строках кода.
Введение в Bitcoin и существующие концепции
История
Концепция децентрализованной цифровой валюты, как и альтернативные приложения, такие как реестры собственности, существует уже несколько десятилетий. Протоколы анонимных электронных платежей 1980-х и 1990-х годов, в основном опирающиеся на криптографический примитив, известный как ослепление Чаума, обеспечивали высокую степень конфиденциальности валюты, но протоколы в значительной степени не смогли завоевать популярность из-за их зависимости от централизованного посредника. В 1998 году b-money(opens in a new tab) Вэя Дая стали первым предложением, вводящим идею создания денег путем решения вычислительных головоломок, а также децентрализованного консенсуса, но в предложении было недостаточно информации о том, как реализовать децентрализованный консенсус. В 2005 году Хэл Финни представил концепцию многоразовых доказательств выполнения работы(opens in a new tab), систему, которая использовала идеи b-money и вычислительно сложные Hashcash головоломки Адама Бэка для создания концепции криптовалюты, но в очередной раз не дотянула до идеала, положившись на доверенные вычисления в качестве бэкенда. В 2009 году децентрализованная валюта была впервые реализована на практике Сатоши Накамото, сочетающая сложившиеся примитивы для управления правом собственности (криптография с открытым ключом) с алгоритмом консенсуса для отслеживания владельцев монет, известным как «доказательство выполнения работы».
Механизм, лежавший в основе доказательства выполнения работы был значительным прорывом, так как он одновременно решил две проблемы. Во-первых, он обеспечил простой и умеренно эффективный алгоритм консенсуса, позволяя узлам в сети коллективно согласовать набор канонических обновлений к состоянию реестра биткоина. Во-вторых, он обеспечил механизм, позволяющий свободно вмешиваться в процесс консенсуса, решая политическую задачу о том, кто получит возможность влиять на консенсус, одновременно предотвращая атаки Сивиллы. Это достигается путем замены формального барьера для участия, такого как требование быть зарегистрированным как уникальная организация в конкретном списке, экономическим барьером — вес отдельного узла в процессе консенсусного голосования прямо пропорционален вычислительной мощности, которой располагает узел. С тех пор был предложен альтернативный подход, называемый доказательством доли владения, вычисляющий вес узла пропорционально его валютным резервам, а не вычислительным ресурсам; обсуждение относительных достоинств двух подходов выходит за рамки данной статьи, но следует отметить, что оба подхода могут быть использованы как основа для криптовалюты.
Биткоин как система с изменяющимися состояниями
С технической точки зрения, реестр криптовалюты, такой как биткоин, можно рассматривать как систему с изменяющимися состояниями, где есть «состояние», состоящее из статуса принадлежности всех существующих биткоинов, и «функция смены состояния», которая берет состояние и транзакцию и выводит новое результирующее состояние. В стандартной банковской системе, например, состояние является балансом, транзакция — запросом на перемещение $X от A к B, а функция смены состояния уменьшает значение в аккаунте A на $X и увеличивает значение в аккаунте B на $X. Если счет А имеет менее $X, то функция смены состояния возвращает ошибку. Таким образом, формально можно определить:
APPLY(S,TX) -> S' или ERROR
В банковской системе, определенной выше:
APPLY({ Alice: $50, Bob: $50 },"отправить $20 от Alice к Bob") = { Alice: $30, Bob: $70 }
Но:
APPLY({ Alice: $50, Bob: $50 },"отправить $70 от Alice к Bob") = ERROR
«Состояние» в биткоине — это все монеты (технически, «неизрасходованное выводы транзакции» или UTXO), которые были произведены и еще не израсходованы, причем каждый UTXO имеет номинал и владельца (определяется 20-байтовым адресом, который по сути является криптографическим открытым ключомfn1). Транзакция содержит один или более вводов, где каждый ввод содержит ссылку на существующий UTXO и криптографическую подпись, созданную с помощью закрытого ключа, связанного с адресом владельца, и один или более выводов, каждый из которых содержит новый UTXO для добавления к состоянию.
Функцию смены состояния APPLY(S, TX) -> S'
можно определить примерно следующим образом:
- Для каждого входного значения в
TX
:- Если упомянутый UTXO отсутствует в
S
, вернуть сообщение об ошибке. - Если предоставленная подпись не соответствует владельцу UTXO, вернуть сообщение об ошибке.
- Если упомянутый UTXO отсутствует в
- Если сумма номиналов всех вводимых UTXO меньше суммы номиналов всех выводимых UTXO, вернуть сообщение об ошибке.
- Вернуть
S
, где удалены все UTXO ввода и добавлены все UTXO вывода.
Первая половина первого шага не позволяет отправителям транзакций тратить несуществующие монеты, вторая половина первого шага не позволяет отправителям транзакций тратить чужие монеты, а второй шаг обеспечивает сохранение ценности. Для оплаты используется следующий протокол. Предположим, Алиса хочет отправить Бобу 11,7 BTC. Во-первых, Алиса будет искать набор доступных UTXO, которыми она владеет и которые в сумме дают как минимум 11,7 BTC. Алиса не сможет получить ровно 11,7 BTC; скажем, что наименьшее, что она может получить это 6+4+2=12. После этого она создает транзакцию с этими тремя вводами и двумя выводами. Первым выводом будет 11,7 BTC с адресом Боба в качестве владельца, а вторым выводом будет оставшаяся разница в 0,3 BTC, владелец которого — сама Алиса.
Майнинг
Если бы у нас был доступ к надежному централизованному сервису, реализовать эту систему было бы просто. Ее можно было бы просто написать с помощью кода точно так, как описано, используя жесткий диск централизованного сервера для отслеживания состояния. Однако с биткоином мы пытаемся построить децентрализованную валютную систему, поэтому нам нужно будет объединить систему смены состояния с системой консенсуса, чтобы гарантировать, что все согласны с порядком транзакций. Децентрализованный консенсусный процесс биткоина требует наличия узлов в сети, чтобы постоянно пытаться создавать пакеты из транзакций, называемые «блоками». Сеть рассчитана на создание примерно одного блока каждые десять минут, где каждый блок, содержит метку времени, называемую «nonce», ссылку на предыдущий блок (т. е. его хэш) и список всех транзакций, которые произошли после предыдущего блока. Со временем это создает неизменную, постоянно растущую цепочку блоков (так называемый «блокчейн»), которая постоянно обновляется, чтобы представлять последнее состояние реестра биткоина.
Алгоритм проверки достоверности блока в этой модели следующий:
- Проверить, что прошлый блок ссылается на существующий достоверный блок.
- Проверить, что временная метка блока больше, чем временная метка предыдущего блокаfn2 и прошло менее 2 часов с момента создания предыдущего блока
- Проверить, что доказательство выполнения работы над блоком является действительным.
- Пусть
S[0]
будет состоянием в конце предыдущего блока. - Предположим, что
TX
является списком транзакций блока сn
транзакциями. Для всехi
в диапазоне0...n-1
, задатьS[i+1] = APPLY(S[i], X[i])
Если какое-либо приложение возвращает ошибку, выйти и вернуть false. - Вернуть значение true и установить
S[n]
в качестве состояния в конце этого блока.
По сути, каждая транзакция в блоке должна обеспечивать достоверный переход от канонического состояния до выполнения транзакции к новому состоянию. Обратите внимание, что состояние никак не закодировано в блоке. Это чисто абстракция, которая запоминается проверяющим узлом и может быть (безопасно) вычислена для любого блока только начиная с состояния генезиса и последовательно применяя каждую транзакцию в каждом блоке. Кроме того, обратите внимание, что важен порядок, в котором майнер включает транзакции в блок. Если две транзакции A и B в блоке такие, что B тратит UTXO, созданный A, тогда блок будет действителен, если A располагается раньше B, но не иначе.
Одно из условий действительности, приведенное в списке выше, которое не встречается в других системах, является требованием «доказательства выполнения работы». Точное условие состоит в том, что двойной SHA256 хэш каждого блока, рассматриваемый как 256-битное число, должен быть меньше динамически настраиваемого целевого значения, которое на время этой записи составляет приблизительно 2187. Цель этого состоит в том, чтобы сделать создание блоков вычислительно «сложным», тем самым не позволяя злоумышленникам с помощью атаки Сивиллы переделать весь блокчейн в свою пользу. Поскольку алгоритм SHA256 разработан как полностью непредсказуемая псевдослучайная функция, то единственный способ создать действительный блок — методом проб и ошибок, постоянно увеличивая число nonce и проверяя, соответствует ли новый хэш условию.
При текущем целевом значении ~2187 сеть должна сделать в среднем ~269 попыток, прежде чем будет найден допустимый блок. Как правило, цель пересчитывается сетью каждые 2016 блоков, так что в среднем новый блок создается каким-либо узлом в сети каждые десять минут. В качестве вознаграждения за эту вычислительную работу майнер каждого блока имеет право включить транзакцию, дающую ему 25 BTC. Кроме того, если общая сумма вводов транзакции превышает сумму выводов, разница также достается майнеру в качестве комиссии. Кстати, это также единственный механизм выпуска BTC. Состояние генезиса вообще не содержало монет.
Чтобы лучше понять цель майнинга, рассмотрим, что происходит в случае злонамеренной атаки. Поскольку базовая криптография биткоина безопасна, злоумышленник будет атаковать ту часть системы, которая не защищена криптографией напрямую: порядок транзакций. Стратегия злоумышленника проста:
- Отправить 100 BTC продавцу в обмен на некоторый продукт (желательно цифровой товар с быстрой доставкой)
- Дождаться доставки товара
- Создать еще одну транзакцию, отправляя те же самые 100 BTC самому себе
- Постараться убедить сеть в том, что его транзакция самому себе была первой.
Как только первый шаг произойдет, через несколько минут какой-нибудь майнер включит транзакцию в блок, допустим в блок номер 270000. Примерно через час еще пять блоков будут добавлены в цепочку после этого блока, каждый из которых косвенно указывает на транзакцию и таким образом подтверждает ее. На этом этапе продавец примет платеж как завершенный и доставит продукт; так как мы предполагаем, что это цифровой товар, то доставка мгновенна. Теперь злоумышленник создает еще одну транзакцию, отправляя 100 BTC себе. Если злоумышленник просто создаст ее, транзакция не будет обработана; майнеры попытаются запустить APPLY(S,TX)
и заметят, что TX
расходует UTXO, которого больше нет в состоянии. Поэтому вместо этого злоумышленник создает ответвление блокчейна. Для начала он добывает другую версию блока 270000, указывающего на тот самый блок 269999 в качестве родительского, но с новой транзакцией вместо старой. Поскольку данные блока отличаются, потребуется повторное доказательство выполнения работы. Кроме того, новая версия блока 270000 злоумышленника имеет другой хэш, поэтому исходные блоки с 270001 по 270005 не указывают на него; таким образом, исходная цепочка и новая цепочка злоумышленника полностью разделены. Правило таково, что в ответвлении самый длинный блокчейн считается истинным, поэтому майнеры будут работать над цепочкой с последним блоком 270005, в то время как атакующий работает в одиночку над блоком 270000. Чтобы злоумышленник сделал свой блокчейн самым длинным, ему потребуется больше вычислительной мощности, чем у остальной сети вместе взятой (отсюда и название «атака 51%»).
Деревья Меркла
Слева: достаточно представить только небольшое количество узлов в дереве Меркла, чтобы подтвердить правильность ветки.
Справа: любая попытка изменить любую часть дерева Меркла в конечном итоге приведет к несоответствию где-то вверху цепочки.
Важной особенностью биткоина в плане масштабирования является то, что блок хранится в многоуровневой структуре данных. Хэш блока на самом деле является всего лишь хэшем заголовка блока, примерно 200-байтовым фрагментом данных, который содержит временную метку, число nonce, хэш предыдущего блока и корневой хэш структуры данных, называемой деревом Меркла, в котором хранятся все транзакции в блоке. Дерево Меркла — это бинарное дерево, состоящее из множества узлов с большим количеством конечных узлов в нижней части, содержащих исходные данные, множеством промежуточных узлов, где каждый узел — это хеш двух дочерних узлов, и, наконец, одним корневым узлом, который также образован из хеша двух дочерних узлов и представляет вершину дерева. Цель дерева Меркла — обеспечить возможность доставки данных в блоке по частям: узел может загрузить только заголовок блока из одного источника, небольшую часть дерева, относящуюся к нему, из другого источника и при этом быть уверенным, что все данные верны. Причина, по которой это работает, заключается в том, что хеши распространяются вверх: если злоумышленник попытается вставить поддельную транзакцию в нижнюю часть дерева Меркла, эта замена вызовет изменение в узле выше, а затем изменение в узле выше и, наконец, изменит корень дерева и, следовательно, хеш блока — в результате протокол зарегистрирует его как совершенно другой блок (почти наверняка с недействительным доказательством выполнения работы).
Пожалуй, протокол дерева Меркла необходим для долгосрочной устойчивости. Полный узел в сети биткоина, который хранит и обрабатывает полностью каждый блок, занимает около 15 ГБ дискового пространства по состоянию на апрель 2014 года и растет более чем на гигабайт каждый месяц. В настоящее время это приемлемо для некоторых настольных компьютеров, но не телефонов, и в будущем участвовать смогут только компании и любители. Протокол SPV позволяет существовать другому классу узлов, называемому «легкие узлы», которые загружают заголовки блоков, проверяют доказательство выполнения работы в заголовках блоков, а затем загружают только ветви, связанные с транзакциями, имеющими к ним отношение. Это позволяет легким узлам с надежной гарантией безопасности определять статус любой транзакции с биткоином и их текущий баланс при загрузке только очень небольшой части всего блокчейна.
Альтернативные применения блокчейна
Идея взять лежащую в основе блокчейна идею и применить ее к другим концепциям также имеет длинную историю. В 2005 году Ник Сабо выступил с концепцией «безопасных прав на имущество с полномочиями владельца(opens in a new tab)», документом, описывающим, как «новые достижения в технологии реплицирования баз данных» позволят создать основанную на блокчейне систему для хранения реестра владельцев земли, создавая тщательно продуманную структуру, включающую такие понятия, как гомстединг, незаконное владение и земельный налог Генри Джорджа. Однако, к сожалению, в то время не было эффективной реплицируемой системы баз данных, и поэтому протокол не был реализован на практике. Но после 2009 года, когда был разработан децентрализованный консенсус биткоина, быстро начали появляться альтернативные приложения.
- Namecoin. Namecoin(opens in a new tab), созданный в 2010 году, — это децентрализованная база данных регистрации имен. В децентрализованных протоколах, таких как Tor, Bitcoin и BitMessage, должен быть какой-то способ идентификации аккаунтов, чтобы другие люди могли взаимодействовать с ними, но во всех существующих решениях единственным доступным идентификатором является псевдослучайный хеш, вроде
1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy
. В идеале хотелось бы иметь возможность иметь аккаунт с именем, например george. Однако, проблема в том, что если один человек может создать аккаунт с именем george, затем кто-то другой также может зарегистрироваться как george и выдать себя за него. Единственное решение — парадигма первой регистрации, когда второй пользователь, регистрирующий аккаунт, терпит неудачу, — проблема, идеально подходящая для консенсуса протокола биткоина. Namecoin — старейшая и наиболее успешная реализация системы регистрации имен, использующая такую идею. - Цветные монеты — цель цветных монет(opens in a new tab) — служить протоколом, позволяющим людям создавать собственные цифровые валюты или, в важном тривиальном случае валюты с одной единицей, цифровые токены на блокчейне биткоина. В протоколе цветных монет кто-то выпускает новую валюту, публично назначая цвет определенному UTXO биткоина, и протокол рекурсивно определяет цвет других UTXO таким образом, чтобы он совпадал с цветом вводов, на которые была потрачена создавшая их транзакция (в случае вводов смешанного цвета применяются специальные правила). Это позволяет пользователям иметь кошельки, содержащие только UTXO определенного цвета и отправлять их так же, как обычные биткоины, просматривая блокчейн для определения цвета UTXO, который они получают.
- Метакоины. Идея метакоина заключается в том, чтобы иметь протокол, который использует транзакции биткоина для хранения транзакций метакоина, но имеет другую функцию смены состояния,
APPLY'
. Так как протокол метакоина не может предотвратить появления недействительных транзакций метакоинов в блокчейне биткоина, добавляется правило, согласно которому еслиAPPLY'(S,TX)
возвращает ошибку, то протокол по умолчанию имеет значениеAPPLY'(S,TX) = S
. Это обеспечивает простой механизм для создания произвольного протокола криптовалюты, потенциально с расширенными функциями, которые нельзя реализовать внутри самого биткоина, но с очень низкой стоимостью разработки, поскольку сложности майнинга и сетевого взаимодействия уже реализованы в протоколе биткоина. Метакоины использовались для реализации некоторых классов финансовых контрактов, регистрации имени и децентрализованной биржи.
Таким образом, в целом существуют два подхода к созданию протокола консенсуса: создание независимой сети и создание протокола на базе биткоина. Первый подход, хотя и достаточно успешный в случае таких приложений, как Namecoin, трудно реализуем; каждая отдельная реализация требует запуска отдельного блокчейна, а также создания и тестирования всего необходимого кода смены состояния и кода сетевого взаимодействия. Кроме того, мы прогнозируем, что набор приложений для децентрализованных технологий, основывающихся на консенсусе, будут соответствовать закону степенного распределения, где в свою очередь подавляющее большинство приложений будут слишком маленькими, чтобы оправдать их собственный блокчейн, и мы отмечаем, что существуют большое количество классов децентрализованных приложений, а конкретнее, децентрализованных автономных организаций, которые нуждаются во взаимодействии друг с другом.
С другой же стороны, подход, основанный на биткоине, имеет недостаток, так как он не наследует упрощенные функции проверки платежей биткоина. SPV подходит для биткоина, поскольку он может использовать глубину блокчейна в качестве индикатора действительности; в какой-то момент, когда предшественники транзакции уходят достаточно далеко в прошлое, можно смело сказать, что они являются частью состояния. С другой стороны, мета-протоколы, основанные на блокчейне, не могут заставить блокчейн не исключать транзакции, которые не являются действительными в контексте своих собственных протоколов. Следовательно, внедрение полностью безопасного мета-протокола SPV потребует полного сканирования с самого начала блокчейна биткоина, дабы определить действительность определенных транзакций. В настоящее же время, все легкие реализации основанных на биткоине мета-протоколов полагаются на доверенный сервер для предоставления данных, бесспорно весьма неоптимальный результат, особенно учитывая то, что одной из первостепенных предназначений криптовалюты является устранение потребности в доверии.
Сценарии
Даже без каких-либо расширений протокол биткоина обеспечивает простую версию концепции смарт-контрактов. UTXO в биткоине может принадлежать не только открытому ключу, но и более сложному сценарию, выраженному на простом языке программирования на основе стека. В этой модели транзакция, которая тратит данный UTXO, должна предоставлять удовлетворяющие сценарию данные. Действительно, даже самый базовый механизм владения открытым ключом реализован через сценарий: он принимает основанную на эллиптической кривой подпись в качестве входных данных, проверяет ее на соответствие транзакции и адресу, которому принадлежит UTXO и, в случае успешной проверки, возвращает 1, а в противном случае 0. Существуют и другие, более сложные сценарии для различных дополнительных вариантов использования. Например, можно создать сценарий, для проверки которого требуются подписи двух из трех заданных закрытых ключей (мультиподпись), настройка, полезная для корпоративных счетов, безопасных сберегательных счетов и некоторых ситуаций с условным депонированием. Сценарии также можно использовать для выплаты вознаграждений за решения вычислительных задач, и можно даже составить сценарий, который говорит что-то вроде «этот UTXO биткоина будет ваш, если вы сможете предоставить SPV-доказательство того, что вы отправили мне транзакцию с такой-то суммой Dogecoin», по сути, позволяя осуществлять децентрализованный обмен криптовалютами.
Однако язык сценариев, реализованный в Биткоин, имеет несколько важных ограничений:
- Отсутствие полноты по Тьюрингу. То есть, хотя существует огромная подгруппа вычислений, которые поддерживает язык сценариев биткоина, он поддерживает далеко не все. Основная категория, которая отсутствует, — это циклы. Это делается, чтобы избежать бесконечных циклов во время проверки транзакций; теоретически, это препятствие преодолимо для программистов сценариев, поскольку любой цикл можна смоделировать простым повторением базового кода с помощью оператора if, но это приводит к сценариям, которые очень неэффективны с точки зрения использования пространства. Например, реализация альтернативного алгоритма для основанной на эллиптической кривой подписи потребует около 256 повторяющихся этапов умножения, отдельно включенных в код.
- Ценностная слепота. В сценариях UTXO нет метода для обеспечения точного контроля над суммой, которую можно вывести. Например, одним из эффективных вариантов использования контракта оракула может быть контракт хеджирования, где А и В вкладывают BTC на сумму 1000 долларов и после 30 дней сценарий отправляет BTC на сумму 1000 долларов A, а остальное — B. Для этого потребовался бы оракул, определяющий стоимость 1 BTC в USD, но даже в этом случае это значительное улучшение с точки зрения доверия и требований инфраструктуры по сравнению с централизованными решениями, доступными сейчас. Однако, так как UTXO работает по принципу «все или ничего», единственный метод достижения этого — с помощью очень неэффективного костыля — наличия большого количества UTXO разных номиналов (например, один UTXO со значением 2k для каждого k до 30) и оракула, выбирающего, какой UTXO отправить A, а какой — B.
- Отсутствие состояния. UTXO может быть как израсходованным, так и неизрасходованным; нет возможности для использования многошаговых контрактов или сценариев, которые сохраняют любое другое внутреннее состояние, кроме этого. Это затрудняет создание многоэтапных опционных контрактов, предложений децентрализованного обмена или двухэтапных протоколов криптографических обязательств (необходимых для безопасных вычислительных наград). Это также значит, что UTXO можно использовать только для создания простых, одноразовых контрактов, а не более сложных контрактов с сохранением состояния, таких как децентрализованные организации, и затрудняет реализацию метапротоколов. Бинарное состояние в сочетании с ценностной слепотой также означает, что невозможно применять лимиты на вывод.
- Блокчейн-слепота. UTXO слеп к данным блокчейна, таким как nonce, временная метка и хеш предыдущего блока. Это серьезно ограничивает применение в азартных играх и некоторых других категориях, лишая язык сценариев потенциально ценного источника случайности.
Таким образом, мы видим три подхода к созданию современных приложений на основе криптовалюты: создание нового блокчейна, использование сценариев на основе биткоина и создание метапротокола на основе биткоина. Создание нового блокчейна дает неограниченную свободу в создании набора функций, но в убыток времени на разработку, безопасности и усилий по запуску. Использование сценариев легко реализовать и стандартизировать, но их возможности весьма ограничены, а метапротоколы, хотя и просты, страдают от недостатков масштабируемости. С помощью Ethereum мы намерены создать альтернативную платформу, которая упростит разработку, а также укрепит легкий клиент, в то же время позволяя приложениям совместно использовать экономическую среду и безопасность блокчейна.
Ethereum
Целью Ethereum является создание альтернативного протокола для создания децентрализованных приложений, обеспечивающего другой набор компромиссов, которые, по нашему мнению, будут очень полезны для большого класса децентрализованных приложений, с особым акцентом на ситуациях, когда важны быстрое время разработки, безопасность для небольших и редко используемых приложений и способность различных приложений очень эффективно взаимодействовать. Ethereum делает это, создавая то, что по сути является высшим абстрактным базовым уровнем: блокчейн со встроенным языком программирования, полным по Тьюрингу, позволяющим любому человеку писать умные контракты и децентрализованные приложения, где они могут создавать свои собственные произвольные правила владения, форматы транзакций и функции смены состояния. Простую версию Namecoin можно написать с помощью двух строк кода, а другие протоколы, такие как валюты и системы репутации, можно создать с помощью двадцати или менее строк. Смарт-контракты — криптографические «коробки», содержащие ценность и разблокирующие ее только при соблюдении определенных условий, — также можно создавать на основе платформы, что предоставляет гораздо больше возможностей, чем сценарии биткоина, благодаря полноте по Тьюрингу,, осведомленности о ценности, осведомленности о блокчейне и состоянии.
Счета Ethereum
В Ethereum состояние состоит из объектов, называемых «счетами», каждый счет имеет 20-байтный адрес и смены состояний представляют собой прямые переводы сумм и информации между счетами. Счет в Ethereum содержит четыре поля:
- Счетчик nonce, используемый для того, чтобы каждую транзакцию можно было обработать только один раз
- Текущий баланс эфира на счете
- Код контракта счета, если есть
- Хранилище счета (по умолчанию пусто)
Эфир является основным внутренним криптотопливом Ethereum и используется для оплаты комиссий за транзакции. В общем, есть два типа счетов: внешние счета, контролируемые закрытыми ключами, и счета контрактов, контролируемые кодом их контракта. Внешний счет не имеет кода, с него можно отправлять сообщения, создавая и подписывая транзакцию; в счете контракта при получении сообщения его код активируется, что позволяет ему читать и записывать во внутреннюю память и отправлять другие сообщения или создавать контракты в ответ.
Обратите внимание, что контракты в Ethereum не должны выглядеть как что-то, что должно быть «выполнено» или «соблюдено»; скорее они более похожи на «автономных агентов», которые живут внутри среды исполнения Ethereum, всегда выполняя определенный фрагмент кода, в ответ на сообщение или транзакцию, и имеют прямой контроль над принадлежащим им балансом эфира и их собственным хранилищем ключей и значений для отслеживания постоянных переменных.
Сообщения и транзакции
Термин «транзакция» используется в Ethereum для обозначения подписанного пакета данных с сообщением, которое должно быть отправлено с внешнего счета. Транзакции содержат следующие данные:
- Получатель транзакции
- Подпись, идентифицирующая отправителя
- Количество эфира, который нужно перевести получателю
- Необязательное поле данных
- Значение
STARTGAS
, представляющее максимальное количество разрешенных вычислительных шагов для выполнения транзакции - Значение
GASPRICE
, представляющее собой комиссию, которую отправитель платит за вычислительный шаг
Первые три поля стандартны в любой криптовалюте. Поле данных не имеет функции по умолчанию, но виртуальная машина имеет код операции, используя который контракт может иметь доступ к данным; например, когда контракт функционирует как служба регистрации доменов в блокчейне, то он, возможно, пожелает интерпретировать полученные им данные, как содержащие два поля, первое поле — домен для регистрации и второе поле — IP-адрес для его регистрации. Контракт будет считывать эти значения из данных сообщения и соответствующим образом размещать их в хранилище.
Поля STARTGAS
и GASPRICE
имеют решающее значение в Ethereum для предотвращения отказа в обслуживании. Чтобы предотвратить случайные или враждебные бесконечные циклы или другие вычислительные потери в коде, каждая транзакция должна устанавливать ограничение на количество вычислительных шагов выполнения кода, которое она может использовать. Фундаментальная единица вычисления — это газ; обычно, вычислительный шаг стоит 1 газ, но некоторые операции стоят большее количество газа, потому что они являются вычислительно более дорогими или увеличивают объем данных, которые необходимо хранить как часть состояния. Также существует комиссия в размере 5 единиц газа за каждый байт данных транзакции. Цель системы комиссий — требовать злоумышленников платить пропорционально за каждый ресурс, который они потребляют, включая вычисления, пропускную способность и хранение; следовательно, любая транзакция, которая ведет к потреблению сетью большего количества этих ресурсов, должна иметь примерно пропорциональную приросту плату за газ.
Сообщения
Контракты имеют возможность отправлять сообщения другим контрактам. Сообщения — это виртуальные объекты, которые никогда не сериализуются и существуют только в среде выполнения Ethereum. Сообщение содержит следующие данные:
- Отправитель сообщения (неявно)
- Получатель транзакции
- Количество эфира для передачи вместе с сообщением
- Необязательное поле данных
- Значение
STARTGAS
По существу, сообщение похоже на транзакцию, за исключением того, что оно создается контрактом, а не внешним субъектом. Сообщение создается, когда контракт, выполняющий в настоящее время код, выполняет код операции CALL
, которая создает и выполняет сообщение. Как и транзакция, сообщение ведет к счету получателя, запустившего этот код. Таким образом, контракты могут взаимодействовать с другими контрактами, точно таким же образом, как это могут делать внешние субъекты.
Заметьте, что расход газа, назначенный транзакцией или контрактом, используется к общему количеству потребляемого газа по этой транзакции и всем вспомогательным исполнениям. Например, внешний субъект А посылает транзакции субъекту B с 1000 газа, и B потребляет 600 газа перед отправкой сообщения С, а внутреннее выполнение C потребляет 300 газа перед возвратом, то B может потратить ещё 100 газа, прежде чем он закончится.
Функция смены состояния Ethereum
Функцию смены состояния Ethereum APPLY(S,TX) -> S'
можно определить следующим образом:
- Проверяет, хорошо ли сформирована транзакция (т. е. имеет нужное количество значений), действительна ли подпись, и совпадает ли nonce с nonce в счете отправителя. В противном случае возвращает ошибку.
- Вычисляет комиссию за транзакцию как
STARTGAS * GASPRICE
и определяет адрес отправителя исходя из подписи. Взимает комиссию с баланса счета отправителя и увеличивает nonce отправителя. Если баланса недостаточно, возвращает ошибку. - Инициализирует
GAS = STARTGAS
и отнимает определенное количество газа за байт для оплаты байтов транзакции. - Переводит сумму транзакции со счета отправителя на счет получателя. Если счет получателя еще не существует, то создает его. Если счет получателя является контрактом, запускает код контракта либо до его завершения, либо до тех пор, пока не закончится газ.
- Если перевод суммы не удался, из-за того, что отправитель не имеет достаточной суммы денег, или при выполнении кода закончился газ, то отменяются все изменения состояния, кроме оплаты комиссии и ее зачисления на счет майнера.
- Иначе возвращает отправителю весь оставшийся газ и отправляет комиссию за израсходованный газ майнеру.
Например, предположим, что код контракта:
if !self.storage[calldataload(0)]:
self.storage[calldataload(0)] = calldataload(32)
Обратите внимание, что код контракта на самом деле написан на низкоуровневом языке EVM; для ясности этот пример написан на языке Serpent, одном из наших высокоуровневых языков, который можно скомпилировать в код EVM. Предположим, что хранилище контракта изначально пустое, и транзакция отправляется с 10 эфирами, 2000 газа, с ценой GASPRICE в 0,001 эфира и 64 байтами данных, с байтами 0-31, представляющими число 2
и байтами 32-63, представляющими строку CHARLIE
. Процесс функции смены состояния в этом случае выглядит следующим образом:
- Проверьте, что транзакция действительна и правильно оформлена.
- Проверяет, что отправитель транзакции имеет как минимум 2000 * 0.001 = 2 эфира. Если это так, то вычитает 2 эфира со счета отправителя.
- Инициализирует газ = 2000; предположим, что длина транзакции составляет 170 байт, а плата за байт составляет 5, вычитает 850, чтобы осталось 1150 газа.
- Вычитает еще 10 эфиров со счета отправителя и добавляет их на счет контракта.
- Запускает код. В этом случае он простой: проверяет, используется ли хранилище контракта по индексу
2
, замечает, что это не так, и устанавливает в значение хранилища по индексу2
значениеCHARLIE
. Предположим, что для этого требуется 187 газа, так что оставшееся количество газа 1150 – 187 = 963 - Переводит 963 * 0,001 = 0,963 эфира обратно на счет отправителя и возвращает результирующее состояние.
Если бы в приемном конце транзакции не было бы контракта, то общая сумма комиссии просто равнялась бы предоставленной сумме GASPRICE
, умноженной на величину транзакции в байтах, и данные, отправляемые вместе с транзакцией, не имели бы значения.
Обратите внимание, что сообщения работают эквивалентно транзакциям с точки зрения отмен: если для исполнения сообщения недостаточно газа, тогда исполнение этого сообщения и все другие исполнения, вызванные этим исполнением, отменяются, но родительским исполнениям не нужно отменяться. Это означает, что контракту безопасно вызывать другой контракт, так как если А вызывает B, используя G газа, то исполнение A гарантированно теряет максимум G газа. Наконец, обратите внимание, что существует операционный код CREATE
, который создает контракт; его механика выполнения, как правило, похожа на CALL
, за исключением того, что результат выполнения определяет код созданного нового контракта.
Исполнение кода
Код в контрактах Ethereum написан на низкоуровневом языке байт-кода на основе стека, называемом «кодом виртуальной машины Ethereum» или «кодом EVM». Код состоит из набора байтов, где каждый байт представляет операцию. В общем случае, выполнение кода — это бесконечный цикл, состоящий из многократного выполнения операции на текущем счетчике программы (который начинается с нуля) и затем увеличения счетчика программы на единицу, пока не будет достигнут конец кода, обнаружена ошибка или инструкция STOP
или RETURN
. Операции имеют доступ к трем типам пространства для хранения данных:
- Стек, контейнер, работающий по принципу «последним пришел — первым ушел», с операциями push и pop
- Память, бесконечно расширяемый массив байтов
- Долгосрочное хранилище контракта, что хранит ключи и их значения. В отличие от стека и памяти, которые сбрасываются после завершения вычислений, хранилище сохраняется на длительное время.
Код также может получить доступ к значению, отправителю и данным входящего сообщения, а также к данным заголовка блока, код также может возвращать массив байтов данных.
Формальная модель исполнения кода EVM удивительно проста. Во время работы виртуальной машины Ethereum ее полное вычислительное состояние может быть определено кортежом (block_state, transaction, message, code, memory, stack, pc, gas)
, где block_state
является глобальным состоянием, содержащим все счета, балансы и хранилище. В начале каждого раунда исполнения текущая инструкция определяется путем взятия pc
байта из code
(или 0 если pc >= len(code)
), и каждая инструкция имеет свое собственное определение в плане того, как она влияет на кортеж. Например, ADD
извлекает два элемента из стека и помещает их сумму, уменьшает gas
на 1 и увеличивает pc
на 1, а SSTORE
извлекает два верхних элемента из стека и вставляет второй элемент в хранилище контракта по индексу, указанному первым элементом. Хотя существует множество способов оптимизировать выполнение виртуальной машины Ethereum с помощью JIT-компиляции, базовый вариант Ethereum можно реализовать с помощью нескольких сотен строк кода.
Блокчейн и майнинг
Блокчейн Ethereum во многом похож на блокчейн биткоина, хотя и имеет некоторые отличия. Главное отличие между Ethereum и биткоином в отношении архитектуры блокчейна в том, что, в отличие от биткоина, блоки Ethereum содержат копию как списка транзакций, так и копию самого последнего состояния. Помимо этого, два других значения, номер блока и сложность его получения, также хранятся в блоке. Основной алгоритм валидации блока в Ethereum следующий:
- Проверить, существует ли и действителен ли предыдущий указанный блок.
- Проверить, что временная метка блока больше, чем у предыдущего указанного блока и прошло менее чем 15 минут с момента создания предыдущего блока
- Проверить, что номер блока, сложность, корень транзакции, корень брата родителя и лимит на газ (различные низкоуровневые специфические для Ethereum концепции) являются действительными.
- Проверьте, что proof-of-work на блоке является действительным.
- Пусть
S[0]
будет состоянием в конце предыдущего блока. - Пусть
TX
будет списком транзакций блока сn
транзакциями. Для всехi
в0...n-1
задатьS[i+1] = APPLY(S[i], TX[i])
. Если какие-либо приложения возвращают ошибку или если общий объем газа, потребленного в блоке до этой точки, превышаетGASLIMIT
, вернуть ошибку. - Пусть
S_FINAL
будетS[n]
, но с добавлением вознаграждения за блок, выплачиваемого майнеру. - Проверить, равен ли корень дерева Меркла состояния
S_FINAL
корню конечного состояния, указанному в заголовке блока. Если это так, то блок действителен, в противном же случае — нет.
На первый взгляд такой подход может показаться крайне неэффективным, потому что он должен хранить все состояние с каждым блоком, но в действительности эффективность должна быть сравнима с эффективностью биткоина. Причина в том, что состояние хранится в структуре дерева, и после каждого блока нужно изменить лишь небольшую часть дерева. Таким образом, в общем случае, между двумя соседними блоками подавляющее большинство дерева должно быть одинаковым, и поэтому данные могут быть сохранены один раз и ссылаться дважды с помощью указателей (т. е. хешей поддеревьев). Для этого используется специальный вид дерева, известный как дерево Патриции, включающий модификацию концепции дерева Меркла, которая позволяет эффективно вставлять и удалять узлы, а не только изменять их. Кроме того, поскольку вся информация о состоянии является частью последнего блока, нет необходимости хранить всю историю блокчейна — это стратегия могла обеспечить 5-20-кратную экономию пространства, если бы ее можно было применить к биткоину.
Часто задается вопрос «где» выполняется код контракта, в терминах физического оборудования. Ответ прост: процесс выполнения кода контракта является частью определения функции смены состояния, которая является частью алгоритма проверки блоков. Таким образом, если транзакция добавляется в блок B
, то выполнение кода, сгенерированного этой транзакцией, будет выполняться всеми узлами, сейчас и в будущем, которые загружают и проверяют блок B
.
Применения
В общем есть три типа применений на основе Ethereum. Первая категория — это финансовое применение, предоставление пользователям более эффективных способов управления и заключения контрактов с использованием своих денег. Сюда входят субвалюты, производные финансовые инструменты, контракты хеджирования, сберегательные кошельки, завещания и, в конечном итоге, даже некоторые виды полноценных трудовых договоров. Вторая категория — это полуфинансовое применение, в котором задействованы деньги, но в остальном есть и серьезная неденежная сторона; прекрасным примером являются самореализующиеся вознаграждения за решение вычислительных задач. И наконец, есть абсолютно нефинансовое применение, такое как онлайн-голосование и децентрализованное управление.
Системы токенов
Системы токенов на блокчейне имеют много приложений, начиная от субвалют, представляющих такие активы, как USD или золото, до акций компаний, индивидуальный токенов, представляющих умную собственность, безопасных неподделываемых купонов и даже систем токенов без привязки к традиционным ценностям вообще, которые используются в качестве систем очков для вознаграждений. Системы токенов удивительно легко реализовать в Ethereum. Ключевой момент, который нужно понять, заключается в том, что вся валюта или система токенов, по сути, является базой данных с одной операцией: вычесть Х единиц у А и дать Х единиц B, с условием, что (i) А имел как минимум Х единиц до операции и (2) транзакция одобрена А. Все, что нужно для реализации системы токенов — это реализовать эту логику в контракте.
Базовый код для реализации системы токенов на языке Serpent выглядит так:
def send(to, value):
if self.storage[msg.sender] >= value:
self.storage[msg.sender] = self.storage[msg.sender] - value
self.storage[to] = self.storage[to] + value
Это, по сути, буквальное воплощение функции смены состояния «банковской системы», описанной выше в этом документе. Нужно добавить несколько дополнительных строк кода, чтобы обеспечить начальный этап распределения денежных единиц в первую очередь и несколько других пограничных случаев, и в идеале добавить бы функцию, позволяющую другим контрактам запрашивать баланс адреса. Это всё, что требуется! Теоретически, основанные на Ethereum системы токенов, действующие в качестве субвалюты, могут потенциально включать еще одну важную функцию, которая отсутствует у метавалют на блокчейне Bitcoin: возможность платить за транзакцию непосредственно в этой валюте. Это будет осуществляться так, что в контракте будет поддерживаться баланс ether, с помощью которого контракт будет отправлять ether, нужный для оплаты комиссии, отправителю. Контракт пополнял бы этот баланс, собирая внутренние валютные единицы, которые он берет в качестве комиссии, и перепродавая их на постоянном аукционе. Таким образом, пользователям нужно будет «активировать» свои счета с эфиром, но как только эфир будет там, он будет повторно использоваться, потому что контракт будет возмещать его каждый раз.
Производные финансовые инструменты и валюты со стабильной стоимостью
Финансовые деривативы — наиболее распространенное применение смарт-контракта, и одно из самых простых для реализации в коде. Главная проблема при реализации финансовых контрактов заключается в том, что большинству из них требуется связь с внешним трекером цены; например, очень желаемое приложение — это смарт-контракт, который хеджирует волатильность эфира (или другой криптовалюты) по отношению к доллару США, но для этого контракт должен знать, какова стоимость ETH/USD. Самый простой способ решить это — с помощью контракта котировок, поддерживаемого определенной стороной (например, NASDAQ), разработанного таким образом, чтобы эта сторона имела возможность обновлять контракт по мере необходимости и предоставляла интерфейс, позволяющий другим контрактам отправлять сообщение этому контракту и получать ответ, который предоставляет цену.
С учетом этого важного нюанса контракт хеджирования будет выглядеть следующим образом:
- Подождать, пока сторона A внесет 1000 эфира.
- Подождать, пока сторона B внесет 1000 эфира.
- Записать в хранилище стоимость 1000 эфиров в долларах США, рассчитанную путем запроса к контракту котировок, скажем, это $x.
- Через 30 дней позволить A или B повторно активировать контракт, чтобы отправить эфир на сумму $x (рассчитанную путем повторного запроса к контракту котировок для получения новой цены) стороне A, а остальное — стороне B.
Такой контракт имел бы значительный потенциал в криптокоммерции. Одна из основных проблем, связанных с криптовалютой, заключается в ее волатильности; хотя многим пользователям и продавцам может потребоваться безопасность и удобство, которые дает работа с криптографическими активами, они могут не захотеть столкнуться с такой перспективой, как потеря 23% стоимости своих средств за один день. До сих пор наиболее часто предлагаемым решением были активы, обеспеченные эмитентом; идея состоит в том, что эмитент создает субвалюту, в которой он имеет право выпускать и отзывать единицы этой самой валюты, и предоставлять их любому, кто предоставит им (вживую) одну единицу указанного базового актива (например, золото или доллар США). Затем эмитент обещает предоставить одну единицу базового актива любому, кто отправит обратно одну единицу криптоактива. Этот механизм позволяет преобразовать любой некриптографический актив в криптографический при условии, что эмитенту можно доверять.
Однако на практике эмитенты не всегда заслуживают доверия, а в некоторых случаях банковская инфраструктура слишком слабая или слишком враждебная к существованию таких услуг. Альтернативой являются финансовые деривативы. Здесь, вместо одного эмитента, предоставляющего средства для обеспечения актива, играет роль децентрализованный рынок спекулянтов, делающих ставки на то, что цена указанного криптографического актива (например, ETH) будет расти. По сравнению с эмитентами, спекулянты не имеют возможности не выполнить свою часть сделки, потому что контракт хеджирования держит их средства в условном депонировании. Обратите внимание, что этот подход не является полностью децентрализованным, потому что для предоставления тикера цены по-прежнему необходим надежный источник, хотя, возможно, даже это все же значительное улучшение с точки зрения снижения требований к инфраструктуре (в отличие от случая с эмитентом, проблема передачи ценового потока данных не требует лицензий и, вероятно, может быть квалифицирована как свободная речь) и снижает вероятность мошенничества.
Системы идентификации и репутации
Самая первая альтернативная криптовалюта из всех, Namecoin(opens in a new tab), попыталась использовать биткоин-подобный блокчейн для обеспечения системы регистрации имен, в которой пользователи могут зарегистрировать свои имена в общедоступной базе данных вместе с другими данными. В основном упоминается вариант использования системы DNS(opens in a new tab), сопоставляющей доменные имена, такие как bitcoin.org (или, в случае с Namecoin, bitcoin.bit) с IP-адресом. Другие варианты использования включают аутентификацию по электронной почте и потенциально более продвинутые системы репутации. Вот простой контракт для обеспечения системы регистрации имен, подобной Namecoin, на Ethereum:
def register(name, value):
if !self.storage[name]:
self.storage[name] = value
Контракт очень прост; по сути, это просто база данных внутри сети Ethereum, в которую можно добавлять, но нельзя изменять или удалять элементы. Любой может зарегистрировать определенное имя, и эта регистрация останется навсегда. Более сложный контракт регистрации имен также будет иметь функцию условия, позволяя другим контрактам запрашивать ее, а также механизм для владельца (т. е. первого зарегистрировавшего) имени, чтобы он мог изменять данные или передавать права собственности. Можно даже добавить функции репутации и функциональность web-of-trust.
Децентрализованное хранилище файлов
За последние несколько лет появилось несколько популярных онлайн-стартапов по хранению файлов, наиболее известным из которых является Dropbox, стремящихся дать пользователям возможность загружать резервную копию своего жесткого диска и получить услугу хранения резервной копии, а так же предоставить пользователю доступ к ней в обмен на ежемесячную оплату. Однако на данный момент рынок файловых хранилищ относительно неэффективен; беглый взгляд на различные существующие решения показывает, что, особенно на уровне «зловещей долины» в 20-200 ГБ, на который не действуют ни бесплатные квоты, ни скидки для компаний, ежемесячные цены за хранение файлов таковы, что вы платите больше, чем стоимость целого жесткого диска в месяц. Контракты Ethereum могут позволить разработать децентрализованную экосистему хранения файлов, где отдельные пользователи могут зарабатывать небольшие суммы денег, сдавая в аренду собственные жесткие диски и неиспользуемое пространство, что может быть использовано для дальнейшего снижения стоимости хранения файлов.
Ключевой элемент такого устройства — это то, что мы назвали «децентрализованный контракт Dropbox». Этот контракт работает следующим образом. Сначала разделяет нужные данные на блоки, зашифровав каждый блок для конфиденциальности, и строит из них дерево Меркла. Затем он создает контракт с правилом, что каждые N блоков, этот контракт будет выбирать случайный индекс в дереве Меркла (используя хеш предыдущего блока, доступный из кода контракта, как источник случайности), и давать Х эфира первому объекту, который предоставит транзакцию с упрощенной проверкой платежа — как доказательство владения блоком на том конкретном индексе в дереве. Когда пользователь хочет перезагрузить свой файл, он может использовать протокол канала микроплатежа (например, платить 1 сабо за 32 килобайта) для восстановления файла; наиболее эффективным с точки зрения платы подходом является то, что плательщик не публикует транзакцию до конца, вместо этого заменяя транзакцию чуть более выгодной с тем же nonce после каждых 32 килобайт.
Важной особенностью протокола является то, что, хотя может показаться, что приходится доверять множеству случайных узлов, риск можно снизить практически до нуля, разделив файл на множество частей путем разделения секрета между несколькими узлами и следя за контрактами и хранением частей. Если контракт продолжает выплачивать деньги, это служит криптографическим доказательством того, что кто-то все еще хранит файл.
Децентрализованные автономные организации
Децентрализованной автономной организацией называется виртуальная организация, состоящая из конкретных членов или акционеров, которые при наличии большинства голосов (например, 67%) могут принимать решения (например, о трате средств из фонда организации или о модификации ее программного кода) от лица всей организации. Члены коллективно решают, как организация должна распределять свои средства. Поводы для распределения могут быть самые разные: от зарплат и премий за нахождение уязвимостей до более экзотических механизмов, например выплат вознаграждений во внутренней валюте. Это по существу воспроизводит юридические атрибуты традиционной компании или некоммерческой организации, но используя только криптографическую технологию блокчейна для исполнения всего. До сих пор большая часть разговоров вокруг DAO была вокруг «капиталистической» модели «децентрализованной автономной корпорации» с акционерами, получающими дивиденды и продаваемыми акциями; альтернатива, возможно, описывается как «децентрализованное автономное сообщество», предусматривающее, что все члены будут иметь равную долю в процессе принятия решений и 67% существующих членов должны согласиться на добавление или удаление члена. Требование, что один человек может иметь только одно членство, должно быть в таком случае подкреплено коллективно группой.
Общие наброски о том, как запрограммировать DAO, следующие. Самая простая конструкция — это просто кусок самоизменяющегося кода, который меняется, если две трети членов согласны с изменением. Хотя код теоретически неизменяемый, это можно легко обойти и иметь де-факто его изменяемость, имея фрагменты кода в отдельных контрактах, и имея адрес для вызова определенного контракта, хранящийся в модифицируемом хранилище. При простой реализации такого контракта DAO, будет три типа транзакций, отличающихся по данным, предоставленным в транзакции:
[0,i,K,V]
для регистрации предложения с индексомi
для изменения адреса в хранилище с индексомK
на значениеV
[1,i]
для регистрации голоса в пользу предложенияi
[2,i]
для завершения предложенияi
при получении достаточного количества голосов
Контракт будет содержать положения для каждого из этих типов. Он будет вести учет всех общедоступных изменений хранилища, вместе со списком тех, кто за них голосовал. Он также будет иметь список всех членов. Когда любое изменение хранилища получает голоса двух третей членов, завершающая транзакция может осуществить это изменение. Более сложная конструкция также имела бы встроенную возможность голосования для таких функций, как отправка транзакции, добавление членов и удаление членов, и могла бы даже обеспечить делегирование голосов в стиле Ликвидной Демократии(opens in a new tab) (т.е. когда любой может назначить кого-то голосовать вместо него, и назначение является транзитивным, поэтому если А назначает В, а В назначает С, тогда С определяет голос А). Такой дизайн позволил бы DAO органично расти как децентрализованное сообщество, позволяя людям в конечном итоге делегировать задачу проверки членов специалистам, хотя в отличие от «текущей системы» специалисты могут легко появляться и исчезать со временем, по мере того, как отдельные члены сообщества меняют свои позиции.
Альтернативная модель — это децентрализованная корпорация, где любой аккаунт может иметь ноль или более акций, и держатели двух третьих акций должны принимать решение. Полная конструкция будет включать функциональность управления активами, возможность делать предложение о покупке или продаже акций и возможность принимать предложения (предпочтительно с механизмом сопоставления ордеров внутри контракта). Также будет существовать делегация в стиле ликвидной демократии, обобщая концепцию «совета директоров».
Дополнительные применения
1. Сберегательные кошельки. Предположим, Алиса хочет сохранить свои средства в безопасности, но беспокоится о том, что она потеряет или кто-то взломает её приватный ключ. Она ставит эфир в контракт, заключенный с Бобом, банком, следующим образом:
- Алиса в одиночку может выводить максимум 1% средств в день.
- Боб в одиночку может выводить максимум 1% средств в день, но Алиса имеет возможность совершить транзакцию своим ключом, выключающую эту возможность.
- Алиса и Боб вместе могут выводить сколько угодно.
Как правило, 1% в день достаточно для Алисы, и если Алиса хочет вывести больше, она может обратиться к Бобу за помощью. Если ключ Алисы взломают, она бежит к Бобу, чтобы перевести средства в новый контракт. Если она потеряет ключ, Боб в конечном итоге выведет средства. Если Боб окажется злоумышленником, тогда она сможет отключить ему возможность снятия средств.
2. Страхование урожая. Можно легко сделать финансовый производный контракт с использованием источника данных о погоде вместо цены индекса. Если фермер из Айовы покупает производный инструмент, который приносит доход, исходя из количества осадков в Айове, то при засухе фермер автоматически получит деньги, а если дождей достаточно, фермер будет счастлив, потому что его урожай будет хорошо расти. Это может быть распространено на страхование от стихийных бедствий в целом.
3. Децентрализованный канал данных. Для финансовых контрактов на разницу цены, на самом деле можно децентрализовать канал данных через протокол под названием SchellingCoin(opens in a new tab). SchellingCoin в основном работает следующим образом: все N сторон вносят в систему значение заданного элемента данных (например, цены ETH/USD), значения сортируются, и каждый между 25-м и 75-м процентилем получает один токен в качестве награды. У каждого есть стимул дать ответ, который дадут все остальные, и единственное значение, с которым может реально согласиться большое количество игроков, — это правда. Это создает децентрализованный протокол, который теоретически может предоставить сколько угодно значений, включая цену ETH/USD, температуру в Берлине или даже результат конкретного сложного вычисления.
4. Умное депонирование с мультиподписью. Биткоин допускает существование контрактов с мультиподписью для транзакций, где, к примеру, трех из пяти ключей достаточно для траты средств. У Ethereum же возможностей детализировать больше: например, четыре из пяти могут потратить все, три из пяти могут тратить до 10% в день, а два из пяти могут потратить до 0,5% в день. Кроме того, мультиводпись в Ethereum асинхронна — две стороны могут зарегистрировать свои подписи на блокчейне в разное время, а последняя подпись автоматически отправит транзакцию.
5. Облачные вычисления. Технология EVM также может быть использована для создания проверяемой вычислительной среды, позволяющей пользователям просить других выполнять вычисления, а затем при необходимости запрашивать доказательства того, что вычисления на определенных случайно выбранных контрольных точках были выполнены правильно. Это позволяет создать рынок облачных вычислений, в котором может участвовать любой пользователь со своим настольным компьютером, ноутбуком или специализированным сервером, а выборочная проверка вместе с залоговыми депозитами может использоваться для обеспечения надежности системы (т. е. узлы не могут обманывать с выгодой для себя). Хотя такая система может подойти не для всех задач; например, задачи, требующие высокого уровня межпроцессного взаимодействия не легко реализовать на большом облаке узлов. Однако другие задачи параллелизировать гораздо проще; такие проекты, как SETI@home, folding@home и генетические алгоритмы, могут быть легко реализованы на основе такой платформы.
6. Одноранговые азартные игры. Любое количество одноранговых игровых протоколов, таких как Cyberdice(opens in a new tab) Фрэнка Стахано и Ричарда Клейтона, может быть реализовано на блокчейне Ethereum. Самый простой игровой протокол на самом деле представляет собой просто контракт на разницу в следующем хеше блока, и на этом принципе можно создавать более продвинутые протоколы, например игровые сервисы с почти нулевой комиссией и без возможности обмана.
7. Рынки прогнозов. При наличии оракула или SchellingCoin рынки прогнозов также легко реализовать, и рынки прогнозов вместе с SchellingCoin могут оказаться первым массовым применением футархии(opens in a new tab) в качестве протокола управления для децентрализованных организаций.
8. Ончейн децентрализованные торговые площадки, использующие в качестве основы систему идентификации и репутации.
Прочие вопросы и проблемы
Модифицированная реализация GHOST
Протокол Greedy Heaviest Observed Subtree (GHOST) — это инновация, впервые введенная Йонатаном Сомполински и Авивом Зохаром в Декабре 2013(opens in a new tab). Мотивация, стоящая за GHOST: блокчейны с быстрым временем подтверждения в данный момент недостаточно безопасны из-за высокой скорости устаревания: поскольку распространение блоков по сети занимает определенное время, если майнер A добудет блок, а затем майнер B добудет другой блок до того, как блок майнера A распространится на B, блок майнера B будет бесполезным и не повысит безопасность сети. Кроме того, существует проблема централизации: если майнер A — это майнинговый пул, суммарная мощность которого составляет 30% мощности всей сети, а у майнера B эта цифра составляет 10%, в 70% случаев A может создать устаревший блок (поскольку в остальные 30% случаев A создавал последний блок и, таким образом, немедленно получал данные о майнинге), а B будет подвержен этому риску в 90% случаев. Таким образом, если интервал между блоками достаточно короток для того, чтобы скорость устаревания была высокой, A будет существенно эффективнее просто в силу своего размера. Обе этих проблемы приводят к тому, что блокчейны, которые производят блоки слишком быстро, влекут за этим ситуацию, когда один майнинг-пул набирает достаточное количество мощности в сети, чтобы де-факто контролировать процесс майнинга.
Как описано Сомполински и Зохар, GHOST решает первую проблему потери безопасности сети, включив устаревшие блоки в расчет того, какая цепь является самой длинной; то есть не только родительские и дальнейшие предки блока, но также и устаревшие потомки предка блока (на жаргоне Ethereum — «дяди») добавляются к вычислению того, какой блок имеет наибольшее общее доказательство работы, поддерживающее этот блок. Чтобы решить вторую проблему предвзятости централизации, мы выходим за рамки протокола, описанного Сомполински и Зохар, а также предоставляем вознаграждение за блок устаревшим блокам: устаревший блок получает 87,5% своего базового вознаграждения, а племянник, включающий устаревший блок, получает оставшуюся часть — 12,5%. Однако комиссия за транзакции не начисляется «дядям».
Ethereum реализует упрощенную версию GHOST, которая спускается всего на семь уровней вниз. В частности, она определяется следующим образом:
- Блок должен указывать на родительский, и он должен указывать на 0 или более дядей
- Дядя, включенный в блок В, должен иметь следующие свойства:
- Он должен быть прямым дочерним предком B k-го поколения, где
2 <= k <= 7
. - Он не может быть предком B
- У него должен быть допустимый блочный заголовок, но дядя необязательно должен быть ранее проверенным или даже действительным блоком
- Дядя должен отличаться от всех дядей, включенных в предыдущие блоки, и всех других дядей, включенных в этот же блок (т.е. без двойного включения)
- Он должен быть прямым дочерним предком B k-го поколения, где
- За каждого дядю U в блоке B майнер блока B получает дополнительные 3,125% к его вознаграждению, а майнер U получает 93,75% от стандартного вознаграждения.
Эта ограниченная версия GHOST, в которую входили только дяди до 7 поколения, использовалась по двум причинам. Во-первых, GHOST без ограничений будет иметь слишком много сложностей при вычислении допустимых дядей для данного блока. Во-вторых, неограниченный GHOST с компенсацией, используемый в Ethereum, лишает майнера стимула майнить в основной цепочке, а не в цепочке публичного атакующего.
Комиссии
Поскольку каждая транзакция, опубликованная в блокчейне, налагает на сеть затраты на её загрузку и проверку, существует необходимость в каком-то регулирующем механизме, как правило, включающем комиссии за транзакции, для предотвращения злоупотреблений. Стандартный подход, используемый в Bitcoin, заключается в наличии исключительно добровольных комиссий, при этом майнеры выступают в роли контролеров и устанавливают динамические минимумы. Такой подход был очень позитивно воспринят в сообществе Bitcoin, особенно потому, что он «рыночный», позволяющий определять комиссию благодаря спросу и предложению между майнерами и отправителями транзакций. Однако проблема в этих рассуждениях заключается в том, что обработка транзакций не является рынком; хотя интуитивно привлекательно рассматривать обработку транзакций как услугу, которую майнер предлагает отправителю, в действительности же каждая транзакция, которую включает майнер, должна быть обработана каждым узлом в сети, поэтому подавляющее большинство затрат на обработку транзакций несут третьи стороны, а не майнер, который принимает решение о том, включать ее или нет. Следовательно, весьма вероятно возникновение проблем трагедии общих ресурсов.
Однако этот недостаток рыночного механизма при некоторых допущениях магически исчезает. Аргумент следующий. Предположим, что:
- Транзакция состоит из
k
операций и предлагает комиссию вkR
майнеру, который включит её в блокчейн, гдеR
задаётся отправителем; иk
иR
(приблизительно) известны майнеру заранее. - Себестоимость проведения операций каждого узла равна
C
(у каждого узла одинаковая эффективность) - Всего в сети
N
узлов с идентичной мощностью (1/N
общей суммы) - Нет полных узлов, не занятых в майнинге.
Майнер захочет включить в блок только те транзакции, полученная комиссия с которых превысит себестоимость операций. Следовательно, ожидаемый доход равен kR/N
, поскольку майнер имеет 1/N
шанс нахождения следующего блока, а себестоимость майнинга — kC
. Таким образом, майнеры будут включать только те транзакции в блок, где kR/N > kC
, or R > NC
. Заметим, что R
— устанавливаемая отправителем комиссия за одну операцию, и потому R — нижняя граница «пользы» от этой транзакции для отправителя. При этом NC
— себестоимость проведения операции для всей сети. Исходя из этого, майнерам выгодно включать в блок только такие транзакции, польза от которых больше, чем себестоимость её проведения.
Однако в реальности существует несколько важных отклонений от этих предположений:
- Майнеру выходит дороже обработка транзакции, чем другим проверяющим узлам, поскольку дополнительное время проверки задерживает распространение блока и, таким образом, увеличивает вероятность того, что блок станет устаревшим.
- Существуют полноценные узлы, которые не занимаются майнингом.
- Распределение мощности майнинга на практике может оказаться крайне неравномерным.
- Спекулянты, политические враги и сумасшедшие, чья функция включает в себя нанесение вреда сети, действительно существуют, и они могут продуманно создавать контракты, в которых стоимость намного ниже стоимости, уплачиваемой другими проверяющими узлами.
(1) обеспечивает тенденцию для майнера включать меньше транзакций (2) увеличивает NC
; следовательно, эти два эффекта по крайней мере частично покрывают друг друга.Как?(opens in a new tab) (3) и (4) являются основными проблемами; чтобы решить их, мы просто устанавливаем плавающий ограничение: ни один блок не может иметь больше операций, чем BLK_LIMIT_FACTOR
умноженный на долгосрочную экспоненциальную скользящую среднюю. В частности:
blk.oplimit = floor((blk.parent.oplimit \* (EMAFACTOR - 1) +
floor(parent.opcount \* BLK\_LIMIT\_FACTOR)) / EMA\_FACTOR)
BLK_LIMIT_FACTOR
и EMA_FACTOR
— это константы, которые на данный момент будут установлены на значения 65536 и 1,5, но, вероятнее всего, будут изменены после дальнейшего анализа.
Есть еще один фактор, препятствующий созданию больших блоков в Bitcoin: бóльшие блоки будут дольше распространяться, и, следовательно, у них выше вероятность устареть. В Ethereum распространение блоков с высоким потреблением газа также может занять больше времени, поскольку они физически больше и им требуется больше времени на обработку проверки переходов состояний транзакций. Этот сдерживающий фактор задержки имеет важное значение в Bitcoin, но в Ethereum он менее важен из-за протокола GHOST; следовательно, опора на регулируемые ограничения блоков обеспечивает более стабильную основу.
Вычисление и полнота по Тьюрингу
Важно отметить, что виртуальная машина Ethereum является полной по Тьюрингу; это означает, что код EVM может закодировать любое вычисление, которое можно предположительно выполнить, включая бесконечные циклы. Код EVM позволяет делать циклы двумя способами. Первый — это инструкция JUMP
, которая позволяет программе вернуться к предыдущему месту в коде, и инструкция JUMPI
для выполнения условных переходов, позволяющая использовать такие инструкции, как while x < 27: x = x * 2
. Второй — контракты могут вызывать другие контракты, потенциально позволяя зацикливаться через рекурсию. Это естественным образом приводит к проблеме: могут ли злоумышленники по сути отключить майнеров и полные узлы, заставив их войти в бесконечный цикл? Проблема возникает из-за проблемы в компьютерной науке, известной как проблема остановки: в общем случае невозможно сказать, остановится ли данная программа когда-либо.
Как описано в разделе перехода состояния, наше решение работает, требуя от транзакции установить максимальное количество вычислительных шагов, которые ей разрешено выполнить, и если выполнение требует больше шагов, вычисления отменяются, но комиссия все равно платится. Сообщения работают также. Чтобы показать мотив, стоящий за нашим решением, рассмотрим следующие примеры:
- Злоумышленник создает контракт, запускающий бесконечный цикл, а затем отправляет майнеру транзакцию, активирующую этот цикл. Майнер обработает транзакцию, запустив бесконечный цикл, и будет ждать, пока в ней не закончится газ. Даже если при выполнении заканчивается газ и оно останавливается на полпути, транзакция все еще действительна, и майнер по-прежнему возьмет у атакующего комиссию за каждый вычислительный шаг.
- Злоумышленник создает очень длинный бесконечный цикл с целью заставить майнера продолжать вычисления в течение столь длительного времени, что к моменту завершения вычислений будет создано еще несколько блоков, и майнер не сможет включить транзакцию в блок, чтобы получить комиссию. Однако злоумышленнику потребуется предоставить значение для
STARTGAS
, ограничивающее количество вычислительных шагов, которые можно выполнить, поэтому майнер будет заранее знать, что вычисление займет чрезмерно большое количество шагов. - Злоумышленник видит контракт с кодом в некоторой форме, например
send(A,contract.storage[A]); contract.storage[A] = 0
, и отправляет транзакцию с достаточным количеством газа только для выполнения первого шага, но не второго (т. е. сделать вывод, но не дать балансу уменьшиться). Автору контракта не нужно беспокоиться о защите от подобных атак, поскольку если выполнение транзакции останавливается на полпути, то изменения отменяются. - Финансовый контракт работает используя медианное значения девяти собственных каналов данных с целью минимизации риска. Злоумышленник захватывает один из каналов данных, который разработан с возможностью изменения с помощью механизма вызова с переменным адресом, описанного в разделе о DAO, и преобразует его в запуск бесконечного цикла, тем самым пытаясь заставить любые попытки получить средства из финансового контракта исчерпывать газ. Однако финансовый контракт может установить лимит газа в сообщении, чтобы избежать этой проблемы.
Альтернативой полноте по Тьюрингу является неполнота по Тьюрингу, в которой JUMP
и JUMPI
не существуют, и только одна копия каждого контракта может существовать в стеке вызовов в любой момент времени. В этой системе описанная выше система комиссий и неопределенности относительно эффективности нашего решения могут оказаться излишними, поскольку стоимость исполнения контракта будет ограничена его размером. Кроме того, неполнота по Тьюрингу не является таким уж большим ограничением: из всех примеров контрактов, которые мы задумали внутри, только один требовал цикла, и даже этот цикл можно было бы удалить, выполнив 26 повторений однострочного фрагмента кода. Учитывая серьезные последствия полноты по Тьюрингу и ограниченные преимущества, почему бы просто не использовать неполный по Тьюрингу язык? Однако на самом деле неполнота по Тьюрингу далеко не идеальное решение проблемы. Чтобы понять почему, рассмотрите следующие контракты:
C0: call(C1); call(C1);
C1: call(C2); call(C2);
C2: call(C3); call(C3);
...
C49: call(C50); call(C50);
C50: (запустить один шаг программы и записать изменение в хранилище)
Теперь отправьте транзакцию пользователю A. Таким образом, в 51 транзакции мы имеем контракт, который занимает 250 вычислительных шагов. Майнеры могли бы попытаться обнаружить такие логические бомбы заранее, сохраняя значение рядом с каждым контрактом, указывающее максимальное количество вычислительных шагов, которые он может выполнить, и вычисляя его для контрактов, рекурсивно вызывающих другие контракты, но это потребовало бы от майнеров запретить контракты, создающие другие контракты (поскольку создание и выполнение всех 26 контрактов выше можно было бы легко объединить в один контракт). Еще одной проблемой является то, что поле адреса у сообщения является переменной, поэтому в общем случае невозможно заранее сказать, какие другие контракты вызовет данный контракт. Таким образом, в целом, мы приходим к удивительному выводу: с полнотой по Тьюрингу справиться на удивление легко, а с отсутствием полноты по Тьюрингу справиться также на удивление сложно, если только не будут реализованы точно такие же элементы управления. Но в таком случае почему бы просто не позволить протоколу быть полным по Тьюрингу?
Валюта и выпуск
Сеть Ethereum включает собственную встроенную валюту, эфир, которая служит для двух целей: обеспечения первичного слоя ликвидности, чтобы позволить эффективно обмениваться различными видами цифровых активов, и, что более важно, создания механизма оплаты комиссии за транзакции. Для удобства и чтобы избежать споров в будущем (см. текущие дебаты mBTC/uBTC/сатоши в биткоине), номиналы будут предварительно помечены:
- 1: wei
- 1012: szabo
- 1015: finney
- 1018: ether
Это следует воспринимать как расширенную версию понятия "доллары" и "центы" или "BTC" и "сатоши". Мы ожидаем, что в скором будущем ether ("эфир") будет использоваться для обычных транзакций, finney ("финни") для микротранзакций, а szabo ("сабо") и wei ("вей") для технических обсуждений вокруг комиссий и реализации протокола; остальные номиналы могут пригодиться позже и не включены в клиенты на данный момент.
Модель выпуска будет следующей:
- Эфир будет продаваться по цене 1000–2000 эфира за BTC — механизм, предназначенный для финансирования организации Ethereum и оплаты разработки, который с успехом использовался другими платформами, такими как Mastercoin и NXT. Ранние покупатели получат большие скидки. BTC, полученные от продажи, будут полностью использоваться для выплаты заработной платы и вознаграждений разработчикам и инвестироваться в различные коммерческие и некоммерческие проекты в экосистеме Ethereum и криптовалют.
- 0,099x от общей проданной суммы (60102216 ETH) будет выделено организации для компенсации ранним вкладчикам и оплаты расходов, выраженных в ETH, до первого блока.
- 0,099х от общей проданной суммы будет храниться в качестве долгосрочного резерва.
- После этого момента 0,26x от общей суммы продажи будет каждый год выделяться майнерам.
Группа | После запуска | Через 1 год | Через 5 лет |
---|---|---|---|
Денежные единицы | 1,198X | 1,458X | 2,498X |
Покупатели | 83,5% | 68,6% | 40,0% |
Резерв, потраченный до продажи | 8,26% | 6,79% | 3,96% |
Резерв, использованный после продажи | 8.26% | 6.79% | 3.96% |
Майнеры | 0% | 17,8% | 52,0% |
Долгосрочный рост предложения (в процентах)
Несмотря на линейную эмиссию валюты, как и в случае с биткоином со временем темпы роста предложения стремятся к нулю.
Двумя основными вариантами в вышеуказанной модели являются (1) существование и размер пула пожертвований, и (2) существование постоянно линейно растущего предложения, в отличие от ограниченного количества биткоина. Обоснование пула пожертвований следующее. Если бы пула пожертвований не существовало, а линейная эмиссия была бы уменьшена до 0,217x для обеспечения того же уровня инфляции, то общее количество эфира было бы на 16,5% меньше, а каждая единица была бы на 19,8% ценнее. Поэтому, для уравновешивания, на 19,8% больше эфира было бы отведено на продажу, чтобы каждая единица была снова так же ценной, как и раньше. Тогда у организации также будет в 1,198 больше BTC, которые можно считать разделенными на две части: исходные BTC и дополнительные 0,198x. Хоть эта ситуация и полностью эквивалентна пожертвованию, но с одним важным отличием: организация хранит исключительно BTC и поэтому не заинтересована в поддержке стоимости единицы эфира.
Модель постоянного линейного роста предложения снижает риск того, что некоторые считают чрезмерной сосредоточения богатства в биткоинах, и дает людям, живущим в настоящем и будущем, справедливый шанс приобретать денежные единицы, в то же время сохраняя сильный стимул получать и хранить эфир, поскольку темп роста предложения в процентном отношении по-прежнему стремится к нулю с течением времени. Мы также предполагаем, что поскольку монеты со временем всегда теряются из-за беспечности, смерти и т. д., а потерю монет можно смоделировать как процент от общего объема выпуска в год, то общий объем выпуска валюты в обращение в конечном итоге стабилизируется на уровне, равном годовому выпуску, деленному на уровень потерь (например, при уровне потерь 1%, как только объем выпуска достигнет 26 единиц, то 0,26 единиц будет добываться и 0,26 единиц теряться каждый год, что создаст равновесие).
Обратите внимание, что в будущем Ethereum, скорее всего, в целях безопасности перейдет на модель доказательства владения, снизив требования к выпуску до уровня 0–0,05X в год. В случае, если организация Ethereum потеряет финансирование или по какой-либо другой причине исчезнет, мы оставляем открытым «социальный контракт»: любой имеет право создать будущую версию-кандидата Ethereum, с одним только условием, что количество эфира должно быть не более 60102216 * (1,198 + 0,26 * n)
, где n
— количество лет после первого блока. Создатели для оплаты разработки могут свободно продавать или иным образом передавать часть или всю разницу между максимально допустимым расширением предложения и расширением предложения, полученным при переходе к доказательству владения. Обновления-кандидаты, не соответствующие социальному контракту, могут быть законно ответвлены в совместимые версии.
Централизация майнинга
Алгоритм майнинга Bitcoin работает за счет того, что майнеры вычисляют SHA256 на слегка измененных версиях заголовка блока миллионы раз снова и снова, пока в конечном итоге один узел не предложит версию, хеш которой меньше целевого (в настоящее время около 2192). Однако, алгоритм майнинга уязвим к двум формам централизации. Во-первых, в экосистеме майнинга стали доминировать ASIC (специализированные интегральные схемы) — компьютерные чипы, разработанные, и следовательно, в тысячи раз эффективнее для данной задачи, майнинга Bitcoin. Это означает, что майнинг биткоина больше не является высоко децентрализованным и эгалитарным занятием, а также требует миллионы долларов для эффективного участия в обеспечении безопасности сети. Во-вторых, большинство биткоин-майнеров на самом деле не выполняют проверку блоков локально; для предоставления заголовков блока они полагаются на централизованный майнинг-пул. Эта проблема, возможно, ещё хуже первой: на момент написания этой статьи три ведущих майнинг-пула косвенно контролируют примерно 50% мощности в сети биткоина. Хотя нужно учитывать тот факт, что майнеры могут переключиться на другие майнинг-пулы, если пул или коалиция пулов попытается провести атаку 51%.
Текущая цель Ethereum — использовать алгоритм майнинга, в котором майнерам необходимо извлекать случайные данные из состояния, вычислять некоторые случайно выбранные транзакции из последних N блоков блокчейна и возвращать хеш результата. В этом два важных преимущества. Во-первых, контракты Ethereum могут включать в себя любые виды вычислений, поэтому Ethereum ASIC по сути будет ASIC-ом для вычислений в общем, т. е. лучшим процессором. Во-вторых, майнингу необходим доступ ко всему блокчейну, что вынуждает майнеров хранить весь блокчейн и, по крайней мере, иметь возможность проверять каждую транзакцию. Это устраняет необходимость в централизованных пулах для майнинга; хотя пулы для майнинга по-прежнему могут выполнять законную роль уравнивания случайность распределения вознаграждения, эту функцию могут с равным успехом выполнять и одноранговые пулы без централизованного контроля.
Подобная модель ещё не тестировалась, и могут появиться сложности с обходом некоторых умных оптимизаций при использовании контрактов как алгоритма для майнинга. Одна интересная особенность этого алгоритма заключается в том, что она разрешает кому угодно «отравить колодец» путём введения контрактов в блокчейн, которые способны сделать непригодными для их вычисления тот или иной ASIC. Производители ASIC, в теории, имеют финансовый стимул использовать эту особенность для атаки друг друга. Таким образом, решение, которое мы разрабатываем — скорее адаптивное экономически-социальное, нежели сугубо техническое.
Масштабируемость
Одной из распространенных проблем с Ethereum является проблема масштабируемости. Как и биткоин, Ethereum страдает от недостатка, заключающегося в том, что каждая транзакция должна обрабатываться каждым узлом в сети. У биткоина текущий размер блокчейна составляет около 15 ГБ, увеличиваясь примерно на 1 МБ в час. Если бы сеть биткоина обрабатывала в секунду столько же транзакций, сколько обрабатывает Visa — 2000 транзакций Visa в секунду — она увеличивалась бы на 1 МБ каждые три секунды (1 ГБ в час, 8 ТБ в год). Ethereum, скорее всего, столкнется с похожей моделью роста, усугубляемой тем фактом, что поверх блокчейна Ethereum будет создано множество приложений, а не только валюта, как в случае с биткоином, но смягчаемой фактом, что полные узлы Ethereum должны хранить только состояние, а не всю историю блокчейна.
Проблема с таким большим блокчейном — риск централизации. Если размер блокчейна увеличится, скажем, до 100 ТБ, то вероятным сценарием будет то, что только очень небольшое количество крупных бизнесов будут запускать полные узлы, а все обычные пользователи будут использовать легкие узлы с простой проверкой платежей. В такой ситуации возникает потенциальная опасность того, что полные узлы могут объединяться и договариваться о мошенничестве каким-либо прибыльным способом (например, изменять вознаграждение за блок, выдавать себе BTC). Легкие узлы не смогут обнаружить это сразу же. Конечно, по крайней мере один честный полный узел, скорее всего, будет существовать, и через несколько часов информация о мошенничестве будет на таких платформах, как Reddit, но уже будет слишком поздно: обычным пользователям придется организовать усилия по внесению указанных блоков в черный список, что представляет собой огромную и, вероятно, невыполнимую координационную проблему такого же масштаба, как и проведение успешной атаки 51%. В случае с Bitcoin это в настоящее время является проблемой, но существует модификация блокчейна, предложенная Питером Тоддом(opens in a new tab), которая решит эту проблему.
В ближайшем будущем Ethereum будет использовать две дополнительные стратегии против этой проблемы. Первая — из-за алгоритмов майнинга на основе блокчейна, по крайней мере каждый майнер будет вынужден стать полным узлом, что создает нижнюю границу количества полных узлов. Вторая и более важная — это то, что мы включим промежуточный корень дерева состояния в блокчейн после обработки каждой транзакции. Даже если проверка блоков централизована, пока существует хотя бы один честный проверяющий узел, то проблему централизации можно обойти с помощью протокола проверки. Если майнер публикует недействительный блок, этот блок либо плохо отформатирован, либо состояние S[n]
неправильное. Поскольку известно, что S[0]
является правильным, то должно быть некоторое первое состояние S[i]
, которое является неправильным, а S[i-1]
правильным. Проверяющий узел предоставит индекс i
вместе с «доказательством недействительности», состоящим из подмножества узлов дерева Патриции, которым необходимо обработать APPLY(S[i-1],TX[i]) > S[i]
. Узлы смогут использовать эти узлы дерева для выполнения этой части вычислений и увидеть, что сгенерированное S[i]
не соответствует предоставленному S[i]
.
Другая, более сложная атака предполагает публикацию майнерами-злоумышленниками неполных блоков, поэтому даже не существует полной информации, позволяющей определить, являются ли блоки действительными. Решением этой проблемы является протокол вызова и ответа: проверяющие узлы отправляют «вызовы» в форме индексов целевых транзакций, и после получения узла дерева легкий узел рассматривает блок как ненадежный до тех пор, пока другой узел, будь то майнер или другой проверяющий, не предоставит подмножество узлов Патриции в качестве доказательства действительности.
Заключение
Ethereum как протокол изначально рассчитан на то, чтобы быть улучшенной версией криптовалюты, предоставляя дополнительные возможности, такие как гарант-сервис на блокчейне, задание ограничений на снятие денежных сумм, финансовые контракты, рынки азартных игр и подобное посредством высокоуровневого языка программирования. Ethereum не поддерживает применения напрямую, но наличие полного по Тьюрингу языка программирования означает, что контракты могут быть, в теории, созданы для любых транзакций и применений. Что особенно вдохновляет — то, что Ethereum — это гораздо больше, чем криптовалюта. Протоколы для децентрализованного хранения файлов, децентрализованных вычислений и децентрализованных рынков прогнозов, а также десятки других концепций, имеют потенциал существенно увеличить эффективность вычислительной индустрии и придать мощный импульс другим одноранговым протоколам, впервые добавив в уравнение экономический уровень. Разумеется, возможно и значительное количество применений, не имеющих никакого отношения к деньгам.
Концепция функции произвольной смены состояния, реализованная в протоколе Ethereum, обеспечивает платформу с уникальным потенциалом. Ethereum не является закрытым протоколом узкого назначения, предназначенным для определенного набора приложений в области хранения данных, азартных игр или финансов, а является открытым по замыслу, и мы считаем, что он отлично подходит для того, чтобы служить базовым уровнем для большого количества как финансовых, так и нефинансовых протоколов в ближайшие годы.
Примечания и дополнительная литература
Примечания
- Опытный читатель может заметить, что на самом деле адрес биткоина — это хэш открытого ключа эллиптической кривой, а не сам открытый ключ. Однако на самом деле вполне обоснованно называть хеш открытого ключа открытым ключом. Это связано с тем, что криптографию Bitcoin можно рассматривать как специальный алгоритм цифровой подписи, в котором открытый ключ состоит из хеша открытого ECC ключа, подпись состоит из открытого ключа ECC, объединенного с подписью ECC, а алгоритм проверки включает проверку открытого ключа ECC в подписи с хешем открытого ключа ECC, предоставленного в качестве открытого ключа, а затем сравнение подписи ECC с открытым ключом ECC.
- Технически, медиана 11 предыдущих блоков.
- Внутренне 2 и CHARLIE являются числамиfn3, причем последнее имеет представление с порядком байтов от старшего к младшему по основанию 256. Числа могут быть от 0 до 2256-1.
Дальнейшее изучение
- Внутренняя ценность(opens in a new tab)
- Умное имущество(opens in a new tab)
- Умные контракты(opens in a new tab)
- B-money(opens in a new tab)
- Многоразовые доказательства выполнения работы(opens in a new tab)
- Безопасные права на имущество с полномочиями владельца(opens in a new tab)
- Проектный документ биткоина(opens in a new tab)
- Namecoin(opens in a new tab)
- Треугольник Zooko(opens in a new tab)
- Проектный документ цветных монет(opens in a new tab)
- Проектный документ Mastercoin(opens in a new tab)
- Децентрализованные автономные корпорации, Bitcoin Magazine(opens in a new tab)
- Упрощенная проверка платежей(opens in a new tab)
- Деревья Меркла(opens in a new tab)
- Деревья Патриции(opens in a new tab)
- GHOST(opens in a new tab)
- StorJ и автономные агенты, Джефф Гарзик(opens in a new tab)
- Майк Херн об умном имуществе на фестивале Тьюринга(opens in a new tab)
- Ethereum RLP(opens in a new tab)
- Деревья Меркла-Патриции в Ethereum(opens in a new tab)
- Питер Тодд о суммируемых деревьях Меркла(opens in a new tab)
Историю проектного документа смотрите в этой статье(opens in a new tab).
Ethereum, как и многие проекты с открытым исходным кодом, управляемые сообществом, эволюционировал с момента своего создания. Чтобы узнать о последних событиях в Ethereum, и как внесены изменения в протокол, мы рекомендуем это руководство.