В первых двух лекциях были рассмотрены основные механизмы, используемые в Биткоине. В этой лекции будут показаны реальные структуры данных, скрипты и другие подробности реализации этих механизмов.
Повторим основные моменты, рассмотренные в предыдущих лекциях.
Консенсус Биткоина имеет следующие особенности:
Предполагается, что валюта существует, чтобы мотивировать работу майнеров!
Журнал (реестр) в режиме Append-Only предполагает ведение журнала транзакций только в режиме добавления записи. При этом как только запись сделана, она остается в журнале навсегда. Для достижения согласованности по поводу истинности журнала используется децентрализованный протокол и майнеры, которые следуют этому протоколу и утверждают транзакции. Они подтверждают то, что транзакции правильно сформированы, что нет двойных расходов, и что Биткоин исправно функционирует, как валюта.
(рис 3.1) Журнал, основанный на банковском счете (не Биткоин)
Биткоин существует, чтобы мотивировать майнеров добывать биткоин. И чтобы понять этот механизм, рассмотрим, как происходит транзакция Биткоина.
Возьмем упрощенную модель, где вместо блоков транзакций будут индивидуальные транзакции, выполненные по одному разу в каждый момент времени. Можно провести аналогию с банковским счетом (рис 3.1). Чтобы переслать Бобу 17 монет, Алиса создает транзакцию и ставит под ней свою подпись. Информация о сделке сохраняется в журнале.
В качестве подтверждения наличия у Алисы монет, приведена информация о том, что в ходе первой транзакции Алиса получила 25 монет. После передачи 17 монет Бобу у нее осталось 8 монет.
После того, как Боб получил монеты, он может передать какое-то количество монет Чаку, тот в свою очередь Алисе и т.д. В результате у Алисы, Боба и Чака будут разные состояния счета.
На рис 3.1 самая нижняя транзакция – передача Алисой 15 монет Дэвиду. Как можно убедиться, что у нее есть 15 монет для передачи их Дэвиду?
Чтобы это выяснить, нужно проверить всю цепочку транзакций, связанных с Алисой. Всякий раз, когда Алиса отправляла или получала монеты, все эти действия нужно обнаружить и затем выяснить, хватит ли ей тех 15 монет, которые она хочет переслать. Конечно, это можно сделать несколько эффективнее, например, со структурой данных, которая бы отслеживала каждую транзакцию Алисы, но это потребует огромных дополнительных расходов памяти, помимо ведения самого блокчейна.Именно поэтому Биткоин не работает по принципу банковского счета. Вместо этого, у Биткоина есть журнал с историей транзакций. На рисунке 3.2 изображен журнал транзакций, похожий на биткоиновский.
(рис 3.2) Журнал, основанный на транзакциях (Биткоин)
В транзакциях указаны количество вводов и количество выводов. У транзакций также есть свой уникальный индекс. Начнем с транзакции №1, где ничего не вводится, так как здесь формируется валюта, и есть один вывод в размере 25 монет, которые переходят к Алисе.
Поскольку в этой транзакции создаются новые монеты, она не требует подписи.
Чтобы передать 17 монет Бобу Алиса должна сослаться на транзакцию, в рамках которой она получила эти монеты. Таким образом, в качестве ввода для этой транзакции будет транзакция с индексом 0, которая была предыдущей, где говорится, что Алиса получила 25 монет. У транзакции будет 2 вывода. Один, в котором пересылается 17 монет Бобу, и второй, где Алиса получает 8 монет. Для подтверждения транзакции ее подписывает Алиса.
Рассмотрим, зачем Алисе переводить деньги самой себе. Вот она получает 25 монет, которые были предназначены для неё в первой транзакции, из них лишь 17 штук она пересылает Бобу, и теперь ей нужно сделать еще один вывод в размере 8 монет самой себе, пусть и под другим индексом, но все-таки себе.
Эта называется переадресацией. Идея в том, что всегда нужно вывести остаток с предыдущей транзакции. Нельзя сделать так, что со счета потратилось только 17 монет. Можно сделать лишь так, что с одного вывода потратятся все 25 монет. Но так как Алиса хочет потратить только 17 монет, она сделает второй вывод (8 монет) на себя
Добавим новую транзакцию и выясним, действительная ли она. Достаточно будет взглянуть на блокчейн, так как теперь известно, на какие вводы смотреть. Нужно перейти к транзакции 2, вывод 1 и посмотреть, что денег достаточно и они еще не потрачены. Можно посмотреть на транзакцию и сделать вывод о том, что во втором выводе Элис пришли 8 монет, значит, у нее достаточно монет, чтобы совершить все выводы в этой транзакции.
Таким образом, действительность транзакции проверяется методом обратного конечного поиска.
Помимо этого применяются хеш-указатели. У каждой транзакции есть свой уникальный индекс. Это просто номер (хеш) блока. И каждая транзакция, по сути, тоже получает свой уникальный индекс, который является хешем транзакции.
То есть нужно просто пройти на один хеш-указатель вверх и выяснить, достаточно ли денег, чтобы совершить желаемые выводы в следующей транзакции.
(рис 3.3) Две подписи
Еще одна вещь, которую можно сделать - слияние значений. Допустим, есть две разные транзакции, которые переводят деньги Бобу - 17 монет в одной и еще 2 в другой. Боб может сказать: я бы хотел, чтобы у меня была одна транзакция, которую я мог бы потом израсходовать.
Чтобы это сделать, нужно создать новую транзакцию с двумя вводами и одним выводом, чтобы все эти деньги ушли Бобу. Аналогичным образом можно выполнять слияние оплат.
Допустим, Кэрол и Боб хотят переслать деньги Дэвиду. Можно создать транзакцию с двумя вводами, которые совершаются двумя разными людьми и сложить эти значения, тем самым передав Дэвиду все 8 монет.
Единственная особенность здесь в том, что поскольку эти два вывода производятся двумя разными людьми, то нам нужны две подписи: одна от Кэрол, вторая - от Боба (рис 3.3).
(рис 3.4) Реальная транзакция Биткоин
На рис 3.4 показана, как именно выглядит транзакция Биткоина. И это не вся транзакция, а только красиво оформленное представление (скорее всего на языке JSON). В действительности, транзакция представлена в компактном двоичном формате, который компилируется в такую нечитабельную, но крайне похожую на реальную низкоуровневую транзакцию.
Транзакция состоит из трех частей. Во-первых, это метаданные, затем это серия вводов, и серия выводов. Начнем с метаданных.
(рис 3.5) Метаданные транзакции
"Домашняя" информация содержит, например, размер транзакции, количество вводов и количество выводов. Хеш-номер всей транзакции, который служит уникальным индексом для транзакции и позволяет делать хеш-указатели. И еще тут есть некий параметр lock_time, о котором будет рассказано позже.
(рис 3.6) Вводы транзакции
Вводы транзакции - это массив входных данных с одной и той же формой.
Вводы подробно описывают предыдущую транзакцию, поскольку у них есть хеш предыдущей транзакции, или хеш-указатель на нее.
И индекс вывода из указанной транзакции.
Также имеется подпись scriptSig (рис 3.6). Подпись подтверждает вывод из предыдущей транзакции.
(рис 3.7) Выводы транзакции
У каждого вывода есть свое значение. Сумма всех выводов должна быть меньше, чем сумма всех вводов.
В этой структуре есть еще что-то похожее на хеш открытого ключа. Это адрес получателя конкретного вывода. Структура данных похожа на скрипт и об этом будет рассказано в следующих лекциях.
Каждый вывод в транзакции не только описывает простой открытый ключ, но и объявляет скрипт. Для чего этот скрипт используется? Рассмотрим, что из себя представляет скриптовый язык Биткоина, и почему он используется вместо того, чтобы обозначить открытый ключ.
(рис 3.8) Скрипт в качестве адреса выхода
В качестве примера возьмем наиболее распространенный скрипт Биткоина, который исполняет предыдущую транзакцию после ее подписания корректным открытым ключом.
У скрипта будут 4 инструкции, и что же происходит со скриптом? Кто его запускает? Как скрипт понимает, кто имеет право на расходование монет? Секрет в том, что адрес ввода - это тоже скрипт. Это такой вид скрипта, который соединяется со скриптом вывода, они сцеплены вместе и образуют единый скрипт, который должен успешно запуститься, чтобы получить Биткоины.
(рис 3.9) «Адреса» ввода – это тоже скрипты
Как правило, эти два скрипта называются scriptSig и scriptPublicKey, потому что, в самом простом случае, скрипт вывода объявляет открытый ключ, а скрипт ввода создает подпись с тем же самым открытым ключом.
Когда транзакция проходит верификацию, два скрипта соединяют вместе и запускают, и если получившийся скрипт запускается без ошибок, то транзакция признается действительной.
(рис 3.10) Скриптовый язык Биткоина («Скрипт»)
У языка, используемого в Биткойн нет точного названия. Его называют просто "Скрипт" или "скриптовый язык Биткоина", так как он был создан специально для него. Наибольшее влияние на него оказал язык Forth, это старый и простой язык программирования, основанный на работе стеков, однако совсем не обязательно знать Forth, чтобы понимать скриптовый язык Биткоина.
Ключи создавались таким образом, чтобы это было что-то простое и компактное, но в то же время, чтобы его было сложно расшифровать. Поэтому существуют специальные инструкции, чтобы проводить вычисления хеш-функций и верифицирование подписей.
Также это стековый язык программирования. На следующем рисунке будет показано, почему он так называется. В языке существует множество ограничений, которые очень важно помнить. В частности, у скриптового языка Биткоина нет циклов. Каждая инструкция выполняется только один раз линейным путем. Если посмотреть на скрипт, который состоит из некоторого числа инструкций, то можно точно сказать, сколько времени потребуется для его запуска и сколько памяти он займет.
Как следствие, по Тьюрингу этот язык считается неполным.
Он не способен вычислять бесконечно мощные функции. Это все из-за его внешнего вида, потому что майнерам нужно запускать скрипты, которые пересылаются рядовыми участниками сети. Само собой, никто не захочет давать им право переслать скрипт, который будет зациклен или будет работать бесконечно.
И так как это неполный язык по Тьюрингу, он также не подвержен проблеме остановкиМожно посмотреть на любой скрипт языка Биткоина и убедиться, что он уничтожится после конечного числа шагов, которые являются количеством инструкций, содержащихся в скрипте. Рассмотрим конкретный скрипт Биткоина и то, как именно он выполняется.
(рис 3.11) Пример исполнения скрипта Биткоина
На рис 3.11 изображен скрипт, в котором отправитель просто задает открытый ключ получателя, а получатель монет, чтобы их получить, должен объявить подпись, используя тот же самый открытый ключ.
Итак, первые две инструкции в скрипте ввода – это просто инструкции для ввода данных в стек. В стек записывается подпись транзакции и открытый ключ получателя, который может ее проверить.
Исполнение инструкций для данных в стековых языках проводится очень легко. Если есть данные, то они последовательно заносятся в стек.
И это единственный способ работы с памятью, который доступен в стековом языке программирования. Также здесь нет переменных, есть только стеки, так что все, что можно сделать, чтобы записать данные в память - поместить их в стек.
Теперь, когда два значения внесены в стек, запускается вторая часть скрипта. Эта часть называется scriptPubKey.
Дублирущая инструкция OP_DUP гласит: "Возьми значение из верхушки стека, выкинь его, а затем впиши две его копии обратно в стек." Таким образом открытый ключ получателя продублирован.
Следующая инструкция HASH160 говорит: "Возьми верхнее значение в стеке и вычисли из него криптографический хеш."
Верхнее значение из открытого ключа превратится в хеш этого ключа.
На следующем шаге в стек вносится значение хэша открытого ключа получателя, которое было рассчитано отправителем.
Теперь на верху стека два значения: хеш открытого ключа, объявленного отправителем, и хеш того ключа, который использовал получатель, чтобы получить монеты.
Запустим верифицированную обеими сторонами команду OP_EQUALVERIFY, в которой просто объявится, что те два значения, которые находятся на верху стека, равны.
Если же это не так, то будет выведена ошибка, и скрипт прекратит выполняться. Предположим, что значения равны, то есть получатель монет использовал корректный открытый ключ.
(рис 3.12) Пример запуска скрипта Биткоин
Инструкция сравнения поглотит те два элемента данных, которые находились на верху стека. В стеке остались еще два элемента – подпись и открытый ключ.
На этом этапе уже есть уверенность в том, что ключ, который предоставил получатель, правильный. Теперь необходимо проверить действительность подписи. Именно здесь проявляется вся мощь скриптового языка Биткоина. Есть такая инструкция, которая позволяет верифицировать подпись. Так что написать скрипт, подтверждающий действительность подписи, не подключая при этом ни одной специальной библиотеки, очень просто. Все эти возможности уже встроены в скриптовом языке Биткоина.
Рассмотрим, что послужило вводом для функции подписывания?
Единственное, что можно подписать в Биткоине - это весь процесс транзакции. Инструкция checkSig подтверждает, что вся транзакция была успешно подписана.
Всего за один заход инструкция checkSig вынесет из стека два оставшихся элемента, и проверит действительность подписи. После выполнения всех инструкций в скрипте, в стеке больше нет данных, и не появилось ни одной ошибки, выводом скрипта будет простое "Да". Итак, у любого скрипта Биткоина существует два исхода: он может выполниться без ошибок, в таком случае транзакция будет действительной. Если при выполнении скрипта обнаружится ошибка, вся транзакция будет признана недействительной, и она не будет включена в блокчейн.
Инструкции скрипта Биткоина
Всего 256 кодов операций (15 не работают, 75 – в резерве):
Рассмотрим скриптовый язык Биткоина. Он очень маленький, в нем всего 256 инструкций, потому что каждой из них выделяется по одному байту памяти. Из них 15 инструкций нерабочие, и воспользоваться ими никак нельзя. Еще 75 находятся в резерве - в них пока нет особой необходимости. Но в будущем их могут сделать основными. Из основных же инструкций присутствуют такие, которые встречаются в любом языке программирования - основы арифметики, логики, конструкции "If-then". Вбрасывание и не-вбрасывание ошибок, ранние выходы.
Также, как упоминалось выше, в нем присутствуют криптоинструкции. Это и хеш-функции, это и инструкции для верификации подписей, и одна особая, крайне важная инструкция для верификации множества подписей. Она называется CHECKMULTISIG. Это более мощная инструкция, чем та, что проверяет единичную подпись. С помощью нее Биткоин позволяет проверить множество подписей одной инструкцией.
OP_CHECKMULTISIG
Предупреждение о баге: дополнительная единица данных выносится из стека и игнорируется
При помощи MULTISIG объявляется N открытых ключей и параметр T (т.н. "порог"). Чтобы эта инструкция сработала нормально, необходимо, чтобы было T подписей и T из N действительных открытых ключей.
У функции есть один важный баг. Это недоработка, которая существует уже давно, она заключается в том, что в первоначальной инструкции, а именно CHECKMULTISIG выкидывается из стека и игнорируется лишняя единица данных. Это одна из причуд языка Биткоина. С ней можно справиться, если при программировании добавить в стек дополнительную дамми-переменную. В данном случае баг было решено признать особенностью Биткоина и не пытаться его удалить. Исправлять эту ошибку дороже, чем тот ущерб, что она может нанести, так что теперь это просто забавный баг, с которым старается уживаться каждый член Биткоиновского сообщества.
Как уже отмечалось выше, скриптовый язык был использован для того, чтобы можно было описывать, в произвольные условия, которые должны были сцепляться, чтобы получить право на расходование монет.
Скрипты Биткоина на практике ( по состоянию на 2014 год)
Но сегодня он используется не так часто. Если посмотреть на историю Биткоина и обратить внимание на то, каким образом он использовался, то можно заметить, что в 99,9% случаях это был один и тот же скрипт. По факту, это тот же скрипт, который был рассмотренв качестве примера. Тот самый, где объявляется один открытый ключ и запрашивается подпись для этого ключа, чтобы разрешить расход монет.
Есть еще несколько вещей, которые могут пригодиться. Кое-где используется MULTISIG, и еще существует особый тип скрипта, который называется Pay-to-Script-Hash, который будет рассмотрен далее. Других способов проявить креативность в использовании скриптов на текущий момент нет. Причина этого в том, что узлы Биткоина имеют стандартизированный список скриптов, и они отвергают те скрипты, которые воспринимаются ими как нестандартные. Это не значит, что эти скрипты совсем никак нельзя использовать, их просто сложнее применить и этот вопрос будет рассмотрен далее в контексте пиринговой сети Биткоина.
Существуют скрипты, которые называются "proof-of-burn" ("доказательство сжигания"). Этот скрипт называется так потому, что его нельзя исполнить. С помощью скрипта "доказательство сжигания" можно доказать, что монеты были уничтожены, и потратить их теперь невозможно. Такой скрипт очень просто внедрить. Нужно использовать код OP_RETURN, который вбросит ошибку, если он, конечно, вообще сработает, и тогда программа вылетит. Данные, идущие после OP_RETURN, невозможно просмотреть, так что это дает возможность вписать в скрипте какие-нибудь свои данные.
Существует два случая, для которых он используется.
Первый - для того, чтобы вписать произвольные данные в блокчейн. Кто-то может захотеть вписать в блокчейн свое имя, или момент времени, чтобы доказать, что он знал что-то в определенный момент. Для этого нужно создать маленькую сжигаемую Биткоин-транзакцию. То есть, можно уничтожить небольшое количество валюты в обмен на то, чтобы написать что-то в блокчейн навсегда.
О втором случае использования "доказательства сжигания" будет рассказано в лекции про альтернативные валюты.
Должны ли покупатели описывать скрипты?
- Я готов оплатить заказ!
- Хорошо! Мы используем MULTISIG, поэтому мы хотим, что вы добавили скрипт, подтверждающий оплату от 2 из 3 бухгалтеров. Не ошибитесь в деталях. Спасибо за использование Big Box!
= Отправитель монет должен точно описать свой скрипт.
Например, покупатель хочет заказать что-то в интернет-магазине. Он оформил заказ, готов его оплатить и спрашивает у продавца адрес, куда ему следует направить монеты. Продавец в ответ говорит: " Мы используем MULTISIG, поэтому мы хотим, что вы добавили скрипт, подтверждающий оплату от 2 из 3 бухгалтеров. Не ошибитесь в деталях. "
Покупатель может сказать, что не знает, как это сделать. Он просто хочет переслать монеты на конкретный адрес. Для этого в Биткоине существует особая хитрость, которая позволяет вместо описания целого скрипта указать хеш скрипта, который понадобится для пересылки денег.
(рис 3.13) Использование хеша скрипта
На рис 3.13 отправитель описывает очень простой скрипт, который хеширует верхнее значение в стеке и проверяет, соответствует ли он требуемому скрипту оплаты.
Получателю этих монет нужно описать правильный скрипт, и транзакция верифицируется. Получателю нужно в качестве значения данных описать значение скрипта того хеша, который был указан покупателем.
Как только это случится, начнется второй этап валидации.
Верхнее значение данных из стека будет переинтерпретировано в качестве инструкции, и будет исполнено во второй раз в виде скрипта. То есть будет проведено два этапа: во-первых - это традиционный скрипт, который проверил правильность хеша скрипта оплаты, а во-вторых, скрипт оплаты будет преобразован и запущен в виде скрипта. Именно здесь пройдет проверка актуальности подписи.
Это и называется оплата по хэшу скрипта (P2SH) в Биткоине , который выступает как альтернатива обычному режиму оплаты через открытый ключ. Механизм оплаты по хешу достаточно сложен и не был указан в оригинальной спецификации. Он был добавлен в биткоин позднее.
Схема P2SH избавляет отправителя от лишних хлопот, и получателю нужно будет всего лишь указать хеш отправки монет отправителем. Это повышает эффективность системы, поскольку майнерам важно отслеживать те выводные скрипты, которые еще не были исполнены. Сейчас, благодаря P2SH, скрипты вывода стали крайне малы. Это все потому, что они только указывают хеш, а вся сложность смещена в скрипты ввода.
Замена простого указания открытых ключей скриптами имеет множество практических применений, о которых будет рассказано далее. Одно из них - это транзакция под условия.
Рассмотрим классическую ситуацию с онлайн-оплатой. Алиса и Боб хотят заключить между собой сделку, скорее всего, Алиса выиграла какой-нибудь онлайн-аукцион и теперь хочет что-то купить у Боба.
(рис 3.14) Условные транзакции (залог)
И вот Алиса хочет заплатить Бобу биткионами, а Боб в обмен отправил бы Алисе какой-то материальный товар. Но проблема в том, что Алиса не хочет платить, пока не получит товар, а Боб не хочет посылать товар, пока он не будет оплачен.
У Биткоина на этот случай есть отличное решение, которое очень часто используется на практике. Это - привлечь третью сторону и совершить условную транзакцию.
Алиса пересылает деньги не напрямую к Бобу, а создает MULTISIG-транзакцию, которая, чтобы переслать монеты, требует подписи двух или трех человек.
Пусть этими тремя людьми будут Алиса, Боб и Джуди, которая будет в роли судьи и вступит в переговоры в случае спора. Итак, Алиса создаст транзакцию с нужной суммой. Причем с двумя из трех действительных подписей между Алисой, Бобом и Джуди. Элис подписывает транзакцию для пересылки Биткоинов, которыми она владеет, и это опубликуется в блокчейне. В этот момент эти деньги для Алисы, Боба и Джуди будут находиться в состоянии залога. И любой из двоих подписавших могут указать, куда эти деньги нужно переслать.
Боб будет убежден, что он может со спокойной душой отправлять товар Алисе. И тогда он отправит их в материальном виде по почте или посылкой.
Теперь останется надеяться на то, что в реальной жизни Алиса и Боб - честные люди.
В таком случае товар придет вовремя и он будет удовлетворять потребностям Алисы, и тогда она перешлет заложенные деньги Бобу, и он получит право на их личное расходование.
Если это произойдет, Алиса и Боб смогут подписать транзакцию, выпускающую деньги из-под залога и пересылающую их Бобу. И самое приятное в этом то, что Джуди не пришлось вмешиваться. Спора не случилось. И таким образом, Алиса и Боб сработались, и подтверждение тому - два ключевых человека, подписавших MULTISIG-транзакцию, вместо трех.
Что бы случилось, если бы Боб не отправил товар? Или если бы он его отправил, но он потерялся на почте? Или если бы он отправил не тот размер?
Алиса не захочет платить Бобу, потому что она решит, что он ее обманул, и она захочет вернуть деньги назад.
В таком случае, они не подпишут совместную транзакцию, которая бы отправила деньги Бобу. Но также Боб не подпишет транзакцию, которая отправляет деньги назад к Алисе, поскольку будет отрицать обвинения Алисы о своем мошенничестве.
На этом этапе привлекается Джуди. Именно Джуди предстоит рассудить, кто из этих двоих честный, а кто не заслуживает получить деньги.
И если Джуди решит, что обманщик - Боб, то она решит подписать транзакцию совместно с Алисой, чтобы вернуть ей её деньги. То есть Алиса и Джуди сработаются, будут подписаны две ключевые подписи, и Алиса получит деньги назад.
Конечно же, у Джуди есть право пойти по другому пути. Если она решит, что виновата Алиса, что она отказывается платить положенную ей сумму, Джуди подпишет транзакцию, пересылающую деньги Бобу.
То есть, у Джуди появляется полное право действий, но самое хорошее здесь в том, что пока не откроется спор, ей не придется вступать в него.
Проблема: Элис хочет заплатить Бобу. Боб не хочет ждать 6 подтверждений об отсутствии двойных затрат, или не находится в сети.–Еще один способ использования скриптов - "зеленые адреса".
Допустим, Алиса хочет отправить Бобу деньги, а его нет в сети. То есть, Боб не сможет войти в блокчейн и проверить, не приходили ли от Алисы какие-либо транзакции. Может быть, у Боба просто нет времени зайти в блокчейн и подождать подтверждения транзакции (рис 3.15).
(рис 3.15) Зеленые адреса
Чтобы транзакция была прикреплена шестью блоками в блокчейне, потребуется примерно час.
Или у Боба просто нет возможности подключиться к Интернету и проверить блокчейн. В качестве примера может выступить такой случай, что Боб - это простой уличный торговец. Чтобы можно было переслать Биткоины, несмотря на неспособность получателя проверить блокчейн, нужно снова привлекать третью сторону, коей в данном случае окажется банк.
Алиса соединяется со своим Банком и говорит: "Здравствуйте, это Алиса, я ваш постоянный клиент. Вот мое удостоверение личности. Мне нужно переслать деньги Бобу, вы можете мне помочь?"
И в Банке ей говорят: "Конечно, сейчас мы снимем часть денег с вашего счета и выполним транзакцию через один из наших зеленых адресов напрямую к Бобу."
Обратите внимание, что деньги пришли из Банка прямо к Бобу. Часть этих денег в виде переадресации, возможно, перейдет обратно в Банк.
По сути, Банк пересылает Бобу деньги через адрес, подконтрольный Банку. Такие адреса дают гарантию того, что не случится двойной переплаты. Так что, как только Боб увидит, что транзакция подписана Банком, и если он поверит гарантии Банка об отсутствии двойной переплаты, он сможет подтвердить то, что он получил деньги, как только об этом будет сообщено в блокчейне. Заметьте, что эта гарантия была предоставлена не Биткоином, а реальным объектом, и Бобу нужно будет поверить в то, что Банк знает свое дело и заботится о своей репутации, и поэтому не будет требовать двойной переплаты.
Банк также сможет сказать: "Вы можете посмотреть на мою историю и убедиться, что этот зеленый адрес используется уже давно, и двойных трат не было еще ни разу. Поэтому вряд ли это когда-то случится в будущем".
Само собой, если Банк хоть раз совершит двойную трату, то доверие к нему обрушится почти мгновенно.
Существовало два наиболее надежных онлайн-сервиса, предоставлявших зеленые адреса, а именно Instawallet и Mount Gox, и оба они обрушились. Изначально сообществу Биткоина понравилась идея, что оплату можно совершать быстрее и не нужно обращаться для этого в блокчейн. Сейчас же эта идея настораживает людей тем, что банкам оказывается слишком много доверия. В результате, несмотря на всю прелесть этого протокола, в реальности он используется крайне редко.
(рис 3.16) Эффективные микротранзакции
Проблема: Алиса хочет оплатить Бобу каждую минуту услуги. Она не хочет создавать новые транзакции ежеминутно.
Третий пример - это способ эффективного проведения микротранзакций. Алиса покупатель, который хочет оплатить Бобу какую-то недорогостоящую услугу.
Может быть, в данном случае, Боб работает консультантом, и Алиса платит небольшую сумму денег за каждую минуту разговора по телефону.
Если создавать транзакции за каждую минуту разговора, их будет слишком много. За них будет запрошено много пошлин, и никто не будет этому рад. И если разговор Алисы с консультантом займет 2 часа, то потребуется 120 транзакций.
(рис 3.17) Все микротранзакции могли стать двойными тратами!
При помощи последовательных микротранзакций можно объединить маленькие счета в большой. Необходимо создать MULTISIG-транзакцию, которая будет содержать настолько большую сумму денег, насколько Алиса будет планировать потратиться, и потребует как от Алисы, так и от Боба, подписи, которые дадут разрешение на ее расходование.
Теперь, после каждой минуты разговора, или при первой же необходимости у Алисы совершить микротранзакцию, она подписывает транзакцию, которая расходует те монеты, которые были отправлены на MULTISIG-адрес, посылая одну монету Бобу, и возвращая остаток назад к Алисе.
После первой минуты проводимой консультации, Алиса подписывает следующую транзакцию, и тогда у Боба будут уже две монеты, в то время остаток снова окажется у Алисы.
Подписывает транзакции только Алиса, а Боб этого не делает ни разу.
Алиса будет совершать транзакции каждую минуту, которую она тратит на консультацию с Бобом.
Обратите внимание на то, что транзакции в блокчейне не публикуются. Они просто совершаются между Алисой и Бобом.
В определенный момент Алиса решит завершить консультацию. Тогда она скажет Бобу: "Все, завершаем разговор, я не хочу платить еще больше." А Боб скажет: "Хорошо, тогда я отключаюсь. Я возьму последнюю проведенную вами транзакцию, подпишу ее и опубликую в блокчейне."
Итак, поскольку каждая транзакция пополняла Бобу счет, а Алисе наоборот, понижала, то какой бы ни была последняя пересылка, Боб все же решит ее подтвердить, таким образом получив свою оплату за предоставленные услуги, и вернув разницу обратно на счет к Алисе.
Что еще хорошо, так это то, что все транзакции, которые Алиса подписала до нее, не будут вписаны в блокчейн, Бобу не нужно их подписывать, и поэтому они будут стерты.
Технически все эти транзакции будут считаться двойной тратой, в отличие от случая с зелеными адресами. Тем не менее, в реальной жизни, если обе стороны взаимодействуют исправно, Боб не будет подписывать ни одной транзакции, кроме последней, и по этой причине блокчейн не увидит намерения совершить двойную трату.
(рис 3.18) Боб не подписывает последнюю транзакцию
Что произойдет, если Боб так и не подпишет последнюю транзакцию (рис.3.18)? Вдруг он скажет: "Меня устраивает тот факт, что заложенные деньги так и останутся под залогом навсегда." В таком случае, деньги пересланы ему не будут, но Алиса потеряет все, что она вложила в самом начале. Для этого был придуман таймер (Lock_Time).
Чтобы избежать подобной проблемы, Элис и Боб предварительно подписывают транзакцию, которая пересылает все деньги обратно к Элис, но которые остаются недоступными до определенного момента времени.
То есть, до того, как Элис подпишет первую транзакцию об оплате первой минуты консультации, возможно, она захочет создать возвратную сделку, чтобы деньги остались у нее. Она захочет быть уверена, что если в указанный момент времени t Боб не подпишет любую из посланных Элис транзакций, то она сможет опубликовать свою транзакцию, и она вернет себе обратно все деньги.
(рис 3.19) Блокирующий индекс, или отметка реального времени, до которого транзакция не может быть опубликована
Если еще раз посмотреть на метаданные в транзакции Биткоина, то можно понять, что речь идет о параметре "lock_time".
Если в этом параметре опубликовать отличный от нуля момент времени, майнеры не будут публиковать транзакцию до наступления этого момента. Транзакция будет считаться недействительной и не будет публиковаться, пока в блоке будет содержаться особый номер блокировки или момент времени, подкрепленный конкретной точкой отсчета.
Таким образом можно подготовить транзакцию, которая может быть совершена в будущем лишь в том случае, если в этом будущем не случится что-то еще. То есть если Боб не подпишет последнюю транзакцию, деньги вернутся к Алисе.
В этой лекции было рассмотрено три способа применения скриптов. Существуют и другие способы. Один из них - многопользовательские лотереи, которые содержат в себе очень сложный, многоступенчатый протокол, с множеством транзакций и кучей сделок с указанными моментами времени. Все они являются залогами, создаваемыми на случай мошенничества.
С помощью скриптов можно заплатить кому-то, кто знает прообраз хеша и заставить его работать на себя. Есть еще пара отличных протоколов, которые позволяют разным людям перемешивать между собой свои биткоины, чтобы в дальнейшем невозможно было определить, кто каким биткоином владеет. Эти протоколы будут рассмотрены в лекции про анонимность.
Общий термин для подобных контрактов - "смарт-контракты", это означает, что такие контракты осуществляют технический контроль того, что обычно контролируется законами или арбитражными судами.
У Биткоина много замечательных особенностей - можно использовать скрипты, задействовать майнеров и применять валидацию сделок для залогов и микротранзакций. При этом отсутствует централизованное управление этими сделками.
В настоящее время смарт-контракты очень востребованы. Существует множество смарт-контрактов, которые люди хотели бы использовать, но сегодняшние возможности Биткоина не позволяют их реализовать. Эти смарт-контракты либо невозможно создать, либо для реализации не найдено подходящее решение. Тем не менее с помощью скриптов можно создать несколько интересных смарт-контрактов, о которых будет рассказано в следующих лекциях.
В большинстве примеров, которые были рассмотрены до настоящего момента, были использованы единичные транзакции. Рассмотрим, зачем транзакции помещаются в блоки.
На это есть несколько причин. Первая причина - благодаря этому для майнеров создается хороший, одиночный рабочий юнит, который по своему размеру превышает индивидуальные сделки. Если бы майнерам пришлось обрабатывать, хешировать и добавлять метаданные в каждую сделку системы, то нагрузка на них была бы чрезмерной. Во-вторых, это делает хеш-цепочку блоков короче, потому что нужен всего один блок для огромного числа сделок. Все это упрощает верификацию структуры данных блокчейна.
Рассмотрим структуру данных блокчейна (рис 3.20).
(рис 3.20) Структура блока Биткоина
Блок представляет собой комбинацию двух различных, основанных на хешировании, структур данных. Каждая из них имеет заголовок блока и хеш-указатель на некоторые данные о сделке, в том числе указатель на предыдущий блок и на последовательность.
Каждый блок содержит дерево сделок в виде дерева Меркла. Дерево связывает все транзакции в блоке довольно эффективным способом. Таким образом, становится легко провести увеличивающийся логарифмически путь по дереву, и тем самым доказать, что транзакции включены в особый блок.
Рассмотрим, как это выглядит на низком уровне (рис 3.21).
(рис 3.21) Реальная структура блока Биткоин
Заголовок блока содержит в себе все метаданные о данном блоке. Далее идут сделки, сформированные по принципу дерева Меркла. В целом, это большой список сделок, чьи хеши аккуратно разложены в структуре дерева, что дает возможность эффективно показать, какие сделки включены в данный блок.
Самая важная часть, конечно, заголовки (рис 3.22).
(рис 3.22) Заголовок блока Биткоин
Они, в основном, содержат информацию в отношении майнинговой головоломки, о которой шла речь во второй лекции. Чтобы блок был действительным, его заголовок должен начинаться с большого числа нулей,. Есть много факторов, которые влияют на заголовок блока. Это узлы, с которыми работают майнеры, отметки времени,Это показатель сложности нахождения блока. Все это хранится в заголовке. Самое главное в этом то, что заголовок - единственное, что хешируется во время майнинга. Итак, чтобы подтвердить подлинность цепочки блоков, необходимо проверить только заголовки. И единственными данными о транзакции, включенными в заголовок, является корень дерева транзакций. Это - параметр дерева Меркла.
(рис 3.23) Транзакция монетной базы
В дереве Меркла существует особая транзакция – транзакция монетной базы. Именно она создает новые биткоины (рис 3.22). В предыдущей лекции мы говорили о вознаграждении за создание блока, которое на текущий момент равно 25 биткоинам (block reward). Это горизонтальная награда майнинга, которая задается системой и держится в течение 4 лет. В действительности, она всегда будет чуть больше 25 Биткоинов, поскольку она включает в себя также пошлины за сделки, когда-либо собранные с каждой сделки, включенной в блок (transaction fees). Указатель на транзакцию вывода в сделке с монетной базой всегда будет нулевым.. Это как бы говорит, что поскольку здесь создаются новые Биткоины, то этому процессу ничего не предшествует. Не существует предыдущей транзакции, которая была совершена, чтобы создать эти монеты. У сделки с монетной базой есть интересный параметр, в который можно списать всё, что угодно. В самом первом блоке, когда ли добытом в Биткоине, в этом параметре содержалась цитата из газеты. Эта цитата была из "The Times of London", и в ней рассказывалась история про канцлера, спасавшего банки, что было с одной стороны политическим комментарием, объяснявшем мотивацию появления Биткоина, и с другой стороны, данью уважения Биткоину, так как его самый первый блок был добыт вскоре после выхода выпуска этой газеты.
Но с тех пор майнеры получили право писать в параметры сделки с базой все, что им хочется. Произвольный параметр используется, чтобы написать там что-то для себя или чтобы попросить помощи у других майнеров разобраться в новых особенностях, и ограничений для майнеров здесь нет.
Лучший способ изучить структуру блока биткоина – увидеть его своими глазами. Существует множество сайтов, делающих эти данные доступными: можно посмотреть на графы сделок, увидеть, какие транзакции исполняются за счёт других транзакций. Посмотреть на сделки со сложными скриптами, на блочную структуру и увидеть, как одни блоки ссылаются на другие. Все это доступно онлайн, потому что Биткоин - это открытая структура данных.
Рассмотрим, как участники вносят информацию о своих сделках в блокчейн.
Особенности сети P2P Биткоин:
Сеть Биткоина - это пиринговая сеть, и, как следствие, она наследует множество идей от других пиринговых сетей, которые применялись для различных целей. В пиринговой сети все узлы равны -нет иерархии, централизации, специальных узлов или мастер-узлов. Каждый узел в Биткоине равноправен по отношению к другому.
Он работает через TCP-протокол, имеет случайную топологию, это значит, что одни случайные узлы тождественны к другим случайным узлам.
Новые узлы могут появляться в любой момент. Любой человек может загрузить Биткоин-клиент, представить свой компьютер в роли узла и стать одним из узлов, с теми же правами и возможностями, что и другие узлы в сети Биткоина.
Сеть очень динамична. Узлы появляются и исчезают постоянно. Хоть и не существует явного способа покинуть сеть, вместо этого, если от узла не поступает никаких сигналов в течение, как правило, 3 часов, которые вшиты в каждый клиент, о нем начинают забывать другие участники сети. Таким элегантным способом узел отключается от сети.
Означает ли все это, что к пиринговой сети Биткоина можно присоединяться в любое время?
На рис 3.24 изображена сеть в определенный момент времени, немного уменьшенная в масштабах, всего с семью узлами. У каждого узла есть свои случайные связи. Номера узлов разбросаны, потому что нет географической топологии. Сеть соединяет другие узлы в случайном порядке по мере их появления.
(рис 3.24) Присоединение к пиринговой сети Биткоина
Для присоединения нового узла к сети, необходимо обратиться на адрес конкретного узла, который уже в сети. Такой узел называется сидом. Существует несколько способов посмотреть списки сидов, к которым можно присоединиться.
После нахождения сида (на рисунке это узел с номером 5), новый узел посылает ему специальное сообщение с просьбой сообщить адреса узлов сети, которые ему известны (рис 3.25).
(рис 3.25) Сообщение getaddr()
(рис 3.26) Ответ сида
Сид ответит: " Я соединен с узлами 1 и 7, попробуй присоединиться к ним".
Далее новый узел пробует соединиться у узлами 1 и 7 и говорит им: "Привет. Сообщите мне о тех участниках сети, о которых вы знаете". И они также пошлют ему узлы, о которых знают сами, и эти шаги повторяются столько раз, сколько захочет новый узел, пока не получит список пиров, к которым можно подсоединиться.
(рис 3.27) Ответы других узлов сети
Затем новый узел выбирает один из пиров, после чего становится функциональным членом сети Биткоина.
В рассмотренном процессе много случайных факторов. Набор узлов, к которым в итоге будет присоединен новый участник, зависит от узла-сидера и от того, с каким из его пиров контактировал новый узел.
(рис 3.28) Продвижение сделки (заливка)
Рассмотрим, как происходит публикация информации о сделке в сети. Для сообщения всей сети об осуществленной сделке используется простой алгоритм-заливка.
Допустим, узел 4 узнал о новой транзакции, где Алиса хочет прислать Бобу деньги: Алиса создает Биткоиновую сделку и посылает ее на 4 узел. Может быть так, что ее электронный кошелек или обменное ПО действует по своему усмотрению, но тем не менее, транзакция каким-то образом приходит на 4 узел. Теперь этот узел говорит: "Ага, у меня новая сделка: Алиса хочет заплатить Бобу. Давайте сообщим всем об этом". Это называется gossip-протокол (протокол сплетен). В протоколе действует принцип человеческих сплетен – если у узла есть информация, которой он хочет поделиться со всей сетью, он сообщает ее как можно большему числу узлов и те , в свою очередь, транслируют ее дальше в сеть. В рассматриваемом примере узел 4 обратится к своим соседям - узлам 2 и 3. Он им сообщит: "Эй, взгляните на эту сделку. Алиса хочет заплатить Бобу".
Эти узлы тоже добавят ее в свой пул ожидающих сделок, так как каждый узел содержит в себе список сделок, о которых он слышал, но которые еще не были внесены в блокчейн. И потом узлы могут решить продвинуть свои сделки к следующим узлам. Итак, узел 3 контактирует с соседями и говорит: "У меня для вас новая сделка. Алиса хочет заплатить Бобу".
Она так же окажется у них в пуле, и так далее. Необходимо, чтобы у этого процесса был конец. Пусть будет так, что узел 2 активируется и попытается сообщить узлу 7: "Эй, тут новая сделка. Алиса хочет заплатить Бобу".
И тогда узел 7 ответит: "Все в порядке, узел 2, я уже об этом слышал, она у меня в памяти. Мне уже не нужно ее продвигать". Итак, в конце концов, этот процесс когда-то остановится, потому что каждый узел будет знать об этой новой сделке, и им больше не нужно о нем сообщать. Каждая транзакция помечается уникальным хешем, следовательно, каждый узел сможет сообщить, что уже видел этот хеш, и что его уже не нужно больше никому не передавать, чтобы он не циклился в сети бесконечно.
Как же узлы решают, сообщать о поступлении новой сделки или нет? Самое главное, что они делают - они проверяют, в соответствии с их видением блокчейна, действительна ли это сделка, или нет. То есть, они выполняют проверку подлинности транзакции. Они запускают скрипт и видят, что он заработал. Затем они видят, что те деньги, которые планируются к пересылке, еще не были потрачены. И если все проверки будут пройдены, то сделка будет считаться действительной, и ее, с незначительными возражениями, будет решено распространить по сети. По умолчанию, узлы не транслируют сделки, у которых нестандартные скрипты. Если скрипт имеет какие-нибудь странные особенности, если они хоть немного не совпадают со стандартным списком скриптов, которые знакомы узлам, и даже если транзакция будет считать действительной, узлы ее передавать не будут. Они поведут себя так, как будто никогда не слышали об этой транзакции. Это происходит с целью избежать бесконечного зацикливания. Еще одно причина, по которой сделка не будет транслироваться - это подозрение на двойную трату.
Получается, если узлы узнают о транзакции, где Алиса пытается переслать некую сумму денег Бобу, а затем обнаружат еще одну сделку, в которой Алиса попытать переслать ту же сумму Чарли, то узлы не будут сообщать о второй сделке. Несмотря на то, что сделка может быть подлинной, из-за того, что эти монеты до сих пор не были потрачены, о них будет сообщено только в первом случае.
Это дополнительная защита от двойных затрат. Но также важно помнить, что эти проверки нацелены на проверку отсутствия ошибок.
Вообще, все качественные узлы содержат в себе программы проверки с целью сохранить целостность и сохранность всей сети, однако не существует такого правила, что все узлы обязаны следовать этим указаниям. Поскольку сеть - пиринговая, и каждый может к ней присоединиться, всегда остается вероятность того, что узел не последует протоколу. Он будет транслировать двойные затраты, нестандартные и недействительные транзакции. Поэтому важно, чтобы каждый узел проверял себя. Возможно и такое, что у узлов будет различное представление об ожидающей транзакции, все зависит от того, что они обнаружили. Давайте вернемся к примеру, где узел 4 транслировал сделку, в которой Алиса планирует отправить Бобу монеты, и представим, что сделка не разошлась по всей сети. И перед тем, как она разойдется, узел 1 сообщит о новой сделке и скажет: "Эй, я только что узнал, что Алиса хочет заплатить деньги Чарли". С точки зрения узла 1 это действительная транзакция, ведь он не видел другой транзакции, в которой Алиса платит Бобу.
(рис 3.29) Сделки, содержащиеся в узлах, могут отличаться
Итак, узел 1 совершит протокол нормально, и теперь он сообщит о сделке своим соседям.
Соседи, которые еще не узнали об этих конфликтных сделках, так же добавят их к себе в пул.
В свою очередь, другие соседи, такие как узел 6 из примера, уже знают о сделке между Алисой и Бобом. Поэтому, узел 6 сообщит: "Я не хочу хранить в себе две конфликтные сделки, я оставлю себе ту, что у меня уже есть".
Здесь сеть может оказаться в раздвоенном положении, ведь у разных узлов будет разное состояние пулов сделок. Эти сделки еще не вошли в блокчейн, так что это состояние узлов, когда они не знают, какую следующую сделку поместить в блок, временно.
Сделки или блоки могут конфликтовать
По сути, система оказывается в состоянии гонки.
Если у узлов различаются списки ожидающих транзакций, или они видят разные блоки, принятые в блокчейн, - во временном состоянии это нормально. В определенный момент, они все рассортируются.
В случае с теми сделками, где у разных узлов разные представления отложенных сделок, то в зависимости от того, кто будет добавлять следующий блок, тот в конечном итоге и разорвет состояние гонки и решит, которая из двух сделок будет окончательно помещена в блок. И как только одна из двух транзакций будет помещена в блок, другие узлы заметят, что сделка, которая находится у них в состоянии ожидания, уже не будет помещена в блок, потому что это будет считаться двойной тратой, и тогда они ее удалят.
Итак, если та сделка, где Алиса платит Бобу, успешно попадает в блок первой, то те узлы, которые слышали о сделке между Алисой и Чарли, скажут: "Моя транзакция больше не действительна, я могу о ней забыть". То есть, стандартное поведение узлов таково, что они воспринимают то, что они услышали в первую очередь,
Это значит, что положение узла в сети имеет значение. Если две конфликтные сделки будут объявлены в разных точках сети, они обе начнут транслироваться в разных направлениях. И те узлы, которые узнают о той или о другой транзакции, будут зависимы от того, какая часть пространства сети, с которой они начали, находится ближе всего.
Необходимо учитывать, что майнеры могут строить свою логику, определяя, от каких узлов они хотели бы получать информацию в первую очередь. В лекции про майнинг будет более подробно описано, зачем майнеры внедряют логику, отличную от стандартной.
Логика, объявляющая о новых блоках, которые находят майнеры, почти аналогична логике объявления новой транзакции. Используется всё тот же алгоритм-заливка и тот же gossip-процесс. И в данном случае, вместо того, чтобы подтверждать действительность сделки запуском скрипта, узлы подтвердят подлинность нового блока вычислением его хеша. Также они убедятся, что хеш блока начинается с внушительного количества нулей, чтобы оценить сложность цели.
Валидация блока более сложная, так как в этом случае проверяется также и заголовок. И лишь после проверки хеша заголовка, узлы проверят действительность каждой сделки в этом блоке, чтобы убедиться, что блок содержит только подлинные сделки.
Другая проверка, которая является критически важной – проверка Биткоин на согласованность, не продвигается ли блок узлами до тех пор, пока не будет проверена самая его длинная цепочка. У узлов есть представление блокчейна, и они должны продвигать новые блоки лишь тогда, когда они пройдут до конца цепочки, но никак не раньше.
Это помогает избежать построения вилок. Узлы могут по своему желанию внедрять в себя различные логики. Они могут транслировать недействительные сделки, или даже те сделки, которые не дошли до конца самой длинной цепочки блокчейна. То есть, некоторые узлы могут пытаться продвинуть такой блок, который не дошел до конца цепочки, и из-за этого образуется так называемая вилка. И в этом нет ничего страшного, протокол способен с этим справиться. Все же, как долго по времени будет длиться этот плавающий алгоритм? Много ли наложится задержек?
(рис 3.30) Временные затраты на продвижение блока
На рис 3.30 изображен граф, отражающий среднее время продвижения новых блоков в каждом узле сети Здесь три линии, показывающие 25-ю, 50-ю и 75-ю перцентиль длительности достижения блоком каждого нового узла. Если посмотреть на 75-ю перцентиль, то можно обнаружить, что для больших блоков среднее время продвижения составляет примерно 30 секунд.
Причина такой большой задержки в том, то этот протокол не очень эффективный. Он и не создавался эффективным. Он был создан быть простым и бесструктурным, чтобы каждый узел оставался равноправным и мог входить и выходить в любое время.
Как результат, топология может оказаться неоптимизированной для быстрой коммуникации.
Блоку может потребоваться пройти через множество узлов, прежде чем достигнуть самых дальних узлов сети. Чтобы сеть была более эффективной, необходимо обеспечить максимально короткие пути между узлами. Для Биткоина же важнее наличие децентрализованной структуры, где все узлы равны, невзирая на то, что из-за этого продвижение блока может занимать 30 секунд. Итак, насколько велика сеть Биткоина? На самом деле, подробной статистики просто нет, потому что нет централизации и какого-либо органа, который бы вел официальную статистику. Известно лишь то, что сеть состоит из узлов, количество которых постоянно меняется Тем не менее многие исследователи попытались сделать приближенную оценку.
Исходя из наиболее благоприятного сценария, исследователи заявили, в месяц свыше 1 миллиона IP-адресов могут запускать протокол Биткоина и быть, по крайней мере, временно активными в роли узлов.
Но если оценить количество полных узлов, которые подключены постоянно и полностью проверяют каждую полученную, их наберется от 5 до 10 тысяч штук, что является крайне маленьким числом.
По факту, это число может быть и меньше. Пока нет доказательств того, что число полностью проверенных узлов растет. От этого растет и беспокойство по поводу того, что число таких узлов сокращается.
Чтобы узел стал полностью проверенным, его нужно оставлять всегда подключенным, чтобы получать информацию обо всех данных. Чем дольше узел будет в оффлайне, тем дольше ему придется наверстывать, чтобы узнать обо всех пропущенных сделках. И ему придется полностью заполнять блокчейн.
Узлу также нужно иметь хорошее Интернет-соединение, чтобы он мог вовремя узнавать о новой сделке и продвигать ее своим пирам.
Блокчейн постоянно увеличивается, и на данный момент, чтобы добавить весь блокчейн, потребуется около 20 ГБ памяти.
Для того чтобы стать полностью проверенным узлом достаточно иметь компьютер, которому несколько лет, с хорошим Интернет-соединением. Полностью проверенные узлы сопровождают весь набор неизрасходованных выходных транзакций.
Получается, они сопровождают каждую доступную для расходования монету, то есть неизрасходованные выходные транзакции.
В идеале эти транзакции хранить в ОЗУ. Это позволит проверить новую транзакцию очень быстро. Каждый раз когда полный узел узнает о новой транзакции, он запускает исполняющий скрипт и убеждается в том, что она действительна. На текущий момент достаточно 1 ГБ ОЗУ для формирования эффективной структуры данных.
На данный момент существует около 12 миллионов неосуществленных транзакций. И они является частью 44 миллионов транзакций, которые когда-либо были запрошены.
В противовес полностью проверенным узлам, существуют легковесные узлы, которые еще называют "тонкие клиенты" или "клиенты с простой верификацией оплаты".
Среди всех узлов в сети Биткоина, таких узлов - подавляющее большинство, и отличаются они тем, что эти узлы не стараются вместить в себя весь блокчейн.
Они хранят только те части, которые им нужны для подтверждения только важных им конкретных сделок.
Например, есть электронный кошелек, который необходимо использовать как клиента с простой верификацией оплаты. Тогда, если кто-то перешлет на этот кошелек деньги, необходимо действовать как простой узел. Загрузить те биты блокчейна, которые будут необходимы, чтобы подтвердить, конкретную транзакцию и включить ее в блокчейн. При этом простой узел не беспокоится о тысячах других транзакций, которые не оказывают на него влияния.
Тонкие/ПВО-клиенты (не полностью проверенные)
Итак, клиенту с простой верификацией оплаты нет необходимости иметь такой же уровень безопасности, как у полностью проверенного узла.
Все потому, что когда такие узлы узнают о новом блоке, единственное, что они могут проверить - это его заголовок. Они могут проверить и то, насколько сложно было добыть этот блок, но они не сумеют проверить подлинность каждой транзакции в этом блоке, так как у этих узлов нет информации о предыдущих блоках в блокчейне. Они не владеют знаниями обо всех остальных выходных транзакциях. Они могут проверять только те транзакции, которые непосредственно на них влияют, поэтому они доверяют подобные сделки полностью проверенным узлам, которые расположены еще дальше
Таким образом, если у клиента простая верификация оплаты, то происходит значительная экономия затрат.
Когда хранятся только заголовки блоков вместо всех предыдущих транзакций, то затраты уменьшаются примерно в 1000 раз, и вместо хранения 20ГБ памяти, хранится всего лишь 20МБ. Такой объем может хранить почти каждый на своем компьютере, или даже на телефоне, действуя таким образом, как ограниченный узел сети Биткоина.
В заключение рассмотрим ограничения, встроенные в протокол Биткоина. Протокол Биткоина содержит в себе множество жестко закодированных констант, которые были в него внедрены еще в 2009 году, когда никто и представить себе не мог, что Биткоин станет всемирно известной валютой.
Жестко закодированные ограничения в Биткоине:
Одними из ключевых ограничений являются: ограничение по времени, отведенное в среднем на каждый блок; количество блоков; число операций подписывания в блоке, делимость валюты.
Также есть ограничение на максимально существующее число Биткоинов и на систему поощрения майнинга. Скорее всего, они никогда не изменятся, так как экономические последствия их изменения могут быть непоправимы. Майнеры вложили слишком много материальных ресурсов, что стать майнерами, рассчитывая на то, что доходы от Биткоинов станут материальны, и что поддержка Биткоина продолжится по тому пути, что идет сейчас. Если система изменится, майнеры понесут огромные финансовые потери.
Пропускные ограничения Биткоина
В качестве примера:
Проблема Биткоина в том, что он не был идеально спроектирован с самого начала. И исправить это теперь сложно. Ограничение пропускной способности Биткоина исходит от жестко закодированного предела на размер блоков. Каждый блок ограничен одним миллионом байтов.
И каждая транзакция должна иметь размер, по меньшей мере, в 250 байтов, то есть если разделить эти значения и принять во внимание, что каждый блок находится в течение 10 минут, то в результате получится 7 транзакций в секунду - такова пропускная способность сети Биткоина.
Для сравнения приведем платежную систему Visa, которая по оценкам совершает около 2000 транзакций в секунду по всему миру. А в самые загруженные дни, такие как суббота перед Рождеством, это число может увеличиваться до 10 000 транзакций в секунду. Другие платежные системы примерно так же продуктивны. Например, PayPal пропускает через себя около 1000 транзакций в секунду, что в разы превышает пропускную способность Биткоина.
Криптографические ограничения в Биткоине
Еще одно ограничение - криптография Биткоина не меняется. Она содержит лишь пару хеш-алгоритмов и только один алгоритм подписи, - отдельный тип эллиптической кривой SecP256.
Фактически для любого алгоритма подписи и хеш-функции всегда есть вероятность взлома.
(рис 3.31) Твердовилочные изменения в Биткоине
Что будет, если какую-то из указанных проблем исправить в новой версии программного обеспечения? Тогда всем узлам необходимо будет обновиться. Этот процесс называется "твердовилочное изменение" (рис 3.31).
На практике, ошибочным будет считать, что обновится каждый узел. Некоторые узлы сети не смогут перейти на новое ПО или сделают это с опозданием. Давайте посмотрим на сеть, где большая часть узлов обновилась, а малая часть - нет. И вот, один из обновленных блоков говорит: "Смотрите, я нашел этот большой, изящный новый блок. Может быть, одна из его транзакций содержит новый ЭЦП-алгоритм, который мы недавно добавили в Биткоин". Пусть его нашел блок 4, и вот он говорит: "Окей, сейчас я обновлюсь и объявлю, что это самый свежий блок. Индекс блока - 24, остальная сеть знает лишь о 23-ем. Но я сейчас продвину свой блок остальным пирам, использовав стандартный алгоритм-заливку".
(рис 3.32) Изменения «твердая вилка»
Итак, узел 4 посылает блок №24 своим соседям - узлам 3 и 2. Узел 3 его примет и скажет: "Отлично, я его принял, сейчас я обновлю свой блокчейн и объявлю, что этот блок теперь - самый последний".
В свою очередь, узел 2 сообщит: "Это безумие, у вас есть какой-то код операции, который у меня отключен или зарезервирован, я вынужден отвергнуть этот блок, я его не понимаю, я не могу его принять".
Аналогично с узлом 6, он так же даст отказ, сообщив, что он тоже не может принять этот блок.
И теперь новые узлы имеют единую картину о состоянии блокчейна (с последним блоком 24), а старые узлы отказались принять последний блок (у них последний блок 23). В итоге, новые узлы продолжат работу с новым представлением о блокчейне, включая блок со своей новой особенностью, а старые узлы застрянут в старой версии блокчейна и, к сожалению, уже не смогут наверстать упущенное, потому что пока они не обновят свое ПО, они продолжат отвергать все те блоки, которые будут передавать им обновленные узлы с новыми версиями протоколов.
Причиной тому, почему это называется "твердой вилкой", является то, что блокчейн будет разделен, и узлы в сети будут находиться по разные стороны, в зависимости от имеющейся у них версии протокола, и в таком случае, они уже никогда не сработаются. Сообщество посчитало неприемлемым отключать от сети Биткоина те узлы, которые не обновляют свое ПО.
"Мягкие вилки"
Наблюдение: можно добавить новые возможности, которые только ограничат количество подлинных транзакций
Необходимо, чтобы большинство узлов соблюдало новые правила.
Старые узлы продолжат одобрять недействительные блоки.
Для контраста, существует также подход с названием "мягкая вилка". Он позволяет добавлять новые особенности в протокол Биткоина, но лишь в том случае, если это ограничивает набор валидных сделок или набор валидных блоков.
Необходимо, чтобы большинство узлов соблюдало новые правила.
При использовании "мягкой вилки" есть вероятность того, что старые узлы будут майнить недействительный блок, потому что он будет вмещать в себя сделку, которая когда-то считалась валидной, но теперь, согласно новым, более строгим правилам, она больше таковой не является. В определенный момент старые узлы поймут, что блок с их сделкой отвергается участниками сети. Тогда они перейдут на ту версию блокчейна, к которой перешли их пиры и твердая вилка исчезнет. Поначалу у пиров возникнет временная вилка из-за свойств нового блока, который попытались смайнить. Блок отвергнется сетью, но пиры его восстановят и вернут обратно в основную цепочку.
Классический пример изменения через мягкую вилку - оплата по хэшу скрипта, которая была рассмотрена во второй лекции.
Скрипт P2SH не присутствовал в первой версии протокола Биткоина–Скрипт хеширует одно значение данных, а затем проверяет, равно ли оно значению, указанному в скрипте вывода. Старые узлы никогда не выполняют второй этап верификации в P2SH-скрипте.
Возможности "мягкой вилки"
Благодаря мягкой вилке успешно была добавлена оплата по хешу скрипта. Также с мягкой вилкой можно реализовать новые криптографические схемы, или какие-нибудь дополнительные, имеющие смысл, метаданные в блоках. А добавить их можно в параметр монетной базы. На данный момент в параметр монетной базы добавляются любые значения, но в будущем его можно будет использовать под что-то конкретное.
Одной из предложенных идей было, чтобы монетная база содержала корень Меркла, состоящий из полного набора неизрасходованных сделок. Это привело бы к мягкой вилке, потому что старые узлы могут добыть блок, который не будет иметь нового необходимого параметра монетной базы, и будет отвергнут сетью. Но они смогут сойтись и присоединиться к основной цепочке, которую майнит сеть.
"Жесткие вилки"
НА ДАННЫЙ МОМЕНТ ПОДОБНЫЕ ИЗМЕНЕНИЯ МАЛОВЕРОЯТНЫ
Другие изменения могут потребовать твердую вилку, например, если возникнет необходимость добавить новые коды операций для Биткоина, изменить ограничения на блоки или размер транзакции, или исправить множественные баги. Например, исправление бага, где инструкция MULTISIG удаляет из стека одно лишнее значение, потребует твердой вилки, и именно поэтому на первый взгляд раздражающий баг, на текущий момент проще оставить в протоколе, чем использовать твердую вилку для его исправления.
Таким образом добавление любого изменения, требующего твердой вилки, является крайне нежелательным в сети Биткоин. Однако уже были проверены и признаны успешными множество идей и альтернативных валют, которые были созданы с нуля, лишенные этих недостатков. О них будет рассказано в лекции про альткоины
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.