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

Данная модель показывает наглядно почему, даже в случае покупателя и продавца, сторон обмена никак не может быть меньше трех. При любой передаче ресурсов они всегда проходят через некоторые слои контроля. А так же большим плюсом данной модели является применимость к бартерным операциям. Отсутствует необходимость в денежном обращении и оценке.
Цель существования этих слоев была для ограничения и контроля потоков. Ни один субъект, если он желает и дальше сохранять свою субъектность, не может не контролировать потоки ресурсов в зоне своего хозяйствования. Разумеет на бумаге можно писать все что угодно, даже про свободу движения ресурсов, но ее никогда не было, нет и не будет. Это невозможно. Даже если брать совсем дикий капитализм каких-нибудь фантазеров с ‘‘саморегулирующимся рынком’’, для совершения любого обмена нужно как минимум пройти контроль у каждой из сторон этого обмена (достаточность средств что-то купить, вовсе не означает возможность приобретения - вам могут просто отказать) и местного пахана, который в условиях отсутствия централизованной власти всегда появится и объяснит вам сколько, как часто и куда вам нужно заносить для здоровья и долголетия, ничто так не продлевает жизнь.
Для принятия решений в каждом слое контроля решение опирается на некоторые факторы(атрибуты), которые позволяют осуществить контроль. Именно в сверке этих атрибутов и лежит основа того, что необходимо автоматизировать.
Атрибуты
Теперь имея в голове модель обмена ресурсами, можно составить решение. Для корректной работы потребуется наделить каждую сторону атрибутами, а так же передаваемые ресурсы. В этом случае для любого обмена мы сможем получить скомпилированный документ, описывающий обмен:
{ "receiver": { "fio": "Иванов Иван Иванович", "country": "Российская Федерация" }, "sender": { "company_name": "ООО Заварные ватрушки", "country": "Российская Федерация" }, "resource": { "in": { "type": "Рубли", "amount": "10" }, "out": { "type": "Заварная ватрушка", "amount": "1" } } }
По такому документу мы можем:
Ограничить возможность покупки заварных ватрушек для Ивана Ивановича производителями из Российской Федерации;
Установить ценовой диапазон продажи заварных ватрушек;
Выставить квоту на количество заварных ватрушек для Ивана Ивановича за определенный период времени;
На купленные Иваном Ивановичем ватрушки поставить атрибуты, которые не позволят ему их перепродавать;
Так же можно сделать так, что определенные товары смогут покупать только малоимущие.
Даже если в обмене участвуют множество сторон, всегда есть возможность составить для каждой пары свой документ, по которому необходимо осуществить проверки.
Предикаты
Каждая сторона обмена может на основании атрибутов выполнять некоторую предикативную логику, которая скажет - возможно ли провести этот обмен, или нет.
Предикаты могут быть самыми разными:
Логические;
Арифметические;
Встроенные функции проверки, такие как проверка сертификата, что он был выдан нужным УЦ;
Квотирование;
Вычисление изменений атрибутов отправляемого ресурса;
Другое.
У читателя может возникнуть вопрос, каким образом можно при помощи чего-то, что отвечает да/нет получить квотирование или установку атрибутов ресурсов? Все несколько сложнее. Представим себе следующий предикат:
{ "type": "Логический", "logicalType": "И", "operands": [ { "type": "Логический", "logicalType": "Сравнение", "lhs": { "type": "Атрибут", "attributeName": "receiver.fio" }, "rha": { "type": "Константа", "value": "Иванов Иван Иванович" } }, { "type": "Квота", "id": "ЗаварныеВатрушкиОднаШтукаВДень", "amountRef": "resource.out.amount" }, { "type": "УстановкаАтрибута", "resourceDirection": "out", "attributeName": "КупленоУ", "attributeValue": "${sender.companyName}" } ] }
Результат выполнения данного предиката - это объект. Он состоит из собственно результата (Да/Нет), а так же дополнительных полей. Что бы сообщить, что для проведения платежа должна быть квота, достаточно передать ее вместе с результатом выполнения предиката Квота. Аналогично с установкой атрибутов.
Так как любой предикат выполняется в контексте, то ему можно заблаговременно передать список доступных квот, которые можно погасить при выполнении обмена. В случае доступности квоты, предикат всегда возвращает истину и идентификатор квоты, в случае ее отсутствия - ложь.
Так как логическое И подразумевает, что все операнды должны быть истинными, то в случае отсутствия квоты (она была израсходована), выражение будет вычисляться как ложное и обмен будет запрещен. Если бы на месте логического И стояло логическое ИЛИ, то в случае совпадения атрибута, квота не резервируется и не принимает участие в вычислениях.
Т.е. в случае разрешения обмена, результат выполнения предиката будет таким:
{ "result": true, "quotas": [ "ЗаварныеВатрушкиОднаШтукаВДень" ], "attributes": { "КупленоУ": "ООО Заварные ватрушки" } }
Что приведет к тому, что квота “ЗаварныеВатрушкиОднаШтукаВДень” будет уменьшена на 1, а купленная заварная ватрушка получит новый атрибут “КупленоУ”.
В случае отказа (например из-за невозможности создать резерв на квоту):
{ "result": false, "quotas": [], "attributes": {} }
Очевидно, что предикаты всех слоев контроля можно объединить в общий для проверки конкретного обмена ресурсами. Так же очевидным является, что необходимо предикаты писать так, что бы учитывать, возможность нахождения стороны как получателя/отправителя. Либо же сама система должна подстраиваться под ситуацию получения/отправки ресурса и пересчитывать атрибутивный документ.
Альтернативным вариантом является явное разделение предикатов на типы - ограничение приема и отправки. В этом случае атрибутивные документы всегда будут создаваться в нужном формате и не придется гадать о названии атрибутов - они будут закреплены.
Отдельно следует отметить, что применение предикатов позволяет:
Сделать ограничение, например физическое лицо не может купить больше 40 литров бензина в день, и не важно на какой заправке он будет совершать операцию;
Осуществить плавное закручивание/раскручивание гаек: в трудные времена, когда различные лица, нетрадиционной интеллектуальной ориентации, скупают всю гречку, сахар, топливо и иные продукты такое является обязательным;
Осуществить мягкую блокировку (когда можно выполнять только ограниченный список покупок) операций аккаунта по любым кошелькам, либо всем аккаунтам по конкретному кошельку, например в случае подозрения в действиях противоправного характера. Такой подход намного лучше, чем оставлять человека без средств к существованию и заставлять его уходить в тень;
отслеживать движение ресурсов между кошельками, например посредством изменения атрибута (в случае необходимости можно составлять полный список или последние К кошельков, через которые проходил ресурс).
Реализация
Весь код можно найти в репозитории gitlab . Так как развитие LLM уже позволяет весьма эффективно объяснять работу кода, то вдаваться в детали реализации автор не будет, ограничившись лишь ключевыми моментами.
Сейчас полноценно не реализована установка атрибутов на ресурсы и квоты не реализованы до конца, сервис Квоты даже не реализован. Однако фильтровать платежи можно.
Схема обработки контракта была доработана. Теперь при инициализации выполняются следующие шаги, до попытки что-либо списывать:
Все узлы рассылают друг другу публичные атрибуты сторон обмена;
Все узлы формируют и рассылают друг другу ограничения на прием ресурсов (что бы отправитель не пытался отправлять то, что не будет принято);
Продолжение выполнения контракта как было и ранее, но уже с учетом ограничений на списание/зачисление.
Так как все ограничения разделены по типу ресурса и дополнительно по типу операции (списание/зачисление), то это позволяет обеим сторонам корректно учитывать ограничения. У читателя возможно появится вопрос - в предикате есть ссылки на атрибуты, а ранее автор сообщил, что есть публичные атрибуты, значит есть и приватные? Как их получает отправитель? Почему он вообще должен иметь доступ к приватным данным стороны?
Для ответа на данный вопрос следует описать принцип работы предикатов в MireaPay.
Предикат - это не просто некоторое условие, которое выполняется или нет. Это оператор с двумя режимами - вычисление и свертка. Первый - это и есть классический вариант выполнения предиката. Второй - позволяет вычислить все, что можно вычислить в данный момент и вернуть предикат в сокращенной форме. Это позволяет безопасно ссылаться на приватные атрибуты и, при правильном написании предиката - никогда не отправлять ничего кроме результата (истина/ложь), т.е. в худшем случае пределы узла, хранящего приватные данные, покинет только указанный в предикате атрибут, а не все данные клиента.
Свертки позволяют скомпилировать предикат, обогатить его имеющимися значениями атрибутов, отправить и затем уже с недостающими атрибутами получить результат. Именно таким образом осуществляется обработка ресурсов в сервисе Баланс. Он получает уже почти готовый предикат, которому передаются атрибуты каждого ресурса, что бы вычислить возможность его отправки. Очевидно, что помимо ограничений зачисления получателя, так же проверяются ограничения списания отправителя. Таким образом получается полный цикл проверок для каждой передачи. После списания ресурса и отправки его получателю - тот в свою очередь проверяет еще раз, что он может получить такой ресурс и производит зачисление.
Такой подход позволяет экономить ресурсы и наглядно видеть почему произведена (или отклонена) операция, так как все атрибуты и операторы фиксируются в контракте. При этом асимметрия информации в случае обменов между разными субъектами сохраняется. Субъекты передают друг другу только ту информацию, о которой заранее договорились на своем уровне.
Работа с квотами в таком случае осуществляется таким образом:
Для всех сторон резервируются все квоты, упоминаемые в предикатах с учетом максимального теоретического количества, резервирование осуществляется частично, если полностью удовлетворить запрос нельзя;
Проводится свертка предикатов с доступными квотами, из доступного количества вычитается размер использованной квоты по результатам свертки, что бы последующие операторы (для других обменов в контракте) не срабатывали на те квоты, которые не удалось зарезервировать в полном объеме;
Теперь в оператор прошиты доступные квоты, которые потенциально могут использоваться в контракте - мы получили скомпилированный предикат, который можно отправить другой стороне, сервису, при этом он содержит минимум информации, необходимый для финального вычисления.
В дальнейшем, может оказаться так, что какие-то квоты не будут использованы, либо частично. Будущий сервис Квоты - это почти копия сервиса Баланс. Основная разница лишь в том, что списание квоты не приводит к зачислению ее куда-либо, эта операция односторонняя и о ее осуществлении не нужно уведомлять другие стороны. В отличие от сервиса Баланс - новый сервис должен поддерживать расширенные операции платежного API: частичное списание и подтверждение с корректировкой. Второе - специальная операция позволяющая освободить часть резерва перед тем, как подтверждать транзакцию. Корректировки не позволяют увеличить размер заблокированных средств.
Изменение атрибутов ресурсов позволяет модифицировать их согласно политике. Например, предприятие получает льготные средства от государства, но на расходы накладываются ограничения. Если этими же средствами можно выплачивать людям зарплаты, то получится ситуация, когда работник получает зарплату, которую не может ни на что потратить. Для решения этой проблемы и добавлена возможность модификации атрибутов (а возможно позднее и предикатов) ресурса. В случае заработной платы на ресурс может быть выставлен специальный флаг, который отключит предикат и позволит средствам ходить по экономике. При этом сам предикат никуда не делся, так же как и атрибуты, которыми государство наделило ресурс.
Исключением из данного правила будут лишь крупные юридические лица, для которых используется отдельный механизм работы. Так как у них отсутствует возможность вычислять баланс и строго его соблюдать, они по сути “стирают” информацию о атрибутах и предикатах ресурса. Для того, что бы избежать такой ситуации, в MireaPay предусмотрен механизм принудительной установки атрибутов и предикатов на ресурс. Причем можно настроить достаточно гибко. Так как одним кошельком может распоряжаться множество аккаунтов, то на каждый можно предусмотреть свою политику. Такой подход позволяет не только ограничить работу подразделения и сразу выдать ему нужные ресурсы с ограничением и квотами (без необходимости в дальнейшем согласовывать каждый платеж), но так же ограничить само хождение ресурсов, которые будут передаваться от подразделений контрагентам.
Примерами расширенного использования аккаунтов для кошелька являются:
Кассовому аппарату присваивается отдельный аккаунт для совершения всех платежей, теперь организация может видеть движение средств по этому кассовому аппарату, при этом кошелек все равно остается корпоративным, с сохранением корпоративных политик доступа к ресурсам;
Родительский (опекунский) контроль за несовершеннолетним (недееспособным), передавать напрямую кошелек и ресурсы подопечного не нужно, достаточно дать права супервизора на аккаунт в кошельке и тогда можно будет выставить лимиты, дополнительно подтверждать операции и т.д;
Подразделению выдается отдельный аккаунт для закупок оборудования/ресурсов/другое, на него выставляются лимиты (суточные, недельные, месячные), а так же выставляется список контрагентов с которыми можно совершать операции.
Такой функционал возможен, потому что аккаунт наделяется определенными правами в рамках кошелька и не может за них выйти. Например права супервизора не позволяют совершать платежи, но позволяют подтвердить или отклонить операцию, совершаемую другим аккаунтом.
Заключение
В данной работе была представлена обобщенная модель обмена ресурсами и контроля их передачи. Показано, что можно автоматизировать процесс проведения проверок и ограничений. Предлагаемое решение имеет большой плюс в виде простоты и доступности его применения большей частью населения, так как для понимания работы и использования достаточно прочитать брошюру или пройти короткий курс обучения.
Несомненным преимуществом предложенного является возможность независимо всеми сторонами обмена, которых всегда не меньше трех, устанавливать свои ограничения на проводимые операции. Такой подход позволяет использовать один и тот же инструмент всеми сторонами и экономить не только на самом обеспечении обмена (например в виде потраченных кВт электроэнергии), но и обучении персонала. Поддержание в рабочем состоянии существующих аналогов (позволяющих окрашивание) требует высококвалифицированных специалистов, которых от силы тысяча на всю землю. Внедрение систем, требующих столь серьезного опыта, приведет либо к зависимости из-за возможности диктовать условия, либо к деградации инфраструктуры при малейшем кризисном явлении. Платежная система - это инфраструктура, которая должна умирать последней, в случае сокращения доступных ресурсов экономики, которую она и обслуживает. Фиатные деньги именно по такому же примеру превращались в ничто лишь после краха экономики. Для успеха современной платежной системы - такое требование должно быть обязательным. Архитектор платежной системы всегда должен отдавать себе отчет, сколько ресурсов нужно в норме для корректного функционирования. Во сколько раз можно сократить ресурсы выделяемые на поддержание системы, что бы она при этом оставалась в рабочем состоянии, не деградировала?
Разумеется, можно проектировать системы исходя из идеальных условий, что все всегда хорошо и никогда не будет плохих времен, ресурсы на систему будут литься как из рога изобилия. Однако данный подход является примером отсутствия квалификации и понимания хода истории, инженерного подхода. Попытка строить что-либо на крипто-валютах или смарт-контрактах - обречена на провал изначально, либо ее целью было обеспечение криминала, финансирование терроризма. Невозможно построить систему, в которой для обеспечения операции нужно тратить ресурсов сопоставимо с затрачиваемыми ресурсами на саму операцию. Так же как не может быть так, что виртуальная часть экономики превосходит во много раз экономику реальную. Рано или поздно это закончится.
Предлагаемые автором идеи в какой-то степени революционны и требуют серьезных реформ экономики, каковы, по мнению автора, будут производится в начале 30х годов. Следует никогда не забывать, что эволюция иногда заводит в тупик, а упорство превращает его в плаху. Поэтому и возникает вопрос, на который у автора нет ответа: Мейдзи или Романов? Что первый, а затем и второй успешно реформировали свои государства, но есть нюанс.
P.S. Если вы желаете поддержать и отблагодарить автора за его работу, то сделайте пожертвование бойцам вооруженных сил Российской Федерации - это будет лучшей наградой.
