Блокчейн

Большинство моих ЖЖ-друзей, наверное, в курсе, что это, и как это работает. Но вдруг кто не знает или не понимает.

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

Если два эксперта проведут дактилоскопирование одного и того же человека, они получат (во всяком случае, должны) одинаковый результат. Так и с компьютерами — если два человека будут использовать один и тот же алгоритм хеширования на одном и том же наборе данных, они должны получить один и тот же хеш. То-есть, если у тебя есть кусок текста, и у меня есть кусок текста, мы его хешируем одним и тем же алгоритмом, и у нас получается одинаковый хеш — это значит, что куски текста, которые мы анализировали, 100% идентичны (1).

Теперь построим свой собственный примитивный блокчейн. Блокчейн — это block chain, т.е. цепь из блоков. Каждым блоком внутри нашей цепи будут 5 кусков текста, разделённых запятыми: хеш предыдущего блока, три куска “полезной нагрузки”, и хеш для этого блока. Хранить в блокчейне можно любые данные, но допустим у нас будет хранится информация о финансовых транзакциях. Использовать будем алгоритм хеширования MD5 (2)

Построим первый блок. Так как это начальный блок в цепи блоков, у него не может быть хеша предыдущего блока. Ну и плевать, придумаем свой. abcdefghijklmopqrstuvwxyz1234567 — вполне сгодится. Далее указываем транзакцию, кто кому заплатил, и сколько: Маша,Олег,5 рублей. И хешируем всё это вместе:

md5sum <<< "abcdefghijklmopqrstuvwxyz1234567,Маша,Олег,5 рублей", получаем хеш a61d142c8be7fac8b41da05d11c9f76e.

Всё, вот первый блок в нашем блокчейне:

abcdefghijklmopqrstuvwxyz1234567,Маша,Олег,5 рублей,a61d142c8be7fac8b41da05d11c9f76e

Строим второй блок, где Серёжа заплатил Тане 3 рубля:

md5sum <<< "a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля", получаем хеш 20e22c43963d6ee9bbc71d65c4251492, и, соответственно, блок:

a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля,20e22c43963d6ee9bbc71d65c4251492

И теперь наш блокчейн выглядит так:

abcdefghijklmopqrstuvwxyz1234567,Маша,Олег,5 рублей,a61d142c8be7fac8b41da05d11c9f76e
a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля,20e22c43963d6ee9bbc71d65c4251492

Ну, и так далее, блоков можно добавлять до окончания места на жёстком диске.

Чем это круто? Тем, что блокчейн лежит в свободном доступе, и ЛЮБОЙ человек, взяв этот блокчейн, может собственноручно перевычислить все хеши и проверить все записи: если хеши совпадают, значит, информации можно доверять. Именно этим и занимаются майнеры — они перепроверяют транзакции для криптовалют, то-есть, обеспечивают функционирование платёжной системы, за что им отстёгивают денег.

В блокчейне можно хранить всё, что должно быть общим достоянием и в то же время требует строгой проверки — например, завещания, тексты законов, и т.д. В любой момент можно всё перепроверить.

1. 100% гарантии, разумеется, быть не может, но если алгоритм шифрования нормальный и не имеет коллизий (это когда два разных набора данных дают один и тот же хеш), то вероятность совпадения будет примерно 1/количество возможных хешей, т.е. для хеша длиной 128 бит это 2.94E-39, или пренебрежительно мало. Для хеша длиной 512 бит это вообще число со 150+ символами после десятичной точки.
2. Алгоритм хеширования MD5 достаточно хреновый по современным меркам, и имеет коллизии. Правда, для реально читаемого человеком текста можно пренебречь — все существующие примеры коллизий это хеши специально сгенерированных двоичных данных. Но в реально рабочих приложениях, тем не менее, рекомендуется использовать более коллизионноустойчивые алгоритмы, типа SHA-256 (используется в блокчейне для биткоина) или SHA-3.

Mirrored from Лабораторный Журнал №6.

Есть один нюанс, я так понимаю. MD5 равно как и SHA в чистом виде все-таки довольно легок и быстр, так что пересчитать всю цепочку не big fucking deal, в вполне решаемая задача. Поэтому чейнах приходится искуственно ограничивать количество/усложнять получение хэш значений дабы сложность пересчета всей цепочки стала нереальной, отсюда весь этот гемморой с PoW функциями и прочим майнингом ака переводом конских количеств электричества в биты.
Ну это да, алгоритм генерации новых блоков в блокчейне для биткоина намного сложнее будет, чем в моём примитивном примере. Насколько понимаю, там не любой хеш подойдёт; нужен хеш с определёнными свойствами, из-за чего хешировать приходится оригинальные данные + набор случайных данных, до тех пор, пока не получится нужного рода хеш. Собственно, это и занимает машинное время.
из-за чего хешировать приходится оригинальные данные + набор случайных данных
ага, именно так.
Спасибо, давно хотел разобраться но руки не доходили.

Выглядит так, что зашифрованы только цепи, а собственно транзакции видны каждому. Где же пресловутая секретность?

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

Конкретно в случае с биткоином все транзакции доступны для просмотра каждому, например, тут:

https://blockchain.info/

Другое дело, что в транзакции видно только ID кошельков, представляющие собой длинные шестнадцатиричные числа. И никто не знает, кто стоит конкретно за каким кошельком -- Вася Пупкин или кто-то другой. Таким образом, гражданина можно ловить только в тот момент, когда он окешивает биткоины в какую-то реальную валюту.

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

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

> Я думал что майнеры добывают новую валюту, решая какие-то криптологические задачи, где-то читал что то такое.

Майнеры в основном заняты тем, что создают новые блоки для блокчейна. Там такой формат, что требуются хеши с заранее заданными свойствами. Так как заранее предсказать свойства хеша невозможно, приходится заниматься перебором.
Не совсем понятно. Первое впечатление по прочтении было такое, что блоки создаются в результате транзакций и собственно являются записями таковых.

Теперь выглядит так, что майнеры создают новые блоки хотя сами они ничего за биткойны покупают. Путем долгого подбора удаётся создать новый с подходящими свойствами, это видимо и есть криптологическая задача, о которой я читал. Пока не понял, это делается из уже существущего блока или с нуля?

Может быть ты можешь для ясности добавить пример когда в блоке вообще нет элемента типа <Серёжа,Таня,3 рубля>?
> Теперь выглядит так, что майнеры создают новые блоки

Важная оговорка -- с транзакциями.

> Пока не понял, это делается из уже существущего блока или с нуля?

Я не могу назвать себя экспертом конкретно в формате блокчейна Биткоина, но из того, что разбирал, происходит вот так:

Для создания нового блока берётся информация о хеше предыдущего блока, к ней прибавляется транзакция, и всё это хешируется. Мне плохо понятно, почему, но для Биткоина полученный в результате хеш должен обладать определёнными свойствами, например, начинаться с нужной цифры (пусть с нуля для примера).

Теперь, если ты просто хешируешь "a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля", то получаешь хеш 20e22c43963d6ee9bbc71d65c4251492. Он не годится.

Поэтому ты добавляешь ещё одно поле (nonce, одноразовый код) в полезную нагрузку, и начинаешь совать в него дополнительные данные:

md5sum <<< "a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля,0" даёт
f51fe3353512f26572cca11685a706d7 -- не годится

md5sum <<< "a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля,1" даёт
42c490448e679223aba12f824b82bdb1 -- тоже не годится

md5sum <<< "a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля,2" даёт
84d3a5f0dfcf2320adbbc2fae5e1ecf8 -- обратно, не то

md5sum <<< "a61d142c8be7fac8b41da05d11c9f76e,Серёжа,Таня,3 рубля,3" даёт
02863ab02841007aa319e3038c0d141a -- О!! Вот его-то нам и надо.

Подбор nonce, чтобы получился нужный нам хеш, собсно, и есть основная задача майнера (по машинному времени). Тот, кто первым выполнит этот расчёт, и получает награду за работу.
Все понятно кроме того в чем состоит в данном примере транзакция.
Та самая полезная нагрузка. В случае с биткоином это информация о том, откуда и куда ушли деньги.
Но ты же говоришь, что

> ты добавляешь ещё одно поле (nonce, одноразовый код) в полезную нагрузку, и начинаешь совать в него дополнительные данные:

Я было так тебя понял, что вся в майнеры создают "полезную нагрузку" добавлением дополнительных данных, поскольку при майнинге деньги создаются, а не меняют хозяев.
А. Нет, не совсем так -- они просто добавляют случайные данные к информации о транзакции с целью получения хеша с нужными свойствами. Т.е. не на ровном месте -- это всё для осуществления транзакции, платёжной системы в целом.
>Мне плохо понятно, почему, но для Биткоина полученный в результате хеш должен обладать определёнными свойствами, например, начинаться с нужной цифры (пусть с нуля для примера).

В конце прошлого века, когда человечество открыло для себя почтовый спам, кто-то умный предложил усложнить электронную почту, что бы для посылки сообщения требовалось гораздо больше машинного времени.
Ну, типа покупки почтовой марки на письмо, та же идея.
Это предложение было отвергнуто "вышестоящими организациями", поскольку разорило бы много компаний, уже делающими большие деньги на рассылке спама.
Но... несколько годами позднее, нашло себе применение в блокчейне.
Именно эти самые паззлы, решаемые майнерами, делают электронные деньги не бесплатными.
Как известно, биткойн уже потребляет больше электроэнергии чем Польша.
Я вот про блокчейн не читал
Зато читал про git! Там то же самое:)
Принципиально нового в мире вообще очень немного ;-)
> но если алгоритм шифрования нормальный и не имеет коллизий

А можете на пальцах объяснить, как это так может быть, чтобы коллизий не было ?
Строго говоря, невозможно сделать так, чтобы не было коллизий "вообще", так как длина хеша конечна, а количество возможных данных, которые можно скармливать алгоритму, бесконечно.

Простой пример: пусть длина хеша 8 бит. Очевидно, что максимальное количество хешей составляет 256. И что если мы скормим алгоритму 257 разных слов, среди полученного множества хешей у нас будет как минимум два одинаковых (коллизия), тупо по принципу Дирихле https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%94%D0%B8%D1%80%D0%B8%D1%85%D0%BB%D0%B5_(%D0%BA%D0%BE%D0%BC%D0%B1%D0%B8%D0%BD%D0%B0%D1%82%D0%BE%D1%80%D0%B8%D0%BA%D0%B0)

Если алгоритм хеширования хороший, то-есть, не склонен выдавать одинаковые хеши для разных входных данных, то у нас будет только одна коллизия.

Но при том же хорошем алгоритме если длина хеша составляет хотя бы 256 бит, количество возможных хешей составляет 1.16E+77, т.е. всего лишь примерно в тысячу раз меньше количества элементарных частиц в наблюдаемой вселенной, и коллизия нам, скорее всего, не грозит =)
>Строго говоря, невозможно сделать так, чтобы не было коллизий "вообще", так как длина хеша конечна, а количество возможных данных, которые можно скармливать алгоритму, бесконечно.

Вот именно на это я и намекаю, да.