Сейчас в децентрализованных сетях используются несколько механизмов консенсуса. Но началось все с Proof-of-Work (от англ. «доказательство работы»). Рассказываем, как он появился, как работает и почему до сих пор используется в качестве одного из базовых алгоритмов.
Изначально Proof-of-Work не задумывался как фундамент для децентрализованной сети. И вообще не имел ничего общего с какими-либо криптовалютами. С помощью него предполагалось решать проблему защиты от разного рода «злоупотреблений общим ресурсом». Авторы концепции, разработанной еще в 1993 году, предлагали решение, которое ограничивало бы доступ к чему-то, задав требование выполнить сложные вычисления. При этом результат этих вычислений должен был быть легко и быстро проверяемым.
Первый вариант действующего алгоритма был предложен только спустя пять лет, когда Адам Бэк создал проект Hashcash, главной задачей которого была борьба со спамом. Идея заключалась в том, чтобы с помощью криптографии усложнить массовые рассылки. Для этого перед отправкой каждого письма отправитель должен был выполнить сложные вычисления (найти такое значение x, при котором хеш SHA(x) содержал бы N старших нулевых бит) и включить их результат (доказательство работы) в заголовок письма.
Чтобы письмо дошло до получателя, нужно убедиться, что отправитель решил криптографическую задачу. Это можно сделать очень быстро с помощью однократного вычисления SHA-1 с заранее подготовленной меткой. Такая метка формируется отправителем перед началом решения задачи и становится общедоступной для всех участников системы. В результате отправка пары писем не вызывает никаких затруднений, а вот чтобы сделать массовую рассылку, нужны серьезные вычислительные мощности.
Знакомо, не так ли? Эту концепцию и использовал в 2008 году Сатоси Накамото для создания Bitcoin и блокчейна Proof-of-Work.
Как работает PoW-блокчейн
Суть идеи Накамото (до сих пор так и не ясно, реальный это человек или группа разработчиков) заключалась в создании децентрализованной системы электронной наличности, независимой от третьих сторон. То есть чтобы деньги можно было пересылать напрямую, без посредников в виде банков.
Информация о переводах средств хранится в реестре, распределенном между участниками системы. Для упорядочивания транзакции упаковываются в блоки, размер которых ограничен. Каждый блок должен содержать в себе информацию о предыдущем блоке. Для этого все данные о нем (транзакции, хеш предыдущего блока, временная отметка и т. п.) преобразуются с помощью хеш-функции (в случае Bitcoin это SHA-256) в уникальный код — хеш. За цепочки отвечают специальные «полные узлы» (Full Nodes), а созданием новых блоков занимаются узлы-майнеры.
Тут важно понимать, что хеш-функция работает таким образом, что из одного набора данных всегда будет получаться один и тот же хеш. Даже самое незначительное изменение приведет к тому, что хеш будет другим.
Как мы уже сказали, чтобы добавить новый блок в цепочку, майнер должен вычислить его хеш. Но само по себе это действие не требует много времени. Чтобы задачу нельзя было решить быстро, каждые 2016 блоков (примерно раз в две недели) сеть устанавливает новую сложность вычислений таким образом, чтобы на добычу нового блока уходило примерно десять минут. Это нужно для поддержания стабильной скорости работы блокчейна.
Как это работает на практике: майнер получает «на вход» блок и высчитывает его хеш. Но сеть требует от него, чтобы этот хеш был не меньше определенного значения. Стоп! Выше мы сказали, что хеш невозможно изменить. Так как это работает? Дело в специальном случайном числе nonce (от англ. number used once — число, используемое один раз), которое добавляется к блокам. Майнер при расчетах меняет это число, хеш получается другим. Майнер сравнивает получившийся хеш со значением критерия сложности и если значение хеша больше, меняет nonce еще раз, заново высчитывает хеш, и так далее до тех пор, пока не добьется совпадения (результат должен быть равен или меньше значения сложности). И так миллионы раз.
Чтобы лучше понять масштаб задачи, посмотрите на это число:
115792089237316195423570985008687907853269984665640564039457584007913129639936
Это количество возможных комбинаций в хеше SHA-256. Значение, в 115 миллиардов раз больше количества звезд во вселенной.
Путь транзакции
Разберемся, как это все работает, на примере обычной транзакции. Итак, мы пересылаем кому-то средства в BTC. После того как мы сформировали и подписали транзакцию своим приватным ключом, она отправляется сеть. Полная нода проверяет ее на корректность и если все хорошо, транслирует ее дальше. Другие узлы тоже производят проверку и помещают транзакцию в очередь неподтвержденных транзакций (mempool).
Майнеры собирают транзакции из мемпула (в первую очередь выбирая те, за которые они получат большую комиссию), упаковывают их в блок и начинают выполнять расчеты. Когда один из майнеров решает задачу, полные узлы проверяют решение, и если оно верно, майнер получает вознаграждение, блок считается «добытым», добавляется в блокчейн, а информация о нем рассылается всем участникам сети. После этого майнеры приступают к работе над следующим блоком. При этом чем больше блоков будет включено в блокчейн после блока с нашей транзакцией, тем выше уровень ее подтверждения.
Простыми словами: чтобы транзакция считалась легитимной, большинство узлов сети должны прийти к соглашению, что блок, который ее содержит, был рассчитан правильно.
Можно ли обойтись без этого?
Накамото не первый, кто решил создать такую децентрализованную систему. Но он первый, кто догадался использовать механизм консенсуса Proof-of-Work. Без него невозможно решить проблему двойного расходования, когда отправитель может дважды потратить одни и те же средства до того, как система подтвердит транзакцию: майнеры каждый раз проверяют транзакции на предмет двойного расходования при получении их из мемпула.
Да, в блокчейне на базе PoW может возникнуть ситуация, когда два майнера добудут один и тот же блок. Это не обязательно злонамеренная акция. Такое вполне может случиться, если оба майнера завершили расчет почти одновременно, и до одного из них не успела дойти информация, что блок уже добыт. В этом случае появляется параллельная цепочка, берущая начало от ошибочного блока. Чтобы избавиться от неверной «ветви», механизм консенсуса сравнивает два блокчейна и отдает предпочтение более длинной версии.
Проблемы и ограничения
Самая главная проблема PoW в чистом виде — масштабируемость. Например, пропускная способность блокчейна Bitcoin составляет около семи транзакций в секунду, что довольно мало. Из-за этого в моменты пиковых нагрузок мемпул переполняется, а транзакции с низкими комиссиями за обработку могут застрять на несколько часов или даже дней. На первый взгляд может показаться, что увеличить скорость легко — сделать блоки больше, чтобы в них влезло больше транзакций, а добывать их можно и почаще.
Но просто так увеличить блок нельзя: на его добычу придется тратить много вычислительных мощностей. В итоге в сети останутся только крупные майнеры или майнинговые пулы, что понизит децентрализацию.
Если сократить время, есть риск, что узлы сети не смогут вовремя достичь консенсуса до появления следующего блока. Из-за этого вырастет количество «ответвлений» блокчейна и сделает возможными двойные траты.
Все это — трилемма блокчейна — предположение, что децентрализованная сеть может одновременно обеспечить только два преимущества из трех (децентрализация, безопасность, масштабируемость). Для ее решения в контексте PoW используются слои блокчейна, которые работают «поверх» основной системы и повышают скорость обработки транзакций.
Кроме этого, разрабатываются новые протоколы консенсуса, работающие вместе с PoW. Например, в Kaspa PoW используется в качестве механизма защиты сети, а блоки упаковываются не в блокчейн, а в направленный ациклический граф, что позволяет майнерам работать параллельно над разными блоками.
Существует и «бытовая» проблема: чем больше вычислительных мощностей аккумулирует блокчейн, тем выше сложность вычислений и тем больше энергии требуется для майнинга.