Децентрализирана партньорска програма с отворен код в блокчейна на Waves

Децентрализирана партньорска програма, базирана на блокчейн Waves, внедрена като част от грант на Waves Labs от екипа на Bettex.

Публикацията не е спонсорирана! Програмата е с отворен код, нейното използване и разпространение е безплатно. Използването на програмата стимулира развитието на dApp приложения и като цяло насърчава децентрализацията, което е от полза за всеки потребител на мрежата.

Децентрализирана партньорска програма с отворен код в блокчейна на Waves

Представеното dApp за афилиейт програми е шаблон за проекти, които включват афилиейт като част от своята функционалност. Кодът може да се използва като шаблон за копиране, като библиотека или като набор от идеи за техническа реализация.

По отношение на функционалността това е обикновена партньорска система, която реализира регистрация с референт, многостепенно начисляване на възнаграждение за реферали и мотивация за регистрация в системата (кешбек). Системата е „чисто“ dApp, тоест уеб приложението взаимодейства директно с блокчейна без собствен бекенд, база данни и т.н.

Използват се техники, които могат да бъдат полезни и в много други проекти:

  • Обаждане на смарт акаунт на кредит с незабавно погасяване (в момента на разговора в сметката няма токени за плащане на разговора, но те се появяват там в резултат на разговора).
  • PoW-captcha - защита срещу високочестотно автоматизирано извикване на функции на смарт акаунт - подобно на captcha, но чрез доказателство за използването на компютърни ресурси.
  • Заявка за ключове за данни по шаблон.

Приложението се състои от:

  • код на интелигентен акаунт на езика ride4dapps (който, както е планирано, е обединен в основния интелигентен акаунт, за който трябва да внедрите партньорската функционалност);
  • js обвивка, която имплементира абстракционен слой върху WAVES NODE REST API;
  • код на рамката vuejs, което е пример за използване на библиотеката и RIDE кода.

Нека опишем всички изброени характеристики.

Извикване на интелигентна сметка в дълг с незабавно изплащане

Извикването на InvokeScript изисква плащане на такса от сметката, инициираща транзакцията. Това не е проблем, ако правите проект за блокчейн маниаци, които имат определено количество WAVES токени в акаунта си, но ако продуктът е насочен към масите, това се превръща в сериозен проблем. В края на краищата потребителят трябва да се погрижи за закупуването на токени WAVES (или друг подходящ актив, който може да се използва за плащане на транзакции), което увеличава и без това значителния праг за влизане в проекта. Можем да разпределяме активи на потребители, на които ще бъде позволено да плащат за транзакции и да се изправят пред риска от злоупотреба с тях, когато бъдат създадени автоматизирани системи за изпомпване на ликвидни активи от нашата система.

Би било много удобно, ако е възможно да се извика InvokeScript „за сметка на получателя“ (интелигентния акаунт, на който е инсталиран скриптът), и тази възможност съществува, макар и не по очевиден начин.

Ако вътре в InvokeScript се направи ScriptTransfer до адреса на повикващия, който компенсира токените, изразходвани за таксата, тогава такова повикване ще бъде успешно, дори ако няма активи в извикващия акаунт по време на повикването. Това е възможно, тъй като проверката за достатъчно токени се извършва след извикване на транзакцията, а не преди нея, така че е възможно да се правят транзакции на кредит, при условие че те бъдат незабавно изкупени.

ScriptTransfer(i.caller, i.fee, unit)

Кодът по-долу възстановява изразходваната такса, като използва средства от интелигентен акаунт. За да се предпазите от злоупотреба с тази функция, трябва да използвате проверка дали обаждащият се харчи таксата в правилния актив и в разумни граници:

func checkFee(i:Invocation) = {
if i.fee > maxFee then throw(“unreasonable large fee”) else
if i.feeAssetId != unit then throw(“fee must be in WAVES”) else true
}

Също така, за защита срещу злонамерено и безсмислено пилеене на средства е необходима защита срещу автоматично повикване (PoW-captcha).

PoW-captcha

Самата идея за captcha за доказване на работа не е нова и вече е внедрена в различни проекти, включително такива, базирани на WAVES. Смисълът на идеята е, че за да изпълни действие, което хаби ресурсите на нашия проект, повикващият трябва също да изразходва собствените си ресурси, което прави атаката с изчерпване на ресурси доста скъпа. За много лесно и евтино потвърждение, че изпращачът на транзакцията е решил проблема с PoW, има проверка на идентификатор на транзакция:

if take(toBase58String(i.transactionId), 3) != “123” then throw(“доказателство за работа неуспешно”) else

За да извърши транзакция, повикващият трябва да избере такива параметри, така че неговият код base58 (id) да започва с числата 123, което съответства средно на няколко десетки секунди процесорно време и като цяло е разумно за нашата задача. Ако се изисква по-прост или по-сложен PoW, тогава задачата може лесно да бъде модифицирана по очевиден начин.

Заявка за ключове за данни по шаблон

За да използвате блокчейна като база данни, жизненоважно е да имате API инструменти за запитване към базата данни като ключ-вал с помощта на шаблони. Такъв инструментариум се появи в началото на юли 2019 г. като параметър ?съвпада при заявка за REST API /addresses/data?matches=regexp. Сега, ако трябва да получим повече от един ключ, а не всички ключове наведнъж от уеб приложението, а само някаква група, тогава можем да направим избор по името на ключа. Например в този проект транзакциите за теглене са кодирани като

withdraw_${userAddress}_${txid}

което ви позволява да получите списък с транзакции за теглене на средства за всеки даден адрес, като използвате шаблона:

?matches=withdraw_${userAddress}_.*

Сега нека анализираме компонентите на готовото решение.

vuejs код

Кодът е работещо демо, близко до реален проект. Той реализира влизане чрез Waves Keeper и работи с библиотеката affiliate.js, с помощта на която регистрира потребител в системата, прави заявки за данни за транзакциите и също така ви позволява да изтеглите спечелените средства в акаунта на потребителя.

Децентрализирана партньорска програма с отворен код в блокчейна на Waves

Код за RIDE

Състои се от функции за регистриране, фондиране и теглене.

Функцията за регистриране регистрира потребител в системата. Той има два параметъра: референт (адрес на референт) и параметър сол, който не се използва в кода на функцията, който е необходим за избор на идентификатора на транзакцията (PoW-captcha задача).

Функцията (както и останалите функции в този проект) използва техниката на заемане, резултатът от функцията е финансиране на плащането на такса за извикване на тази функция. Благодарение на това решение, потребител, който току-що е създал портфейл, може незабавно да работи със системата и не е необходимо да бъде озадачен от въпроса за придобиване или получаване на актив, който му позволява да плати такса за транзакция.

Резултатът от функцията за регистрация е два записа:

${owner)_referer = referer
${referer}_referral_${owner} = owner

Това позволява търсене напред и назад (референт на дадения потребител и всички реферали на дадения потребител).

Функцията фонд е по-скоро шаблон за разработване на реална функционалност. В представената форма той взема всички средства, прехвърлени от транзакцията, и ги разпределя към препоръчаните сметки на 1-во, 2-ро, 3-то ниво, към сметката „кешбек“ и сметката „промяна“ (всичко, което остава по време на разпределението към предишни сметки стига тук).

Кешбекът е средство за стимулиране на крайния потребител да участва в системата за препоръки. Частта от комисионната, платена от системата под формата на „кешбек“, може да бъде изтеглена от потребителя по същия начин като наградите за реферали.

Когато използвате рефералната система, функцията на фонда трябва да бъде модифицирана, вградена в основната логика на смарт акаунта, върху който ще работи системата. Например, ако се изплаща награда за препоръка за направен залог, тогава функцията за фондиране трябва да бъде вградена в логиката, където се прави залогът (или се извършва друго целево действие, за което се изплаща наградата). Има три нива на награди за реферали, кодирани в тази функция. Ако искате да направите повече или по-малко нива, това също се коригира в кода. Процентът на наградата се задава от константите level1-level3, в кода се изчислява като сума * ниво / 1000, тоест стойността 1 съответства на 0,1% (това също може да се промени в кода).

Извикването на функцията променя баланса на акаунта и също така създава записи за целите на записване на формуляра:

fund_address_txid = address:owner:inc:level:timestamp
Для получения timestamp (текущего времени) используется такая вот связка
func getTimestamp() = {
let block = extract(blockInfoByHeight(height))
toString(block.timestamp)
}

Тоест времето на транзакцията е времето на блока, в който се намира. Това е по-надеждно от използването на клеймото за време от самата транзакция, особено след като не е достъпно от извиквания.
Функцията за теглене изтегля всички натрупани награди в сметката на потребителя. Създава записи за целите на регистриране:

# withdraw log: withdraw_user_txid=amount:timestamp

App

Основната част от приложението е библиотеката affiliate.js, която е мост между партньорските модели на данни и WAVES NODE REST API. Внедрява независим от рамката абстракционен слой (може да се използва всеки). Активните функции (регистрация, оттегляне) предполагат, че Waves Keeper е инсталиран в системата, самата библиотека не проверява това.

Прилага методи:

fetchReferralTransactions
fetchWithdrawTransactions
fetchMyBalance
fetchReferrals
fetchReferer
withdraw
register

Функционалността на методите е очевидна от имената, параметрите и връщаните данни са описани в кода. Функцията за регистриране изисква допълнителни коментари - тя стартира цикъла за избор на идентификатор на транзакция, така че да започне от 123 - това е PoW captcha, описана по-горе, която предпазва от масови регистрации. Функцията намира транзакция с необходимия идентификатор и след това я подписва чрез Waves Keeper.

Партньорска програма DEX, достъпна на GitHub.com.

Източник: www.habr.com

Добавяне на нов коментар