Согласование решения по масштабированию пропускной способности сети Биткоина к концу 2015 года зашло в тупик. Оба основных предложения - BIP100, выгодный для майнеров, и BIP101, подходящий бизнесу, имеют свою влиятельную группу поддержки, которая не хочет уступать позиций. Подробности ведущейся "подковерной борьбы" нам неизвестны, но все понимают, что решение необходимо принимать как можно быстрее.
Поэтому, презентованный разработчиком Петером Вюлле проект под названием Segregated Witness был встречен с энтузиазмом. Решение заручилось поддержкой технической части сообщества, и на него возлагаются большие надежды. Некоторые считают его тем самым долгожданным решением вопроса масштабируемости, которое, наконец, вернет мир и спокойствие в сообщество Биткоина. Строго говоря, это предложение не касается максимального размера блока и не решает проблему полностью, однако может значительно "притормозить" рост блокчейна, который уже прибавляет по несколько гигабайт в месяц.
Что же такое Segregated Witness и как это работает?
Еще раз о транзакциях Биткоина
Чтобы понять, что представляет собой Segregated Witness, необходимо понимать техническую сторону транзакций Биткоина. Протокол Биткоина предназначен для пересылки транзакций. Узлы пиринговой сети отправляют друг другу не биткоины; они отправляют пакеты с данными транзакции.
В каждой транзакции содержится два главных компонента. Первый компонент разблокирует биткоины, заблокированные в предыдущих транзакциях, используя для этого фрагменты данных под названием "входы" (inputs). Входы содержат скрипты - инструкции по разблокировке входа, которые называются подписями scriptSigs. Второй компонент транзакции состоит из одной или нескольких частей, называемых "выходами" (outputs). Выходы вновь блокируют то же самое или меньшее количество биткоинов, но уже для следующего получателя. Выходы содержат скрипты, связанные с открытыми ключами (scriptPubKeys). То есть, биткоины передвигаются внутри каждой транзакции от входов к выходам, и одновременно перепрыгивают между самими транзакциями.
Однако, из этого правила есть одно важное исключение. Транзакция coinbase представляет собой транзакцию, которая автоматически генерируется кошельком майнера при создании нового блока и содержит награду за блок: на данный момент это 25 биткоинов. Майнер может увеличить награду coinbase количеством биткоинов, разблокированным в транзакциях, но не заблокированным вновь: то есть разницей между входами и выходами. Это "комиссионные сборы" за транзакции, добровольно оставляемые пользователями за поддержку сети.
Все эти «разблокировки» и «блокировки» Биткоина производятся отправителями транзакций. Далее они передаются по сети Биткоин в виде пакетов данных. После этого узлы (ноды) сети проверяют правильность проведения процесса разблокировки и блокировки. Если проверка пройдена, транзакция отправляется дальше к другим нодам. В случае, если нода также является майнером, она может включать транзакцию в блок. Как бы то ни было, только клиенты сети, принадлежащие майнерам решают на основе своих алгоритмов, каким образом поступать с приходящими транзакциями; именно поэтому имеет смысл включать комиссионный сбор.
Крайне важно, чтобы правила, применяемые для подтверждения транзакций нодами пользователей, не противоречили правилам, применяемым большинством майнеров. Если кто-то из майнеров включает в блок транзакции, отвергаемые другими нодами, то весь блок будет считаться данной нодой ошибочным. Если эта нода является майнером, это может привести к двойным тратам и раздвоению блокчейна.
Правила консенсуса, с которыми соглашаются все узлы сети, позволяют транзакциям блокировать и разблокировать биткоины разными способами. Выходы содержат открытый ключ scriptPubKey, говорящий что-то вроде: «Докажи, что ты владеешь закрытым ключом, составляющим пару открытому ключу, соответствующему данному адресу Биткоин».
Восстановить открытый ключ из закрытого довольно просто. Однако практически невозможно сделать обратное. То же самое относится к адресу Биткоина: легко восстановить адрес Биткоина из открытого ключа, но невозможно восстановить открытый ключ из адреса Биткоина. Похоже на улицу с односторонним движением.
Адрес Биткоин, который используется в открытом ключе scriptPubKey - это адрес, который предоставляет сторона-получатель транзакции. Поскольку именно получатель создает адрес, использующий известный ему одному закрытый ключ, только он может создать корректную подпись scriptSig и, следовательно, он один может создать новую транзакцию и потратить заблокированный биткоин.
Где находятся подписи?
Теоретически, для доказательства владения закрытым ключом, этот ключ можно вставить в подпись scriptSig транзакции, но это далеко не безопасно. Ллюбой, кто прочитает транзакцию, может взять закрытый ключ и создать новую транзакцию, либо изменить оригинальную. По сути, он становится равноправным владельцем этих биткоинов, до включения оригинальной транзакции в блок. Если крупный майнер поступит таким образом, украсть биткоины не составит никакого труда: ведь именно он выбирает, какие транзакции подтверждать.
Поэтому открытый ключ scriptPubKeys обычно требует, чтобы в scriptSig содержалась одна или более подписей для разблокировки биткоина.
Подписи представляют собой криптографический прием, который использует закрытый ключ в комбинации с другими данными для подсчета уникальной последовательности чисел. Благодаря криптографической магии соответствующий открытый ключ может использоваться для подтверждения того, что подпись создана с использованием закрытого ключа. Так подписи доказывают и владение закрытым ключом, и подтверждение определенного фрагмента данных владельцем этого закрытого ключа.
В случае с Биткоином закрытые ключи обычно используются для подписи данных транзакции за минусом входов. Отсюда открытые ключи scriptPubKeys, заблокированные суммы и некоторые дополнительные детали. Подпись и открытый ключ добавляются в область входа транзакции. Это доказывает то, что владелец закрытого ключа действительно намеревался создать транзакцию, и гарантирует ее подлинность.
Далее, все эти данные транзакции – на этот раз, включая входы, - хэшируются вместе, создавая идентификатор транзакции, который позволяет опознать транзакцию. Если впоследствии транзакция включается в блок, майнер хэширует идентификатор транзакции вместе с другими идентификаторами для создания нового хэша. И этот хэш хэшируется снова, на этот раз вместе с хэшем из двух других идентификаторов транзакций. Этот процесс продолжается до тех пор, пока не останется один последний хэш. Такая структура хэшей называется MerkleTree, а оставшийся хэш - MerkleRoot. MerkleRoot соединяется с дополнительными данными блока, формируя заголовок блока, который используется для идентификации собственно блока. Наконец, хэш блока должен быть включен в следующий заголовок блока, сцепляя блоки между собой.
Считается, что данные в блокчейне Биткоина неизменяемы, поскольку изменение любой части транзакции в дальнейшем изменяет ее идентификатор, что, в свою очередь, влечет за собой изменения в заголовке блока. Этот измененный заголовок блока больше не будет отвечать требованиям модели PoW (доказательство работы). А поскольку заголовок блока влияет на состав заголовков последующих блоков, соответствовать PoW не будет вся цепочка.
Что такое Segregated Witness?
Но вернемся к предложению Segregated Witness. В основе решения лежит модель, применяемая в сайдчене Blockstream под названием Elements, а также идеи разработчика Bitcoin Core Люка Дэша Младшего (Luke Dash jr). Предложение разрабатывалось в течение нескольких последних месяцев при участии Грегори Максвелла (Gregory Maxwell) и Эрика Ломброзо (Eric Lombrozo) и может быть реализовано в течение следующего года.
С точки зрения узлов Биткоина, не использующих Segregated Witness (назовем их «старыми нодами»), некоторые из только что созданных выходов очень скоро могут начать использовать странный тип открытых ключей scriptPubKeys. Странный, потому что эти scriptPubKeys вряд ли можно считать блоком. Так как обычно такие ключи характеризуются фразой: «Любой может потратить», в основном они (scriptPubKeys) заявляют, что им не требуется подпись. Кроме этого они будут включать в себя некий бессмысленный текст.
Старые ноды посчитают такие транзакции неправильными. Они подумают, что любой может создать новую подпись scriptSig, разблокировав данные выходы, то есть они, мягко говоря, небезопасны. Однако старые ноды не будут и отвергать эти транзакции. В конце концов, это не их биткоины, а другие люди могут делать со своими биткоинами все, что им вздумается. Бессмысленные тексты посчитают странными, но не более того. Поэтому транзакции будут подтверждены и отправлены другим нодам сети.
Однако, узлы с поддержкой Segregated Witness (назовем их «новыми нодами») заметят еще кое-что. Они прочитают "бессмысленный текст" в открытом ключе scriptPubKey, однако вовсе не посчитают его бессмысленным. Наоборот, новые ноды определят этот фрагмент текста в качестве еще одного – очень специфического – типа выхода.
Подобно обычным выходам, для разблокировки биткоина этому новому типу выхода потребуется одна или несколько подписей. Однако в отличие от обычных выходов, новый тип не требует, чтобы подпись была включена в scriptSig соответствующей транзакции. Вместо этого ему нужно, чтобы подпись включалась в абсолютно новый фрагмент транзакции: Segregated Witness.
По сути, Segregated Witness представляет собой «дополнительный компонент»), содержащий подписи и некоторые другие данные. Очень важно, что Segregated Witness полностью игнорируется старыми нодами, однако признается новыми. Более того, данные, которые несет в себе Segregated Witness, не хэшируются вместе с другими фрагментами транзакции в ее идентификатор.
Таким образом, и старые, и новые ноды посчитают корректными транзакции, содержащие подписи в Segregated Witness. Старые ноды подтверждают их, потому что, с их точки зрения, эти транзакции не требуют подписи, а новые ноды подтверждают их, так как требуемая подпись находится в Segregated Witness. А поскольку и старые, и новые ноды хэшируют данные транзакции в один и тот же идентификатор, каждый соглашается с составом блоков и со структурой всего блокчейна.
Очень важно, чтобы все майнеры (или их большинство) использовали Segregated Witness для предотвращения двойных трат и форков цепи. Если все майнеры будут применять Segregated Witness, старые ноды в сети могут заинтересоваться, почему некоторые транзакции не включаются в блоки. Однако, поскольку эти транзакции им не принадлежат, они не будут против.
Здесь есть одна проблема: если подписи не влияют на состав блокчейна, блокчейн уже не выступает в роли доказательства того, что в блок были включены правильные транзакции.
Чтобы быть уверенным в том, что подписи включены в блокчейн, поддерживающие Segregated Witness майнеры применяют хитрый прием. Вместо того, чтобы создавать из всех транзакций только структуру данных Merkle Tree, майнер создает Merkle Tree из всех Segregated Witnesses, чтобы отражать дерево транзакций. В таком случае, Merkle Root с Segregated Witness включается в область входа транзакции coinbase. Таким образом, Merkle Root с поддержкой Segregated Witness изменяет данные транзакции coinbase, ее идентификатор транзакции, и оказывает влияние на заголовок блока, то есть по-прежнему записывает данные в блокчейн.
Предложение Segregated Witness позволяет извлекать подписи из транзакций Биткоина, одновременно поддерживая их неизменность и не нарушая ни одного из существующих правил консенсуса.
Что делает Segregated Witness?
Если коротко - позволяет увеличить эффективность блокчейна без увеличения размера блока. Преимущество предложения Segregated Witness заключается в том, что исключение подписей из блока в 1Мб может эффективно увеличить размер блока Биткоина. Это значит, что в каждый блок можно будет записать большее количество транзакций, или, другими словами, повысить пропускную способность блокчейна. Все это происходит без нарушения существующих правил консенсуса.
Предложение Вюлле действительно предлагает новый подход к решению проблемы размера блока. Формула, которая используется для расчета предельного размера, выглядит не очень определенно:
Данные блока плюс "четверть" Segregated Witnesses не должны превышать 1 Мб. В таком случае, все блоки покажутся старым нодам меньше 1 Мб, поскольку четверть Segregated Witness (которую они не видят) должна быть установлена в тот же самый 1 Мб. При этом новые ноды увидят блоки, превышающие 1 Мб, так как фактический размер Segregated Witness больше того, что считается одной четвертью.
Точное количество дополнительного пространства, предоставляемого Segregated Witness, зависит от типов транзакций, входящих в новые блоки. Если больше транзакций хранят большее количество данных в Segregated Witness, как происходят в транзакциях с мультиподписью, эффективный размер блока увеличивается. Это добавляет около 1.75МБ в максимальный размер блока для нормальных транзакций, и размер в 4Мб устанавливается в качестве жесткого ограничения, которое невозможно превысить, даже если в Segregated Witness вместились (почти) все данные.
Попрощайтесь с эластичностью транзакций
У Segregated Witness есть еще одно важное преимущество: это решение может позаботиться об "эластичности транзакций" Биткоина. Фактически, изначально это и было мотивацией для Вюлле и других в разработке модели.
Эластичность транзакций вызывается криптографическим приемом смены подписи без изменения содержимого. Это можно сделать без закрытого ключа, используемого для создания оригинальной подписи. В случае с Биткоином это значит, что любой участник может подобрать из пиринговой сети любую транзакцию, и изменить одну подпись на другую такую же ценную подпись. Эта новая подпись будет отражать точно такие же данные, какие она изначально подписала, и ее все так же можно подтвердить при помощи того же самого открытого ключа. Она абсолютно не меняет того, что выполняет транзакция. Но так как она выглядит по-другому, она действительно полностью меняет идентификатор транзакции.
Эластичность транзакций вызывает две основные проблемы. Во-первых, она вносит хаос в сторонних приложениях, которые используют идентификаторы транзакций в учете совершенных сделок. По одной из версий, именно на эту удочку в свое время был пойман Марк Карпелес, когда хакеры "выносили" биткоины с MtGox, используя эту уязвимость. Но еще важнее то, что эластичность транзакций сильно ограничивает возможности любых сделок с биткоинами, использующих неподтвержденные транзакции для ускорения операций - например, платежные каналы или Lightning Network.
Segregated Witness удаляет подписи из компонента транзакции, используемого для создания идентификаторов транзакций. Поэтому, новый формат никак не влияет на приложения, использующее идентификаторы транзакций. Это также не играет роли для платежных каналов или Lightning Network, таким образом предоставляя готовую площадку для внедрения дополнительных слоев масштабирования.
Как Биткоин может стать универсальным
Еще одно важное преимущество предложения Segregated Witness – это версии скриптов. Как уже объяснялось, Segregated Witnesses содержит подписи scriptSigs, которые разблокируют биткоины. Однако они включают в себя еще кое-что, а именно: байты версий. Эти байты версий предшествуют подписям scriptSigs в Segregated Witnesses, демонстрируя вид подписи scriptSig. Если клиент, читающий байт версии, опознает этот тип, он может сообщить, какие требования необходимо выполнить для разблокировки биткоина в scriptSig. Если же в байте версии не опознан этот тип, она интерпретирует подпись scriptSig как «Может потратить любой».
Это открывает множество новых способов блокировки биткоинов в транзакциях. По сути, данное преимущество можно использовать для любых блокировок биткоинов. Сложно сказать, каким образом это преимущество можно будет использовать в будущем, поскольку большую часть приложений еще только предстоит придумать. Однако предполагается, что это будут подписи Schnorr, более быстрые для подтверждения по сравнению с традиционными подписями, а также более сложные виды транзакций с мультиподписями; возможно даже скрипты наподобие Ethereum.
Доказательства обмана
И это еще не все. Segregated Witness может также представить решение под названием "доказательства обмана" (fraud proofs). Их предвидел еще Сатоши Накамото, и доказательства обмана могут значительно повысить безопасность SPV-клиентов («легких кошельков») - это узлы Биткоина, которые не подтверждают транзакции в сети и не хранят полный блокчейн.
Чтобы проверить, действительно ли транзакции состоялась, SPV-клиенты просто сканируют блокчейн на наличие соответствующего идентификатора транзакции. Если они его находят, это означает, что майнер включил транзакцию в блок. Но SPV-клиенты не определяют, соблюдает ли транзакция правила консенсуса Биткоина. Таким образом, SPV-клиенты доверяют майнерам. В худшем случае, это может означать, что майнеры могут оплачивать SPV-клиентам биткоинами, созданными из ничего, например, создавая транзакции без входов или награждая себя повышенными комиссионными в транзакции coinbase.
Такие проблемы можно решить, если требовать от майнеров включать лишние данные в структуру данных Merkle Tree в Segregated Witness, определяя тем самым, откуда именно поступил биткоин, заблокированный в данной транзакции.
Таким образом, если блок содержит некорректные транзакции, короткое и легко проверяемое доказательство обмана может быть создано любым полным клиентом. Эта полная нода может отправить доказательство обмана SPV-клиентам, чтобы они знали, что блок необходимо отвергнуть.
Таким образом, даже при наличии доказательств обмана, SPV-клиенты не могут предложить такой же уровень защиты, как полные. Самое главное, что решение доказательства обмана (fraud proof) требует, чтобы SPV-ноды могли связываться с сетью без цензуры. Дополнительно, SPV-клиентам необходимо, чтобы по крайней мере одна полная нода в сети производила доказательства обмана.
Сжатие блокчейна
Наконец, что наиболее важно держателям "полных узлов" Segregated Witness может уменьшить количество данных, необходимое узлам Биткоина для хранения на своих жестких дисках. Это сокращает требования для запуска полной ноды и уменьшает время, которое требуется на синхронизацию в сети при первой установке.
Тогда как полные узлы обычно хранят все данные транзакций для всей истории Биткоина, подписи могут считаться неактуальными по прошествии определенного промежутка времени. После того, как транзакция определяется как корректная, подтверждается в блоке, и закрепляется в блокчейне, скажем, на один год, она может быть подделана, только если майнеры все время коллективно занимались майнингом в некорректной цепи, и никто якобы этого не замечал. Гипотетически, это снижает защиту сети, но на практике со временем может быть применено.
Segregated Witness и BIP10х
Как же Segregated Witness может решить проблему масштабируемости блока? Segregated Witness извлекает подпись из транзакции и помещает ее в отдельную структуру данных. Когда из транзакции удаляется подпись, размер транзакции уменьшается. Следовательно, каждая транзакция уменьшается приблизительно на 47%, и мы получаем на 47% больше транзакций при том же размере блока.
Однако, нельзя считать, что эта технология полностью решает проблему масштабируемости. Остается все тот же 1Мб пространства блока, и когда оно снова будет заполняться во всех блоках, проблемы появятся вновь. Предлагаемое Segregated Witness сжатие данных может быть очень полезно. Однако, его можно использовать только в качестве дополнения к действительно эффективному решению проблемы размера блока.
Таким образом, Segregated Witness в качестве "весомого аргумента" включается в "войну BIP-ов" и может стать козырем для той стороны, которая найдет этой технологии наилучшее применение. Вероятно, лучшие шансы на этот раз у BIP102 Джеффа Гарзика и BIP248 от Адама Бэка - руководителя компании Blockstream, одного из основных игроков в этой схватке. Эти два предложения наиболее консервативно подходят к изменению размера блока, а значит, их поддержит осторожная часть сообщества, которая страшится резких перемен.
Проверка в SegNet
Сейчас уже можно говорить о том, что технология Segregated Witness активно продвигается и в ближайшем будущем найдет себе применение в действующей сети Биткоина. Команда разработчиков Bitcoin Core создала специальную тестовую сеть под названием SegNet для проверки этой инновации, способной внести в протокол радикальные изменения, подобных которым не было уже несколько лет. SegNet представляет собой полную копию блокчейна Биткоина и была официально запущена 31 декабря.
В проекте участвуют Петер Вюлле (Pieter Wuille), Эрик Ломброзо (Eric Lombrozo), Джонсон Лоу (Johnson Lau), Алекс Моркос (Alex Morcos) и еще несколько программистов, которые с помощью различных патчей будут проводить тестирование и искать уязвимости, которые может вызвать вынесение подписей транзакций в отдельный компонент блокчейна.
Вероятно, до интеграции в Bitcoin Core первоначальная концепция Segregated Witness может претерпеть некоторые изменения. Сроки эксперимента и условия, необходимые для внедрения Segregated Witness в основную сеть, пока не афишируются.