Батарейка

Назначение смарт-контракта golos.charge

Смарт-контракт golos.charge выполняет прикладную функцию — позволяет ограничивать активность пользователей в создании постов, комментариев, а также в голосовании за посты. Непосредственного взаимодействия пользователя со смарт-контактом golos.charge не происходит, обращение к операциям-действиям происходит через смарт контракт публикации.

Принцип работы смарт-контракта golos.charge

Механизм, регулирующий активность пользователя в системе, реализован на основе батареек. Создание батареек позволяет вести учет как отдельных операций пользователя, так и его общую активность. Количество, выделенных пользователю батареек, может быть более одной, каждая из которых может быть настроена на учет одной из операций, выполняемых этим пользователем за определенный интервал времени (например, учет комментариев осуществляется одной батарейкой, отправка голосов в виде «upvote» — другой). Батарейка содержит количественный ресурс, значение которого зависит от наличия суммы вестинга пользователя и частоты выполняемых им операций. На каждую выполняемую операцию пользователя расходуется часть ресурса батарейки с учетом стоимости этой операции. При достижении граничного значения ресурса батарейки выполнение операции блокируется. Ресурс батарейки полностью восстанавливается по истечении времени.

Обращение к батарейкам происходит через вызовы операций-действий. В смарт-контракте golos.charge реализованы встраиваемая (англ. inline) функция get_stored и операции-действия use, useandstore, removestored, setrestorer, usenotifygt, usenotifylt.

Одним из обязательных параметров, используемых в этих операциях-действиях, является token_code, с помощью которого идентифицируется конкретный токен. Аккаунт, вызывающий любое из этих операций-действий, должен быть наделен правами в соответствии с требованиями авторизации издателя токена. Издателем токена может являться либо пользователь, либо аккаунт, которому этот пользователь предоставил соответствующие права.

Каждая батарейка идентифицируется следующими параметрами: кодом токена (token_code) и непосредственно идентификатором батарейки (charge_id). У каждого токена может быть более одной батарейки. Конкретная батарейка конкретного токена задается параметром charge_id. Батарейка представляет собой значение, которое при использовании увеличивается и по истечении времени уменьшается, то есть восстанавливается.

Операция-действие use

Операция-действие use используется для учета ресурса батарейки при выполнении пользователем каких-либо действий. Операция-действие use имеет вид:

[[eosio::action]] void use(
    name user,
    symbol_code token_code,
    uint8_t charge_id,
    int64_t price,
    int64_t cutoff,
    int64_t vesting_price
);

Параметры: user — имя аккаунта, используемого ресурс батарейки; token_code — код токена, имеющего привязку к батарейке charge_id; charge_id — идентификатор батарейки. Данное значение в совокупности с кодом токена token_code обеспечивают идентификацию батарейки; price — количество ресурса батарейки (в условных единицах), на которое уменьшится заряд батарейки при выполнении пользователем user определенного действия; cutoff — пороговое значение ресурса батарейки, при достижении которого прекращается выполнение действия; vesting_price — сумма средств (в вестинге), которую необходимо потратить пользователю user за выполняемое им действие в случае нехватки ресурса батарейки, то есть в случае, если значение батарейки превысит пороговое значение cutoff.

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

Для того, чтобы пользователь смог оплатить выполнение действия в случае нехватки ресурса батарейки, необходимо предоставить доступ смарт-контракту батарейки к средствам вестинга этого пользователя, а также право на «сжигание» соответствующей суммы. На балансе пользователя должна быть необходимая сумма вестинга в разблокированном состоянии.

Операция-действие useandstore

Операция-действие useandstore также как и use используется для учета ресурса батарейки при выполнении пользователем каких либо действий. В отличие от use операция-действие useandstore сохраняет значения используемых ресурсов батареек в таблицах, находящихся внутри смарт-контракта golos.charge, и остаются доступными по чтению другим смарт-контрактам.

Операция-действие useandstore имеет вид:

[[eosio::action]] void useandstore(
    name user,
    symbol_code token_code,
    uint8_t charge_id,
    int64_t stamp_id,
    int64_t price
);

Параметры: user — имя аккаунта, используемого ресурс батарейки; token_code — код токена, имеющего привязку к батарейке charge_id; charge_id — идентификатор батарейки. Данное значение в совокупности с кодом токена token_code обеспечивают идентификацию батарейки; stamp_id — идентификатор сохраняемого значения ресурса батарейки charge_id, используемого аккаунтом user. Значение сохраняется в отведенной для аккаунта user таблице данной батарейки; price — сумма средств (в условных единицах батарейки), начисляемая аккаунту user за используемую часть ресурса батарейки.

Операция-действие removestored

Операция-действие removestored используется для удаления ранее сохраненных данных по использованию ресурсов батареек в смарт-контракте батарейки. Ключом к поиску удаляемых данных является совокупность значений параметров charge_id, token_code и stamp_id. Операция-действие removestored может быть вызвана из любого смарт-контракта.

Операция-действие removestored имеет вид:

[[eosio::action]] void removestored(
    name user,
    symbol_code token_code,
    uint8_t charge_id,
    int64_t stamp_id
);

Параметры: user — имя аккаунта, используемого ресурс батарейки; token_code — код токена, имеющего привязку к батарейке charge_id; charge_id — идентификатор батарейки. Данное значение в совокупности с кодом токена token_code обеспечивают идентификацию батарейки; stamp_id — идентификатор значения ресурса батарейки charge_id, используемого аккаунтом user, которое удаляется из таблицы данной батарейки.

Операция-действие setrestorer

Операция-действие setrestorer используется для задания алгоритма, по которому происходит восстановление ресурса батарейки. Операция-действие setrestorer имеет вид:

[[eosio::action]] void setrestorer(
    symbol_code token_code,
    uint8_t charge_id,
    std::string func_str, 
    int64_t max_prev,
    int64_t max_vesting,
    int64_t max_elapsed
);

Параметры: token_code — код токена, имеющего привязку к батарейке charge_id; charge_id — идентификатор батарейки. Данное значение в совокупности с кодом токена token_code обеспечивают идентификацию батарейки; func_str — математическое выражение, задающее функцию восстановления ресурса батарейки; max_prev — максимально допустимое значение предыдущего ресурса батарейки; max_vesting — максимально возможное значение вестинга, которое может быть израсходовано функцией в качестве аргумента в процессе восстановления ресурса батарейки; max_elapsed — максимально допустимый период времени с момента предыдущего обращения к батарейки.

Значение параметра func_str вычисляется задаваемой функцией с тремя переменными, а именно: p — задает предыдущее значение ресурса батарейки; v — задает значение вестинга пользователя; t — задает период времени с момента последнего вызова setrestorer.

Например, если в качестве параметра func_str передается строка вида sqrt(v / 500000) × (t / 150) , то батарейка, идентифицируемая параметрами token_code и charge_id, будет восстанавливаться в соответствии с этой функцией. При наличии у пользователя суммы средств равной 500 000 (в вестинге) в течение периода 150 (с) значение func_str составит func_str = sqrt(500000 / 500000) × (150 / 150) = 1 То есть, за время 150 с значение батарейки увеличится на единицу.

Операции-действия usenotifygt и usenotifylt

Данные операции являются внутренними и пользователю недоступны.

Смысловое значение названий операций: usenotifygt — использовать ресурсы батарейки и нотифицировать, если заряд батарейки больше (англ. great than) порогового значения. usenotifylt — использовать ресурсы батарейки и нотифицировать, если заряд батарейки меньше (англ. less than) порогового значения.

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

Операция-действие usenotifygt имеет вид:

void usenotifygt(
    name user,
    symbol_code token_code,
    uint8_t charge_id,
    int64_t price_arg,
    int64_t id,
    name code,
    name action_name,
    int64_t cutoff
)

Параметры: user — имя аккаунта владельца батарейки; token_code — код токена, имеющего привязку к батарейке charge_id; charge_id — идентификатор батарейки. Данное значение в совокупности с кодом токена token_code обеспечивают идентификацию батарейки; price_arg — количество ресурса батарейки (в условных единицах), на которое уменьшится заряд батарейки при выполнении пользователем определенного действия; id — внутренний идентификатор контракта code; code — код контракта, которому высылается нотификация о количестве затраченных ресурсов; action_name — действие, которое выполняет нотификацию в контракте с кодом code; cutoff — пороговое значение ресурса батарейки, при достижении которого необходимо отправить нотификацию.

Операция-действие usenotifylt имеет аналогичную структуру и параметры.

Пользователь может за определенный период времени опубликовать несколько постов и при этом превысить отведенный ему ресурс батарейки (превышение допустимой активности пользователя). За посты, опубликованные с превышением отведенного ему ресурса батарейки, сумма вознаграждения будет снижена. Для того, чтобы смарт-контракт публикации располагал информацией о таких постах, используются вызовы usenotifygt и usenotifylt.

Перед публикацией поста смарт-контракт golos.publication отправляет операцию-действие usenotifygt/usenotifylt другому смарт-контракту с кодом code для использования другим смарт-контрактом ресурсов батарейки пользователя user. Смарт-контракт code информирует смарт-контракт golos.publication о текущем заряде батарейки. Получив соответствующую нотификацию, логика смарт-контракта публикации вычисляет сумму вознаграждения за пост.

Встраиваемая функция get_stored

Встраиваемая функция get_stored позволяет определить ресурс батарейки конкретного пользователя в конкретный момент времени. Встраиваемая функция get_stored имеет вид:

int64_t get_stored(
    name code,
    name user,
    symbol_code token_code,
    uint8_t charge_id,
    uint64_t stamp_id) {

}

Параметры: code — идентификатор аккаунта; user — имя аккаунта, ресурс батарейки которого определяется; token_code — код токена, имеющего привязку к батарейке charge_id; charge_id — идентификатор батарейки. Данное значение в совокупности с кодом токена token_code обеспечивают идентификацию батарейки; stamp_id — идентификатор сохраняемого значения ресурса батарейки charge_id, используемого аккаунтом user, которое требуется получить из таблицы батарейки.

Значение ресурса батарейки сохраняется в таблице батарейки при выполнении useandstore. Впоследствие для получения значения из данной таблицы необходимо вызвать get_stored. Вызов get_stored не требует дополнительной авторизации.

Данные о сохраненных значений ресурсов батареек доступны для получения из любого смарт-контракта. Функция get_stored не обрабатывает данные, а только получает сохраненные значения из таблиц смарт-контракта golos.charge.

Взаимодействие смарт-контракта батарейки с любым из смарт-контрактов позволяет контролировать действия (активность) пользователя в этих смарт-контрактах. Одна батарейка может взаимодействовать одновременно с действиями нескольких смарт-контрактов.

Last updated