Транзакции Биткоина
Транзакции Биткоина
В первых двух лекциях были рассмотрены основные механизмы, используемые в Биткоине. В этой лекции будут показаны реальные структуры данных, скрипты и другие подробности реализации этих механизмов.
Повторим основные моменты, рассмотренные в предыдущих лекциях.
Консенсус Биткоина имеет следующие особенности:
- Журнал (реестр) в режиме Append-Only
- Децентрализованная согласованность
- Проверка подлинности транзакций майнерами
Предполагается, что валюта существует, чтобы мотивировать работу майнеров!
Журнал (реестр) в режиме Append-Only предполагает ведение журнала транзакций только в режиме добавления записи. При этом как только запись сделана, она остается в журнале навсегда. Для достижения согласованности по поводу истинности журнала используется децентрализованный протокол и майнеры, которые следуют этому протоколу и утверждают транзакции. Они подтверждают то, что транзакции правильно сформированы, что нет двойных расходов, и что Биткоин исправно функционирует, как валюта.
Биткоин существует, чтобы мотивировать майнеров добывать биткоин. И чтобы понять этот механизм, рассмотрим, как происходит транзакция Биткоина.
Возьмем упрощенную модель, где вместо блоков транзакций будут индивидуальные транзакции, выполненные по одному разу в каждый момент времени. Можно провести аналогию с банковским счетом ( рис. 3.1). Чтобы переслать Бобу 17 монет, Алиса создает транзакцию и ставит под ней свою подпись. Информация о сделке сохраняется в журнале.
В качестве подтверждения наличия у Алисы монет, приведена информация о том, что в ходе первой транзакции Алиса получила 25 монет. После передачи 17 монет Бобу у нее осталось 8 монет.
После того, как Боб получил монеты, он может передать какое-то количество монет Чаку, тот в свою очередь Алисе и т.д. В результате у Алисы, Боба и Чака будут разные состояния счета.
На рис. 3.1 самая нижняя транзакция – передача Алисой 15 монет Дэвиду. Как можно убедиться, что у нее есть 15 монет для передачи их Дэвиду?
Чтобы это выяснить, нужно проверить всю цепочку транзакций, связанных с Алисой. Всякий раз, когда Алиса отправляла или получала монеты, все эти действия нужно обнаружить и затем выяснить, хватит ли ей тех 15 монет, которые она хочет переслать. Конечно, это можно сделать несколько эффективнее, например, со структурой данных, которая бы отслеживала каждую транзакцию Алисы, но это потребует огромных дополнительных расходов памяти, помимо ведения самого блокчейна.Именно поэтому Биткоин не работает по принципу банковского счета. Вместо этого, у Биткоина есть журнал с историей транзакций. На рисунке 3.2 изображен журнал транзакций, похожий на биткоиновский.
В транзакциях указаны количество вводов и количество выводов. У транзакций также есть свой уникальный индекс. Начнем с транзакции №1, где ничего не вводится, так как здесь формируется валюта, и есть один вывод в размере 25 монет, которые переходят к Алисе.
Поскольку в этой транзакции создаются новые монеты, она не требует подписи.
Чтобы передать 17 монет Бобу Алиса должна сослаться на транзакцию, в рамках которой она получила эти монеты. Таким образом, в качестве ввода для этой транзакции будет транзакция с индексом 0, которая была предыдущей, где говорится, что Алиса получила 25 монет. У транзакции будет 2 вывода. Один, в котором пересылается 17 монет Бобу, и второй, где Алиса получает 8 монет. Для подтверждения транзакции ее подписывает Алиса.
Рассмотрим, зачем Алисе переводить деньги самой себе. Вот она получает 25 монет, которые были предназначены для неё в первой транзакции, из них лишь 17 штук она пересылает Бобу, и теперь ей нужно сделать еще один вывод в размере 8 монет самой себе, пусть и под другим индексом, но все-таки себе.
Эта называется переадресацией. Идея в том, что всегда нужно вывести остаток с предыдущей транзакции. Нельзя сделать так, что со счета потратилось только 17 монет. Можно сделать лишь так, что с одного вывода потратятся все 25 монет. Но так как Алиса хочет потратить только 17 монет, она сделает второй вывод (8 монет) на себя
Добавим новую транзакцию и выясним, действительная ли она. Достаточно будет взглянуть на блокчейн, так как теперь известно, на какие вводы смотреть. Нужно перейти к транзакции 2, вывод 1 и посмотреть, что денег достаточно и они еще не потрачены. Можно посмотреть на транзакцию и сделать вывод о том, что во втором выводе Элис пришли 8 монет, значит, у нее достаточно монет, чтобы совершить все выводы в этой транзакции.
Таким образом, действительность транзакции проверяется методом обратного конечного поиска.
Помимо этого применяются хеш-указатели. У каждой транзакции есть свой уникальный индекс. Это просто номер (хеш) блока. И каждая транзакция, по сути, тоже получает свой уникальный индекс, который является хешем транзакции.
То есть нужно просто пройти на один хеш-указатель вверх и выяснить, достаточно ли денег, чтобы совершить желаемые выводы в следующей транзакции.
Еще одна вещь, которую можно сделать - слияние значений. Допустим, есть две разные транзакции, которые переводят деньги Бобу - 17 монет в одной и еще 2 в другой. Боб может сказать: я бы хотел, чтобы у меня была одна транзакция, которую я мог бы потом израсходовать.
Чтобы это сделать, нужно создать новую транзакцию с двумя вводами и одним выводом, чтобы все эти деньги ушли Бобу. Аналогичным образом можно выполнять слияние оплат.
Допустим, Кэрол и Боб хотят переслать деньги Дэвиду. Можно создать транзакцию с двумя вводами, которые совершаются двумя разными людьми и сложить эти значения, тем самым передав Дэвиду все 8 монет.
Единственная особенность здесь в том, что поскольку эти два вывода производятся двумя разными людьми, то нам нужны две подписи: одна от Кэрол, вторая - от Боба ( рис. 3.3).
На рис. 3.4 показана, как именно выглядит транзакция Биткоина. И это не вся транзакция, а только красиво оформленное представление (скорее всего на языке JSON). В действительности, транзакция представлена в компактном двоичном формате, который компилируется в такую нечитабельную, но крайне похожую на реальную низкоуровневую транзакцию.
Транзакция состоит из трех частей. Во-первых, это метаданные, затем это серия вводов, и серия выводов. Начнем с метаданных.
"Домашняя" информация содержит, например, размер транзакции, количество вводов и количество выводов. Хеш-номер всей транзакции, который служит уникальным индексом для транзакции и позволяет делать хеш-указатели. И еще тут есть некий параметр lock_time, о котором будет рассказано позже.
Вводы транзакции - это массив входных данных с одной и той же формой.
Вводы подробно описывают предыдущую транзакцию, поскольку у них есть хеш предыдущей транзакции, или хеш-указатель на нее.
И индекс вывода из указанной транзакции.
Также имеется подпись scriptSig ( рис. 3.6). Подпись подтверждает вывод из предыдущей транзакции.
У каждого вывода есть свое значение. Сумма всех выводов должна быть меньше, чем сумма всех вводов.
В этой структуре есть еще что-то похожее на хеш открытого ключа. Это адрес получателя конкретного вывода. Структура данных похожа на скрипт и об этом будет рассказано в следующих лекциях.