Вот эта статья //infostart.ru/public/986126/. Я прочел ее с удовольствием, но меня несколько расстроила позиция автора насчёт того, что криптовалюты - это, с его же слов, "МММ 21 века". Дескать, настоящие деньги имеют какое-никакое обеспечение, а криптовалюты они все пустые пустышки и ничего более. Мне всегда досадно слышать такое от нашего брата-ИТишника. Ведь деньги - это, в сущности, ничто иное, как информация. Когда я прихожу к вам купить пирожок, общество посредством денег передает вам информацию о том, что я в чём-то хороший человек. И вы можете отдать мне пирожок, и тогда общество будет уже вас считать в чём-то хорошим человеком. Нуждается ли информация в каком-либо обеспечении? Конечно нет.
Во избежание дальнейших недоразумений, нам следует поставить здесь большой полосатый столб. Он будет отделять то, что было до появления компьютеров, от того что мы имеем сейчас. Очень часто ставят знак равенства между информационными и компьютерными технологиями. Но это неправильно. Информационные технологии существовали и до изобретения компьютеров. Просто они были немного другими. В описанном мною только что случае с продажей пирожка, людям, не имеющим компьютеров, требовалось найти какой-то способ верификации передаваемой информации. И способ был найден. Простой и эффективный. Информация была привязана к ценности. Мне не нужно золото само по себе. Но я его ношу с собой, потому что с одной стороны оно надёжно верифицирует информацию, а с другой - его много не надо, и поэтому его не очень сложно носить. Но суть всего этого в том, что я ношу с собой не золото. Я ношу информацию на золотом носителе. И надо понимать, что такая привязка - это вынужденная мера. С изобретением компьютера необходимость в ней отпадает. В комментариях к той статье многие справедливо замечали, что современные валюты уже давным-давно ни к чему не привязаны. Все так. Только не "давным-давно", а с появлением компьютеров.
Вот тут самое время поставить другой полосатый столб. И этот столб будет посерьёзнее первого. Он отделяет тех, кто утверждает что:
никогда, никогда, никогда, никогда...
люди не договорятся друг с другом. Им безусловно нужен всеобщий арбитр, называемый государством или ещё каким-нибудь другим словом. И поэтому, пусть за деньгами уже и не стоит ничего ценного, но всеобщий арбитр все равно должен стоять. Иначе, ничего работать не будет.
С другой стороны находятся люди, которые говорят что есть способ договориться. И не один. Как вы наверное уже догадались, я принадлежу именно этой группе. И я вам сейчас расскажу об этих способах.
Я буду использовать понятия и термины 1С. Более того, я опишу вам словами некую конфигурацию. Таким образом, большинству из вас будет сразу понятно - работает то, о чем я говорю или нет. В принципе эту конфигурацию можно будет и воспроизвести в реальности, если у кого-то возникнет такая безумная идея.
Итак, допустим несколько 1С-ников решили сделать себе криптовалюту. Для этого им не нужно ничего, кроме базы. Они договорились, что база будет храниться не у кого-то одного, а сразу у всех. Примем одно необязательное упрощение. Предположим, что они договорились обмениваться данными в строгом порядке. Первый участник вносит изменения в базу и передает ее второму участнику (если изменений не было, просто передает базу). Второй делает то же самое и передает базу третьему и т.д. Последний участник передает базу снова первому. Если говорить умными словами, в этой базе будет высший уровень изоляции транзакций, и не будет коллизий. Ниже я покажу, каким образом можно разрешать коллизии и установить произвольный порядок обмена, но будет лучше, если мы съедим этого слона по кусочкам.
Конфигурация у этой базы будет очень простая. Один справочник. Назовем его "Кошельки". И один документ. Пусть его имя будет "Платежи".
У справочника кроме стандартных реквизитов, будет один строковый реквизит неограниченной длины под названием "ПубличныйКлюч" (о нем чуть ниже). У документа тоже будет не так чтобы очень много реквизитов. Всего четыре:
КошелекОтправитель
КошелекПолучатель
Сумма
Подпись (строка неограниченной длины)
Далее участники проводят особый, первый цикл обмена. Каждый из участников создает кошелек, заполняет реквизит "ПубличныйКлюч" и создает один документа платежа. В этом документе "КошелекОтправитель" будет пустым. "КошелекПолучатель" - будет кошелек участника. Сумма 100, или любая другая, о которой заранее договорятся участники. Подпись можно оставить пустой. Такого рода операции допустимы только в первом цикле обмена. В дальнейшем "КошелекОтправитель" должен быть обязательно заполнен. База готова и наши участники могут начинать проводить платежи между собой. Как это будет происходить. Представьте, что сейчас ваша очередь поработать с базой и передать ее дальше. Что вы можете сделать с базой? Как хороший 1С-ник, конечно, все что угодно. Но если учесть, что ваши действия будут проверены принимающей стороной, то не так уж много. Вы можете добавить один или несколько платежей. При этом, "КошелекОтправитель" может быть только вашим кошельком и никаким другим. Добиться такого эффекта позволяет ассиметричное шифрование. Его теория была неплохо описана в статье, о которой я говорил в самом начале. Что касается практики применения, то она тоже достаточно хорошо, и не раз, описана на Инфостарте. Можно посмотреть хотя бы здесь: //infostart.ru/public/633032/ или здесь: //infostart.ru/public/176244/. Смысл в том что в ОС Windows, например, есть встроенные инструменты криптографии. Есть объект System.Security.Cryptography.RSACryptoServiceProvider. Вы можете работать с ним через COM (описание методов здесь: https://docs.microsoft.com/ru-ru/dotnet/api/system.security.cryptography.rsacryptoserviceprovider?view=netframework-4.7.2) или через 1С-овский МенеджерКриптографии. Там все просто. Когда вы создаете объект, в его реквизитах формируются два ключа. Открытый и закрытый. Открытый вы копируете в соответствующий реквизит своего кошелька. А закрытый вы записываете на бумажку и съедаете ее )))... Закрытый вы храните у себя каким-нибудь надежным способом. Когда вы создаете платеж, вы создаете новый объект этого самого криптопровайдера, заполняете соответствующие реквизиты объекта сохраненными ранее ключами (открытым и закрытым). И выполняете метод: Подписать(стр). На вход метода вы подаете что-то типа:
КошелекОтправитель.Код+"/"+КошелекПолучатель.Код+"$"+строка(Сумма)
Можно использовать не коды, а ID. Можно ЗначениеВСтрокуВнутр(). Не суть. На выходе вы получите строку подписи. Ее-то вы и вставите в реквизит "Подпись" вашего документа. Теперь принимающая сторона сможет в свою очередь запустить метод ПроверитьПодпись(Подпись,ОткрытыйКлюч). На входе будет проверяемая подпись и открытый ключ кошелька-отправителя, а на выходе получится то, что ранее подавалось на вход метода Подписать() и останется только сверить это с данными самого документа. Фишка в том, что не имея закрытого ключа вы не сможете получить правильную подпись. Как следствие, вы можете потратить только свои деньги.
Следующий момент заключается в том, что вы не можете поратить больше, чем у вас осталось. Я думаю все знают, как сделать контроль отрицательных остатков. Только надо понимать, что для надежности все эти процедуры контроля (проверка подписи и контроль отрицательных остатков) должны быть за пределами нашей конфигурации. Например, во внешних обработках. Так же во внешней обработке должна лежать процедура создания платежа, потому что она так или иначе должна получать доступ к закрытому ключу.
В нашей системе осталась только одна "дырка", но очень серьезная. Она обозначается термином, который хорошо знаком всем 1С-никам. Это - "изменение задним числом". Да, я могу изменять только записи расходов с моего кошелька. Но тогда, я возьму и поменяю свою же запись недельной (месячной, годовой) давности. Например вместо расхода 20 монет на счет Васи, поставлю 10 или 5. Если я подойду к делу вдумчиво и поставлю такую сумму, что у Васи нигде после этого не возникнет отрицательных остатков, то я, по сути, заберу себе деньги с Васиного счета и никакие процедуры контроля этого не заметят.
Вася, конечно, обнаружит пропажу. Но, во-первых, когда еще это будет (особенно если сумма незначительна). А во-вторых, какие у него доказательства?
Способ решения этой проблемы называется словом "блокчейн". Блокчейн - это организация базы данных таким образом, что незаметное изменение "задним числом" полностью исключается. Вобще его (блокчейн) можно использовать в любой базе данных. Возни совсем немного (несколько десятков строк кода), а польза огромная. Подробнее об этом, с примерами кода 1С можно почитать здесь: //infostart.ru/public/728995/
Добавим в документ еще два строковых реквизита: "КлючНачальный" и "КлючКонечный". В 1С есть такой объект "ХешированиеДанных". Хеширование - это когда мы подаем на вход строку любой длины (хоть десять символов, или хоть "Войну и Мир" целиком), а на выходе получаем строку фиксированной длины, например 32 символа. Мне знакомый математик (не криптограф) говорил: ну как же так, будут же повторяющиеся строки на выходе при разных на входе. Будут. Но тут надо понимать - как часто. Если бы у нас на выходе было всего два возможных варианта, например "0" и "1", тогда совпадения происходили бы в каждом втором случае. При десяти возможных вариантах уже пореже. А если мы имеем на выходе 32 символа, то количество вариантов находится где-то рядом с количеством всех атомов в наблюдаемой вселенной. Поэтому, на практике возможностью совпадений пренебрегают.
Теперь при создании нового документа, мы первым делом запишем в "КлючНачальный" "КлючКонечный" из предыдущего документа. Затем получим хэш документа с помощью примерно такой функции:
Функция ПолучитьХешДокумента(ссылка)
хд=новый ХешированиеДанных(ХешФункция.SHA256);
хд.Добавить(ПолучитьДокументСтрокой(ссылка));
рез=строка(хд.ХешСумма);
рез=стрзаменить(рез," ","");
возврат рез;
КонецФункции
На вход будем подавать ссылки на кошельки, сумму и начальный ключ (он же - конечный из предыдущего документа, не забыли?). Полученный хэш запишем в конечный ключ нашего документа. Теперь у нас есть связанная цепочка документов. Внести в нее незаметные изменения нельзя. Если вы удалите какой-либо документ, тогда несовпадут начальный и конечный ключи. Если вы измените документ, тогда содержимое документа перестанет соответствовать конечному ключу. А если подогнать значение конечного ключа под содержимое документа, тогда возникнет расхожение с начальным ключом следующего. Все это очень легко и быстро может быть проверено в автоматическом режиме. А для того, чтобы обмануть автоматическую проверку потребуется заново рассчитать все конечные(начальные) ключи, начиная с того документа, который вы изменили. Ваше изменение как-бы всплывает на поверхность из недр базы. В этом суть и магия технологии блокчейн. Можно ли проверить натурально, глазами всю базу от начала до конца? Оказывается - можно, надо только посмотреть на одну-единственную хеш-сумму.
Все, что я хотел вам рассказать, явно не умещается в одну статью. Поэтому, здесь я закончу, но в ближайшее время напишу продолжение, в котором расскажу о том что такое "доказательство работы", что будет, если кто-то решит поменять правила игры, кто такие "византийские генералы", зачем Дуров взялся ими командовать и что из всего этого следует.