Что такое Segregated Witness и как он может улучшить биткоин
Segregated Witness стало одним из самых интересных предложений, вызвавших оживленную дискуссию в сообществе. Предложение было сделано Питером Велле в ходе воркшопа Scaling Bitcoin в Гонконге.
Нашедшее поддержку у многих участников сообщества, SegWit, как полагают, способно улучшить работу биткоина сразу в нескольких областях. Кто-то даже предполагает, что SegWit — то долгожданное решение проблемы масштабирования, которое способно привнести мир в раздираемое спорами о размере блока сообщество.
Принцип работы
Чтобы понять, как работает SegWit, нужно понимать сущность биткоин-транзакций на достаточно глубоком техническом уровне. Для начала, конечно, важно понимать, что протокол биткоина в сущности состоит из транзакций. Ноды в р2р-сети не отправляют друг другу биткоины – они шлют пакеты с данными транзакций.
Можно сказать, что транзакции являются набором «замков», состоя из двух основных компонентов. Одна часть «высвобождает» биткоины, содержащиеся в предыдущих транзакциях с помощью данных под названием «вводы». Вводы содержат скрипты – то есть инструкции касательно того, как исполнить ввод. Они называются scriptSigs. Другая часть содержит набор новых замков – так называемые выводы – которые «запирают» то же или меньшее количество биткоинов. В их состав входят скрипты под названием scriptPubKeys. Таким образом, биткоины перемещаются от вводов к выводам за одну транзакцию, при этом перескакивая от одной транзакции к другой.
В этом правиле, однако, есть принципиальное исключение. Транзакция coinbase, которая, конечно, никакого отношения к одноимённой компании не имеет, создаётся майнером, когда тот находит новый блок. Coinbase транзакция содержит вознаграждение за блок – сейчас это 25 биткоинов. Кроме того, майнер может увеличить вознаграждение на любую сумму в биткоинах, которые были «высвобождены» в транзакциях, но обратно «заперты» не были – то есть, разность между вводами и выводами. Эта разность – комиссия за транзакцию.
Всё это «запирание» и «отпирание» биткоинов осуществляется отправителями транзакций, и в сущности передаётся по сети в виде пакетов информации. Все узлы сети, также именуемые нодами, проверяют правильность выполнения процесса отпирания и запирания. Если всё в порядке, они передают транзакцию другим нодам. Если нода к тому же ещё и майнер, то она может включить транзакцию в блок. Делать это или нет, решает майнер – поэтому и нужно включать комиссии. Также жизненно важно, чтобы правила, используемые всеми нодами при верификации транзакций, соответствовали правилам, которыми пользуется подавляющее большинство майнеров. Если некоторые майнеры станут включать в блоки те транзакции, которые остальные майнеры отвергли, весь блок будет считаться недействительным этой нодой. Если она майнер, то может случиться двойная трата и форк.
Эти правила консенсуса, то есть те, по поводу которых согласны все ноды, позволяют транзакциям одновременно разными способами запирать и отпирать транзакции. Однако выводы, которые запирают биткоин, как правило содержат scriptPubKey, смысл которого состоит примерно в этом: «докажи, что владеешь или знаешь приватный ключ, который соответствует публичному ключу, привязанному к данному биткоин-адресу».
Приватные ключи
Из приватного ключа восстановить публичный достаточно просто, а вот обратный процесс фактически невозможен. Точно так же легко восстановить адрес из публичного ключа, а вот приватный ключ из адреса не добыть никак.
Адрес, использованный для запирания биткоина в scriptPubKey, конечно, является адресом, предоставленным получателем транзакции. Поскольку именно получатель создал этот адрес с помощью одному ему известному ключа, только он и может создать валидный scriptSig, таким образом, становясь единственным, кто может создать новую транзакцию и израсходовать запертый биткоин.
Для доказательства владения приватным ключом теоретически можно включить этот ключ в scriptSig транзакции – но так никто не делает, поскольку это довольно опасно. Прежде всего, в этом случае любой, кто увидит транзакцию, сможет присвоить себе приватный ключ и создать новую транзакцию (или изменить исходную), таким образом фактически приписав себе все биткоины, запертые до того, как исходная транзакция попадёт в блок. Если же это сделает майнер, то красть биткоины станет проще простого, поскольку именно он выбирает, какие транзакции подтверждать, а какие нет. Поэтому в scriptPubKeys обычно заложено требование, согласно которому scriptSig должен включать одну или несколько подписей для отпирания биткоина.
Подписи
Подписи – это криптографический приём, в котором для вычисления уникальной последовательности чисел используется приватный ключ в сочетании с любыми другими данными. Соответствующий публичный ключ может использоваться для верификации того, что данная подпись была создана с использованием данного приватного ключа. Таким образом, подписи доказывают как владение приватным ключом, так и подтверждение конкретной части данных владельцем приватного ключа – и всё это без его разглашения. В случае биткоина приватные ключи обычно используются для подписи данных транзакции за исключением вводов, а заодно scriptPubKeys, запертых сумм и некоторых других данных. В результате подпись и публичный ключ, по которому расходуются биткоины добавляются к транзакции в поле ввода. Это доказывает то, что владелец ключа действительно желал совершить транзакцию, и гарантирует, что её нельзя было подделать.
Далее все данные транзакции, включая на этот раз и вводы, совместно хешируются, благодаря чему возникает ID транзакции, который служит её идентификатором. Если транзакция в конце концов попадает в блок, майнер хеширует её ID вместе с ID другой транзакции, получая новый хеш. Этот хеш также хешируется, на этот раз с хешем двух других ID транзакций. Процесс продолжается, пока не останется всего один хеш. Эта система хешей называется деревом Меркля, а оставшийся хеш – корнем Меркля. Корень сочетается с дополнительными данными блока из заголовка, которые используются для идентификации конкретного блока. Хеш заголовка блока в итоге включается в заголовок следующего блока, что и связывает один блок с другим.
Биткоин считается неизменяемым, поскольку изменение любой части любой транзакции задним числом поменяет ID транзакции, что приведёт к изменению заголовка блока – однако такой блок уже не будет соответствовать условленным требованиям. И поскольку заголовок блока влияет на структуру последующих заголовков блока, они также не будут им соответствовать.
SegWit основан на концепции сайдчейнов, разработанной Blockstream, и дополняет идею разработчика ядра биткоина Люка Дэша. Общая концепция была разработана спустя несколько месяцев в сотрудничестве с разработчиками ядра Грегори Максвеллом и Эриком Ломброзо. Система должна быть готова уже к середине наступившего года.
С точки зрения нод, которые не используют SegWit (условно назовём их старыми) некоторые вновь созданные выводы могут начать использовать странный тип scriptPubKeys. Странно в них то, что их едва ли можно будет считать замком. В целом именуемые «тратят все», эти ключи в целом заявляют, что подписи им не нужны. Кроме того, в них ещё и присутствует совершенно бессмысленный текст.
Старые ноды посчитают эти транзакции бессмысленными. Им покажется, что любой может создать новый scriptSig, высвобождая эти выводы – а это значит, что они практически полностью незащищены. В то же время, старые ноды технически не смогут не принимать новые транзакции. Текст ScriptPubKeys покажется им бессмысленым, но технически он вполне допустим. Так что старые ноды подтвердят транзакции как валидные, и передадут их другим нодам.
А вот ноды с SegWit (назовем их новыми) поведут себя немного иначе. Текст ScriptPubKeys совсем не покажется им бессмысленным. Они заметят в нём весьма специфический тип вывода.
Подобно прежним выводам, эти новые выводы будут нуждаться в нескольких подписях для высвобождения биткоина – однако в отличие от них, для этого им не нужна будет подпись, включённая в scriptSig следующей транзакции. Вместо этого подпись должна будет включаться в совершенно новую часть транзакции – SegWit.
SegWit по сути является аддоном, содержащим подписи и некоторые другие данные. Главное здесь то, что SegWit полностью игнорируется старыми нодами, но признается новыми. Более того, их данные не хешируются заодно с другими частями транзакции для создания ID.
Таким образом, и старые и новые ноды будут считать транзакции с SegWit валидными. Старые ноды будут их валидировать, поскольку с их точки зрения им вовсе не нужны подписи, а новые – потому, что нужная подпись находится в SegWit. Поскольку и те и другие ноды хешируют данные транзакции в один и тот же ID, консенсус по компоновке блоков будет достигнут, а следовательно, блокчейн также не будет вызывать споров.
Есть, однако, небольшая проблема: если подписи не влияют на компоновку блокчейна, он уже не может являться доказательством того, что в транзакции включены корректные подписи.
Чтобы подписи всё равно включались в блокчейн, майнер с SegWit проворачивает небольшой фокус – создаёт дерево Меркля не только из транзакций, но и из SegWit, причём последнее полностью соответствует дереву транзакций. Корень дерева SegWit включается в поле ввода транзакции coinbase. Таким образом корень дерева SegWit меняет данные транзакции coinbase, её ID, а значит и заголовок – в результате меняется вся компоновка блокчейна.
Предложение Велле позволяет удалить подписи из транзакций биткоина, сохранив его неизменяемость и не нарушая ни одного из принятых правил консенсуса.
Размер блока
Однако, больше всего внимания привлёк тот факт, что удаление подписей из блоков в 1 мегабайт может фактически увеличить размер блока биткоина. Это значит, что можно будет записывать в блокчейн больше транзакций за секунду – то есть, увеличится пропускная способность транзакций. Более того, всё это не нарушит даже правило о максимальном размере блока.
В предложении Велле речь не идёт о новом типа максимального размера блока. Формула, используемая для расчёта предельных значений, задана достаточно произвольно – блок без свидетеля плюс четвёртая часть SegWit в сумме не должны превышать 1 мб. Таким образом старые ноды будут считать все блоки меньшими, чем 1 мб, поскольку четверть SegWit, которых они вовсе не видят, входит во всё тот же 1 мегабайт. Новые ноды тем временем будут видеть, что блоки превышают 1 мегабайт, поскольку реальный размер SegWit больше, чем учитываемая четверть.
Точные объёмы дополнительной памяти зависят от типов транзакций, включаемых в новые блоки. Если больше транзакций хранят большее количество данных в SegWit, как это наверняка случится с мультисигнатурными транзакциями, общий размер новых блоков возрастёт. Это делает максимальный размер нового блока равным примерно 1,75 мегабайт для нормальных транзакций, и 4 мегабайтам в качестве жёсткого потолка, который нельзя превысить ни при каких условиях, даже если в SegWit запихнуть вообще все данные.
Есть, однако, ещё одно – и, возможно, главное преимущество: SegWit может обеспечить гибкость транзакций. Ради этого его, собственно, когда-то и начинали разрабатывать.
Эта гибкость обеспечивается за счёт криптографической техники изменения подписи без изменения обозначаемого ею параметра. Это можно сделать даже без исходного приватного ключа. В случае биткоина это значит, что любой может выбрать любую транзакцию из р2р-сети, и заменить одну валидную подпись другой. Новая подпись будет соответствовать всё тем же данным, и может верифицироваться всё тем же ключом. Она вообще не меняет на работу транзакции. Однако, поскольку выглядит она иначе, ID транзакции меняется до неузнаваемости.
Гибкость транзакций порождает две основных проблемы – она спутывает все карты ПО, которое использует ID для верификации подтверждения транзакций, но, что ещё важнее, она заметно ограничивает поле деятельности для всевозможных сложных приёмчиков мира биткоина, основанных на неподтверждённых транзакциях – например, платёжных каналов и Lightning Network. SegWit убирает подписи из той части транзакции, которая используется для создания ID – так что хотя подписи в нём изменяться и могут, это никак не помешает ПО использовать ID транзакций, равно как не будет иметь никакого значения для платёжных каналов или Lightning Network. Поэтому открывается пространство для дополнительных уровней масштабирования.
Версии скриптов
Третье преимущество SegWit вызвало у биткоин-кодеров ничуть не меньший, если не больший, восторг – версии скриптов.
Помимо scriptSigs, SegWit несут кое-что ещё: байты версии. Они предшествуют скрипту, обозначая его тип. Если нода, считывающая байты версий, опознает тип, станет понятно, какие требования должны выполняться для высвобождения биткоина. Если байты не опознаны, нода интерпретирует scriptSig как «тратят все». Всё это создаёт совершенно новые способы для блокировки биткоина в транзакциях. Фактически, это позволит запирать его каким угодно способом – некоторые способы необъяснимы, потому как ещё не изобретены. Однако среди первых идей были Подписи Шнорра, которые верифицируются куда быстрее нынешних, а также более сложные типы мультисигнатурных транзакций – и даже скрипты, подобные Ethereum. При этом сохраняется всё тот же консенсус относительно правил – но этом случае принять нововведение должно просто большинство майнеров, а не все – что существенно облегчает внедрение схемы.
Но кроме этого SegWit предлагает нечто под названием «защита от подлога» (fraud proof). Придуманные ещё Сатоши Накамото, эти защиты могут заметно усилить безопасность «лёгких кошельков», то есть, нод, которые не верифицируют все транзакции сети и не хранят весь блокчейн. Для проверки того, произошла ли транзакция, такая нода просто сканирует блокчейн на предмет соответствующего ID транзакции. Найдя его, нода убеждается, что какой-то майнер включил транзакцию в блок. Однако такие ноды не подтверждают, соответствует ли транзакция правилам. По этой причине подобные ноды по умолчанию полагаются на честную игру майнеров, никак их не проверяя. В худшем случае это может привести к тому, что майнеры станут платить им биткоинами, созданными на ровном месте – например, за создание транзакций без вводов, или присуждая себе же огромные комиссии в транзакции coinbase.
Подобные проблемы решаются, если майнеров обязать включать дополнительные данные в дерево SegWit – эти данные должны указывать, откуда именно взялся биткоин, запертый во всех транзакциях. Таким образом, если блок содержит недействительные транзакции, любая полная нода сможет выстроить защиту от подлога легко и непринуждённо, после чего отправить подтверждения лёгким нодам, так что те смогут отвергать недействительные блоки. Тем не менее, даже в этом случае лёгкие ноды не смогут обеспечивать тот же уровень безопасности, что и полные. Предложенное решение требует работы в свободной от цензуры сети (например, речь идёт о правительственных блокировках). Кроме того, лёгким нодам нужна будет хотя бы одна полная нода, чтобы действительно обеспечивать защиту от подлога.
Наконец, SegWit способен уменьшить объём данных, который ноды хранят по месту. Это также снижает затраты на работу полной ноды и заметно снижает время, необходимое для синхронизации с сетью при первой установке. Хотя ноды обычно хранят все данные транзакции, подписи считаются недействительными по прошествии какого-то времени. Если транзакция признана действительной и вписанной в блок, и закреплена в блокчейне, скажем, на год – её можно будет подделать, только если майнеры все вместе станут майнить недействительную цепь на протяжении всего этого срока, и никто за целый год этого не заметит.
Влияние SegWit
Чтобы понять, какую роль SegWit может сыграть в спорах о размере блока, сперва имеет смысл бегло вспомнить, о чём же, вообще говоря, спорят.
В целом, речь идёт о компромиссе между пропускной способностью и децентрализацией с небольшим добавлением экономики. Текущий размер блока в 1 мегабайт позволяет сети обрабатывать до семи транзакций в секунду. Так называемые «прогрессоры» считают, что это слишком мало – особо популярно сравнение с Visa, чья система спокойно обрабатывает тысячи транзакций за секунду. Слишком маленькие блоки, по мнению прогрессоров, могут ограничить потенциал биткоина и увеличить стоимость транзакций по блокчейну настолько, что позволить себе это смогут только централизованные сервисы, и приведёт к массовому уходу пользователей в поисках альтернативных платёжных решений, а возможно и краху всей системы.
На другом фланге находятся так называемые «децентралисты», которые опасаются, что излишнее увеличение размера блока может так или иначе центарилизовать биткоин на уровне протокола. Один из вариантов, о которых они говорят – более крупные блоки медленней распространяются от ноды к ноде, а верификация на каждой отдельной ноде занимает больше времени, что ещё сильнее замедляет распространение. Это играет на руку майнерам или пулам, которые находят больше блоков, поскольку у них появляется фора. Децентралисты опасаются, что это может отдать весь майнинг в руки очень небольшого количества пулов. Более того, крупные блоки сделают работу полных нод дороже, так как для этого потребуется большая пропускная способность и больше памяти. Это может затруднить работу биткоина как механизма, не требующего доверия, создав стимул для пользователей передавать право определять консенсус другим, что дополнительно способно централизовать систему. Большинство децентралистов также уверены, что ограничение размера блока необходимо по экономическим соображениям, чтобы блоков было не слишком много. Это, как они полагают, может привести к тому, что майнеры начнут сокращать друг у друга комиссии, пока транзакции не станут полностью бесплатными. Если они станут почти бесплатными, майнеры не смогут достаточно зарабатывать, чтобы обеспечивать безопасность сети.
Некоторые прогрессоры думают, что комиссии установятся сами собой. Добавление транзакций увеличивает размер блоков, что увеличит количество заброшенных блоков на выходе. Это гарантирует, что майнеры получат достаточно комиссий, чтобы скомпенсировать добавочный риск. Децентралисты же возражают, что эта динамика просто приведёт к очередному риску централизации, так как в итоге вовсе не позволит забрасывать блоки.
Всё это, как думают децентралисты, способно учинить регулирование биткоина на уровне протокола, что повредит его устойчивости к цензуре. Хотя они и признают, что меньшие по размеру блоки ограничивают количество транзакций, которые могут обрабатываться в блокчейне, они полагают, что будущее биткоина лежит в работе с надстройками вроде той же Lightning Network или древообразных блокчейнов. Прогрессоры, как правило, признают пользу таких дополнительных надстроек – однако не в качестве решения для масштабирования. По их мнению, биткоин должен сперва масштабироваться «на уровне цепочек».
Как уже стало понятно, свойства SegWit, при всех своих плюсах, не способны решить суть спора о размере блока. Прогрессоры не считают Lightning Network решением проблемы масштабируемости. Защита от подлога полезна, но лёгкие блоки всё равно останутся менее надёжными, чем полные. Отказ от данных старых транзакций может быть не лишним, но разработчики ядра предлагали сходные решения ещё до появления SegWit. Байты версий могут сыграть свою роль в будущем, однако пока не совсем ясно, что именно с ними делать.
Вопрос, таким образом, состоит в том, удовлетворит ли SegWit оба лагеря – а именно, хватит ли 2 мегабайт прогрессорам (именно столько реальных данных транзакции предполагает система), и достаточно ли консервативны 4 мегабайта для децентралистов (ведь крупные майнеры могут вытеснить более скромных конкурентов, начав майнить 4-мегабайтные блоки). В SegWit хорошо то, что он совершенно опционален – пользователь сам решает, апгрейдить свой софт или нет. Те, кто желает пользоваться SegWit, получат условную «скидку» на комиссии, так как будут фактически использовать меньше редкого блокового пространства. Те, кто не хочет им пользоваться из-за роста стоимости работы полной ноды, совершенно не обязаны его устанавливать. Таким образом, как минимум одна из озабоченностей децентралистов (о росте стоимости работы полной ноды) снимается. Другая озабоченность децентралистов – увеличение времени распространения – несколько сложнее. Но Велле, который сам децентралист, не думает, что это создаст проблемы.
Механизм верификации нод SegWit таков, что дополнительное время для отдельных нод скорее всего будет ничтожно малым. Время распространения слегка вырастет, однако модели Велле показывают, что 4 мегабайта находятся в пределах возможностей нынешней сети.
В результате большинство децентралистов выступают за SegWit, считая его жизненно важной частью «дорожной карты» масштабирования, составленной Грегори Максвеллом. Эта карта даёт некоторый выигрыш во времени и оттягивает момент, когда блоки окажутся полностью заполнены (если SegWit будет работать как задумано), при этом не нарушая существующие общепризнанные правила. Это выигранное время децентралисты хотят потратить на поиск долгосрочных решений, в том числе и на создание более живучей политики в отношении размера блоков, дополнительных уровней надстроек и прочих оптимизаций. Прогрессоры, однако, не считают, что 2 мегабайт достаточно – например в предложении Гэвина Андрессена размер блока через 20 лет должен вырасти до 8 гигабайт.
Хард-форк и софт-форк
Более того, некоторые прогрессоры указывают, что полноценно функционировать SegWit сможет не раньше, чем через год. Из-за этого некоторые разработчики, склонные к прогрессорству, хотели бы, чтобы вся сеть переключилась на большие размеры блока ещё до того, как будет внедрён SegWit. Именно это и приводит нас к основной проблеме. Предложение Велле может быть реализовано как софт-форк – то есть, внедряться по сути только майнерами. Увеличение размера блока «по старинке» же возможно только через хард-форк.
Из-за отсутствия консенсуса часть пользователей может решиться на хардфорк, вероятно, надеясь, что остальные внедрят изменения, когда возражать будет уже поздно. Однако, если остальные не последуют их примеру, вся сеть разделится. Такое уже происходило, когда Гэвин Андресен и Хёрн внедрили Bitcoin XT, но так и не снискали существенной поддержки. Более того, некоторые девелоперы предпочитают внедрять сам SegWit как хард-форк, у которого есть некоторые преимущества перед софт-форком.
Во-первых, хард-форк нацелен на то, чтобы все ноды в сети исполняли один и тот же набор правил – полные ноды должны валидировать все транзакции по этим правилам, даже если в них не участвуют их биткоины. Во-вторых, хард-форк был бы более «чистым» решением. Предложение SegWit избегает нарушения существующих правил, используя части протокола биткоина – ввод транзакции coinbase – совсем не таким образом, на который они рассчитаны, так что некоторые опасаются, что это усложнение может привести к проблемам в будущем. В-третьих, в результате может усложниться написание ПО для биткоина – например, софта кошельков. Другие разработчики, большинство из которых смотрят на ситуацию более консервативно, считают, что хард-форк должен быть последней из возможных мер. Больше всего они желают избежать разделения сети – и если хард-форку быть, о нём нужно объявить заранее, и всё как следует организовать, чтобы у каждого пользователя был шанс обновиться. Софт-форк же можно организовать едва будет готов код – при согласии майнеров, а остальные могут проводить апгрейд, если и когда захотят.
Реальный вопрос, таким образом, состоит в том, найдет ли потенциальный хард-форк достаточно поддержки в среде пользователей биткоина. И хотя консенсус многие считают понятием растяжимым, некоторые всё же полагают, что относительно хард-форка он уже достигнут.
Наиболее вероятным решением на данный момент кажется дорожная карта Максвелла – единственный план, который не требует скорейшего хард-форка, поддержанный большинством разработчиков биткоина. Таким образом, сейчас ей не хватает лишь поддержки обладателей большей части хешевых мощностей. Тем не менее, попытку хард-форка – возможно, учинённую крупными игроками отрасли – также нельзя исключать. К тому же, Bitcoin XT тоже где-то неподалёку.
Рассылки ForkLog: держите руку на пульсе биткоин-индустрии!