Опубликован: 01.02.2018 | Уровень: для всех | Доступ: платный
Лекция 3:

Транзакции Биткоина

< Лекция 2 || Лекция 3: 123456 || Лекция 4 >

Сеть Биткоина

Рассмотрим, как участники вносят информацию о своих сделках в блокчейн.

Особенности сети P2P Биткоин:

  • Специальный протокол (работает на TCP-порте 8333)
  • Специальная сеть со случайной топологией
  • Все узлы равноправны
  • Новые узлы могут подключаться в любое время
  • Неактивные узлы забываются через 3 часа

Сеть Биткоина - это пиринговая сеть, и, как следствие, она наследует множество идей от других пиринговых сетей, которые применялись для различных целей. В пиринговой сети все узлы равны -нет иерархии, централизации, специальных узлов или мастер-узлов. Каждый узел в Биткоине равноправен по отношению к другому.

Он работает через TCP-протокол, имеет случайную топологию, это значит, что одни случайные узлы тождественны к другим случайным узлам.

Новые узлы могут появляться в любой момент. Любой человек может загрузить Биткоин-клиент, представить свой компьютер в роли узла и стать одним из узлов, с теми же правами и возможностями, что и другие узлы в сети Биткоина.

Сеть очень динамична. Узлы появляются и исчезают постоянно. Хоть и не существует явного способа покинуть сеть, вместо этого, если от узла не поступает никаких сигналов в течение, как правило, 3 часов, которые вшиты в каждый клиент, о нем начинают забывать другие участники сети. Таким элегантным способом узел отключается от сети.

Означает ли все это, что к пиринговой сети Биткоина можно присоединяться в любое время?

На рис. 3.24 изображена сеть в определенный момент времени, немного уменьшенная в масштабах, всего с семью узлами. У каждого узла есть свои случайные связи. Номера узлов разбросаны, потому что нет географической топологии. Сеть соединяет другие узлы в случайном порядке по мере их появления.

Присоединение к пиринговой сети Биткоина

Рис. 3.24. Присоединение к пиринговой сети Биткоина

Для присоединения нового узла к сети, необходимо обратиться на адрес конкретного узла, который уже в сети. Такой узел называется сидом. Существует несколько способов посмотреть списки сидов, к которым можно присоединиться.

После нахождения сида (на рисунке это узел с номером 5), новый узел посылает ему специальное сообщение с просьбой сообщить адреса узлов сети, которые ему известны ( рис. 3.25).

Сообщение getaddr()

Рис. 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 ГБ против 23 МБ)

Итак, клиенту с простой верификацией оплаты нет необходимости иметь такой же уровень безопасности, как у полностью проверенного узла.

Все потому, что когда такие узлы узнают о новом блоке, единственное, что они могут проверить - это его заголовок. Они могут проверить и то, насколько сложно было добыть этот блок, но они не сумеют проверить подлинность каждой транзакции в этом блоке, так как у этих узлов нет информации о предыдущих блоках в блокчейне. Они не владеют знаниями обо всех остальных выходных транзакциях. Они могут проверять только те транзакции, которые непосредственно на них влияют, поэтому они доверяют подобные сделки полностью проверенным узлам, которые расположены еще дальше

Таким образом, если у клиента простая верификация оплаты, то происходит значительная экономия затрат.

Когда хранятся только заголовки блоков вместо всех предыдущих транзакций, то затраты уменьшаются примерно в 1000 раз, и вместо хранения 20ГБ памяти, хранится всего лишь 20МБ. Такой объем может хранить почти каждый на своем компьютере, или даже на телефоне, действуя таким образом, как ограниченный узел сети Биткоина.

< Лекция 2 || Лекция 3: 123456 || Лекция 4 >
Александр Шабанов
Александр Шабанов
Россия, Москва, МГОУ, 2007
Максим Кучинский
Максим Кучинский
Россия