Технология «блокчейн» прекрасна и перспективна. Всё в ней было бы совсем замечательно, если бы несколько досадных нюансов:
- Очень долго. Время добавления транзакции в цепочку биткоина, например, оценивается от минуты до получаса. В Ethereum добавляется быстрее, но в любом случае довести время до долей секунды невозможно. Нечего и думать о том, чтобы сделать добавление данных в блокчейн частью OLTP-транзакции.
- Майнинг — это очень ресурсоёмко. Он, собственно, и нужен для того, чтобы добавить в архитектуру вычислительную сложность.
- Очень дорого. Следствие ресурсоёмкости.
- Технология отвратительно масштабируется как вверх, так и вниз. Если нужно построить систему, которая будет регистрировать миллиарды записей ежедневно, блокчейн не годится. Также блокчейн будет стрельбой из пушки по воробьям, если его пытаться приспособить для надёжного логирования какой-нибудь мелкой ерунды.
Хотелось бы иметь технологию, которая бы одновременно и реестры позволяла вести непрошибаемо надёжным образом, и была бы как-то попроще и подешевле.
Модельная ситуация (художественный вымысел по мотивам реальных событий)
В одной крупной производственно-дистрибьюторской компании был большой департамент продаж, в котором, как водится, бонусы менеджерам зависели от объёмов проданного.
Самые сладкие объёмы продаж делаются на самом ходовом и, как следствие, дефицитном товаре. Менеджеры-продажники — ребята ушлые. Они быстро сообразили, что самый верный способ иметь хорошие бонусы — постоянно мониторить поставки, и как только на складе появляется дефицит, быстренько резервировать его под себя. Создавать фиктивный «Заказ покупателя», набивать его дефицитом и говорить всем, что это клиент, который пока что думает, что ему нужно взять ещё (в общем, нормальная ситуация). Потом, когда появляется реальный запрос на дефицит, быстренько убирать требуемое количество из фиктивного счёта, и в ту же секунду добавлять в реальный.
В результате бизнес несёт убытки. На складе неделями валяется товар, который должен был бы уйти в первый же день. Департамент продаж вместо того, чтобы заниматься поиском новых клиентов и выстраиванием взаимоотношений с ними, целыми днями мониторит поставки. Склоки, нервотрёпка, взаимные упрёки и обиды. С этим что-то надо было сделать, но так, чтобы это не повредило основному бизнес-процессу. Решили для начала логировать операции резервирования. Отследить ситуации, когда дефицит резервируется «заказом покупателя», но потом это резервирование не превращается в продажу этим же документом. Тех, кто этим больше всех злоупотребляет, вешать на позорном столбе.
Поначалу помогло, но потом начал наблюдаться странный эффект: показатели зависания дефицита на складе вернулись к прежним, хотя по логам всё было шоколадно. Оказалось, что что в реализации не была учтена сила обаяния менеджеров по продажам. Ради высоких бонусов они повадились сговариваться с системными администраторами, чтобы те вычищали из логов компромат. В ход пошёл весь арсенал средств — подкуп, шантаж, флирт, женские слёзы. Парням из службы администрирования оказалось нечего противопоставить такой атаке.
Встал вопрос о том, чтобы техническими средствами сделать невозможным искажение лога задним числом. Посмотрели в сторону блокчейна, но выяснили, что пропускать резервирование товара через популярные блокчейн-платформы слишком накладно, а городить отдельную серверную стойку под собственный блокчейн для улаживания дрязг в департаменте продаж тоже никакого желания нет. Что делать — не понятно.
Самые сладкие объёмы продаж делаются на самом ходовом и, как следствие, дефицитном товаре. Менеджеры-продажники — ребята ушлые. Они быстро сообразили, что самый верный способ иметь хорошие бонусы — постоянно мониторить поставки, и как только на складе появляется дефицит, быстренько резервировать его под себя. Создавать фиктивный «Заказ покупателя», набивать его дефицитом и говорить всем, что это клиент, который пока что думает, что ему нужно взять ещё (в общем, нормальная ситуация). Потом, когда появляется реальный запрос на дефицит, быстренько убирать требуемое количество из фиктивного счёта, и в ту же секунду добавлять в реальный.
В результате бизнес несёт убытки. На складе неделями валяется товар, который должен был бы уйти в первый же день. Департамент продаж вместо того, чтобы заниматься поиском новых клиентов и выстраиванием взаимоотношений с ними, целыми днями мониторит поставки. Склоки, нервотрёпка, взаимные упрёки и обиды. С этим что-то надо было сделать, но так, чтобы это не повредило основному бизнес-процессу. Решили для начала логировать операции резервирования. Отследить ситуации, когда дефицит резервируется «заказом покупателя», но потом это резервирование не превращается в продажу этим же документом. Тех, кто этим больше всех злоупотребляет, вешать на позорном столбе.
Поначалу помогло, но потом начал наблюдаться странный эффект: показатели зависания дефицита на складе вернулись к прежним, хотя по логам всё было шоколадно. Оказалось, что что в реализации не была учтена сила обаяния менеджеров по продажам. Ради высоких бонусов они повадились сговариваться с системными администраторами, чтобы те вычищали из логов компромат. В ход пошёл весь арсенал средств — подкуп, шантаж, флирт, женские слёзы. Парням из службы администрирования оказалось нечего противопоставить такой атаке.
Встал вопрос о том, чтобы техническими средствами сделать невозможным искажение лога задним числом. Посмотрели в сторону блокчейна, но выяснили, что пропускать резервирование товара через популярные блокчейн-платформы слишком накладно, а городить отдельную серверную стойку под собственный блокчейн для улаживания дрязг в департаменте продаж тоже никакого желания нет. Что делать — не понятно.
В принципе, на этом можно было бы публикацию закончить и предложить уважаемой публике пофантазировать в комментах о том, как можно сделать супернадёжную запись трензакций в условиях тотального недоверия всех ко всем без того, чтобы бессмысленно прожигать процессорные мощности никчёмным подбором хеш-функций. Но для того, чтобы единственным ответом на вопрос не было банальное «это невозможно» или что-нибудь про сайдчейны, попробую предложить свой вариант.
Сразу оговорюсь, что речь вовсе не о том, «как нам реорганизовать биткоин». Пусть биткоин остаётся таким, какой он есть, а мы поговорим о том, как сделать что-то функционально аналогичное блокчейну, но пригодное к использованию для самых разных нужд в частности в корпоративных системах. Дешёвое и сердитое.
Для начала внимательно посмотрим на саму задачу. Во-первых, мы уже имеем сам защищаемый от фальсификации реестр. Во-вторых, нам не очень важна распределённость системы. Удобнее всего, если система защиты реестра будет централизованной. В идеале — на том же самом сервере, что и сам реестр. Распределённость реестра и системы его защиты тоже может быть во многих случаях полезна, но начать нужно с простого. С принципа защиты.
Система защиты реестра в инфраструктуре корпоративной системы:
Априорно считаем, что всё происходящее на серверах — в полной власти администраторов, и эти администраторы с их человеческими страстями — слабое звено. Поэтому функция контроля целостности реестра частично возлагается на рабочие места пользователей. Реализуется принцип «не доверяй, проверяй». Администратор может сделать что угодно с расположенными на сервере данными, но он не в силах отследить, куда и по каким компьютерам (а также смартфонам, планшетам, флешкам и т.п.) расползлись контрольные суммы, фиксирующие целостность реестра. В клиентское приложение (или, возможно, в отдельное специальное контролирующее приложение) встраивается функция, которая при обнаружении факта нарушения целостности реестра зажигает красную лампочку и позволяет сформировать криптографически достоверное обвинительное заключение.
Защищаемый реестр и его контрольные суммы:
Для каждой записи реестра подсчитывается собственный хеш (H0i), а также автоматически наращивается бинарное дерево хешей второго, третьего и так далее порядков (H1, H2,...). После того, как очередная запись занесена в реестр, клиентскому приложению возвращается сама занесённая запись, а также такой набор хешей более высоких уровней, чтобы он полностью покрывал все предыдущие записи реестра. Например, при добавлении шестой записи возвращается D5, H05, H12 и H20 (удобнее смотреть на картинке ниже). При добавлении 15-й записи, соответственно, возвращается D14, H014, H16, H22 и H30. Получив ответ от сервера, клиентское приложение:
- Проверяет соответствие Di тому, что оно собиралось занести в реестр.
- Самостоятельно рассчитывает H0i и проверяет, равно ли получившееся тому, что прислал сервер.
- Запоминает себе в локальную базу полученный от сервера ответ.
Для того, чтобы исключить подделку ответа сервера и прочие неприятности, этот ответ можно защитить электронной подписью сервера.
Экспресс-проверка неизменности собственных записей клиента
Когда клиент добавил в реестр очередную запись, он может сверить новый полученный срез хешей со срезами, полученными при предыдущих обращениях. Поскольку с предыдущего обращения могли нараститься дополнительные уровни, для сверки хешей может потребоваться некоторое количество дополнительны данных от сервера. Например, если клиент сначала добавил D5, а потом добавил D14, то для сверки H20 с H30 он запрашивает с сервера значение H13, затем на основании H12 и H13 вычисляет H21, после чего на основании H20 и H21 рассчитывает H30, которое сравнивает с полученным. Если значения не совпадают, включается красная лампочка и сигнал тревоги.
Серым цветом показаны данные, отсутствующие на клиенте. При добавлении первой своей записи (D5) клиент в своей локальной базе сохранил данные, выделенные зелёным, а при добавлении следующей записи (D14) получил данные, выделенные синим. Выделенное жёлтым запрашивается с сервера защиты дополнительно.
Сплошная проверка участка реестра
Клиент запрашивает с сервера участок реестра и проверяет, возможно ли от полученных данных выйти на те значения хешей, которые сохранены в его локальном хранилище.
В результате имеем:
- Скорость добавления данных в реестр. Майнить коины оказывается незачем. Увеличение производительности вплоть до того, что данные в защищённый реестр можно записывать внутри OLTP-транзакции.
- Надёжность. Незаметно удалить запись из реестра невозможно. Сложность искажения данных равна сложности подбора полной хеш-коллизии.
- Простота реализации. Прекрасная масштабируемость «вниз».
- Прекрасная масштабируемость «вверх». Даже если в реестре сто миллиардов записей, количество уровней бинарного дерева оказывается равным 36. Если используется хеширование SHA-256, передаваемые с сервера данные хешей составляют менее 2 килобайт.
- Хоть ведение реестра становится централизованным (что для случая криптовалюты в стиле биткоина не очень хорошо), вполне возможна распределённая архитектура на основе репликации и оперативного переключения со скомпрометированных узлов на те, которые не были уличены в подлоге.
P.S. Про исходники на гитхабе, пожалуйста, не спрашивайте. Их нет. Идея уходит в публикацию с колёс.