Segregated Witness, часто сокращаемое до SegWit, — это обновление протокола, активированное в Bitcoin Core в 2017 году. SegWit улучшил несколько аспектов Биткойна и открыл возможности для дальнейших обновлений, включая Taproot.
Во-первых, и это самое важное, в SegWit была решена проблема пластичности транзакций. Также это обновление увеличило лимит размера блоков, позволяя включать в каждый из них больше транзакций. Наконец, с SegWit было введено два новых типа скриптов — способов отправки и получения биткойнов — и новая схема кодирования: bech32.
Обновление SegWit было спорным, и его активация вызвала глубокие разногласия в биткойн-комьюнити. Однако в результате оно сделало Биткойн более сильным и масштабируемым, попутно доказав, что его децентрализованная модель способна успешно противостоять сильнейшему давлению со стороны майнеров и лидеров сообщества.
Что такое пластичность транзакций?
Пластичностью транзакции называют способность транзакции иметь более одного валидного txid. Пластичность возникает, когда часть транзакции можно изменить после ее подписания, не сделав при этом подпись недействительной. Поскольку txid представляет собой хеш транзакции, любое изменение транзакции приведет к изменению ее txid. Однако изменения, которые приводят к изменению txid и делают подпись недействительной, не являются проблемой; проблему пластичности создают только те изменения, которые изменяют txid, но не делают подпись транзакции недействительной.
Почему пластичность транзакций — это проблема
Пластичность транзакций — это проблема для разработчиков и пользователей, которые в новой расходной транзакции хотят сослаться на предыдущую транзакцию до того, как она была подтверждена в блокчейне. Проблема возникает из-за того, что для использования выхода, созданного предыдущей транзакцией, расходная транзакция должна ссылаться на txid предыдущей транзакции. Если txid предыдущей транзакции будет изменен, ссылка станет ошибочной, и новая расходная транзакция будет признана недействительной.
В частности, именно проблема пластичности транзакций препятствовала успешной реализации Lightning Network, работа которой по большей части основана на обмене биткойн-транзакциями, неподтвержденными ончейн.
Как SegWit решает проблему пластичности транзакций
Вызвать проблему пластичности можно двумя способами. Во-первых, уже после того, как транзакция подписана, дополнительные данные могут быть добавлены в scriptSig, часть транзакции, которая содержит подпись и другие данные, используемые для разблокировки биткойнов. Во-вторых, может быть изменена сама подпись, содержащаяся в scriptSig. Оба этих варианта возможны, потому что подпись не может подтверждать сама себя, а значит, не может обеспечить собственную неизменность. Поскольку scriptSig и подписи, которые он содержит, являются частью прообраза txid, если они изменятся, изменится и txid.
SegWit устраняет эту возможность, удаляя все данные из scriptSig. Это достигается путем перемещения данных scriptSig — обычно подписей и открытых ключей — в witness, новую часть SegWit-транзакций, которая не хешируется при вычислении txid. Таким образом, scriptSig для SegWit-входов после подписания транзакции становятся неизменными, а данные, необходимые для разблокировки биткойнов, которые не являются неизменными, содержатся в разделе witness. В такой конфигурации scriptSig не может быть изменен, а значит, и txid не может быть изменен без признания недействительной всей транзакции.
SegWit сделал возможной создание Lightning Network
Активация SegWit позволила запустить Lightning Network, протокол второго уровня, работающий поверх сети Биткойна. До активации SegWit это было невозможно, потому что работа Lightning Network во многом строится именно на неподтвержденных биткойн-транзакциях, и пластичные транзакции открывали бы возможности для атаки сеть.
Увеличение размера блока с SegWit
Хотя технически SegWit являлся софт-форком, он обратно совместимым образом изменял одно из важных правил консенсуса Биткойна, чтобы увеличить количество транзакций, которые могут быть включены в каждый блок.
До активации SegWit объем каждого блока был ограничен 1 Мб, что соответствует примерно 1650 транзакциям в полном блоке. С SegWit было введено понятие вес блока, которое заменило в качестве ограничивающего фактора размер блока. Сегодня полные блоки содержат около 2700 транзакций.
Размер блока — это мера общего количества байтов в транзакции. До SegWit этот ограничение было установлено на 1 Мб, или 1 млн байт.
Вес блока рассчитывается в единицах веса (wu, от weight unit). Один байт данных транзакции, помимо раздела witness, соответствует 4 wu, а один байт witness-данных — 1 wu. Предельный вес блока установлен на уровне 4 млн wu. Важно, что для блока, содержащего только транзакции старого типа (не-SegWit), этот лимит в 4 млн wu будет эквивалентен старому лимиту в 1 млн байт.
Этот новый метод измерения позволяет увеличить размер блока обратно-совместимым образом, чтобы обновление можно было реализовать через софт-форк, не прибегая к хард-форку, но также создает для майнеров и пользователей Биткойна финансовые стимулы для использования SegWit. Пользователи, отправляя SegWit-транзакции, могут сэкономить на комиссиях, потому что witness-данные расходуют меньше веса блока, а майнеры, включая в блоки SegWit-транзакции, могут вместить в свои блоки больше транзакций и за счет этого увеличить доход от комиссий.
Новые типы скриптов в SegWit
Типы скриптов — это разные способы отправки биткойнов через блокчейн с использованием скриптового языка Bitcoin Script. В SegWit, с появлением в транзакции поля witness, были введены два новых типа скриптов, его использующие: Pay-to-Witness-Pubkey-Hash (P2WPKH) и Pay-to-Witness-Script-Hash (P2WSH).
Pay-to-Witness-PubKey-Hash (P2WPKH)
До SegWit подавляющее большинство пользователей использовали скрипты Pay-to-Pubkey-Hash (P2PKH), привязывающие биткойны к хешу открытого ключа. Функциональные возможности Pay-to-Witness-Pubkey-Hash (P2WPKH), введенного с SegWit, почти идентичны P2PKH, с одним важным отличием. Когда пользователи расходуют P2WPKH-выход, подпись и открытый ключ — две точки данных, необходимые для разблокирования P2PKH- и P2WPKH-выходов, — сохраняются в поле witness, а scriptSig оставляется пустым. Как уже упоминалось, это делается для предотвращения пластичности txid.
Pay-to-Witness-Script-Hash (P2WSH)
Второй по популярности старый тип скрипта — это Pay-to-Script-Hash (P2SH), позволяющий привязывать биткойны к хешу произвольного скрипта, называемого redeemScript. Затем эти биткойны могут быть разблокированы любым, кто сможет представить соответствующий redeemScript и выполнить указанные в нем требования.
До SegWit P2SH чаще всего использовался в мультиподписях, поскольку позволял сэкономить место в сравнении с альтернативными вариантами, такими как простая мультиподпись.
В SegWit реализован скрипт Pay-to-Witness-Script-Hash (P2WSH), который функционирует аналогично P2SH. P2WSH-выходы можно расходовать, предоставив witnessScript (SegWit-эквивалент redeemScript), а также подписи и открытые ключи, определенные в witnessScript.
Wrapped SegWit
Введение двух новых типов скриптов стало серьезным нововведением в протоколе Биткойна, и нельзя было ожидать, что множество различных кошельков, приложений и сервисов немедленно подстроятся под это большое изменение. Чтобы упростить внедрение SegWit и сделать его более постепенным, был построен «мост» между устаревшими типами скриптов и типами скриптов SegWit.
Этот мост называется Wrapped SegWit и представляет собой форму старого P2SH-скрипта. Wrapped SegWit скрипты берут нативный SegWit скрипт, P2WPKH или P2WSH, и используют его в качестве redeemScript для P2SH-скрипта. Таким образом, два типа Wrapped SegWit скриптов — это P2SH-P2WPKH и P2SH-P2WSH.
Такой дизайн позволяет старым кошелькам и другому ПО отправлять биткойны на SegWit-адреса, даже если сами они не поддерживают SegWit. Получатель Wrapped SegWit транзакции может потратить биткойны в качестве SegWit-входа, и, следовательно, сэкономить на комиссиях.
Новая схема кодирования SegWit
Обновление SegWit также ввело новую схему кодирования для SegWit-адресов, называемую bech32. До SegWit биткойн-адреса и секретные ключи кодировались по схеме Base58, в которой используются и строчные, и прописные буквы.
Bech32 была предложена и принята как улучшение по сравнению с Base58, поскольку в ней никогда не используется смешанный регистр символов, что делает ее более легкой для чтения или расшифровки и более подходящей для QR-кодирования. Кроме того, bech32 имеет встроенный механизм обнаружения ошибок, помогающий пользователям и кошелькам обнаруживать и даже исправлять опечатки или изменения в биткойн-адресах.
Bech32 также делает нативные SegWit-адреса легко узнаваемыми, поскольку они начинаются с bc1 и в них используются только строчные буквы. Поскольку bech32 использует только 32 буквы алфавита, длина таких адресов немного больше, чем адресов со схемой кодирования Base58, однако они занимают меньше места в самом блокчейне.
История и активация SegWit
Обновление SegWit было чрезвычайно спорным, и имело длительное влияние на процесс разработки Биткойна и его сообщество. Однако успех Биткойна перед лицом такой проблемы для многих стало доказательством его устойчивости.
SegWit был впервые предложен для Bitcoin Core в 2015 году, чтобы решить проблему пластичности транзакций и освободить больше места в блокчейне. Однако в это время биткойн-комьюнити было озабочено способностью Биткойна масштабироваться и обрабатывать растущее число транзакций.
В попытке масштабировать Биткойн некоторые члены сообщества предложили обновление Segwit2x, предполагавшее введение поддержки SegWit и удваивавшее ограничение веса блока до 8 wu, эквивалентных 2 Мб. SegWit2x получил поддержку 95% майнеров, считая по хешрейту сети. Более 50 компаний из биткойн-индустрии подписали так называемое Нью-Йоркское соглашение, обязавшись активировать Segwit2x и удвоить размер блока.
Нью-Йоркское соглашение стало отходом от открытого процесса консенсуса Биткойна, и по этой причине не получило достаточной поддержки от операторов нод и разработчиков, в конечном счете провалившись.
Вместо этого, анонимный, ранее неизвестный разработчик выдвинул BIP 148, которое получило поддержку операторов нод и успешно активировало SegWit, явно отвергая Segwit2x. Чтобы продвинуть это изменение, многие ноды приняли альтернативные реализации Bitcoin Core, что вынудило майнеров принять SegWit перед лицом риска отклонения их блоков сетью.
Почему операторы нод выступили против Segwit2x
Операторы нод хранят полную копию блокчейна и многие из них используют для этого небольшие маломощные машины. Активация Segwit2x увеличила бы скорость роста блокчейна более чем в два раза, вынуждая операторов хранить быстро растущий объем данных. Это повлекло бы за собой увеличение затрат для операторов нод, замедлило бы начальную загрузку блоков и оттолкнуло пользователей от запуска собственной ноды.
Большинство разработчиков тоже выступали против SegWit2x по аналогичным причинам. Они опасались, что, если запустить свою ноду смогут меньше людей, сеть может стать более централизованной и, следовательно, менее устойчивой к цензуре и захвату.
Чему SegWit научил нас
Результат конкуренции между SegWit и Segwit2x показал, что именно ноды, а не майнеры, бизнесы или даже разработчики, реально контролируют сеть. Ноды, используя ПО по собственному выбору, смогли отстоять свою волю перед лицом подавляющего большинства майнеров и активировать SegWit, отвергнув Segwit2x.
Это вселяет уверенность в том, что правила консенсуса Биткойна, включая жесткое ограничение общего объема эмиссии 21 миллионом единиц, не могут быть изменены без согласия операторов нод.