// личный канал‑лог
gavrilovlog
← все записи

"Каждому по труду!" или как распределить награды в блокчейне с использованием с…

👁 508
Для многих криптопроектов возникает типичная проблема: "Проект каждый блок генерирует награду, которая затем распределяется среди всех пользователей в соответствии с их долями вложенных средств. Как определить, сколько каждый пользователь сможет получить в будущем?" На первый взгляд, решение кажется простым: разделить количество вложенных средств пользователя на общую сумму вложенных средств и умножить полученную долю на награду за один блок и продолжительность времени. Вроде проблема решена и пост можно заканчивать, но как бы не так! Что, если пользователь менял свой вклад в течение периода начисления наград? В таком случае, нам придется пересчитывать доли всех пользователей при каждом изменении вложений, вычислять текущую награду и сохранять ее. Ну вот теперь то проблема решена, уже можно расходиться? К сожалению опять нет, так как в смарт-контрактах отсутствуют циклы совсем или они сильно ограничены количеством повторений. Ну и как тогда решить эту задачу? Ответ заключается в использовании интегралов. Да, мне тоже первое, что приходит на ум при слове «интеграл»* это старый анекдот «Алгебра мне в жизни понадобилась один раз, чтобы сделать из проволоки интеграл и достать ключи из унитаза», но не всё так страшно на практике. Давайте рассмотрим, как можно решить нашу задачу. Мы будем вычислять начисленные награды с момента первого блока, в котором началась выдача наград. Размер награды за один блок будет записан как RewardPerBlock, а первое значение интеграла (LastTotalIntegral – последнее общее значение интеграла; LastUserIntegral – последнее значение интеграла для пользователя) будет равно 0. Нам также понадобится информация о том, сколько всего средств было вложено (LastTotalAmount), и сколько средств вложено пользователем (LastUserAmount). Логика расчетов следующая: каждый раз, когда какой-либо пользователь вносит или выводит свои средства или забирает накопившиеся награды, нам нужно обновлять общее значение интеграла и для пользователя, а также обновлять общее количество средств и количество средств пользователя. Мы также должны сохранить высоту блока, на которой последний раз выполнилось одно из этих действий (LastHeight). Формула для расчета интеграла выглядит следующим образом:
CurrentTotalIntegral = LastTotalIntegral + RewardPerBlock * (CurrentHeight – LastHeight) / LastTotalAmount
Теперь, как мы можем вычислить, какую награду пользователь может получить? Для этого используем формулу:
UserRewards = LastUserAmount * (CurrentTotalIntegral – LastUserIntegral)
"Вы видели интеграл? А он есть!" С помощью таких простых формул можно рассчитывать вознаграждение для каждого пользователя, учитывая их доли вкладов на протяжении всего периода.