Протоколы и алгоритмы консенсуса
Успешные инвестиции невозможны без понимания теории. И стоит начать разбираться с самых азов, даже, если не очень хочется. Но надо. В конце-концов незнание может позже стоить очень дорого.
Тут мы даем не полноценное понимание, а лишь вектор мысли, из какой оперы эти понятия, в целом о чем они и зачем нужны.
Понять эти важные для работы с криптой термины, не понимая, что такое блокчейн, хеши и нонсы, сложно.
Все знают про майнинг Биткоина, но все понимают, в чем его суть. Если коротко:
— Все транзакции происходят в блокчейне, то есть в децентрализованной сети блоков, хранящей данные. То есть в блокчейне хранится инфо о том, кто кому что перевел, и не только.
Эта информация записывается в блок, из цепи блоков и состоит блокчейн.
Кстати, блокчейн это не только про криптовалюты, эти «базы данных» используются и в других сферах и только набирают обороты. Например, в медицине, когда сведения о пациентах хранятся в блокчейне, это решает многие проблемы, например, когда данные о пациентах хранятся в разных базах данных, и сложно получить инфо об аллергиях, например, при стоматолоческой помощи. И любое вмешательство, помощь, сразу отображается там и это очень полезно для принятия решений при следующей медицинской помощи. Но сейчас не об этом.
– майнинг заключается в том, что майнеры подверждают и проверяют транзакции, выполняя вычислительные действия на специальном оборудовании.
– у каждого блокчейна есть свой протокол, то есть правила, по которым майнеры подтверждают транзакции (записи в блокчейне). И Bitcoin и Ethereum.
– это разные протоколы, то есть совершенно разные блокчейны, функционирующие на своих определенных правилах.
– а алгоритм консенсуса – это механизм, который проверяет верность тех или иных правил, то есть он проверяет, что транзакция верна и протокол соблюден.
Алгоритмов консенсуса много, самые распространенные – PoW и PoS.
Не будем сейчас подробно про них рассказывать, главное их отличие – в PoW (алгоритм у Биткоина) нужно производить вычислительные действия, то есть майнить и тратить много элеткроэнергии.
В PoS (на него стремится перейти Etherium) нет майнинга, там транзакции подтверждаются не вычислениями, а голосованием участников, которые «замораживают» свои активы в качестве гарантии, что будут голосовать верно, и в случае обмана рискуют эти активы потерять.
Эти алгоритмы консенсуса не единственные, но самые распространенные, у них есть свои плюсы и недостатки, о которых надо знать.
Главное запомнить, что PoS был создан с целью закрыть недостатки PoW, среди которых, например, огромное электропотребление.
Для чего нужно это знать и с этим разбираться?
1. Эти технологии внутри криптовалют раскрывают их фундаментальную ценность. Понимая их, вы понимаете, что «под капотом» у той или иной монеты.
2. У крупных институциональных инвесторов есть свои настроения по поводу этих технологий, и важно понимать, куда они смотрят, так как они двигают цены.
3. С алгоритмами консенсуса связаны пассивные заработки на крипте, такие, как стейкинг, например, работать с которым тоже очень важно, потому что просто непозволительно инвестировать в крипту, и при это не зарабатывать на ней пассивно 10-30% годовых.
В общем, одни знания тянут за собой другие, полноценно инвестировать в крипту, не понимая базовых технологий, невозможно.
Иначе не будет никакого понятия о фундаментальной ценности, а значит куча вытекающих проблем, начиная с того, что не сможете нормально анализировать, заканчивая паникой на просадках, так как в голове не будет нужной теории, ценности и эмоции победят над логикой. Но это уже другая тема.
Что такое PoW и PoS?
Механизмы консенсуса составляют основу всех криптовалютных блокчейнов и обеспечивают их безопасность.
В любой блокчейн-сети передаются два основных типа сообщений — транзакции и блоки. Транзакции формируются участниками системы и для их отправки достаточно знать приватный ключ от кошелька. А вот блоки необходимо защищать дополнительно.
В децентрализованных сетях любой её участник может вносить изменения в базу данных, но без дополнительных механизмов защиты это чревато различного рода манипуляциями, поэтому ещё при создании криптовалют были продуманы способы обезопасить блокчейн от подмены данных или проблемы повторной траты средств (double spending). Чтобы блокчейн отражал решение большинства, участникам сети необходимо прийти к соглашению, используя «механизмы консенсуса».
Например, для того, чтобы нельзя было исправить данные в предыдущих блоках информации, используется хэш-функция с захватом подписи предыдущего блока. То есть, чтобы изменить какие-то данные в старых блоках, злоумышленнику придётся пересчитать и все блоки после него, что обычно крайне трудозатратно и экономически нецелесообразно.
Хэш — это произвольный набор букв и цифр,который создаётся при обработке данных через хэш-функцию.Если хэшировать одни и те же данные, то результат будет прежним, однако при изменении хотя бы одной цифры в исходных данных хэш станет абсолютно другим. Также это однонаправленная функция, то есть, видя конечный результат нельзя сказать, какая информация была пропущена через эту функцию.
Блоки создаются особой категорией узлов сети блокчейна — так называемыми узлами консенсуса.
В случае биткойна эти узлы называют майнерами, поскольку они вознаграждаются за майнинг генерацией новых порций криптовалюты. Именно майнеры биткоина формируют его блокчейн, постоянно группируя входящие транзакции в блоки и распространяя их по сети.
Консенсус — это процесс, в ходе которого группа узлов сети определяет, какие транзакции в блокчейне действительны, а какие нет.
Proof of Work (PoW)
PoW стал прародителем всех остальных алгоритмов консенсуса. Впервые он был реализован в Биткоине, но сама концепция появилась задолго до этого. Доказательство работы было описано ещё в начале 90-х и применялось тогда для защиты от спама. Но использование PoW для нахождения консенсуса распределённой сети — и стало определённой инновацией.
Название «доказательство работы» отражает тот факт, что для нахождения блока надо совершить вычислительную работу, ожидаемое количество которой измеримо.
Суть технологии заключается в том, что майнеры должны перетасовывать данные, которые они хотят включить в блок, таким образом чтобы его хэш содержал в начале определённое количество нулей: например, 00000000022f88d2da21bd2802268966050f5a0b031058ce4562939c13727303.
Каждый последовательно идущий ноль в начале хэша усложняет задачу майнерам, поэтому им приходится тратить всё больше вычислительной мощности (совершать работу).
Сложность майнинга заключается в степени трудоёмкости нахождения походящего хэша, который используется для подписи блока. Сложность в сети автоматически корректируется в зависимости от вычислительной мощности, чтобы скорость нахождения новых блоков оставалась примерно на одном уровне.
Актуальный журнал транзакций при механизме PoW представляет из себя цепочку блоков с наибольшей суммарной сложностью. То есть майнеры должны искать новые блоки поверх уже существующих, иначе они будут отброшены остальными участниками сети как недействительные. Хотя, теоретически, никто не запрещает создавать новые блоки на основе какого-то старого блока, но суммарная сложность такой цепочки будет ниже и поэтому такая цепочка будет отброшена.
Иногда случаются технические расщепления блокчейна, если два майнера находят новый блок практически одновременно. В таком случае механизм PoW помогает защитить блокчейн от повторных трат, просто отбрасывая более короткую ветку, оставляя только одну из них актуальной. Именно из-за таких потенциальных расщеплений в сообществе существует негласное правило – ждать не одно, а несколько подтверждений (то есть количества блоков после).
Для биткоина достаточно подождать 3 подтверждения. Считается, что вероятность отбрасывания цепочки из трёх блоков стремится к нулю, поэтому ей уже можно полностью доверять.
Но вычисления, которые выполняются в рамках PoW, не служат никакой общественно-полезной цели, это лишь архитектурная особенность блокчейнов. Иными словами, на майнинг тратится неоправданно много ресурсов, которые можно было бы использовать не на защиту блокчейна, а для решения более насущных проблем человечества.
PoW используют Bitcoin (BTC), Ethereum Classic (ETC), Dogecoin (DOGE), Litecoin (LTC), Monero (XMR), Zcash (ZEC), Dash (DASH) и др.
Proof of Stake (PoS)
На фоне критики PoW сообщество предлагает множество альтернативных алгоритмов консенсуса, которые не требуют «работы». Самая популярная категория таких алгоритмов основана на доказательствах доли (Proof of Stake). Доказательство доли похоже на доказательство работы, только вместо совершения определённой работы автор нового блока показывает, что у него есть необходимая доля токенов сети. Для «майнинга» на PoS достаточно иметь некий запас криптовалюты и просто получать с неё «проценты».
Узлы консенсуса в таких сетях называют валидаторы (вместо майнеров), а сам процесс нахождения консенсуса – стейкингом (вместо майнинга).
Система PoS не требует участия майнеров, использования специального оборудования или массового потребления электроэнергии — хватит обычного персонального компьютера. Поэтому он считается более экологичным.
PoS используют Ethereum (ETH), Cardano (ADA), Algorand (ALGO), Tezos (XTZ) и др.
Delegated Proof of Stake (DPoS)
Но оба рассмотренных механизма имеют как свои плюсы и минусы, поэтому постоянно появляются и другие версии. Например, существует модификация механизма консенсуса PoS, в которой происходит делегирование доли (Delegated Proof of Stake). Такая система опирается на голосование на основе репутации для достижения консенсуса. Пользователи сети «голосуют» за выбор валидаторов из некоего определённого перечня надёжных узлов.
DPoS используют Lisk (LSK), EOS (EOS), Steem (STEEM), Ark (ARK) и др.
Кроме доказательства работы и доли, блокчейн-энтузиасты постоянно экспериментируют и с другими алгоритмами.
Криптобиржа Blocktopia раздает 30 $ новым пользователям до 09.02.23
Proof of Authority (PoA)
«Доказательство репутации» работает путём выбора валидаторов сети на основе репутации. В PoA валидаторы не блокируют свои монеты в стейкинге, а должны поставить на кон свою репутацию за право подтверждать блоки. Это сильно отличается от большинства протоколов блокчейна, которые обычно не требуют раскрытия личности для участия.
Proof of Capacity (PoC) / Proof of Space
Чтобы выступать в качестве валидатора в таких сетях необходимо поделиться своим местом на жёстком диске. Это помогает за вознаграждение делиться неиспользованными ресурсами ПО.
Proof of Elapsed Time (PoET)
Доказательство истёкшего времени используется в блокчейн-сетях с допуском (тех, которые требуют от участников идентифицировать себя). PoET использует доверенные вычисления для обеспечения случайного времени ожидания при создании блока.
Proof of History (PoH)
PoH позволяет встраивать «временные метки» в сам блокчейн, «засекая» прошедшее между транзакциями время без какой-либо необходимости полагаться на другие узлы.
Directed Acyclic Graphs (DAG)
Направленный ациклический граф (DAG) не использует стандартную структуру блокчейна, а обрабатывает транзакции в основном асинхронно.
Узлы распределяют свои транзакции связывая их с другими узлами наугад, поэтому в итоге все транзакции переплетаются друг с другом.
Это теоретически даёт бесконечное количество транзакций в секунду, но и у консенсуса в DAG есть как сильные, так и слабые стороны.
DAG используют Iota, Hashgraph, Raiblocks/Nano и др.
До сих пор не существует универсального метода нахождения консенсуса. Каждый механизм консенсуса имеет свой набор преимуществ и недостатков, поэтому нет единого устоявшегося принципа.
Сообществу только предстоит найти механизм, который удовлетворит всем критериям доверия в распределённых сетях, и при этом будет эффективно использовать вычислительные ресурсы его пользователей.
Как на самом деле работает протокол Биткоин
Много тысяч статей было написано для того, чтобы объяснить Биткоин — онлайн, одноранговую (p2p) валюту. Большинство из этих статей поверхностно рассказывают суть криптографического протокола, опуская многие детали. Даже те статьи, которые «копают» глубже, часто замалчивают важные моменты. Моя цель в этой публикации — объяснить основные идеи, лежащие в протоколе Биткоин в ясной, легкодоступной форме. Мы начнем с простых принципов, далее пойдем к широкому теоретическому пониманию, как работает протокол, а затем копнем глубже, рассматривая сырые (raw) данные в транзакции Биткоин.
Достаточно сложно понять работу протокола в деталях. Намного проще вместо этого принять Биткоин как данность и участвовать в спекуляциях о том, как разбогатеть с помощью Биткоин, является ли Биткоин пузырем, может ли Биткоин в один прекрасный день уничтожить обязательное налогообложение, и так далее. Это все весело, но существенно ограничивает ваше понимание. Понимание деталей протокола Биткоин открывает недоступные перспективы. В частности, это основа для понимания встроенного языка сценариев (скриптовый язык программирования) Биткоин, который делает возможным использование Биткоин для создания новых видов финансовых инструментов, таких как умные контракты (1 2). Новые финансовые инструменты могут, в свою очередь, быть использованы для создания новых рынков и получения новых форм коллективного поведения человека.
Я опишу такие концепции, как контракты, в следующих публикациях. Эта публикация концентрируется на объяснении внутренности протокола Биткоин. Чтобы понять меня, вы должны быть знакомы с идеей публичного криптоключа, и с тесно связанной идей о цифровой подписи. Я также предполагаю, что вы знакомы с криптографической хэш-функцией (изменение вводных данных всего на один бит кардинально меняет хэш-сумму, прим. пер.). Ничто из этого не представляет большой сложности. Основные идеи можно получить из программ первого курса по математике в университете или классов по компьютерной информатике. Идеи красивы, так что если вы не знакомы с ними, я рекомендую потратить несколько часов, чтобы ознакомиться.
Это может показаться удивительным, что основой Биткоин является криптография. Разве Биткоин не валюта, не способ отправки секретных сообщений? На самом деле, проблемы, которые должен решать Биткоин, касаются в основном обеспечения безопасности сделок – быть уверенным, что люди не могут красть друг у друга, или выдавать себя за друг друга, и так далее. В мире атомов мы достигаем такой безопасности с помощью таких устройств, как замки, сейфы, подписи и банковские хранилища. В мире битов мы достигаем такого рода безопасности с помощью криптографии. И вот почему Биткоин в душе — криптографический протокол.
Стратегия, которую я буду использовать в моей публикации, предполагает создание Биткоин поэтапно. Я начну с объяснения очень простой цифровой валюты, основанной на идеях, которые практически очевидны. Мы назовем эту валюту Инфокоин, чтобы отличить ее от Биткоин. Конечно, наша первая версия Инфокоин будет иметь много недостатков, и поэтому мы будем проходить через несколько итераций Инфокоин, с каждой новой итерацией будем вводить только одну или две простые новые идеи. После нескольких таких итераций мы придём к полному протоколу Биткоин. Мы заново откроем Биткоин!
Эта стратегия работает медленнее, чем если бы я объяснил работу всего протокола Биткоин залпом. Даже если вы можете понять механику Биткоин через такое залповое объяснения, будет трудно понять, почему Биткоин спроектирован таким вот образом. Преимущество медленного, итерационного объяснения в том, что это дает нам гораздо более четкое понимание каждого элемента Биткоин.
Наконец, я должен упомянуть, что я новичок в Биткоин. Я наблюдаю за ним с 2011 года (и за криптовалютами с конца 1990-х годов), но серьёзно вник в детали протокола Биткоин только в начале этого года. Так что буду благодарен за исправления любых заблуждений с моей стороны. Кроме того, я в своем материале включил ряд «проблем для автора», — заметки для себя о вопросах, которые возникли у меня во время написания. Вы можете найти их интересными, но вы также можете пропустить их полностью, не теряя основного текста.
Первые шаги: подписан протокол о намерениях
Так как мы можем спроектировать цифровую валюту?
На первый взгляд, цифровая валюта кажется чем-то невозможным. Представим себе человека — назовем ее Алиса – она имеет некоторые цифровые деньги, которые она хочет потратить. Если Алиса может использовать строку битов в качестве денег, как мы можем помешать ей использовать одну и ту же строку битов снова и снова, таким образом, создав неограниченное количество денег? Или, если мы можем как-то решить эту проблему, как мы можем предотвратить подделывания такой строки битов и использование ее для кражи у Алисы?
Это лишь две из многих проблем, которые должны быть преодолены, чтобы использовать информацию в качестве денег.
В первой версии Инфокоин давайте найдем способ, чтобы Алиса могла использовать строку битов в (очень примитивной и неполной) форме денег, но таким образом, чтоб у нее была хоть какая-то защита от подделки. Предположим, Алиса хочет дать другому человеку, назовем его Боб, один инфокоин. Чтобы сделать это, Алиса записывает сообщение «Я, Алиса, даю Бобу один инфокоин». Затем она подписывает в цифровом формате сообщение с использованием закрытого ключа шифрования (криптоключ), и заявляет о подписанной строке битов всему миру.
(Кстати, я использую «Инфокоин» с большой буквы для обозначения протокола и общей концепции, и «инфокоин» с маленькой буквы для обозначения конкретного денежного знака. Подобная практика является обычным явлением, хотя и не всеобщей, в мире Биткоин.)
Такой прототип цифровой валюты вас не очень впечатлит! Но у него есть некоторые достоинства. Любой человек в мире (в том числе и Боб) может использовать открытый ключ Алисы для проверки, что Алиса на самом деле была человеком, который подписал сообщение «Я, Алиса, даю Бобу один инфокоин». Никто другой не смог бы создать эту строку битов, а значит Алиса не может повернуться и сказать: «Нет, я вовсе не имела в виду, что хочу отдать Бобу один инфокоин». Таким образом, протокол устанавливает, что Алиса действительно намерена дать Бобу один инфокоин. Такой же факт — никто не смог бы составить такое подписанное сообщение — дает Алисе некоторую ограниченную защиту от подделки. Конечно, после того, как Алиса опубликовала свое сообщение, существует возможность дублировать ее сообщение другими людьми, так что в некотором смысле подделка возможна. Но это не возможно с нуля. Эти два свойства — установление намерения со стороны Алисы и ограниченная защита от подделки – действительно примечательные особенности этого протокола.
Я (совсем) не сказал о том, что, собственно, есть цифровые деньги. Объясняю: это просто само сообщение, т. е. последовательность битов, а точней, подписанное цифровой подписью сообщение: «Я, Алиса, даю Бобу один инфокоин». В будущем протоколы будут похожи в том, что все наши формы цифровых денег будут просто более содержательными сообщениями.
Использование серийных номеров с целью обозначить монеты
Проблема с первой версией Инфокоин в том, что Алиса может продолжать посылать Бобу то же подписанное сообщение снова и снова. Предположим, Боб получает десять копий подписанного сообщения «Я, Алиса, даю Бобу один инфокоин». Означает ли это, что Алиса послала Бобу десять различных инфокоинов? Было ли ее послание случайно дублированным? Возможно, она пыталась обмануть Боба, притворяясь, что она дала ему десять различных ифнокоинов, в то время как сообщение лишь доказывает всему миру, что она намерена передать один инфокоин.
Чего бы нам хотелось, так это найти способ сделать инфокоины уникальными. Они нуждаются в лейбле или серийном номере. Алиса подпишет сообщение «Я, Алиса, даю Бобу один инфокоин, с серийным номером 8740348». Потом, позже, Алиса может подписать сообщение «Я, Алиса, даю Бобу один инфокоин, с серийным номером 8770431», и Боб (и все остальные) будет знать, что другой инфокоин был передан.
Чтобы эта схема работала, нам нужен надежный источник серийных номеров для инфокоинов. Один из способов создания такого источника является открытие банка. Этот банк будет предоставлять серийные номера для инфокоинов, отслеживать, кто имеет какие инфокоины, и проверять, что сделки действительно являются легитимными.
Более конкретно, давайте предположим, что Алиса приходит в банк и говорит: «Я хочу снять (withdraw) один инфокоин с моего счета». Банк уменьшает ее баланс счета на один инфокоин, и присваивает ему новый, никогда ранее не используемый серийный номер, скажем 1234567. Затем, когда Алиса хочет передать ее инфокоин Бобу, она подписывает сообщение «Я, Алиса, даю Бобу один инфокоин с порядковым номером 1234567». Но Боб не просто принимает инфокоин. Вместо этого, он вступает в контакт с банком, и проверяет, что: (а) инфокоин с этим серийным номером принадлежит Алисе; и (б) Алиса еще не потратила этот инфокоин. Если условия верны, то Боб информирует банк о том, что он хочет принять этот инфокоин, и банк обновляет свои записи, чтобы отображать, что инфокоин с этим серийным номером в настоящее время в распоряжении Боба и больше не принадлежит Алисе.
Создавать банк совместными усилиями
Это последнее решение выглядит довольно перспективным. Тем не менее, оказывается, что мы можем сделать что-то гораздо более амбициозное. Мы можем полностью исключить банк из протокола. Это значительно меняет характер валюты. Это означает, что больше нет единой организации, отвечающий за валюту. И если вы представите об огромной власти в руках центрального банка — контроль над денежной массой — это довольно серьезное изменение.
Идея состоит в том, чтобы каждый (в совокупности) был банком. В частности, мы допустим, что все пользователи Инфокоин хранят полную запись о том, кому инфокоины принадлежат. Вы можете представить это как открытую общую книгу учета с указанием всех операций Инфокоин. Мы назовём эту книгу «цепочка блоков» (blockchain), именно так в Биткоин и называется публичная запись всех транзакций.
Теперь предположим, что Алиса хочет передать инфокоин Бобу. Она подписывает сообщение «Я, Алиса, даю Бобу один инфокоин с порядковым номером 1234567», и отправляет подписанное сообщение Бобу. Боб может использовать свою копию цепочки блоков, чтобы проверить, действительно ли инфокоин принадлежит Алисе. Если это проверяется, то потом он посылает одновременно сообщение Алисы и свок сообщение о принятии сделки по всей сети и все обновляют свои копии цепочки блоков.
У нас еще есть проблема «откуда берется серийный номер», но это, оказывается, довольно легко решить, и поэтому я отложу ее на потом, когда будем обсуждать Биткоин. Более сложной проблемой является то, что этот протокол позволяет Алисе обманывать через повторное расходование (double spending) ее инфокоинов. Она отправляет подписанное сообщение «Я, Алиса, даю Бобу один инфокоин с порядковым номером 1234567» Бобу, и сообщение «Я, Алиса, даю Чарли один инфокоин, с [тем же] серийный номером 1234567» Чарли. Оба, Боб и Чарли, используют свою копию цепочки блоков для проверки того, что инфокоин принадлежит Алисе. При условии, что они делают эту проверку в то-же самое время (до того, как они имели возможность услышать друг от друга), оба увидят, что да, цепочка блоков показывает принадлежность монеты Алисе. Итак, они оба принимают перевод и также вместе транслируют информацию о принятие сделки. Вот теперь мы имеем проблему. Как другие люди должны обновлять свои цепочки блоков? Может быть не так уж просто найти способ получения согласующей общей книги транзакций. И даже если все могут согласиться на постоянной основе обновлять свои цепочки блоков, есть еще одна проблема, что Боб или Чарли могут быть обманутыми.
На первый взгляд повторное расходование выглядит трудным для Алисы в реализации. В конце концов, если Алиса посылает сообщение сначала Бобу, то Боб может проверить сообщение, и рассказать всем остальные в сети (в том числе Чарли), чтобы они обновили свои цепочки блоков. Как только это произошло, Чарли уже не сможет быть одураченным Алисой. Так что, скорее всего, только в коротком промежутке времени Алиса может делать повторные расходования. Тем не менее, очевидно, любой такой промежуток времени нежелателен. Хуже того, существуют методы, благодаря которым Алиса может сделать этот период дольше. Она может, например, использовать анализ сетевого трафика, чтобы найти время, когда Боб и Чарли имеют много задержек в связи. Или, возможно, она может что-то сделать, чтобы сознательно сорвать их связь. Если она может замедлить связь даже на малость, то это позволит упростить ей задачу с повторным расходованием.
Как мы можем решить проблему двойных расходов? Очевидным решением будет, что, когда Алиса посылает Бобу один инфокоин, Боб не должен пытаться проверить сделку в одиночку. Скорее всего, он должен транслировать о возможной сделки всем пользователям сети Инфокоин, и попросить их помочь ему определить, является ли сделка легитимной. Если они все вместе решат, что сделка в порядке, то Боб может принять этот инфокоин, и все обновят свои цепочки блоков. Этот тип протокола может помочь предотвратить проблему двойных расходов, так как, если Алиса попытается потратить ее инфокоин вместе с Бобом и Чарли, другие люди в сети заметят, и пользователи сети скажут Боб и Чарли, что есть проблема с транзакцией, и сделка не должна быть осуществлена.
Более подробно, давайте предположим, что Алиса хочет дать Бобу один инфокоин. Как и прежде, она подписывает сообщение «Я, Алиса, даю Бобу один инфокоин с порядковым номером 1234567», и дает подписанное сообщение Бобу. Так же, как и прежде, Боб делает проверку работоспособности, используя его копию цепочки блоков, чтобы проверить действительно ли монета в настоящее время принадлежит Алисе. Но в этот момент протокол изменен. Боб не просто идет вперед и принимает сделку. Вместо этого, он передает сообщение Алисы всей сети. Другие члены сети проверяют, имеет ли Алиса этот инфокоин. Если это так, они передают сообщение «Да, Алиса владеет инфокоином 1234567, теперь он может быть передан Бобу». Как только достаточное количество людей распространят этот послание в сети, все обновят свои цепочки блоков, которые будут показывать, что инфокоин 1234567 теперь принадлежит Бобу, и сделка завершена.
Этот протокол имеет много неточных элементов в настоящее время. Например, что значит сказать «достаточное количество людей должны транслировать это сообщение»? Что значит «достаточно»? Это не может означать всех в сети, так как мы априори не знаем, кто находится в сети Инфокоин. По той же причине, это не может означать некоторую фиксированную долю пользователей в сети. Мы не будем пытаться разобраться в этом прямо сейчас. Вместо этого, в следующем разделе я буду указывать серьезные проблемы в подходе, который мы описали. Обращая внимание на эту проблему, мы будем иметь приятный побочный эффект от создания идей выше более понятными.
Доказательство работы
Предположим, Алиса хочет повторно потратить в протоколе, который я только что описал. Она может сделать это, взяв на себя контроль сети Инфокоин. Давайте предположим, что она использует автоматизированную систему для настройки большого количества отдельных идентичностей (пользователей), скажем, миллиард, в сети Инфокоин. Как и прежде, она пытается дважды оплатить тот же самым инфокоин Бобу и Чарли. Но когда Боб и Чарли попросят сеть проверить сделки, дополнительные пользователи Алисы завалят сеть, объявив Бобу, что они подтвердили его сделку, и Чарли, что они подтвердили его сделку, обманув одного или обоих одновременно, принимая такую транзакцию.
Существует способ избежать этой проблемы, используя идею, известную как доказательство правильности работы (proof-of-work). Идея парадоксальна и включает в себя сочетание двух других идей: (1) (искусственно) сделать подтверждение транзакций затратными для пользователей сети в виде компьютерных вычислений; и (2), вознаградить их за помощь проверки транзакций. Награда используется для того, чтобы люди в сети пробовали помочь проверить сделки, несмотря на необходимость тратить вычислительную мощность на этот процесс. Польза от того, что проверка транзакций требует затрат, помогает избежать зависимости от количества идентичностей (пользователей сети), подконтрольных кому-либо. Таким образом, только общая вычислительная мощность может оказывать давление на проверку. Как мы увидим, используя некоторый умный дизайн, мы можем сделать так, чтобы мошеннику потребовались огромные вычислительные ресурсы для обмана, что делает это практически нецелесообразным.
Вот суть доказательства правильности работы. Но чтобы по-настоящему понять, мы должны присмотреться к деталям.
Предположим, Алиса транслирует в сеть новость «Я, Алиса, даю Бобу один инфокоин с порядковым номером 1234567».
Услышав это сообщение, каждый добавляет его в очередь ожидающих подтверждения (pending) сделок: услышаны, но еще не были утверждены сетью. Например, другой пользователь сети по имени Дэвид может иметь следующую очередь незавершенных сделок:
Я, Том, даю Сью один инфокоин, с серийным номером 1201174.
Я, Сидней, даю Синтии один инфокоин, с серийным номером 1295618.
Я, Алиса, даю Бобу один инфокоин с порядковым номером 1234567.
Дэвид проверяет свою копию цепочки блоков, и видит, что каждая сделка годна. Он хотел бы помочь, отправив новость о годности сделок для всей сети.
Тем не менее, прежде чем сделать это, как часть протокола проверки, Дэвиду требуется решить непростую вычислительную задачу — доказательство правильности работы. Без решения этой задачи, остальная часть сети не будет принимать его проверку сделок.
Что за задачу Давиду нужно решить? Чтобы объяснить это, давайте h будет фиксированной хэш-функцией известной всем в сети — она встроена в протокол. Биткоин использует известную хеш-функцию SHA-256, но любая криптографически безопасная хэш-функция подойдет. Давайте дадим очереди незавершенных сделок Дэвида лейбл L, чтоб нам удобней было ссылаться. Предположим, Дэвид добавляет число х (так называемый одноразовый номер) и вычисляет хэш-суму из комбинации. Например, если мы используем L = «Hello, world!» (Очевидно, что это не список операций, просто строка используется для иллюстрации) и одноразовый х = 0, то (выход получаем в шестнадцатеричном формате)
h(«Hello, world!0») = 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64
Задача, которую Дэвид должен решить — доказательство правильности работы — это найти простое число х так, что когда мы добавляем х к L и результат хеширования комбинации начинается с ряда нулей. Задачу можно сделать более или менее трудной, изменяя число нулей, необходимых для решения этой задачи. Относительно простым доказательством правильности работы задачи может потребовать только три или четыре нуля в начале хэша, в то время как более трудным доказательством правильности работы задача может потребовать гораздо большее количество нулей, скажем 15 последовательных нулей. В любом случае, выше попытка найти подходящий одноразовый номер с х = 0 не удалась, так как результат не начинается с нуля. Попробуем х = 1,. Тоже не сработает:
h(«Hello, world!1») = e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8
Мы можем продолжать искать разные значения для х =2,3,4….наконец, при значении x=4250 мы получаем:
h(«Hello, world!4250») = 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9
Это число дает нам строку из четырех нулей в начале выхода хэш. Этого будет достаточно, чтобы решить простую задачу «доказательство работы», но не достаточно, чтобы решить более трудную задачу «доказательство работы».

Есть вещь, которая делает эта задачу сложной для решения. Результат криптографической хеш-функции ведет себя как случайные числа: поменяй хоть один бит в исходных данных и результат будет кардинально отличаться настолько, что его невозможно предугадать. Так что, если мы хотим иметь значение хэш суммы с 10 нулями вначале, то Дэвиду будет нужно, в среднем, перебрать различных значений х, прежде чем он найдет подходящий простой номер. Это довольно сложная задача, требующая большой вычислительной мощности.
Существует возможность сделать эту задачу более или менее трудно решаемой через большее или меньшее количество нулей на выходе из хэш-функции. На самом деле, протокол Биткоин получает довольно хороший уровень контроля над трудностью задачи, используя незначительную вариацию головоломки на доказательство правильности работы (proof-of-work), описанной выше. Вместо того, чтобы требовать нули, Биткойн в качестве доказательства правильности работы требует, чтобы хэш заголовка блока транзакций быть меньше или равным числу, известному как цель. Эта цель автоматически регулируется для того, чтобы блок Биткойн занимал, в среднем, около десяти минут для авторизации.
(На практике есть значительная случайность в том, как много времени потребуется для утверждения блока — иногда новый блок утвержден всего за минуту или две, а в других случаях это может занять 20 минут или даже больше. Это напрямую меняется в протоколе Биткойн, так что время для проверки обычно достигает максимум около десяти минут. Вместо того, чтобы решать одну задачу, мы можем потребовать решения нескольких задач; используя тщательно разработанный программный дизайн, можно значительно уменьшить дисперсию во времени для проверки блока сделок.)
Хорошо, давайте предположим, что Дэвиду повезло и он нашел подходящее число х. Ура! (Он получит вознаграждение за нахождение числа, как будет описано ниже). Он транслирует блок операций, который он утверждает, в сеть вместе со значением х. Другие участники сети Инфокоин могут проверить, что х является решением доказательства правильности работы задачи. И они затем должны обновить свои цепочки блока, чтобы включить новый блок операций в цепочку.
Чтобы идея доказательства правильности работы имела шансы на успех, пользователям сети нужен стимул, чтобы они помогали проверять транзакций. Без такого стимула, они не имеют никаких оснований расходовать ценную вычислительную мощность просто так, чтобы помочь проверить операции других людей. И если пользователи сети не готовы тратить эту мощность, то вся система не будет работать. Решением этой проблемы является вознаграждение людям, которые помогают проверять сделки. В частности, предположим, мы награждаем тех, кто успешно проверил блок сделок, путем зачисления им некоторого количества инфокоинов. Награда в инфокоин настолько велика, что даст им стимул участвовать в проверке.
В протоколе Биткоин, этот процесс подтверждения называется майнинг (mining). За каждый проверенный блок сделок, успешный майнер получает вознаграждение в биткоинах. Вначале эта награда была установлена на уровне 50 биткоинов. Но на каждые 210 тысяч проверенных блоков (примерно, раз в четыре года) награда уменьшается вдвое. Это произошло только один раз. На сегодняшний день вознаграждение за добычу блока составляет 25 биткоинов. Это снижение ставки в два раза будет продолжаться каждые четыре года до года 2140. В тот момент, награда за майнинг упадет ниже 10^-8 биткоинов за блок.10^-8 биткоинов, на самом деле, минимальная единица Биткоин, и известна как Сатоши. Таким образом, в 2140 году общее предложение биткоинов перестанет увеличиваться. Однако это не устранит стимул, чтобы продолжать проверки транзакций. Биткоин также дает возможность выделить некоторую сумму в сделке в качестве платы за транзакцию, что попадет к майнеру, который помогает акцептовать сделки. В первые дни Биткоин плата за транзакцию составляла ноль, но с ростом популярности Биткоин платы за транзакцию постепенно возросли, и в настоящее время являются дополнительной прибавкой к награде в 25 биткоинов за майнинг блока.
Вы можете думать о доказательстве правильности работы (proof-of-work) как о соревновании кто быстрей акцептует сделки. Каждый вход в соревнование стоит немного вычислительной мощности. Шанс победы майнера в соревновании является (грубо говоря, и с некоторыми оговорками) равным отношению к общей вычислительной мощности, что они контролируют. Так, например, если майнер контролирует один процент всей вычислительной мощности используемого для проверки транзакций в Биткоин, то он имеет примерно один процент шансов на победу. То есть при условии, что в соревновании задействовано много вычислительной мощности, нечестный майнер скорее всего будет иметь относительно небольшой шанс исказить процесс проверки, если только он не потратит огромное количество вычислительных ресурсов.
Конечно, в то время как это вызывает воодушевление, что нечестная сторона имеет лишь относительно небольшой шанс испортить цепочку блока, но этого не достаточно, чтобы вызвать доверие к валюте. В частности, мы еще не окончательно решили вопрос о повторных расходах.
Я проанализирую двойные расходы уже скоро. Прежде чем сделать это, я хочу заполнить важную деталь в описании Инфокоин. Идеально было бы согласовать порядок в сети Инфокоин, в котором имели место транзакции. Если у нас нет такого порядка, то в любой момент может стать непонятно, кто владеет какими инфокоинами. Чтобы решить это, мы будет требовать, чтобы новые блоки всегда включали указатель на предыдущий блок, утвержденный в цепочке, в дополнение к списку транзакций в блоке. (Указатель на самом деле просто хэш предыдущего блока). Итак, у нас есть цепочка блоков (block chain) – это просто прямая цепочка блоков транзакций, один за другим, где каждый блок содержит указатель на непосредственно предыдущий блок:

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

Казалось бы, это вызывает проблему, которую мы пытаемся избежать — уже не ясно, в каком порядке произошли сделки, и это не проясняет, кто владеет какими инфокоинами. К счастью, есть простая идея, которая может быть использована для удаления любой вилки. Правило таково: если вдруг случается вилка, люди в сети отслеживают оба разветвления. Но в любой момент времени, майнеры работают только над продолжением того разветвления, в котором длиннее копия цепочки блоков.
Предположим мы имеем вилку, в которой некоторые майнеры получают сначала блок А и некоторые майнеры получают блок В. Те майнеры, которые получают блок А сначала, будут продолжать работать вдоль этого разветвления, в то время как другие майнеры будут идти вместе с разветвлением B. Предположим, что майнеры, работающие на разветвлении B успешно добыли блок:

После того, как все получают известие, что это произошло, майнеры, работающие на разветвлении А заметят, что разветвление B теперь уже длиннее и переключатся на работу по этому разветвлению. Вот и все! Тотчас же работа на разветвлении А перестанет, и все будут работать на той же линейной цепочки, и блок А можно проигнорировать. Конечно, любые неподтвержденные транзакции, включенные в блок А, еще будут ожидать решения в очередях майнеров, работающих на разветвлении B, и в последствии все сделки будут подтверждены. Кроме того, может оказаться, что майнеры, работающие на разветвлении А, раньше ее расширят. В этом случае работа на разветвлении B быстро прекратиться, и снова у нас есть одна линейная цепочка.
Независимо от результата, этот процесс гарантирует, что цепочка блоков имеет согласованное во времени упорядочение блоков транзакций. В Биткоин принято, что сделка не считается подтвержденной до того как: (1) она является частью блока в длинном разветвлении, и (2), по меньшей мере, 5 блоков последовали за ним в самом длинном разветвлении. В этом случае мы говорим, что сделка имеет «6 подтверждений ». Это дает время сети прийти к согласованной упорядоченности блоков. Мы будем также использовать эту стратегию для Инфокоин.
С упорядочением мы разобрались, давайте вернемся к размышлению о том, что происходит, если нечестный пользователь пытается дважды потратить. Предположим, Алиса пытается дважды потратить инфокойн с Бобом и Чарли. Один из возможных подходов для нее, попытаться самостоятельно проверить блок, который включает в себя обе транзакции. Предполагая, что у нее есть один процент общей вычислительной мощности, ей может повезти, и она подтверждает блок, решая математическую задачу правильности работы (proof-of-work). К сожалению, для Алисы, повторный платеж будет сразу замечен другими людьми в сети Ифнокоин и отклонен, несмотря на решение задачи с доказательством правильности работы. Так что нам не нужно беспокоиться.
Более серьезная проблема возникает, если она транслирует отдельно две сделки, в которых она проводит тот же инфокоин с Бобом и Чарли, соответственно. Она может, например, транслировать одну транзакцию одной группе майнеров, а другую транзакцию — другой, надеясь получить одобрение сделок таким образом. К счастью, в этом случае, как мы видели, сеть будет окончательно подтверждать только одну из этих сделок, но не обе. Так, например, сделка Боба в конечном счете может быть подтверждена, и в этом случае Боб может быть спокоен. Между тем, Чарли увидит, что его сделка не была подтверждена, и он откажется от предложения Алисы. Так что в этом нет проблемы. На самом деле, зная, что это будет происходить, нет особых причин для Алисы пробовать это.
Существует другой важный вариант двойных расходов, если Алиса = Боб, т.е. Алиса старается оплатить монету Чарли, которую она также «расходует» сама себе (то есть, отдавая себе). Выглядит это так, что легко заметить и справиться с этим, но в то же время, конечно, легко в сети настроить несколько пользователей, связанных с тем же лицом или организацией, так что такую возможность необходимо учитывать. В таком случае, стратегия Алисы ждать, пока Чарли не примет инфокоин, что произойдет после того, как сделка была подтверждена 6 раз в самой длинной цепи. Она будет пытаться разветвить цепочку до сделки с Чарли, добавляя блок, в который включена транзакция оплаты самой себе:

К сожалению, для Алисы сейчас очень трудно догнать более длинное разветвление. Другие майнеры не хотят помочь ей, так как они будут работать на более длинном разветвлении. И до тех пор, пока Алиса не сможет решить доказательство правильности работы, по крайней мере так быстро, как и все остальные в сети вместе — грубо говоря, это означает, что контролируя более пятидесяти процентов вычислительной мощности — то она будет просто отставать дальше и дальше позади. Конечно, ей может повезти. Мы можем, например, представить себе сценарий, в котором Алиса управляет одним процентом вычислительной мощности, но случится удача и она найдет шесть дополнительных блоков в ряд, прежде чем остальная часть сети нашла какой-либо новый блок. В этом случае она могла бы опередить, и получить контроль над цепочкой блоков. Но это в частности событие произойдет с вероятностью 1/(100^6) = 10^-12. Более общий анализ в этом направлении показывает, что вероятность Алисы догнать более длинное разветвление блоков бесконечно мала, если она не в состоянии решить доказательство правильности работы со скоростью, близкой ко всем другим майнерам вместе взятым.
Конечно, это не тщательный анализ безопасности, показывающий невозможность Алисы осуществить повторные расходы. Это всего лишь неофициальный аргумент достоверности. Оригинальный текст, представляющий Биткоин, по сути, не содержит тщательного анализа безопасности, только неформальные аргументы по моментам, что я представил. Сообщество, которые интересуются безопасностью, по-прежнему анализирует Биткоин, и пытается понять возможные уязвимости. Вы можете увидеть некоторые из этих исследований здесь, и я упомяну несколько проблем в «Проблемы для автора » ниже (см. в оригинальном тесте). На данный момент, я думаю, что справедливо сказать, что жюри все еще не знают, насколько безопасным Биткоин является.
Идеи доказательства правильности работы и майнинга порождают много вопросов. Какова награда нужна, чтобы убедить людей добывать? Как изменения в эмиссии инфокоин повлияет на экономику Ифнокоин? Будет майнинг Инфокоин в конечном итоге сконцентрирован в руках немногих, или многих? Если майнеров всего лишь несколько, поставит ли это под угрозу безопасность системы? Предположительно стоимость транзакций со временем сбалансируется — не приведет ли это к нежелательному источнику трения, и не сделает ли маленькие транзакции менее желательными? Это все большие вопросы, которые выходят за рамки этой статьи. Я могу возвратиться к этим вопросам (в контексте Биткоин) в будущих публикациях. В настоящее время, мы сфокусируемся на понимании того, как работает протокол Биткоин.
Биткоин
Давайте отойдем от Инфокоин, и опишем фактический протокол Биткоин. Есть несколько новых идей здесь, но с одним исключением (см. ниже), что они в основном очевидные модификации Инфокоин.
Для того, чтобы использовать Биткоин на практике, сначала устанавливаем программу- бумажник на вашем компьютере. Чтобы дать вам понимание, что это значит, вот скриншот из программы-бумажника с названием Multbit. Вы можете видеть баланс биткоинов слева — 0.06555555 биткоин, или около 70 долларов по курсу на день, когда я сделал этот скриншот — и справа две недавние сделки, которые формируют 0,06555555 биткоинов:

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

Затем вы отправьте Биткоин-адрес человеку, который хочет покупать у вас. Вы можете сделать это по электронной почте, или даже поместить адрес публично на веб-странице. Это безопасно, поскольку адрес является лишь значением результата хэширования вашего открытого ключа, который может безопасно быть известен в мире так или иначе. (Я вернусь позже к вопросу о том, почему адрес Биткоин — это хэш, а не только открытый ключ.)
Человек, который будет платить вам генерирует транзакцию. Давайте взглянем на данные из реальной сделки передающей 0.31900000 биткоинов. Ниже показаны почти необработанные данные. Они изменены в трех моментах: (1) данные были преобразованы из последовательной формы в параллельную (deserialized); (2) номера строк, которые были добавлены, для удобства пользования; и (3) я сократил различные хэши и открытые ключи, просто отображая первые шесть шестнадцатеричных цифр каждого, когда на самом деле они гораздо длиннее. Вот данные:
- «ver»:1,
- «vin_sz»:1,
- «vout_sz»:1,
- «lock_time»:0,
- «size»:224,
- «in»:[
- «n»:0>,
- «scriptSig»:«304502… 042b2d…»>],
- «out»:[
- «scriptPubKey»:«OP_DUP OP_HASH160 a7db6f OP_EQUALVERIFY OP_CHECKSIG»>]>
Давайте пройдемся строка за строкой.
Строка 1 содержит хэш оставшейся части сделки, 7c4025 …, выраженное в шестнадцатеричном виде. Это используется в качестве идентификатора транзакции.
Строка 2 говорит нам, что это сделка в версии 1 протокола Биткоин.
Строки 3 и 4 говорят нам, что сделка имеет один ввод и один вывод, соответственно. Я поговорю ниже о сделках с большим количеством вводов и выводов, и почему это полезно.
Строка 5 содержит значение lock_time, которое может быть использовано для контроля, когда транзакция будет завершена. Для большинства транзакций Биткоин сегодня lock_time установлен в 0, это означает, что транзакция немедленно завершена.
Строка 6 говорит нам размер (в байтах) сделки. Обратите внимание, что это не денежная сумма передается! Об этом далее.
Строки с 7 по 11 определяют вводные биткоины к операции. В частности, строки с 8 по 10 говорят нам, что ввод должен быть взят с вывода из предыдущей сделки с соответственной хэш-суммой, которая выражается в шестнадцатеричном формате как 2007ae ….n = 0 говорит нам о том, что это будет первый вывод из той транзакции; мы увидим в ближайшее время, как работают несколько выводов (и вводов) в транзакции, так что не волнуйтесь слишком много об этом сейчас. Строка 11 содержит подпись лица, передающего деньги — 304502 …, затем пробел, а затем соответствующий открытый ключ -04b2d …. Опять же в шестнадцатеричном формате.
Единственное, что следует отметить о вводе, так это отсутствие точного указания сколько биткоинов от предыдущей транзакции должны быть потрачены в этой транзакции. На самом деле, все биткоины от n = 0-го вывода предыдущей транзакции потрачены. Так, например, если n = 0-й вывод из предыдущей сделки составил 2 биткоина, то 2 биткоина будут потрачены в этой транзакции. Это кажется неудобным ограничением – все равно, что пытаться купить хлеб с купюрой в 20 долларов, и не в состоянии разбить на мелкие банкноты. Решение, конечно, должно иметь механизм для получения сдачи. Это можно сделать с помощью транзакций с несколькими вводами и выводами, которые мы обсудим в следующем разделе.
Строки с 12 по 14 определяют вывод биткоинов из сделки. В частности, строка 13 говорит нам значение вывода: 0,319 биткоинов. Строка 14 является достаточно сложным процессом. Важно отметить, что значение a7db6f … является Биткоин-адресом предполагаемого получателя средств (написанный в шестнадцатеричном формате). На самом деле, строка14 ни что иное как отображение языка сценариев Биткоин. Я не собираюсь описывать этот язык программирования в деталях в этой заметке, главное для нас понять, что a7db6f … является лишь Биткоин-адресом.
Между прочим, теперь видно, как биткоин взывает к проблеме, что я «припрятал в рукаве» в прошлой главе: откуда берутся серийные номера Биткоин? На самом деле, роль серийного номера играет хеш-сумма транзакций. В приведенной выше транзакции, например, получатель получает 0,319 биткоинов, которые приходят из первого вывода предшествующей операции с хэш-суммой 2007ae … (строка 9). Если вы идете и смотрите в цепочку блока для этой транзакции, вы увидите, что его вывод поступает из еще более ранней сделки. И так далее.
Есть две умные вещи в том, чтобы использовать хэш-суммы транзакций вместо серийных номеров. Во-первых, в Биткоин совсем нет действительно никаких отдельных, постоянных (виртуальных) «монет». Имеет место просто длинная серия сделок в цепочке блоков. Это умная идея, чтобы понять, что вам не нужны монеты, и можно просто обойтись книгой сделок. Во-вторых, при работе таким образом мы убираем необходимость любого центрального органа, который выдает серийные номера. Вместо этого, серийные номера могут быть генерированы автоматически, лишь путем хеширования сделки.
На самом деле, можно продолжать следовать по цепочке сделок дальше в прошлое. В конечном счете, этот процесс должен завершиться. Это может произойти двумя способами. Первая возможность возникнет, когда вы придёте к самой первой транзакции Биткоин, содержащейся в так называемом Начальном блоке (Genesis block). Это особая транзакция, не имеющая вводов, а только вывод в 50 биткоинов. Другими словами, эта сделка устанавливает первоначальную денежную массу. Начальный блок обращается отдельно клиентами (программами) сети Биткоин. И я не буду вдаваться в подробности сейчас, хотя это очень похоже на сделку, описанную выше. Вы можете увидеть преобразованные из последовательной формы в параллельную исходные данные здесь.
Вторая возможность будет, когда вы последуете по цепочке сделок назад во времени, то в конечном итоге вы прибудете к так называемой базовой транзакции (coinbase transaction). За исключением Начального блока, каждый блок операций в цепочке блоков начинается со специальной базовой транзакции. Это сделка — награждение майнера, который проверит этот блок операций. Он использует аналогичный, но не идентичный формат транзакции, представленной выше. Я не буду вдаваться в детали по формату, и если вы хотите увидеть пример, см. здесь. Вы можете прочитать немного больше о базовых сделках здесь. Кое в чем я не был точным из представленного выше, а именно в том, что конкретно подписывается цифровой подписью в строке 11. Очевидно, что плательщик должен подписать всю транзакцию (кроме хэш транзакции, которая генерируется позже). В настоящее время, это не так — некоторые части транзакции опущены. Это делает некоторые части сделки изменяемыми, т. е. они могут быть изменены позже. Однако, эта пластичность не включаются в сумму к выплате, отправителей и получателей, которые не могут быть изменены позже. Я должен признать, я не влезал в детали. Как я понимаю, эта пластичность находится в стадии обсуждения в сообществе разработчиков Биткоин, и предпринимаются усилия в направлении сокращения или ликвидации этой пластичности.
Операции с несколькими входами и выходами
В последнем разделе я описал, как сделка с одним вводом и одним выводом работает. На практике, часто очень удобно создать Биткоин транзакцию с несколькими вводами или несколькими выводами. Я поговорю позже о том, почему это может быть полезно. Но сначала давайте взглянем на данные фактической сделки:
- .
- «ver»:1,
- «vin_sz»:3,
- «vout_sz»:2,
- «lock_time»:0,
- «size»:552,
- «in»:[
- «hash»:«3beabc…»,
- «n»:0>,
- «scriptSig»:«304402… 04c7d2…»>,
- «hash»:«fdae9b…»,
- «n»:0>,
- «scriptSig»:«304502… 026e15…»>,
- «hash»:«20c86b…»,
- «n»:1>,
- «scriptSig»:«304402… 038a52…»>],
- «out»:[
- «scriptPubKey»:«OP_DUP OP_HASH160 e8c306… OP_EQUALVERIFY OP_CHECKSIG»>,
- «scriptPubKey»:«OP_DUP OP_HASH160 d644e3… OP_EQUALVERIFY OP_CHECKSIG»>]>
Давайте пройдемся строка за строкой. Это очень похоже на транзакцию с одним вводом и одним выводом, так что я буду делать это довольно быстро.
Строка 1 содержит хэш остальной части транзакции. Это используется в качестве идентификатора транзакции.
Строка 2 говорит нам, что это сделка версии 1 протокола Биткоин.
Строки 3 и 4 говорят нам, что сделка имеет три ввода и два вывода, соответственно.
Строка 5 содержит lock_time. Как и в случае с одним вводом и одним выводом значение равно 0, что означает, что транзакция немедленно завершена.
Строка 6 говорит нам размер сделки в байтах.
Строки с 7 по 19 определяют список вводов к сделке. Каждый соответствует выводу из предыдущей сделки Биткоин.
Первый ввод определяется в строках с 8 до 11.
В частности, строки с 8 по 10 говорят нам, что ввод должен быть взят от n = 0-го вывода из сделки с значением хэша 3beabc …. Строка 11 содержит подпись, затем пробел, а затем открытый ключ отправителя биткоин.
Строки 12 по 15 определяют второй ввод в формате подобно строкам с 8 по 11. И строки с 16 по 19 определяют третий ввод.
Строки с 20 по 24 определяют список, содержащий два вывода из сделки.
Первый вывод определяется в строках 21 и 22. Строка 21 говорит нам значение вывода в 0,01068000 биткоинов. Как и прежде, строка 22 является выражением скриптового языка Биткоин. Главное, на что стоит тут обратить внимание, строка e8c30622 … является Биткоин адресом предполагаемого получателя средств.
Второй вывод определяется в строках 23 и 24 в форме подобно первому выводу.
Одна очевидная странность в этом описании в том, что хотя каждый вывод имеет указание суммы в биткоин, связанной с ним, в вводах такого нет. Конечно, значения соответствующих вводов можно найти, обратившись к соответствующим выводам в предыдущих сделках. В стандартной операции Биткоин, сумма всех вводов в транзакции должна быть по крайней мере столько, сколько сумма всех выводов. (Единственное исключение из этого принципа являются Начальный блок и базовые сделки (coinbase), оба формируют новое предложение в сети Биткоин.) Если вводов насчитается больше чем выводов, то избыток используется как плата за транзакцию. Это платится майнеру за успешно проверенный блок, в который включена текущая транзакция.
Вот и все о транзакциях с многочисленными вводами и выводами! Они довольно простая вариация транзакций с одним вводом и одним выводом.
Одно хорошее применение таких транзакций является идея сдачи. Предположим, например, что я хочу послать вам 0,15 биткоинов. Я могу сделать это, отправив вам деньги из предыдущей сделки, в которой я получил 0,2 биткоинов. Конечно, я не хочу отправить вам все 0,2 биткоинов. Решение будет отправить вам 0,15 биткоинов, и направить 0,05 биткоинов на свой Биткоин-адрес, который принадлежит мне. Эти 0,05 биткоинов являются сдачей. Это несколько отличается от процесса получения сдачи в магазине, так как сдача в данном случае есть плата самому себе. Но общая идея схожа.
Вывод
На этом завершаю базовое описание основных идей, лежащих в технологии Биткоин. Конечно, я опустил много деталей – мы ведь не техническое описание делали. Но я описал основные идеи к наиболее распространенным случаям использования Биткоин.
Хотя правила Биткоин просты и легки для понимания, это не значит, что легко понять все последствия этих правил. Можно гораздо больше сказать о Биткоин, и я буду исследовать некоторые из этих вопросов в будущем.
Я завершу свой пост обращением к нескольким спорным моментам.
Насколько анонимен Биткоин? Многие люди утверждают, что Биткоин можно использовать анонимно. Это утверждение привело к образованию рынков, таких как Шелковый путь (Silk Road) и различных преемников, которые специализируются на нелегальных товарах. Между тем, утверждение что Биткоин анонимен является мифом. Цепочка блоков публична и открыта, что означает возможность для каждого увидеть любую транзакцию Биткоин когда-либо. Хотя Биткоин-адреса не сразу ассоциируется с реальных людьми, ученые-компьютерщики сделали большую работу, выясняя, как осуществлять де-анонимизацию «анонимных» социальных сетей. Цепочка блоков является идеальной целью для этих методов. Я буду очень удивлен, если подавляющее большинство пользователей Биткоин не будут опознаны с относительно высокой степенью уверенности и легкости в ближайшем будущем. Эта уверенность не будет достаточно высокой для достижения признания виновности, но будет достаточно высокой, чтобы определить вероятные цели. Кроме того, идентификация будет ретроспективной, это означает, что тот, кто купил наркотики на рынке Шелковый путь в 2011 году по-прежнему будет возможен для идентификации на основе цепочки блока, скажем, в 2020 году. Эти методы де-анонимизации хорошо известны ученым, и, предположительно, Агентству Национальной Безопасности (США). Я бы не удивился, если АНБ и другие учреждения уже распознали многих пользователей. Парадоксально, что Биткоин часто преподносится как анонимный. Это не так. Наоборот, Биткоин, возможно, наиболее открытый и прозрачный финансовый инструмент, какого мир еще не видел.
Можете ли вы разбогатеть с Биткоин? Ну, может быть. Тим О’Рейли однажды сказал: «Деньги, как бензин в машине — нужно обращать внимание или вы, в конечном итоге, окажитесь на обочине дороги; но хорошо прожитая жизнь не экскурсия по АЗС! » Много интереса к Биткоин исходит от людей, чья жизненная позиция направлена на то чтобы найти действительно большую бензоколонку. Я должен признать, я нахожу это озадачивающим. На мой взгляд, гораздо более интересно и приятно думать о Биткоин и других криптовалютах, как о пути новых форм коллективного поведения. Это интеллектуально увлекательно, предлагает чудесные возможности для творчества, является социально ценным, и можно также положить деньги в банк. Но если деньги в банке является вашей главной задачей, то я считаю, что другие стратегии имеют гораздо больше шансов на успех.
Детали я опустил: хотя этот пост описал основные идеи, лежащие в Биткоин, есть много деталей, которые я не упомянул. Вот, например, особенность по сохранению размера, что используется протоколом, основанная на модели структурирования данных, известной как дерево Меркле (Merkle Tree). Это деталь, но великолепная деталь, и стоит узнать больше, если структуры данных — ваша фишка. Вы можете загрузить и изучить оригинальные страницы Биткоин. Во-вторых, я уже говорил немного о сети Биткоин — вопросы типа как сеть имеет дело с атаками в отказе обслуживания (denial of service attack), как узлы присоединяются и покидают сеть, и так далее. Это увлекательная тема, но это также требует много деталей, так что я опустил это. Вы можете узнать больше об этом на некоторых из приведенных выше ссылках.
Скриптовый язык Биткоин: В этой статье я объяснил Биткоин как форму цифровых онлайн денег. Но это только малая часть гораздо большей и более интересной истории. Как мы уже видели, каждая Биткоин транзакция связана со сценарием (script) на языке программирования Биткоин. Сценарии, которые мы видели в этом материале описывают простые операции, как «Алиса дала Бобу 10 биткойнов». Но язык сценариев также можно использовать, чтобы выразить гораздо более сложные транзакции. Иными словами, Биткоин – это программируемые деньги. В более поздних публикациях я поясню систему сценариев, и как можно использовать Биткоин сценарии в качестве платформы для экспериментов со всеми видами удивительных финансовых инструментов.
Перевод: Андрей Дубецкий, Игорь Корсаков
Обзор актуальных протоколов достижения консенсуса в децентрализованной среде
Эта статья посвящена поверхностному обзору ключевых подходов к достижению консенсуса в децентрализованной среде. Материал позволит разобраться с задачами, которые решают рассмотренные протоколы, областью их применения, особенностями проектирования и использования, а также позволит оценить перспективы их развития и имплементации в децентрализованных системах учета.
Отметим, что в децентрализованной сети применяется принцип избыточности, который основан на том, что узлы могут делать одну и ту же работу. Для централизованной сети это, естественно, неэффективно, а для децентрализованной это является обязательным условием. Перейдем к базовым требованиям.
Требования к протоколам достижения консенсуса
Протоколы должны обеспечивать надежную работу пользователей в достаточно суровых условиях и при этом удовлетворить минимальным требованиям. Ниже перечислены основные.
Отсутствие центральной доверенной стороны. Сеть состоит из равноправных узлов. Если злоумышленник или третья сторона попытаются вывести из строя определенное количество узлов, то сеть продолжит нормально работать до тех пор, пока честные участники будут контролировать подавляющее большинство узлов сети.
Честные участники не знают, какие узлы контролируются злоумышленниками. Предполагается, что другие узлы могут в произвольные моменты времени выходить из строя или функционировать произвольным образом, в том числе координироваться злоумышленниками для проведения атаки на сеть. Опять же, честные участники не знают, какие из узлов честные, а какие сбойные, или ненадежные.
Предполагается, что сеть заведомо ненадежная. Некоторые сообщения могут быть доставлены с серьезной задержкой, а другие могут быть потеряны в сети и остаться вовсе недоставленными. Именно в таких условиях децентрализованный консенсус должен продолжать нормально функционировать: все честные узлы должны приходить к одному и тому же состоянию базы данных подтвержденных транзакций.
Протоколы должны быть полностью формальными. Никакого дополнительного участия человека быть не должно и никаких дополнительных данных не требуется. Все честные узлы должны приходить к одному и тому же решению, полностью следуя алгоритму, который выполняется компьютером.
Кроме того, существуют определенные допущения, при которых протокол гарантирует корректную работу. Честные узлы должны составлять большую часть всех участников: более ½ или ⅔ от общего их количества. Однако время принятия решения не ограничено. Ограничение может касаться количества шагов для принятия решения, но не времени.
Области применения протоколов достижения консенсуса
Цифровые валюты
В первую очередь это применимо к криптовалютам: в Bitcoin применяется алгоритм Nakamoto, в Ethereum применяется упрощенный вариант GHOST, в Bitshares реализован Delegated PoS и т. д.
Нужно отметить, что сообщество, которое поддерживает определенную цифровую валюту не всегда бывает многочисленным и децентрализованным. Существует ряд других цифровых валют, которые являются централизованными. Однако это не значит, что механизм достижения консенсуса не понадобится. Например, Ripple использует BFT-протокол в централизованной среде.
Высоконадежные и критические системы
Протоколы достижения консенсуса используются в высоконадежных вычислительных системах. Они могут использоваться для доступа к распределенным базам данных при построении кластеров, а также обязательно используются в критических технических системах: это могут быть системы управления авиационным оборудованием, системы управления ядерными реакторами, а также в космических технологиях.
В 2018 году, 6 февраля, произошел запуск Falcon Heavy. Было интересно наблюдать за ним и читать технические обзоры. Но не менее интересно было читать о том, какие алгоритмы достижения согласия использует команда. Инженеры вынуждены были использовать простую электронику, которая продается в обычных магазинах и не совсем надежно работает в сложных космических условиях. Поэтому они применяют многократную избыточность в своей работе и достижение консенсуса в данном случае необходимо.
Криптовалюты
Криптовалюты работают в peer-to-peer сетях. При этом сообщения или транзакции передаются между участниками сети в произвольные моменты времени. Предположим, что в сети есть участники, находящиеся в США, и участники, находящиеся в Австралии. Платежи, которые отправлены из США, участники из Америки увидят раньше, чем платежи, отправленные из Австралии. Это происходит из-за наличия серьезной, по компьютерным меркам, задержки при доставке сообщения с одного континента на другой. Аналогичной будет ситуация и для австралийцев, потому что они будут видеть платежи из Австралии раньше, чем платежи из США.
Описанная выше ситуация значит, что разные участники сети увидят в один момент времени увидят разное итоговое состояние базы данных с транзакциями. Поскольку транзакции приходят от пользователей к валидаторам в разное время, нужен протокол, который позволит каждому узлу вне зависимости от его места нахождения получить все транзакции в одном и том же порядке.
В основном для работы учетных систем криптовалют используется два подхода: PoW, который является наиболее распространенным, и PoS, который активно развивается в последнее время.
В PoW выполняется дополнительный объем работы, который сейчас заключается в поиске прообраза хеш-функции. Фактически здесь происходит искусственное замедление сети для обеспечения безопасности. Чтобы осуществить злонамеренное действие, злоумышленнику придется выполнить необходимый объем работы. Это требует колоссальных затрат энергии и делает реализацию атак не очень эффективной. За счет такого подхода обеспечивается надежность в работе сети. Однако необходимость выполнять настолько требовательную к ресурсам задачу ограничивает пропускную способность сети, которая работает по данному протоколу. Но над подходом PoW ученые продолжают трудиться и предлагать альтернативные схемы, а также другие ресурсоемкие задачи, помимо поиска прообраза хеш-функции. Недавно был предложен алгоритм на базе proof-of-space-and-time.
PoS позволяет обеспечить более высокую пропускную способность сети и не требует избыточных затрат электроэнергии, как PoW. Однако PoS требует более серьезного анализа при разработке и реализации криптовалюты.
В учетных системах на базе PoS предполагается, что пользователям, которые владеют большим количеством монет, невыгодно делать атаки. Если в учетных системах на базе PoW системе предприниматель вкладывает деньги в оборудование и оплачивает электроэнергию, а потом совершает успешную атаку на систему, то он будет терять свои инвестиции в майнинг. В PoS применяется другой подход: если предполагается, что злоумышленник инвестировал в конкретные монеты, в ценности которых он заинтересован, то в случае успешной атаки на систему он потеряет свои вложения, поскольку произойдет обесценивание монет. Поэтому наиболее выгодной стратегией принято считать честное следование протоколу.
Краткий глоссарий
Safety – способность учетной системы сохранять основные принципы функционирования и интересы честных участников при любых злоумышленных воздействиях.
Finality – свойство, которое указывает на неотменяемость принятого решения или подтвержденных данных.
Liveness – свойство, которое гарантирует, что если все честные участники хотят добавить запись в общую базу данных, то в итоге она будет туда добавлена.
Persistence – способность учетной системы сохранять неизменность конечного состояния своей базы данных даже после того, как все ее валидаторы отказали.
Permissioned – указывает на ограничение, то есть необходимость получить разрешение на участие в некотором процессе.
Permissionless – означает свободный доступ к принятию участия в некотором процессе.
Протокол достижения консенсуса Ouroboros
Ouroboros – это протокол на базе PoS, который обеспечивает достижение консенсуса между валидаторами транзакций цифровой валюты Cardano. Причем сам алгоритм является первым доказуемо стойким среди всех PoS-альтернатив.

Сначала рассмотрим более простой вариант, ориентированный на static stake, когда предполагается, что существующее распределение монет не меняется.
Есть некоторый genesis block и пользователи формируют новые транзакции, но они не влияют существенным образом на распределение.
Genesis block содержит в себе данные с некоторым случайным значением, с помощью которого происходит выбор валидаторов. Они позволяют выпускать блок в определенный момент времени. Валидатор, получивший такое право, собирает транзакции, получая их от другого валидатора, проверяет корректность и выпускает блок в сеть. Если он видит несколько цепочек, то он выбирает самую длинную из них и присоединяет блок к ней.
В контексте ситуации, связанной со static stake, мы можем использовать такой подход на протяжении определенного периода времени, но потом распределение доли (stake distribution) между различными пользователями может поменяться. Иначе говоря, часть денег переходит от одних пользователей к другим, и нужно скорректировать вероятность получения права выбора блока.
Примечание: static stake подразумевает, что некоторый промежуток времени stake валидатора считается неизменным. Валидатор может в это время участвовать в принятии решения и совершать платежи, но количество монет в его stake, а следовательно, и вес его голоса останутся неизменными до следующего периода времени.
В случае dynamic stake время делится на слоты, а слоты делятся на эпохи. Продолжительность одной эпохи приблизительно приравнивается к продолжительности одного дня. Это соотношение определено из того, что в течение этого промежутка времени распределение монет не может существенно измениться.
По завершении эпохи фиксируется текущее распределение монет у каждого из пользователей. Кроме того, генерируется новое значение случайности, чтобы гарантировать, что в следующей эпохе пользователи, получающие право генерировать блоки, будут действительно выбраны случайным образом в соответствии с количеством имеющихся у них монет.
Подобным образом происходит защита от так называемых grinding-атак, когда конкретный пользователь может перебрать различные варианты блоков, различные варианты случайности, чтобы сформировать ту цепочку, в которой он может максимизировать свою прибыль. К таким атакам потенциально уязвимы криптовалюты, основанные на PoS-протоколах первого поколения, таких как Peercoin и NXT.
Создатели данного алгоритма решили вышеперечисленные проблемы. Валидаторы запускают между собой специальный протокол, который называется MPC (multi-party computation) и дает возможность сгенерировать случайность совместно. Этот протокол также является доказуемо стойким, он основан на уже давно известных подходах.
Протокол Ouroboros обеспечивает стойкость при условии большинства честных валидаторов в системе. Если честные участники, которые работают над выпуском блоков, контролируют больше 50% монет в системе, протокол можно считать защищенным.
Разработан механизм стимулов (мотивации) к честному поведению. С помощью теории игр доказано, что максимальную выгоду валидатор получает, когда следует правилам протокола. Любое участие в совершении атак не только не увеличивает прибыль участника, но в ряде случаев может и уменьшить ее. Поэтому наиболее выгодная стратегия для валидатора – это честно следовать правилам протокола.
Пропускная способность учетной системы будет ограничена только задержками при синхронизации сети. Данный протокол обеспечивает высокую энергоэффективность по сравнению с proof-of-work, поскольку здесь не нужны майнинговые фермы. Сейчас для сбора транзакций и выпуска блоков достаточно обычного персонального компьютера. В перспективе эти вычисления можно будет осуществлять даже на обычном смартфоне.
К ограничениям протокола Ouroboros можно отнести тот факт, что первая версия протокола является синхронной. Это значит, что сообщения между участниками должны доставляться в ограниченный промежуток времени. Если в сети будут появляться более длительные задержки, чем заложены в правилах, это может снизить безопасность. Тем не менее уже запланировано использование следующей версии протокола – Ouroboros Praos. В ней даже при увеличении задержек в сети гарантируется полная безопасность.
Проблемы с PoW в Биткоине
Рассмотрим способ достижения консенсуса, который лежит в основе Bitcoin. Часть блоков, которые генерируются честными пользователями все равно отбрасывается – это так называемые orphan blocks. Эти блоки сгенерированы параллельно с основной цепочкой, но большая часть сети решила, что эту цепочку не стоит продолжать, и блоки отбрасываются.
Когда таких блоков мало, в этом нет ничего страшного. Однако если их много, сеть не успевает синхронизироваться и получается, что часть вычислительных мощностей честных пользователей сети теряется впустую. Это значит, что теперь злоумышленнику необходимо бороться не за 51% вычислительной мощности сети, а фактически за меньший процент. Если это значение 20%, то злоумышленник с 20% вычислительной мощности и большой задержкой доставки сообщений сети может реализовать double-spending атаку.
Поэтому в Биткоине установлен промежуток времени между добытыми блоками длительностью 10 минут. Благодаря этому сеть успевает четко синхронизироваться и вероятность появления таких блоков снижается. Если потребуется увеличить пропускную способность сети через увеличение частоты формирования блоков, то понадобится другое решение.
GHOST

Первым таким решением был PoW-протокол GHOST. Его упрощенная версия используется в платформе Ethereum.
В этом случае злоумышленник может тянуть свою цепочку (обозначенную на рисунке красным цветом) и сделать ее самой длинной, но она не будет выигрышной. Честные пользователи будут следовать той цепочке, которую они строили до этого.
У честных пользователей в этом случае может быть две цепочки. Самая длинная (1B-2D-3F-4C-5B), но она будет короче, чем цепочка злоумышленника. Особенность GHOST в том, что алгоритм ориентируется не на самую длинную цепочку, а на количество блоков в дереве, образуемом текущей цепочкой. Учитывается не только длина самой цепочки, но и блоки на разных ее высотах. Таким образом, получается не линейная цепочка, а дерево. Учитывается количество блоков, которое в нем находится.
Если посмотреть на цепочку 1B-2C-3D-4B, то видны сопровождающие блоки 3E и 3C. По количеству блоков и затраченной работы эта цепочка обладает наибольшей сложностью и именно она будет принята за основную. Честные пользователи продолжат считать ее основной, несмотря на попытки злоумышленника атаковать сеть. В традиционном консенсусе Nakamoto такая атака была бы успешной, но для GHOST она не представляет угрозы.
Тем не менее недостатком GHOST остается тот факт, что часть блоков по-прежнему теряется. В данном случае цепочка 2D-3F-4C-5B все равно будет отброшена. Следовательно, вопрос отбрасывания блоков честных пользователей остается открытым.
SPECTRE и PHANTOM

C целью увеличения частоты формирования блоков и решения проблемы с отбрасыванием блоков честных пользователей было предложено еще два PoW-протокола: SPECTRE и PHANTOM.
Они используют уже даже не древовидную структуру, а так называемый направленный ациклический граф (directed acyclic graph, DAG). В этом случае валидатор включает в заголовок своего блока указатели на блоки, на которые еще не ссылаются другие валидаторы, по крайней мере в том состоянии сети, которое он видит на текущий момент времени, и отправляет блок дальше.
Поэтому получается такая структура, в которую включаются вообще все блоки, которые видят валидаторы на текущий момент времени. Здесь майнинговые мощности честных пользователей вообще не теряются. Более того, обеспечивается высокая пропускная способность сети и высокий уровень безопасности. Преимуществом такого подхода является тот факт, что система по-настоящему децентрализована.
Давайте сравним особенности сети Биткоин и сети, которая работает с помощью протоколов SPECTRE и PHANTOM. Если говорить о текущем положении в сети Биткоин, то большое значение стоит придавать майнинговым пулам. В современном Биткоине за сутки выходит 144 блока. Именно такая цифра получается, если количество минут в сутках поделить на 10. Вполне реальной может быть ситуация, когда валидатор купил оборудование, долгое время оплачивал электроэнергию, но сгенерировать блок у него так и не получилось, а за это время оборудование устарело и использовать его больше нет смысла. Чтобы избежать этой ситуации предприимчивые валидаторы объединяются в майнинговые пулы. В большинстве майнинговых пулов есть ведущий (компания/организация), что склоняет современный Биткоин к централизации процесса валидации новых транзакций.
В случае со SPECTRE и PHANTOM майнинговые пулы вообще не нужны. Если мы проведем параллель с современной сетью Биткоина, то каждый пользователь сети, которая использует протоколы SPECTRE и PHANTOM, имеет шанс выпустить один блок в сутки. Таким образом, в майнинговых пулах потребность вообще отпадает и мы приходим к действительно децентрализованной сети.
Итак, протоколы SPECTRE и PHANTOM обеспечивают высокий уровень децентрализации и высокую пропускную способность сети, но требуется хранить большой объем информации.
BFT-протоколы

Следующий тип протоколов, которые применяются – это BFT-протоколы (Byzantine Fault Tolerance).
Название имеет происхождение из шуточного описания проблемы, которое было сделано в 80-х годах XX столетия при разработке протокола для высоконадежных систем. Был приведен пример про византийских генералов, которые организовывают атаку на какой-то город. Задача генералов заключалась в том, чтобы прийти к единому решению. Но нужно было учесть, что среди них есть несколько предателей. Предатели могли вести себя произвольным образом и, более того, они могли влиять на передачу сообщений между честными генералами, для которых важно или одновременно атаковать город, или одновременно отступить. Если какой-то из честных генералов отступит, то противник победит армию по частям. Поэтому им необходимо было прийти к согласованному решению. Постановка задачи таким образом была сделана в работе, откуда и пошло такое название алгоритма достижения консенсуса.
Для BFT-протоколов предполагается взаимодействие равноправных узлов сети. Предполагается, что есть определенное количество злоумышленников, которые могут действовать скоординированно. Они неизвестны честным участникам. В сети возможны сбои и задержки, то есть часть сообщений может пропадать, а часть может приходить с большой задержкой. Однако накладывается ограничение на количество шагов, в течение которого все честные валидаторы должны прийти к общему решению. В примере задачи есть два варианта: атаковать или отступить.
Допускается, что честные узлы составляют более ⅔ участников. BFT-протоколы гарантированно приходят к общему решению, которое в будущем не может быть отменено. Для не BFT-протоколов вероятность отмены решения является экспоненциально убывающей, но не нулевой.
В основе Биткоина и других современных широко распространенных криптовалют лежат не BFT-протоколы. Для Биткоина есть ненулевая вероятность, которая ничтожно мала, что есть альтернативная цепочка, тянущаяся, например, еще с предыдущего месяца, года или даже с Genesis блока. Вероятность отмены текущей цепочки экспоненциально убывающая, но она существует. В случае BFT-протокола принятое решение не может быть отменено.
Примеры BFT-протоколов
Practical BFT
Первый протокол, который был применен на практике, назывался Practical BFT. Он был предложен в 1999 году. У него достаточно простое функционирование. Клиент обращается к серверу, которого выбирает лидером. Лидер передает эти сообщения другим серверам. После этого сервера сообщают друг другу о том, что пришли определенные сообщения и их необходимо внести в совместную базу данных. Каждый из валидаторов должен подтвердить, что он получил подтверждение от ⅔ других участников.

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

HoneyBadger BFT хорошо зарекомендовал себя и был разработан как усовершенствованная версия одного из существующих алгоритмов. Он использует ряд особенностей, в том числе криптографическую защиту всех сообщений, которые передаются по сети. Транзакции дешифруются только после достижения определенного соглашения по ним. HoneyBadger состоит из двух протоколов: RBC (Reliable broadcast) и BA (Byzantine Agreement).
С помощью RBC-протокола сообщения доставляются по сети. Этот протокол завершает свою работу только после того, как получит подтверждение, что как минимум ⅔ честных валидаторов получили необходимый набор сообщений. После этого валидаторы переходят к BA-протоколу и согласованию самих транзакций, которые далее направляются в сеть.
Данный протокол обеспечивает надежную криптографическую защиту. Он хорошо работает в сетях с плохим качеством передачи данных, где есть пропуски передаваемых сообщений и задержки в их доставке, а также в сетях с серьезным злонамеренным вмешательством в работу. Здесь нет лидера. Протокол страдает при попытках значительного масштабирования: при сотнях узлов-валидаторов он еще работает нормально, но при нескольких тысячах уже оказывает слишком большую нагрузку на сеть и время подтверждения транзакций сильно увеличивается. В условиях полностью децентрализованной сети учетной системы, где работают тысячи валидаторов, протокол становится малоэффективным.
Результатом дальнейшего развития стали протоколы Algorand и Hashgraph.
Algorand

Протокол Algorand был предложен в 2017 году. Он использует тот же BFT-подход, но ориентирован он на то, что среди всех участников случайным образом выбирается некоторый подкомитет, который выполняет подтверждение транзакций. Причем это подтверждение происходит в несколько этапов, на каждом из которых выбирается свой подкомитет.
Протокол гарантирует с высокой вероятностью, близкой к единице, что подкомитет является честным, если более ⅔ участников сети являются честными, то есть каждый из подкомитетов также будет иметь ⅔ честных участника. Здесь нет лидера, поэтому и нет точки для атаки типа «отказ в обслуживании» (DoS-атаки). Этот протокол обеспечивает высокую пропускную способность учетной системы, быстрое подтверждение транзакций, а также защиту от adaptive corruption.
Предполагается, что злоумышленник может выбрать произвольного валидатора и заявить, что именно он работает в его интересах. Злоумышленник может выбирать те узлы, которые будут работать на него (обязательным для корректной работы является условие, что честных участников остается больше ⅔). И даже в таких условиях протокол обеспечивает стойкость.
Поскольку это BFT-протокол, то в любом случае он обеспечивает свойства safety и persistence. А остальные его свойства будут зависеть от задержек в передаче данных по каналам связи.
Если данный протокол работает в проблемной сети, то существует угроза liveness, связанная с тем, что новые транзакции могут не получать подтверждения. Если в сети появляются слишком большие задержки или злоумышленник получает возможность выбрасывать те сообщения, которые ему нужно выбросить для достижение цели, то это никак не скажется на старых (уже подтвержденных) транзакциях. Их он отменить не сможет. Суть в том, что он сможет отклонять именно принятие новых транзакций.
Hashgraph

Протокол Hashgraph является свежим решением с очень хорошими свойствами. Каждый из валидаторов собирает свои транзакции, выбирает произвольным образом другого участника и направляет ему данные о своих транзакциях, а также информацию, которую сообщили ему другие узлы, когда подключались к нему.
Итак, функционирование очень простое: валидатор «слушает», принимает все сообщения, которые приходят к нему, а после этого произвольным образом выбирает другого участника и отправляет ему все транзакции вместе со своими.
Hashgraph гарантирует, что за конечное число шагов, то есть раундов работы протокола, все узлы приходят к единому решению. Протокол работает быстро и хорошо масштабируется. Он требует большего объема трафика, чем Algorand, но в то же время является очень эффективным. Hashgraph обеспечивает свойства safety и liveness, то есть добавление новых транзакций и приход к единому решению. Он работает даже в условиях полностью асинхронной сети, когда сообщения могут быть задержаны на очень большой промежуток времени или вообще выброшены.
Кроме того, в сети отсутствует лидер, что позволяет злоумышленнику выводить из строя те узлы, которые ему окажутся интересными, может заставлять их работать сообразно своим намерениям. Однако пока сохраняется ⅔ честных пользователей, протокол обеспечивает высокий уровень безопасности.
Итоги по BFT
Подведем итоги по BFT-протоколам. Они обеспечивают очень высокую пропускную способность и позволяют валидаторам приходить к согласию по поводу состояния транзакций в течение фиксированного количества шагов. Данные свойства позволяют им успешно применяться в криптовалютах. Протокол обеспечивает надежную работу даже в ненадежных сетях при условии, что более ⅔ валидаторов учетной системы являются честными. Такие протоколы, как Algorand и Hashgraph, поддерживают высокую пропускную способность и в них может работать действительно большое количество валидаторов.
В то же время у них есть очень серьезный недостаток: в текущем состоянии развития протоколы разработаны для так называемых permissioned учетных систем. Иначе говоря, они разработаны без учета стимула для валидаторов честно работать в самой сети. Предполагается, что такие стимулы находятся за пределами работы данного протокола. Не рассматриваются награды за формирование блока, различные стратегии поведения пользователей.
Чтобы развернуть такие протоколы для работы в permissionless учетных системах, исследователям понадобится провести серьезную работу. В этом отношении у них остается широкая область для исследований с точки зрения теории игр и с точки зрения разработки системы вознаграждения для валидаторов и т. д.
Distributed Lab подготовила данную статью, опираясь на материал видеолекции Романа Олейникова.
Часто задаваемые вопросы
– Возможно ли в ближайшее время внедрение кардинально нового протокола консенсуса и есть ли разработки?
Сейчас, действительно, активно ведутся разработки протоколов консенсуса. Некоторые из них мы сегодня обсуждали: Algorand и Hashgraph из BFT-протоколов, а также протокол на основе PoS-консенсуса Ouroboros. В начале 2018 года был представлен протокол PHANTOM. Это новые протоколы с новыми принципами.
– Чем в Ouroboros обеспечивается, что список узлов, имеющих право формировать блок в определенные временные интервалы, одинаковый для всех узлов?
Вопрос связан с grinding-атаками, которые упоминались выше. Ouroboros обеспечивает свойства persistence и liveness: если транзакция попала в определенный момент времени и получила подтверждение, то она уже не может быть отменена или удалена, так как вероятность замены этого блока стремится к нулю. Иначе говоря, разработчики полагают, что транзакция не может пропасть из совместной базы данных, поскольку она доступна любому желающему.
За счет свойства persistence все узлы сети формируют одинаковый набор транзакций в своей локальной копии базы данных. Потенциальные валидаторы отправляют транзакции со своей случайностью, которая поначалу скрыта, а в момент завершения протокола MPC все могут рассчитать результирующую случайность. У всех пользователей есть согласованная история транзакций, благодаря чему все узлы получают одинаковый список фактических валидаторов. Манипулировать случайностью здесь невозможно, потому что протокол MPC обеспечивает свойства, связанные с тем, что ни один из участников не может получить эту случайность до того момента, пока все не внесли ее в блокчейн. Только после этого случайность вскрывается. Даже если кто-то не хочет вскрывать свою случайность, сам протокол гарантирует, что эти данные будут вскрыты. У всех одинаковое видение истории и случайности. Даже если хотя бы один потенциальный валидатор «пробросил» действительно случайное значение в блокчейн (достаточно одного), результирующая случайность будет непредсказуема.
– В какой книге можно почитать про алгоритмы достижения консенсуса, рассмотренные в этой главе?
К сожалению, пока еще таких книг нет. Есть только отдельные научные работы и статьи. Можно посмотреть статьи по PHANTOM, SPECTRE и Ouroboros. Можно посмотреть сайт, на котором эти статьи можно найти по названию.
– Зачем так много блоков выпускать в PHANTOM и SPECTRE, если нет такого большого количества транзакций? Большинство блоков будут пустыми или содержать мало транзакций.
PHANTOM и SPECTRE ориентируются именно на масштабирование. Для Биткоина уже не раз возникали ситуации, когда транзакции с низкой комиссией могли находиться в сети неподтвержденными даже несколько месяцев. PHANTOM и SPECTRE гарантируют, что все транзакции будут включены в блоки и пропускная способность сети будет увеличена. Эти протоколы могут обеспечить десятки тысяч транзакций в секунду, при этом каждая получит подтверждение. Иначе говоря, они могут обеспечить очень низкую стоимость транзакций в самой сети. Если транзакций нет, то можно, действительно, выпускать пустые блоки.
– Как и кем в BFT выбирается сервер-лидер?
Это зависит от конкретного протокола. Если мы говорим о PBFT, то в этом случае конкретный пользователь выбирает себе сервер-лидер, который будет вести его транзакцию. Если мы говорим про Algorand или Hashgraph, там лидера вообще нет.
– Что будет если в PBFT изначальный запрос придет к скомпрометированному узлу?
В этом случае скомпрометированный (или неработающий) узел его может не обработать. Если пользователь случайным образом выбирает узел, к которому он обращается, и мы имеем две трети честных узлов, то в этом случае с высокой вероятностью через несколько попыток его транзакция получит подтверждение.
– Правильно ли утверждать, что Algorand – это нечто вроде DPoS (Delegated Proof-of-stake)
Нет, это не совсем корректно. Delegated Proof-of-stake подразумевает, что пользователи должны выбрать валидатора и делегировать ему право голоса. Здесь узлы выбираются для подтверждения транзакций действительно случайно. Если посмотреть далеко в будущее и рассматривать варианты построения криптовалюты на Algorand, то дальше действительно необходимо будет разрабатывать варианты делегирования, но для работы самого протокола делегирование не нужно.
– Какие из перечисленных протоколов еще не применяются, но считаются перспективными в будущем?
SPECTRE и PHANTOM – действительно перспективные протоколы. А разработчики SPECTRE работают над тем, чтобы запустить новую цифровую валюту.