Полная версия
Введение в технологию Блокчейн
Это одноранговая сеть, и она наследует многие идеи одноранговых сетей.
В сети Bitcoin все узлы равны.
Здесь нет иерархии, и нет особых узлов или главных узлов.
Эта сеть работает через протокол TCP и имеет случайную топологию, где каждый узел связан с другими случайными узлами.
Новые узлы могут присоединиться в любое время.
Фактически, сегодня вы можете скачать клиент Bitcoin, развернуть свой компьютер в качестве узла, и он будет иметь равные права и возможности, как и любой другой узел в сети Bitcoin.
Сеть меняется со временем и очень динамична из-за входа и выхода узлов.
Не существует явного способа покинуть сеть.
Вместо этого, если узел не был слышен некоторое время – три часа – это длительность, которая жестко закодирована в большинстве клиентах – другие узлы начинают забывать этот узел.
Таким образом, сеть обрабатывает узлы, переходящие в офлайн режим.
Напомним, что узлы соединяются со случайными одноранговыми узлами и нет никакой географической топологии.
Теперь предположим, что вы запустили новый узел и хотите присоединиться к сети.
Вы начинаете с простого сообщения для одного узла, о котором вы знаете.
Обычно он называется вашим семенным узлом seed node, и есть несколько разных способов поиска списков семенных узлов, к которым можно подключиться.
Вы отправляете специальное сообщение «Скажите мне адреса всех других узлов в сети, о которых вы знаете».
Вы можете повторить процесс с новыми узлами, о которых вы узнаете, столько раз, сколько хотите.
Затем вы можете выбрать, к каким из них следует подключиться, и вы станете полнофункциональным членом сети Bitcoin.
Существует несколько шагов, которые используют случайность, и результатом является то, что вы получаете случайный набор узлов.
Чтобы присоединиться к сети, все, что вам нужно знать, – это связаться с одним узлом, который уже находится в сети.
Для чего нужна сеть?
Конечно, чтобы поддерживать цепочку блоков.
Чтобы опубликовать транзакцию, мы хотим, чтобы об этом узнала вся сеть.
Это происходит с помощью простого алгоритма наводнения, иногда называемого протоколом сплетен.
Если Алиса хочет заплатить Бобу, ее клиент создает, и ее узел отправляет эту транзакцию ко всем узлам, с которыми она связана.
Каждый из этих узлов выполняет серию проверок, чтобы определить, принять и транслировать или нет дальше эту транзакцию.
Если проверки проходят успешно, узел, в свою очередь, отправляет транзакцию всем своим узлам-пирам.
Узлы, которые принимают эту транзакцию, помещают ее в пул транзакций, о которых они слышали, но которые еще не находятся в цепочке блоков.
Если узел получает транзакцию, которая уже находится в пуле, он больше не транслирует ее.
Это гарантирует, что протокол наводнения прекратится, и транзакции не будут циклически перемещаться по сети вечно.
Помните, что каждая транзакция однозначно определяется своим хешем, поэтому ее легко найти в пуле.
Теперь вопрос, когда узлы узнают о новой транзакции, как они решают, должны ли они ретранслировать ее?
Для этого существуют четыре проверки.
Первая и самая важная проверка – проверка транзакции – транзакция должна быть валидной для текущей цепочке блоков.
Узлы запускают скрипт для каждого предыдущего выхода, который тратится, и проверяют, чтобы скрипт вернул true.
Во-вторых, они проверяют, чтобы выходы, потраченные в этой транзакции, еще не были потрачены.
В-третьих, они не будут передавать уже полученную ранее транзакцию.
В-четвертых, по умолчанию, узлы будут принимать и ретранслировать «стандартные» скрипты на основе небольшого белого списка скриптов.
Все эти проверки – это просто проверки на основе здравомыслия.
Честные узлы выполняют их, чтобы попытаться поддерживать работоспособность сети, но не существует правила, согласно которому узлы должны выполнять эти проверки.
Так как это одноранговая сеть, и может присоединиться любой узел, всегда существует вероятность того, что какой-то узел будет транслировать двойные траты, нестандартные транзакции или совершенно недействительные транзакции.
Вот почему, желательно, чтобы каждый узел выполнял эти проверки.
Так как в сети существует латентность, возможно, что узлы будут иметь разные пулы ожидающих включение в блокчейн транзакций.
Это становится особенно интересным и важным, когда есть попытка двойной траты.
Предположим, что Алиса пытается заплатит один и тот же биткойн как Бобу, так и Чарли, и отправляет две транзакции примерно в одно и то же время.
Некоторые узлы сначала услышат о транзакции Алиса → Боб, а другие сначала услышат о транзакции Alice → Charlie.
Когда узел слышит любую из этих транзакций, он добавляет ее в свой пул транзакций, и, если он услышит о другой транзакции позже, это будет выглядеть как двойная трата.
Узел откажется от последней транзакции и не будет ретранслировать ее или добавлять ее в пул транзакций.
В результате временно между узлами возникнет разногласие о том, какие транзакции следует поместить в следующий блок.
Это называется созданием условия гонки.
Хорошей новостью является то, что все будет в порядке.
Тот, кто замайнит следующий блок, по существу разорвет эту связь и решит, какая из этих двух ожидающих транзакций должна быть окончательно помещена в блок.
Скажем, транзакция Алисы → Чарли попадает в блок.
Когда узлы с транзакцией Алиса → Боб услышат об этом блоке, они выведут эту транзакцию из своих пулов ожидающих транзакций, потому что это двойная трата.
Также, когда узлы с транзакцией Alice → Charlie услышат об этом блоке, они выведут и эту транзакцию из своих пулов, потому что она уже попала в цепочку блоков.
Так что больше не будет никакого разногласия, когда этот блок распространится в сеть.
Так как поведение по умолчанию заключается в том, что узлы должны принимать во внимание то, что они слышат в первую очередь, имеет значение местоположение узлов в сети.
Если две конфликтующие транзакции или блока будут объявлены в двух разных позициях в сети, оба они начнут распространяться по всей сети и какая транзакция узла будет услышана первой, будет зависеть от того, где этот узел находится в сети.
Конечно, это предполагает, что каждый узел реализует эту логику, согласно которой узлы сохраняют все, что они слышат в первую очередь.
Однако не существует центрального органа, обеспечивающего соблюдение этой логики, и узлы могут реализовать любую другую логику, которую они захотят и могут выбрать, какие транзакции ретранслировать.
Мы рассмотрим этот вопрос позже и обсудим, почему майнеры, в частности, могут захотеть реализовать другую логику, отличную от поведения по умолчанию.
До сих пор мы в основном обсуждали распространение транзакций.
Логика объявления новых блоков, когда шахтеры добывают новый блок, почти точно такая же, как распространение новой транзакции, и они также подвержены тем же условиям гонки.
Если одновременно запускаются два валидных блока, только один из них может быть включен в долгосрочную консенсусную цепочку.
В конечном итоге, какой из этих блоков будет включен в долгосрочную консенсусную цепочку, будет зависеть от того, из каких блоков строят цепочки другие узлы, и тот блок, который не попадает в консенсусную цепочку, останется сиротой.
Проверка блока является более сложной, чем проверка транзакций.
В дополнение к проверке заголовка и того, что значение хеша заголовка находится в допустимом диапазоне, узлы должны проверять каждую транзакцию, включенную в блок.
Наконец, узел будет ретранслировать блок только в том случае, если он основывается на самой длинной ветви цепочки блоков.
Это позволяет избежать образования вилок.
Но, как и при транзакциях, узлы могут реализовать различную логику, если они этого захотят – они могут ретранслировать блоки, которые недопустимы, или блоки, которые строятся из более ранней точки в цепочке блоков.
Это создаст вилку, но все будет в порядке, потому что протокол биткойна разработан таким образом, чтобы противостоять этому.
Теперь вопрос, какова латентность алгоритма наводнения или сплетен?
График на слайде показывает среднее время, за которое новые блоки распространяются в каждый узел сети.
Три линии показывают время покрытия блоком 25, 50 и 75 процентов сети.
Как вы можете видеть, время распространения пропорционально размеру блока.
Это связано с тем, что пропускная способность сети является узким местом.
Большие блоки занимают более 30 секунд для распространения на большинство узлов в сети.
Таким образом, это не очень эффективный протокол.
В Интернете 30 секунд довольно долгое время.
В дизайне Биткойна наличие простой сети с простой структурой, где узлы равны и могут приходить и уходить в любое время, имеют приоритет над эффективностью.
Таким образом, блоку может потребоваться пройти через множество узлов, прежде чем он достигнет самых отдаленных узлов в сети.
Если бы сеть была разработана сверху вниз для повышения эффективности, тогда путь между любыми двумя узлами был бы коротким.
Теперь вопрос, какой размер сети биткойнов.
Трудно измерить, насколько велика сеть, так как она динамична, и не существует центрального узла.
Ряд исследователей дают разные оценки.
Некоторые говорят, что более миллиона IP-адресов действуют одновременно, как узлы биткойна.
С другой стороны, оценивают, что в сети находятся только от 5000 до 10000 узлов, которые постоянно подключены и полностью проверяют каждую транзакцию, которую они слышат.
Полностью проверяющие узлы должны быть постоянно подключены, чтобы слышать обо всех данных.
Чем дольше узел находится в автономном режиме, тем ему дольше придется восстанавливать актуальность данных, когда он снова присоединиться к сети.
Такие узлы должны хранить полную цепочку блоков и нуждаются в хорошем сетевом соединении, чтобы иметь возможность слышать каждую новую транзакцию и пересылать ее пирам.
Полностью проверяющим узлам требуется хранить несколько десятков гигабайт данных полного блокчейна.
Наконец, полностью проверяющие узлы должны создавать полный набор неизрасходованных выходов транзакций, которые можно потратить, и хранить этот набор в оперативной памяти, так что, слушая новую предлагаемую транзакцию в сети, узел смог бы быстро найти выходы транзакций, которые пытаются потратить, запустить скрипты, посмотреть, действительно ли действительны подписи, и добавить транзакцию в пул транзакций.
На сегодняшний день, в блочной цепочке насчитывается около 300 миллионов транзакций, из которых около 60 миллионов остались неизрасходованными.
В отличие от полностью проверяющих узлов, существуют легковесные узлы, также называемые тонкими клиентами или клиентами Simple Payment Verification (SPV).
Фактически, подавляющее большинство узлов в сети Биткойн – это легкие узлы.
Они отличаются от полностью проверяющих узлов тем, что они не хранят полную цепочку блоков.
Они хранят только те части, которые им необходимы, чтобы проверить конкретные транзакции, которые им интересны.
Если вы используете программу кошелька, она обычно включает узел Simple Payment Verification (SPV).
Узел загружает заголовки блоков и транзакции, которые представляют платежи на ваши адреса.
У узла SPV нет уровня безопасности полностью проверяющего узла.
Поскольку узел имеет заголовки блоков, он может проверить, что блоки были добыты, но он не может проверить, что каждая транзакция, включенная в блок, действительно валидная, так как узел не имеет истории транзакций и не знает набор неизрасходованных транзакций.
Узлы SPV могут только проверять транзакции, которые на самом деле влияют на них.
Поэтому они, по сути, доверяют полностью проверяющим узлам, которые подтвердили все остальные транзакции, которые там есть.
Это не плохой компромисс.
Они предполагают, что существуют полностью проверяющие узлы, которые выполняют тяжелую работу, и что, если майнеры добыли этот блок, что является очень дорогостоящим процессом, они, вероятно, также выполнили проверки, чтобы убедиться, что этот блок не будет отброшен.
Экономия затрат на создание узла SPV огромная.
Заголовки блоков составляют примерно 1/1000 размера цепочки блоков.
Поэтому вместо хранения нескольких десятков гигабайт, это всего несколько десятков мегабайт.
Даже смартфон может легко выступать в качестве узла SPV в сети Bitcoin.
Так как биткойн опирается на открытый протокол, в идеале должно быть много разных реализаций, которые легко взаимодействуют друг с другом.
Таким образом, если в одной из них есть ошибка, это вряд ли приведет к разрушению всей сети.
Хорошей новостью является то, что протокол успешно реализуется.
Есть реализации на разных языках, таких как C ++ и Go, и люди создают много других реализаций.
Плохая новость заключается в том, что большинство узлов в сети работают с базовой библиотекой биткойнов, написанной на C ++, поддерживаемой базовыми разработчиками Bitcoin, а некоторые из этих узлов используют предыдущие устаревшие версии, которые не были обновлены.
В любом случае большинство из узлов используют некоторые вариации этого стандартного общего клиента.
Ограничения протокола
Поговорим о некоторых встроенных ограничениях протокола Bitcoin и почему их сложно улучшить.
Есть много ограничений, жестко закодированных в протоколе биткойнов, которые были определены, когда Биткойн был предложен в 2009 году, прежде чем кто-либо действительно подумал, что он может превратиться в глобально важную валюту.
К ним относятся ограничения на среднее время на блок 10 минут, размер блоков 1 мегабайт, количество подписей в блоке 20000, и делимость валюты (биткойны делятся только на 8 знаков после запятой), общее количество биткойнов 21 миллион, и структуру вознаграждения блока, которое начиналось с 50 биткойнов и делится пополам каждые 210000 блоков, и другие ограничения.
Ограничения на общее количество существующих биткойнов, а также структура вознаграждения за майнинг, скорее всего, никогда не будут изменены, поскольку экономические последствия их изменения слишком велики.
Майнеры и инвесторы сделали слишком большие ставки в системе, полагая, что структура вознаграждения Биткойна и ограниченная поставка биткойнов останутся такими, как планировалось.
Если это изменится, возникнут большие финансовые последствия для людей.
Поэтому сообщество в основном согласилось с тем, что эти аспекты, независимо от того, были ли они выбраны разумно, не изменятся.
Однако существуют другие изменения, которые, казалось бы, улучшают протокол, потому что некоторые первоначальные варианты дизайна не кажутся совершенно правильными с учетом ретроспективного анализа.
Главными из них являются ограничения, влияющие на пропускную способность системы.
Сколько транзакций может выполнять сетевой процесс Bitcoin в секунду?
Это ограничение исходит из жесткого кодированного ограничения на размер блоков.
Каждый блок ограничен мегабайтом, около миллиона байт.
Каждая транзакция составляет не менее 250 байт.
Разделив 1,000,000 на 250, мы видим, что каждый блок имеет ограничение в 4000 транзакций, и, учитывая, что блоки добываются примерно каждые 10 минут, у нас получается около 7 транзакций в секунду, что все, что может обслуживать сеть Bitcoin.
Может показаться, что изменение этих ограничений было бы вопросом настройки константы в исходном файле кода где-нибудь.
Однако на практике это очень сложно осуществить по причинам, которые мы рассмотрим.
Итак, с чем сравнить семь транзакций в секунду?
Это довольно медленно по сравнению с пропускной способностью любого крупного оператора кредитных карт.
Например, сеть Visa обслуживает в среднем около 2000 транзакций в секунду по всему миру и способна обрабатывать 10 000 транзакций в секунду в пиковые периоды.
Даже Paypal, который меньше, чем Visa, может обрабатывать 100 транзакций в секунду в пиковые периоды.
Это на порядок больше, чем биткойн.
Еще одно ограничение, которое обсуждают, заключается в том, что набор криптографических алгоритмов в биткойне фиксирован.
Доступно только несколько алгоритмов хэширования и только один алгоритм подписи (ECDSA, по определенной эллиптической кривой, называемой secp256k1).
Существует некоторая озабоченность тем, что в течение жизни Биткойна, которая, как надеются люди, будет очень долгой – этот алгоритм может быть взломан.
Криптографы могут придумать умную новую атаку, которую мы не предвидели, что сделает алгоритм небезопасным.
То же самое относится к хэш-функциям; на самом деле, в последние десятилетия хеш-функции усиленно изучались.
Хэш функция SHA-1, которая используется в биткойне, уже имеет некоторые известные криптографические недостатки, хотя и не фатальные.
Чтобы обойти это ограничение, требуется расширить язык скриптов биткойнов для поддержки новых криптографических алгоритмов.
Как мы можем внедрять новые функции в протокол Bitcoin?
Вам может показаться, что это просто – просто выпустить новую версию программного обеспечения и сообщить всем узлам об обновлении.
В действительности, однако, это довольно сложно.
На практике невозможно быть уверенным, что каждый узел обновится.
Некоторые узлы в сети могут не получить новое программное обеспечение или могут не получить его вовремя.
Последствия обновления большинства узлов, в то время как некоторые узлы будут использовать старую версию, во многом зависят от характера изменений в программном обеспечении.
Мы можем различать два типа изменений: те, которые вызовут жесткий форк, и те, которые вызовут мягкий форк.
Жесткий форк, это когда вводятся новые функции, которые раньше считались бы недействительными.
То есть новая версия программного обеспечения распознает блоки как действительные, однако старое программное обеспечение эти блоки отбросит.
Теперь рассмотрим, что произойдет, когда большинство узлов обновятся, а некоторые узлы не обновятся.
Очень скоро самая длинная ветвь будет содержать блоки, которые не обновленные узлы считают недействительными.
Поэтому не обновленные узлы будут отбрасывать эту ветвь и будут работать с веткой цепочки блоков, которая не содержит блоки с новой функцией.
Пока они не обновят свое программное обеспечение, они будут считать, что их, более короткая ветка является самой длинной валидной веткой блокчейна.
Этот тип изменений называется жестким форком, поскольку он жестко разделяет цепочку блоков.
Каждый узел в сети будет находиться на той или иной стороне, в зависимости от того, какая версия протокола на нем запущена.
Конечно, при этом ветки никогда не смогут объединиться снова.
Это считается неприемлемым для сообщества, поэтому старые узлы будут эффективно отключены от сети Bitcoin, если они не обновят свое программное обеспечение.
Второй тип изменений или мягкий форк, которые мы можем внести в биткойн, – это добавление функций, которые делают правила проверки более строгими.
То есть они ограничивают набор допустимых транзакций или набор допустимых блоков, так что старая версия будет принимать все блоки, тогда как новая версия будет отбрасывать некоторые блоки.
Этот тип изменений называется мягким форком, и здесь можно избежать постоянного раскола, который создает жесткий форк.
Подумайте, что произойдет, когда мы представим новую версию программного обеспечения с мягким форком.
Узлы, на которых запущено новое программное обеспечение, будут применять новый, более жесткий набор правил.
При условии, что большинство узлов переключится на новое программное обеспечение, эти узлы обеспечат применение новых правил.
Существует риск того, что не обновленные майнеры могут использовать недействительные блоки, поскольку они будут включать некоторые транзакции, которые недействительны в соответствии с новыми, более строгими правилами.
Но не обновленные узлы, по крайней мере, поймут, что некоторые из их блоков отклоняются, даже если они не понимают причину этого.
Это может побудить их обновить программное обеспечение.
Кроме того, если их ветку обгонят обновленные майнеры, не обновленные майнеры переключаются на новую ветку, потому, что блоки, считающиеся действительными для новых майнеров, также считаются действительными старыми майнерами.
Таким образом, здесь не будет жесткой развилки; вместо этого будет много маленьких временных вилок.
И в конце концов все они объединятся в длинную ветку, при условии, что большинство улов обновится, так как все эти маленькие ветки будут обгоняться длинной веткой обновленных узлов.
Классическим примером изменения, которое было сделано с помощью мягкого форка, является введение функции pay-to-script-hash, о котором мы говорили ранее.
В первой версии протокола биткойнов нет pay-to-script-hash.
Это мягкая вилка, потому что с точки зрения старых узлов действительная транзакция с оплатой за скрипт будет проверяться корректно.
С точки зрения старых узлов, скрипт прост – он хэширует одно значение данных и проверяет, соответствует ли этот хэш значению, указанном в выходном скрипте.
Старые узлы не знают, как выполнить дополнительный шаг для запуска этого значения или скрипта, чтобы увидеть, является ли он допустимым скриптом.
Мы полагаемся на новые узлы для обеспечения соблюдения новых правил, то есть скрипт должен потратить эту транзакцию.
Что мы можем добавить с помощью мягкой вилки?
Кроме Pay-to-script-hash.
Также возможно, что новые криптографические схемы могут быть добавлены мягким форком.
Мы могли бы также добавить некоторые дополнительные метаданные в параметр coinbase, которые бы что-то значили.
Сегодня любое значение принимается в параметре coinbase.
Но мы могли бы в будущем сказать, что coinbase должнен иметь определенный формат.
Одна идея, которая была предложена, состоит в том, что в каждом новом блоке coinbase будет указывать корень Merkle дерева, содержащего весь набор не потраченных транзакций.
Это приведет только к мягкой вилке, потому что старые узлы могут иметь блок, у которого нет требуемого нового параметра coinbase и который был отклонен сетью, но они наверстают упущенное и присоединятся к основной цепочке, которую ведет сеть.
Для других изменений может потребоваться жесткая вилка.
Примером этого является добавление новых опккодов в биткойн, изменение ограничений на размер блоков или транзакций, или различные исправления ошибок.
Чтобы исправить ошибку, о которой мы говорили ранее, где инструкция MULTISIG выталкивает дополнительное значение из стека, на самом деле требуется жесткая вилка.
Это объясняет, почему, несмотря на то, что это раздражающая ошибка, гораздо проще оставить ее в протоколе и заставить людей работать с ней, а не создавать жесткий форк в биткойне.
Жесткие форки, даже если они были бы успешными, вряд ли произойдут в нынешнем Биткойне.
Но многие из этих идей были протестированы и оказались успешными в альтернативных крипторесурсах, которые стартовали с нуля.
Как хранить и использовать биткойны
Начнем с простейшего способа хранения биткойнов, который просто помещает их на локальное устройство.
Чтобы потратить биткойн, вам нужно знать определенную публичную информацию и определенную секретную информацию.
Публичная информация – это то, что происходит в цепочке блоков – движение монеты, ее стоимость и так далее.
Секретная информация – это секретный ключ владельца биткойна.
Вам не нужно беспокоиться о том, как хранить публичную информацию, потому что вы всегда можете ее получить, когда она вам понадобится.
Но секретный ключ цифровой подписи – это то, что вам следует тщательно охранять.
Поэтому на практике хранение биткойнов – это хранение и управление секретными ключами.
Когда вы определяете, как хранить и управлять ключами, нужно иметь в виду три цели.
Первая – это доступность: возможность тратить свои монеты, когда вы этого захотите.