Публикация

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

Смарт-контракт golos.publication обеспечивает работу с постами, в том числе предоставляет возможность пользователям выполнять следующие действия: публиковать посты, оставлять комментарии, голосовать за посты и закрывать посты, а также обеспечивает выплату вознаграждения авторам постов.

Операции-действия смарт-контракта golos.publication

Cмарт-контракт golos.publication поддерживает следующие операции-действия пользователей: setlimit, setrules, createmssg, updatemssg, deletemssg и downvote, upvote.

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

Операция-действие setlimit устанавливает правила, ограничивающие действия пользователей. Механизм ограничения действий пользователей основан на взаимодействии смарт-контрактов публикации и батарейки (golos.charge). Создается привязка конкретного действия смарт-контракта публикации к конкретной батарейке смарт-контракта батарейки. В операции-действия указывается название действия (например, голосование или публикация поста), указывается идентификатор и параметры определенной батарейки.

Операция-действие setlimit имеет следующий вид:

setlimit(
    std::string act,
    symbol_code token_code,
    uint8_t     charge_id,
    int64_t     price,
    int64_t     cutoff,
    int64_t     vesting_price,
    int64_t     min_vesting
);

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

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

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

Операция-действие setrules устанавливает правила в рамках приложения (сообщества) по распределению вознаграждения между пользователями за публикации постов и курирование. Операция-действие setrules имеет следующий вид:

void setrules(
    const funcparams&    mainfunc,
    const funcparams&     curationfunc,
    const funcparams&    timepenalty,
    int64_t             curatorsprop,
    int64_t             maxtokenprop,
    symbol                 tokensymbol
);

Параметры: mainfunc — функция, вычисляющая суммарное значение вознаграждения для автора и кураторов поста в соответствии с установленным алгоритмом (например, линейным алгоритмом или алгоритмом квадратного корня). Используемый в функции алгоритм выбирается делегатами голосованием. Функция содержит два параметра: математическое выражение (непосредственно алгоритм), по которому вычисляется сумма вознаграждения, и максимально допустимое значение аргумента для функции. При установке значений параметров для setrules выполняется их проверка на корректность (в том числе на монотонность и неотрицательность); curationfunc — функция, вычисляющая значение вознаграждения для каждого из кураторов в соответствии с установленным алгоритмом (аналогично вычислению для mainfunc); timepenalty — функция, вычисляющая вес голоса с учетом времени голосования и длительности штрафного окна; curatorsprop — выделяемая доля всем кураторам от суммарного значения вознаграждения; maxtokenprop — максимально возможное значение вознаграждения (сумма токенов и вестингов), которое может получить автор. Этот параметр устанавливается делегатами голосованием; tokensymbol — тип токена (в рамках приложения Голос предусматривается хождение только токенов Голоса).

Правом на запуск операции-действия setrules обладает делегат приложения. Для запуска операции-действия setrules требуется наличие в транзакции подписи смарт-контракта golos.publication (multisig-аккаунта).

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

Операция-действие createmssg используется для создания сообщения в виде ответа на ранее полученное (родительское) сообщение. Операция-действие createmssg имеет следующий вид:

void createmssg(
    name             account,
    std::string     permlink,
    name             parentacc,
    std::string     parentprmlnk,
    std::vector<structures::beneficiary> beneficiaries,
    int64_t         tokenprop,
    bool             vestpayment,
    std::string     headermssg,
    std::string     bodymssg,
    std::string l    anguagemssg,
    std::vector<structures::tag> tags,
    std::string     jsonmetadata
);

Параметры: account — имя аккаунта-автора сообщения; permlink — строковое представление относительного адреса сообщения; parentacc — имя аккаунта-автора родительского сообщения, на которое формируется ответ в виде настоящего сообщения. В случае нулевого значения parentacc, созданное сообщение будет являться постом; parentprmlnk — строковое представление относительного адреса родительского сообщения; beneficiaries — значение в виде структуры, содержащей имена бенефициаров и долю (в процентах) выплаты им от суммы вознаграждения за сообщение; tokenprop — размер вознаграждения (количество токенов). Данное значение ограничено сверху параметром maxtokenprop, задаваемым в set_rules; vestpaymenttrue, если пользователь дает разрешение на оплату в вестингах отправки сообщения в случае исчерпания ресурса батарейки (сообщение отправляется независимо от ресурса батарейки). По умолчанию принимает значение false; headermssg — заголовок сообщения; bodymssg — тело сообщения; languagemssg — язык сообщения; tags — тэг, который присваивается сообщению; jsonmetadata — метаданные в формате JSON.

Параметры parentaccи parentprmlnk идентифицируют родительское сообщение, на которое создается ответ с использованием createmssg в виде сообщения.

Для запуска операции-действия createmssg требуется наличие в транзакции подписи аккаунта-автора сообщения.

Ключ, по которому ведется поиск сообщения, имеет привязку к параметрам account и permlink.

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

Операция-действие updatemssg используется для внесения пользователем изменений в ранее отправленное им сообщение.

Операция-действие updatemssg имеет следующий вид:

void updatemssg(
    name         account,
    std::string     permlink,
    std::string     headermssg,
    std::string     bodymssg, 
    std::string     languagemssg,
    std::vector<structures::tag> tags,
    std::string     jsonmetadata
);

Параметры: account — имя аккаунта-автора сообщения; permlink — строковое представление относительного адреса редактируемого сообщения; headermssg — заголовок редактируемого сообщения; bodymssg — тело редактируемого сообщения; languagemssg — язык редактируемого сообщения; tags — тэг, который будет присвоен редактируемому сообщению; jsonmetadata — метаданные в формате JSON.

Для запуска операции-действия updatemssg требуется наличие в транзакции подписи аккаунта-автора сообщения.

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

Операция-действие deletemssg используется для удаления пользователем ранее отправленного им сообщения.

Операция-действие deletemssg имеет следующий вид:

void deletemssg(
    name account,
    std::string permlink
);

Параметры: account — имя аккаунта-автора сообщения; permlink — строковое представление относительного адреса удаляемого сообщения.

Сообщение не может быть удалено в следующих случаях:

  • на сообщение создан комментарий;

  • сообщение имеет положительный вес всех отданных за него голосов. Вес голоса пользователя зависит от используемого им вестинга и силы голоса. Сообщение не может быть удалено, если взвешенный вес всег голосов имеет положительное значение.

Для запуска операции-действия deletemssg требуется наличие в транзакции подписи аккаунта-автора сообщения.

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

Операция-действие upvote используется для подачи пользователем голоса в виде «upvote» при голосовании за сообщение. Операция-действие upvote имеет следующий вид:

void upvote(
    name voter,
    name author,
    std::string permlink,
    uint16_t weight
);

Параметры: voter — имя голосующего аккаунта; author — имя аккаунта-автора сообщения; permlink — строковое представление относительного адреса сообщения, за которое голосует аккаунт voter; weight — вес голоса аккаунта voter.

Ключ, по которому ведется поиск сообщения, имеет привязку к значениям параметров author и permlink.

Операция-действие upvote требует наличия подписи в транзакции аккаунта voter.

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

Операция-действие downvote используется для подачи пользователем голоса в виде «downvote» при голосовании за сообщение. Операция-действие downvote имеет следующий вид:

void downvote(
    name voter,
    name author,
    std::string permlink,
    uint16_t weight
);

Параметры: voter — имя голосующего аккаунта; author — имя аккаунта-автора сообщения; permlink — строковое представление относительного адреса сообщения, против которого голосует аккаунт voter; weight — вес голоса аккаунта voter.

Ключ, по которому ведется поиск сообщения, имеет привязку к значениям параметров author и permlink.

Операция-действие downvote требует наличия подписи в транзакции аккаунта voter.

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

Операция-действие unvote используется для отзыва пользователем собственного голоса вида upvote или downvote, отданного им ранее. Операция-действие unvote имеет следующий вид:

void unvote(
    name voter,
    name author,
    std::string permlink
);

Параметры: voter — имя аккаунта, удаляющего свой голос с сообщения; author — имя аккаунта-автора сообщения; permlink — строковое представление относительного адреса сообщения, от которого отзывается голос.

Ключ, по которому ведется поиск сообщения, имеет привязку к значениям параметров author и permlink.

Операция-действие unvote требует наличия подписи в транзакции аккаунта voter.

Другие параметры, используемые и настраиваемые в смарт-контракте golos.publication

Вызов set_params в смарт-контракте golos.publication позволяет настроить следующие переменные:

  • cashout_window — интервал времени, по истечении которого осуществляется выплата вознаграждения за пост;

  • max_vote_changes — максимально возможное количество переголосований пользователя за пост (показывает, сколько раз пользователь может поменять свой голос за пост);

  • max_beneficiaries — максимально возможное количество бенефициаров;

  • max_comment_depth — максимально возможная глубина комментариев (показывает допустимый уровень вложенности дочерних комментариев относительно родительского;

  • social_acc — имя аккаунта social;

  • referral_acc — имя аккаунта referral.

Определение сумм вознаграждений за публикацию на веб-сайте приложения Голос

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

В смарт-контракте golos.publication реализована логика, позволяющая рассчитать все необходимые выплаты за пост и поместить текущие результаты расчета на веб-сайте приложения Голос. Работа логики основана на обработке актуальных данных, получаемых из сообщений от событийной модели Event Engine. Результаты расчета корректируются после каждого принятого сообщения от Event Engine и зависят в основном от таких параметров как размер пула вознаграждений, количества появляющихся постов, а также веса каждого голосующего пользователя.

В этом разделе приводятся методы, которые могут быть применены в приложениях для определения (прогнозируемых) сумм вознаграждений в процессе голосования за пост в режиме реального времени, в том числе:

  • общей суммы вознаграждения за пост;

  • общей суммы вознаграждения кураторам поста;

  • сумм вознаграждения для каждого из кураторов поста;

  • общей суммы вознаграждения бенефициарам поста;

  • сумм вознаграждения для каждого из бенефициаров поста;

  • суммы вознаграждения автору поста.

Данные, на основе которых определяются вознаграждения за пост

С момента создания поста и до момента его закрытия проводится голосование за этот пост. Размер вознаграждения за созданный пост в основном зависит от результатам голосования за него и наличием средств в пуле вознаграждений. Пул вознаграждения выбирается по времени создания поста.

Каждый поданный за пост голос регистрируется в смарт-контракте публикации как событие, информация о котором отправляется в событийную модель Event Engine и далее по запросу в приложение Голос. На основе получаемой от Event Engine актуальной информации о событиях, относящихся к процессу голосования за пост, появляется возможность на веб-сайте приложения отображать в режиме реального времени интересующие пользователей (прогнозируемые) суммы вознаграждений за данный пост.

Методы вычисления сумм вознаграждений за пост в режиме реального времени в каждом из приложений могут быть различными. Рекомендуется в методах использовать получаемую от Event Engine информацию о следующих событиях: rewardweight, poststate, poolstate и votestate.

Событие rewardweight

Структура события rewardweight содержит данные о текущем весе поста.

struct reward_weight_event {
    mssgid message_id;
    uint16_t rewardweight;
};

Параметры: message_id — ключ-структура поста; rewardweight — вес поста на текущий момент времени с учетом размера вознаграждения за него (параметр принимает целочисленное значение, определяет вес поста с точностью до сотой доли процента).

Событие poststate

Структура события poststate содержит данные о текущем состоянии поста.

struct post_event {
    name author;
    std::string permlink;
    base_t netshares;
    base_t voteshares;
    base_t sumcuratorsw;
    base_t sharesfn;
};

Параметры: author — имя аккаунта, автора поста; permlink — относительный адрес сообщения, представленный в виде строки; netshares — доля вознаграждения, выделяемая в пуле за пост (значение параметра вычисляется как сумма значений voteshares всех голосов); voteshares — доля вознаграждения за пост, определяемая отдельным голосом с учётом его знака (значение отдельного голоса вычисляется как произведение количества вестинга голосующего на его вес. Параметр может принимать как положительное, так и отрицательное значения. Голосу вида «против» присваивается знак «минус», голосу вида «за» присваивается знак «плюс»); sumcuratorsw — суммарный вес голосов всех кураторов на текущий момент времени. sharesfn — функция для расчета вознаграждений, применимая к shares поста.

Событие poolstate

Структура события poolstate содержит данные о текущем состоянии пула вознаграждений.

struct pool_event {
    uint64_t created;
    counter_t msgs;
    eosio::asset funds;
    wide_t rshares;
    wide_t rsharesfn;
};

Параметры: created — время создания поста (идентификатор пула); msgs — количество постов, вознаграждения за которые выплачиваются из пула created; funds — количество токенов в пуле вознаграждений; rshares — суммарное значение rshares всех постов в пуле; rsharesfn — суммарное значение rsharesfn всех постов в пуле.

Событие votestate

Структура события votestate содержит данные о текущих результатах голосования за пост.

struct vote_event {
    name voter;
    name author;
    std::string permlink;
    int16_t weight;
    base_t curatorsw;
    base_t rshares;
};

Параметры: voter — имя аккаунта (пользователя), который голосует за пост; author — имя аккаунта, автора поста; permlink — относительный адрес поста; weight — вес голоса аккаунта voter. Во время голосования вес голоса указывается с точностью до сотой доли процента в виде целочисленного значения в интервале от 0 до 10000 (значение 10000 соответствует 100%). Вес голоса «против» указывается со знаком «минус»; curatorsw — процент кураторского вознаграждения (доля вознаграждения, выделяемая отдельному куратору от общей суммы вознаграждения кураторам. Величина доли зависит от веса данного куратора); rshares — условный параметр, используемый в расчетах вознаграждений за пост. Значение параметра определяется как произведение веса голоса на количества активного вестинга голосующего на вес голоса в процентах (rshares = eff_vesting * weight / 10000). Параметр может принимать как положительное, так и отрицательное значения. Голосу вида «против» присваивается знак «минус».

Метод вычисления общей суммы вознаграждения за пост

Для определения прогнозируемой суммы вознаграждения за пост в режиме реального времени рекомендуется воспользоваться формулой

payout = reward_weight × funds × (sharesfn / rsharesfn)          (1)

Компоненты формулы: payout — результирующая общая сумма вознаграждения за пост на момент получения данных от событийной модели; reward_weight = rewardweight::reward_weight — вес поста; funds = poolstate::state.funds — общее количество токенов в пуле вознаграждений; sharesfn = poststate::sharesfn — доля токенов, выделенных на вознаграждение за пост, от общего их количества в пуле вознаграждения (значение параметра зависит от веса поста); rsharesfn = poolstate::state::rsharesfn — количество токенов, выделенных на вознаграждение всех постов в пуле вознаграждения (значение параметра зависит от суммарного веса всех постов).

Для вычисления payout по формуле (1) необходимо использовать данные, полученные от событийной модели только в один и тот же момент времени.

Метод вычисления сумм вознаграждения кураторам за пост

Общая сумма кураторских вознаграждений представляет собой часть средств в виде процентного отчисления от общей суммы вознаграждения за пост. Значение процентного отчисления curators_prcnt пользователь может указать самостоятельно во время создания поста. Если пользователь не указывает этот параметр, то в качестве него из таблицы pstngparams берется параметр min_curators_prcnt — минимально возможная доля, выделяемая кураторам от общего вознаграждения за пост.

Для определения общей суммы вознаграждения кураторам рекомендуется воспользоваться формулой

curation_payout = payout - (sumcuratorsw × payout)              (2)

Компоненты формулы: curation_payout — результирующая общая сумма вознаграждения кураторам за пост на момент получения данных от событийной модели; payout — общая сумма вознаграждения за пост, вычисленная по формуле (1); sumcuratorsw = poststate::sumcuratorsw — доля, выделяемая кураторам от общей суммы вознаграждения (суммарный вес голосов всех кураторов на текущий момент времени).

Вычисленная по формуле (2) общая сумма вознаграждения распределяется между кураторами в соответствии с правилами, принятыми в приложении. Ниже приводится рекомендуемый метод определения суммы вознаграждения для каждого из кураторов.

Для определения суммы вознаграждения curator_rewardⱼ отдельному куратору j рекомендуется воспользоваться формулой

curator_rewardⱼ = curation_payout × (curatorswⱼ / weights_sum)         (3)

Компоненты формулы: curation_payout — общая сумма вознаграждения кураторам за пост, вычисленная по формуле (2); curatorswⱼ = votestate::curatorswⱼ — вес голоса куратора j, отдавшего за пост голос вида «за»; weights_sum = poststate::weights_sum — общий вес голосов кураторов, отдавших за пост голоса вида «за»; (curatorswⱼ / weights_sum) — доля, выделяемая куратору j от общей суммы вознаграждения кураторам.

Вычисление суммы вознаграждения по формуле (3) выполняется для каждого куратора, данные о котором содержатся в структуре vote_event.

После вычисления всех сумм вознаграждений кураторам может появиться остаточная (невостребованная) сумма, образуемая за счет штрафов во время голосования (например, за раннее голосование). Этот штраф не учитывается в суммарном значении sumcuratorsw, но влияет на величину curatorsw конкретного голоса. Возможная остаточная сумма в виде «сдачи» будет возвращена обратно в пул вознаграждения за посты. Эта остаточная сумма unclaimed_rewards вычисляется по формуле

unclaimed_rewards = curation_payout - ∑(curator_rewardⱼ)            (4)

Компоненты формулы: curation_payout — общая сумма вознаграждения кураторам за пост, вычисленная по формуле (2); ∑(curator_rewardⱼ) — сумма всех выплат, вычисленных по формуле (3).

Метод вычисления сумм вознаграждения бенефициарам за пост

Та часть средств, которая выделяется автору в виде вознаграждения за пост, распределяется между бенефициарами и автором этого поста. Доля общей суммы вознаграждений, выделяемой бенефициарам, а также количество бенефициаров, определяется самим автором во время публикации поста. Правила, в соответствии с которыми распределяется вознаграждение между бенефициарами, устанавливаются для каждого приложения отдельно. Ниже приводится рекомендуемый метод определения суммы вознаграждения для каждого из кураторов.

Для определения суммы вознаграждения ben_rewardⱼ бенефициару j рекомендуется воспользоваться формулой

ben_rewardⱼ = (payout - curation_payout) × deductprcntⱼ            (5)

Компоненты формулы: payout — общая сумма вознаграждения за пост, вычисленная по формуле (1); curation_payout — общая сумма вознаграждения кураторам за пост, вычисленная по формуле (2); (payout - curation_payout) — общая сумма вознаграждения, выделяемая бенефициарам и автору поста; deductprcnt = post::beneficiary::deductprcnt — доля вознаграждения, выделяемая бенефициару j. Устанавливается автором во время публикации поста.

Вычисление суммы вознаграждения по формуле (5) выполняется для каждого бенефициара, данные о котором приводятся в таблице message поля beneficiaries — массив, содержащий структуры с полями имен и процентных отчислений.

Общая сумма выплат бенефициарам ben_payout_sum вычисляется по формуле

ben_payout_sum = ∑(ben_rewardⱼ)                         (6)

Определение размера вознаграждения автору поста

Для определения размера вознаграждения author_reward автору поста рекомендуется воспользоваться формулой

       author_reward = payout - curation_payout - ben_payout_sum

Компоненты формулы: payout — общая сумма вознаграждения за пост, вычисленная по формуле (1); curation_payout — общая сумма вознаграждения кураторам за пост, вычисленная по формуле (2); ben_payout_sum — общая сумма выплат бенефициарам, вычисленная по формуле (6).

Определение общей суммы вознаграждения за пост в токенах и вестингах

Часть вознаграждения за пост выплачивается в виде вестинга, а часть — в виде токенов. Процентное их соотношение указывается во время создания поста. После вычисления суммы вознаграждения за пост по формуле (1) можно определить количество ликвидных токенов, а также вестингов, составляющих данное вознаграждение.

Для вычисления количества ликвидных токенов token_payout, выделяемых в виде вознаграждения за пост в режиме реального времени, рекомендуется воспользоваться формулой

        token_payout = payout × tokenprop

Компоненты формулы: payout — общая сумма вознаграждения за пост, вычисленная по формуле (1); tokenprop = post::tokenprop — процентное содержание токенов в вознаграждении.

Количество вестингов в вознаграждении vesting_payout составляет

        vesting_payout = payout - token_payout

Заключение

Представленные методы вычисления сумм вознаграждений за пост в режиме реального времени предназначены для их применения в приложении Голос. Данные методы носят рекомендательный характер и могут быть также применены в других приложениях.

Last updated