Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Основы технологии блокчейн и криптовалют для менеджеров. Учебное пособие

.pdf
Скачиваний:
6
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
архитектуры Ethereum и неизменности общедоступных цепочек блоков опубликованный код сложно удалить, поэтому очень важно, чтобы в смарт-контрактах не было ошибок. Это был важный момент для сооб­щества Ethereum в целом, и он научил разработчиков, особенно разра­ботчиков с открытым исходным кодом, полностью контролировать без­опасность критически важного кода.
Coincheck позиционировалась как одна из крупнейших и самых популярных криптовалютных бирж в Азии, по крайней мере до взлома в январе 2018 г., который, после того как улеглась пыль, оказался круп­нейшим взломом криптовалюты в истории. В результате взлома Coin­check в январе 2018 г. было украдено более полумиллиарда долларов США. Сравните это со взломом биржи Mt.Gox в 2014 г., в результате которого было украдено или потеряно 400 миллионов долларов США. Coincheck подсчитал, что более 250000 пользователей пострадали от взлома, и заверил пользователей, что это была не проблема внутренней работы биржи, а взлом. Большая часть криптовалюты, украденной при взломе Coincheck, была потеряна в результате одного события. И срав­ните это со взломом биржи Mt.Gox, о котором мы упоминали, в резуль­тате которого она потеряла большую часть своей криптовалюты в про­цессе многочисленных краж за несколько лет. В настоящее время это уже вряд ли может произойти, но тем не менее, поскольку блокчейн еще молод, важно проявлять должную осмотрительность при использова­нии программного обеспечения блокчейн.
41
Г л а в а 3 . Т Е Х Н И Ч Е С К И Е О С Н О В Ы
Ф У Н К Ц И О Н И Р О В А Н И Я Т Е Х Н О Л О Г И И Б Л О К Ч Е Й Н
И К Р И П Т О В А Л Ю Т
В этой главе рассмотрим особенности биткоин, которые застав­ляют его работать. Во-первых, обсудим криптографические хеш-функ­ции: что это такое и как они используются в биткоин. Затем рассмотрим возможности использования криптографических хеш-функций для со­здания базы данных с защитой от несанкционированного доступа. Об­судим цифровые подписи, алгоритм цифровой подписи с эллиптиче­ской кривой и то, как мы на самом деле генерируем и используем наш закрытый ключ, открытый ключ и адрес. Наконец, вы познакомитесь со сценарием биткоин и его функциями, а также с его ролью в повышении гибкости биткоин.
Вспомним наши предыдущие предположения о биткоине: нам не нужно испытывать чувство доверия. Раньше мы рассматривали доверие в контексте консенсуса, но как насчет информации, которая перемеща­ется по сети? Например, если кто-то видит блок с моей транзакцией, что им помешает изменить или даже заменить его? Ранее мы продемон­стрировали, как достичь консенсуса по обновлениям цепочки блоков с помощью Proof-of-Work. Теперь продемонстрируем, как мы можем быть уверены, что обновление одинаково для всех, разработав систему защиты от несанкционированного доступа.
Очевидно, что несанкционированный доступ, вмешательство в систему передачи информации означает, что информация может быть изменена, что с ней произошли некоторые манипуляции. Для разра­ботки нашей базы данных с функцией отслеживания очевидного вме­шательства понадобится источник стандартизированной случайности. Для этого будем использовать криптографические хеш-функции.
В качестве самого простого способа понять, что собой представ­ляют и для чего используются хеш-функции, рассмотрим в качестве примера систему снятия отпечатков пальцев. Каждый из отпечатков пальцев уникален, трудно подделать и почти невозможно предсказать. При въезде в другую страну часто просят ваш отпечаток пальца, по­скольку это ваш уникальный идентификатор. Если мы сможем разрабо­тать способ создания отпечатков наших значимых данных, то сможем обеспечить целостность нашей информации. По аналогии с системой отпечатков пальцев: если информация изменилась, то изменится
42
43
и отпечаток пальца. Отпечатки пальцев – это просто стандартизирован­ная случайность. Вы не можете угадать, как будет выглядеть человек, просто взглянув на его отпечатки пальцев. Точно так же вы не должны угадывать данные, которые привели к созданию их цифрового отпе­чатка. Но как мы все договоримся о способах создания отпечатков паль­цев? Нам нужна стандартизированная случайность.
Криптографические хеш-функции – это односторонние функции, которые на входе принимают некоторую информацию и производят псевдослучайный вывод. Мы говорим «псевдослучайно», потому что, хотя нам это кажется случайным, на самом деле это всегда будет один и тот же вывод для некоторой заданной и введенной информации. Дру­гими словами, если я обработаю словосочетание «Здравствуй, Москва!» хеш-функцией и получу некоторый хеш этого словосочета­ния, то он будет таким же, если эту операцию провести еще один раз. Мы получим некий стандартный результат, что очень важно для стан­дартизации деятельности сторон.
Криптографическая хеш-функция всегда выводит сообщение определенного размера. Одно замечание: мы называем введенную на входе хеш-функции информацию прообразом, а на выходе – изображе­нием. Криптографические хеш-функции отличаются от обычных хэш­функций тем, что они созданы для обеспечения безопасности, но для удобства теперь будем называть криптографические хеш-функции хеш­функциями.
Прежде чем использовать хеш-функцию, необходимо опреде­лить, какими свойствами она должна обладать. Обсудим три важных свойства.
Во-первых, мы хотим быть уверены, что никто не сможет рекон­струировать наш отпечаток пальца, или, иначе говоря, никто не сможет рассекретить информацию, если мы этого не хотим. Техническое опре­деление выглядит следующим образом: учитывая некоторую хеш­функцию H и некоторый выходной сигнал функции H от x, вычислить x сложно. Другими словами, мы не можем легко обнаружить введенную информацию, на основе которой была создана выходная информация.
Во-вторых, мы хотим убедиться, что никто не может украсть от­печатки пальцев. Если кто-то другой может сгенерировать мой отпеча­ток пальца с другим вводом, тогда никто не сможет сказать, кто изна­чально сделал отпечаток. В данном случае техническое определение выглядит следующим образом: для некоторой хеш-функции H и неко­торого выходного значения H для x вычислительно сложно найти
44
другой вход x*, такой, что H для x равняется H для x*. Невыполнение этого условия приведет к неприятной ситуации наличия двух произ­вольных входов, приводящих к одному и тому же выходу.
В-третьих, чтобы этого не произошло, необходима защита, тех­ническое определение которой звучит следующим образом: для неко­торой хеш-функции H вычислительно сложно найти два разных входа x и y таких, что H для x равно H для y.
Следствием этих свойств является так называемый эффект ла­вины. Это означает, что любое изменение на входе приводит к псевдо­случайному изменению на выходе. Это предотвращает игру с вход­ными данными, в которой вы пытаетесь угадать выходные данные на основе входных данных. Можно хешировать строку «Я – Сатоши Нака­мото0», «Я – Сатоши Накамото1» вплоть до 19, при этом каждый полу­ченный результат будет псевдослучайным. Между хешами нет никакой связи, несмотря на то что входные данные очень похожи.
Конкретная хеш-функция, которую биткоин выбирает для ис­пользования во многих сценариях, называется SHA-256 (Secure Hash Algorithm ). SHA-256 – это криптографическая хеш-функция, разрабо­танная Агентством национальной безопасности США. SHA-256 явля­ется членом семейства криптографических хеш-функций SHA-2, а SHA – это алгоритм безопасного хеширования. SHA-256 принимает входные данные размером менее 264 бит и выдает 256-битный выходной сигнал фиксированного размера. На практике верхняя граница размера ввода 264 бит настолько велика, что мы обычно просто говорим, что она принимает произвольный объем информации. Биткоин во многих слу­чаях использует SHA-256 дважды подряд. Один раз в исходном сооб­щении, которое вы хотите хешировать, а в другой раз – в выводе этого первого хеша.
Рассмотрим некоторые метаданные, содержащиеся в заголовке блока, которые помогут нам получить свидетельство вмешательства в систему передачи информации. Так как же на самом деле выглядит эта база данных с очевидным вмешательством? Рассмотрим реальный пример блока, найденного на Blockchain.info, компании, которая отсле­живает всю информацию о биткоин на условиях открытого доступа. Вот как выглядит блок концептуально. Он состоит из четырех основ­ных компонентов: заголовка блока, размера блока, счетчика транзакций и транзакций. Поле «Заголовок блока» представляет метаданные, необ­ходимые для понимания компонентов блока. В поле «Размер блока» указано, насколько велик блок, в поле «Счетчик транзакций» – сколько
45
транзакций находится в блоке. Поле «Транзакции» – это фактические данные транзакции.
Сначала сосредоточимся на составе заголовка блока, информа­ции, которая обеспечивает безопасность цепочки блоков. Заголовок блока относится ко всем метаданным, связанным с каждым блоком, но мы будем рассматривать три наиболее важных показателя (поля в заго­ловке), которые реализуют протокол биткоин. Это поля Merkle Root (корень дерева Меркла), Previous Block Hash (хеш предыдущего блока) и Nonce (числовой параметр, искомый в ходе майнинга (алгоритме PoW) и записываемый в заголовок блока). Previous Block Hash – хеш предыдущего блока, представляет собой цепочку. Nonce представляет собой доказательство работы. Заголовок блока – это просто хеш всех объединенных полей. Корень дерева Меркла представляет собой сводку транзакций. Он содержит хеш от всего набора данных, т. е. хеш-дерево является одно­направленной хеш-функцией (рис. 3.1). Итак, что такое корень дерева Меркла и что мы подразумеваем под сводкой транзакций? Означает ли это, что мы собрали всю информацию о наших транзакциях в одном фрагменте информации? Что ж, на самом деле это означает, что мы со­брали все отпечатки информации в одном фрагменте данных. Корень дерева Меркла – это вершина дерева Меркла, которое представляет со­бой криптографическую структуру данных.
Это определенно сложно, поэтому не будем торопиться и начнем с самого начала. Прежде всего, дерево в информатике – это структура данных, которая имеет некоторый корневой узел и несколько дочерних элементов, которые также могут быть корнями других деревьев. Бинар­ное дерево – это дерево, в котором каждый узел имеет не более двух дочерних элементов. Дерево Меркла – это просто очень специфическая версия двоичного дерева. Двоичное дерево – иерархическая структура данных, в которой каждый узел имеет не более двух потомков. В листо­вые вершины двоичного дерева помещены хеши от блоков данных, а внутренние вершины содержат хеши от сложения значений в дочер­них вершинах. Возможно, лучший способ объяснить дерево Меркла – это описать его конструкцию.
Начинаем с набора транзакций и раскладываем их по одному (L1–L4), как показано на рис. 3.1. Хешируем каждый, чтобы получить уровень хешей. Затем хешируем каждую пару вместе, создавая новый уровень с вдвое меньшим количеством хешей. Продолжаем этот про­цесс до тех пор, пока у нас не останется только один хэш наверху. Этот
46
хеш на самом верху – это корень Меркла. Таким образом, мы можем обнаружить любые изменения транзакции после фиксации с помощью Merkle Root. Здесь мы видим, что если какая-либо транзакция изменя­ется, то это затрагивает корень Меркла.
Возникает вопрос: «Разве не дорого проверять, была ли транзак­ция включена в дерево Меркла?». На самом деле не дорого, для этого не нужно вспоминать каждую транзакцию. Мы действительно можем доказать это с помощью всего лишь одного фрагмента информации на каждом уровне дерева Меркла.
Совершенно очевидно, что каждый хеш блока содержит хеш предыдущего блока. Это означает, что если какой-либо блок изменя­ется, то блок после него также будет изменен, как и все последующие блоки. Заголовки (первый строки) блоков начиная со второго – это по сути хеш-коды предыдущих блоков (рис. 3.2). Это пример того, что происходит, когда ранее подделанный корень Меркла проявляется в блокчейне. Он изменяет заголовок блока, который изменяет хеш сле­дующего блока, что также влияет на остальные хэши будущих блоков. Остальная часть сети отклонит историю, предложенную этим блок­чейн, потому что они не согласятся. Вот почему блокчейн считается неизменным, потому что любое вмешательство легко увидеть.
Рассмотрим Nonce, физическое проявление Proof-of-Work (PoW). Nonce («нонс»)  –  числовой параметр, искомый в ходе майнинга (алго­ритме PoW) и записываемый в заголовок блока. Целью майнинга как соревновательного процесса за право добавить блок транзакций в блок­чейн и есть подбор такого Nonce, чтобы искомый хеш блока (Block Hash) был меньше некоторого заданного числа Target, что равнозначно получению хеша блока, начинающегося с определенного числа нуле­вых битов.
В биткоин мы делаем это с помощью хеш-головоломки с частич­ным прообразом, что означает частичный ввод. В биткоин нам дается часть ввода, и мы должны найти другую часть, которая производит определенный вывод. Условие, которое должно быть выполнено, – это то, что хеш заголовка блока меньше некоторого целевого значения. Это условие того, как Proof-of-Work реализован в биткоин и почти во всех других популярных криптовалютах. Чтобы удовлетворить наши по­требности в головоломке, эти хеш-головоломки должны иметь три ха­рактеристики: они должны быть сложными в вычислительном отноше­нии, параметризуемыми и легко проверяемыми.
47
Вычислительная сложность означает, что решение головоломки не может быть легко найдено, поэтому нет смысла, если Proof-of-Work требует немного усилий. Параметризуемый означает регулируемый. Сложность головоломки должна регулироваться, чтобы она никогда не становилась слишком легкой или слишком сложной. И, наконец, легко проверяемая головоломка гарантирует, что компьютерам не придется проделывать слишком много работы, чтобы убедиться, что ответ пра­вильный. Например, достаточно одного хеша, чтобы доказать, что ка­кое-то одноразовое значение является правильным, даже если на поиск одноразового номера уходят миллионы попыток.
Сложность реализована как требование наличия начального числа нулей в хэше заголовка блока. По мере увеличения количества нулей увеличивается и сложность, и наоборот. Эта сложность зависит от глобального хешрейта (хешрейт – единица вычислительной мощно- сти в сети биткоин).
Известно, что количество вычислительных мощностей в сети все­гда будет меняться, по мере того как майнеры присоединяются к сети и покидают ее, но мы хотим, например, поддерживать время расчета блока в десять минут. По этой причине мы должны повышать и пони­жать сложность наряду с ростом хеш-мощности и распадом сети. Если мы потратили слишком много времени, то это потому, что головоломку было слишком сложно решить, а если мы не потратили достаточно много времени, то загадка была слишком простой. В дальнейшем будем вносить коррективы в сложность головоломки. Итак, сложность об­ратно пропорциональна времени.
Может возникнуть вопрос: «куда вообще девается вознагражде­ние за блок для майнеров?». Он идет в транзакцию с базой монет. Вся­кий раз, когда майнер создает блок, он сначала выполняет транзакцию на основе монеты, которая всегда является первой транзакцией дерева Меркла. Эта транзакция с базой монет предоставляет майнерам возна­граждение в виде биткоинов, которые можно потратить позже. Вот как новые биткоины чеканятся или вводятся в сеть. Кроме того, транзакция Coinbase имеет отдельное поле Nonce, которое также используется в нашей хеш-головоломке. Расчеты повторяются бесконечно, пока не будет найден действительный блок. В каждом цикле мы сначала про­буем одноразовый номер Coinbase, а затем во внутреннем цикле исчер­пываем все возможные значения одноразовых номеров заголовков, за­тем увеличиваем одноразовый номер Coinbase и повторяем этот цикл.
48
Теперь рассмотрим, как использовать цифровые подписи для от­правки сообщений и транзакций как псевдонимно, так и без довери­тельных отношений с контрагентом. Ранее было показано, как транзак­ции, содержащиеся в предыдущих блоках в цепочке блоков, будут счи­таться действительными. Используя цифровые подписи, мы также мо­жем гарантировать, что текущие транзакции, которые мы отправляем в остальную сеть, также действительны. Мотивация наличия цифровых подписей связана с необходимостью аутентификации личности, чтобы мы знали, что полученное нами сообщение могло быть отправлено только одним другим пользователем, потому что он был подписан кон­кретным закрытым ключом этого пользователя, что доказывает владе­ние открытым ключом.
Рассмотрим двух пользователей в сети и назовем их Алиса и Бо­рис. Напомним, что у них обоих есть закрытый и открытый ключи. За­крытые и открытые ключи в биткоинах генерируются с помощью алго­ритма, называемого ECDSA, или алгоритма цифровой подписи с эллип­тической кривой, который мы рассмотрим позднее.
Итак, Алиса хочет отправить сообщение Борису. Как она может сделать это и убедиться, что никто не вмешивается в ее сообщение? Сначала мы указываем, что Борис имеет доступ к открытому ключу Алисы, поскольку это общедоступная информация, которая использу­ется для идентификации Алисы. Позже мы видим, что это важно, чтобы помочь Борису проверить, что сообщение, пришедшее от Алисы, дей­ствительно было отправлено ею. Перед отправкой сообщения Алиса подписывает сообщение своим закрытым ключом. Это генерирует уни­кальную подпись, которая доказывает, что она создала именно это со­общение. Затем Алиса отправляет свою подпись вместе со своим исход­ным сообщением Борису. Идея состоит в том, что сообщение является основной полезной нагрузкой, а подпись может использоваться, чтобы доказать, что Алиса была именно тем, кто создал это сообщение.
Затем Борис может легко проверить правильность подписи, учи­тывая открытый ключ Алисы и исходное сообщение. А если подпись действительна, значит, сообщение не было подделано. Чтобы Алиса со­здала эту подпись, у нее должен быть связанный закрытый ключ. Кроме того, в любой момент времени, если ее сообщение было подделано, подпись больше недействительна. Вот как схемы цифровой подписи де­лают сообщения действительными.
Ключевым моментом является то, что Борис или кто-либо еще не должен угадывать закрытый ключ Алисы, учитывая только ее
49
открытый ключ. В противном случае Борис или кто-либо другой смо­жет воссоздать подписи Алисы и таким образом подделать ее личность. Чтобы избежать этого, рассмотрим, как мы генерируем пары открытого и закрытого ключей.
Итак, вкратце, вот некоторые ключевые свойства, о которых мы должны помнить. Это важные свойства схем цифровой подписи, кото­рые активируются функциональностью, которую мы только что рас­смотрели, когда Алиса отправила сообщение Борису. Во-первых, имея сообщение и подпись, а также копию открытого ключа отправителя, по­лучатель должен иметь возможность идентифицировать источник со­общения. Поскольку сообщение было подписано закрытым ключом от­правителя, это означает, что исходный отправитель авторизовал это со­общение. Поскольку сообщение подписано закрытым ключом, его нельзя отменить, чтобы отменить эту подпись или аннулировать ее. Из­менение сообщения сделало бы его таким, что подпись больше не соот­ветствовала бы ему. Наконец, получатели сообщения также должны иметь возможность проверить целостность сообщения. Начинаем с закрытого ключа, который генерируем случайным образом. Затем можем использовать скалярное умножение точек эллип­тической кривой для получения открытого ключа. Далее можем ис­пользовать хеш-функции, чтобы наконец получить наш биткоин-адрес. Одно важное замечание: все упомянутые процессы – скалярное умно­жение точек эллиптической кривой и хеширование – являются односто­ронними. Мы можем идти вперед, но не назад. Закрытый ключ не был бы таким закрытым, если бы мы могли угадать его из соответствую­щего открытого ключа или адреса.
Обратимся к эллиптическим кривым. Биткоин использует ECDSA, или алгоритм цифровой подписи с эллиптической кривой, для создания закрытых и открытых ключей. Эллиптическая кривая – это просто математическая кривая, определяемая общей формой y2=x3 + ax + b. Мы хотим закодировать каждое возможное значение в пространстве поля эллиптической функции. Эллиптическая кривая биткоина, secp256k1: y2 = x3 +7. Это уравнение y2 = x3 + 7, показанное на рис. 3.3а, было выбрано специально так, чтобы эллиптическая кривая биткоина обладала определенными уникальными свойствами. Эта кри­вая задается парой параметров, включая саму формулу кривой (с ее ко­эффициентами), поле и точку генератора. Обратите внимание на симмет­рию кривой относительно оси x. Эта симметрия сохраняется даже при переходе к так называемому конечному полю. Конечные поля получили
широчайшее применение в криптографии. Алгоритмы на основе эллип-
а
б
тических кривых, являющиеся одним из ключевых объектов изучения в современной криптографии, также используют конечные поля.
Также обратите внимание, что любая невертикальная линия на этой кривой будет пересекать кривую не более чем в трех точках. На рис. 3.1а прямая, проходящая через точки P и Q, пересекает эллиптиче­скую кривую в точке R. На этой эллиптической кривой можем добав­лять точки, используя линии и точки. Чтобы добавить P плюс Q, доста­точно просто провести через них линию, пересекающуюся в третьей точке R, а затем отразить точку R поперек оси x, получив в результате: P + Q. И это называется процессом касательной к хорде. Это – лазейка, или односторонняя функция, потому что для точки K, которая является P + Q, трудно найти отдельные точки P и Q.
Рис. 3.1. Эллиптическая кривая биткойна, secp256k1: y2 = x3 +7
Рассмотрим еще одну иллюстрацию (рис. 3.1б). Начнем с точки генератора P, которая известна каждому, поскольку она встроена в спе­цификацию secp256k1. Чтобы сложить P с собой, просто возьмите ка­сательную в точке P. Если линия пересекает кривую, назовем ее –2P. Затем отражаем эту точку по оси x, в результате чего получаем от­вет: 2P. Чтобы получить 3P, можем добавить P к 2P с помощью того же процесса. Проведите линию через точки P и 2P, найдите, где они пере­секаются, что составляет –3P, а затем снова отразите эту линию по оси
x, чтобы получить ответ 3P.
50
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]