Program de afiliere descentralizat open source pe blockchain-ul Waves

Un program de afiliere descentralizat bazat pe blockchain-ul Waves, implementat ca parte a unui grant Waves Labs de către echipa Bettex.

Postarea nu este sponsorizată! Programul este open source, utilizarea și distribuția sa sunt gratuite. Utilizarea programului stimulează dezvoltarea aplicațiilor dApp și, în general, promovează descentralizarea, ceea ce este benefic pentru fiecare utilizator al Rețelei.

Program de afiliere descentralizat open source pe blockchain-ul Waves

DApp-ul prezentat pentru programele de afiliere este un șablon pentru proiecte care includ afiliatul ca parte a funcționalității lor. Codul poate fi folosit ca șablon pentru copiere, ca bibliotecă sau ca set de idei pentru implementare tehnică.

Din punct de vedere al funcționalității, acesta este un sistem de afiliat obișnuit care implementează înregistrarea cu indicarea unui referrer, acumularea pe mai multe niveluri a remunerației pentru trimiteri și motivația pentru înregistrarea în sistem (cashback). Sistemul este o dApp „pură”, adică aplicația web interacționează direct cu blockchain-ul, fără propriul backend, bază de date etc.

Sunt folosite tehnici care pot fi utile și în multe alte proiecte:

  • Apelarea unui cont inteligent pe credit cu rambursare imediată (la momentul apelului, nu există jetoane pe cont pentru a plăti apelul, dar acestea apar acolo ca urmare a apelului).
  • PoW-captcha - protecție împotriva apelurilor automate de înaltă frecvență a funcțiilor contului inteligent - similar cu captcha, dar prin dovada utilizării resurselor de calcul.
  • Solicitare chei de date după șablon.

Aplicația constă din:

  • codul de cont inteligent în limbajul ride4dapps (care, așa cum a fost planificat, este îmbinat în contul inteligent principal, pentru care trebuie să implementați funcționalitatea de afiliat);
  • js wrapper care implementează un strat de abstractizare peste API-ul WAVES NODE REST;
  • cod pe framework-ul vuejs, care este un exemplu de utilizare a bibliotecii și a codului RIDE.

Să descriem toate caracteristicile enumerate.

Atragerea unui cont inteligent la datorii cu rambursare imediată

Apelarea InvokeScript necesită plata unei taxe din contul care inițiază tranzacția. Aceasta nu este o problemă dacă faceți un proiect pentru geek blockchain care au o anumită cantitate de jetoane WAVES în cont, dar dacă produsul este destinat maselor, aceasta devine o problemă serioasă. La urma urmei, utilizatorul trebuie să se ocupe de achiziționarea de jetoane WAVES (sau un alt activ adecvat care poate fi folosit pentru a plăti tranzacții), ceea ce crește pragul deja considerabil de intrare în proiect. Putem distribui active utilizatorilor cărora li se va permite să plătească pentru tranzacții și să se confrunte cu riscul utilizării lor greșite atunci când sunt create sisteme automate pentru a pompa active lichide din sistemul nostru.

Ar fi foarte convenabil dacă ar fi posibil să apelați InvokeScript „pe cheltuiala destinatarului” (contul inteligent pe care este instalat scriptul), iar această posibilitate există, deși nu într-un mod evident.

Dacă, în interiorul InvokeScript, se face un ScriptTransfer către adresa apelantului, care compensează jetoanele cheltuite pentru taxă, atunci un astfel de apel va reuși, chiar dacă nu existau active în contul apelantului la momentul apelului. Acest lucru este posibil deoarece verificarea pentru tokenuri suficiente se face după apelarea tranzacției, și nu înainte de aceasta, astfel încât să fie posibilă efectuarea tranzacțiilor pe credit, cu condiția ca acestea să fie răscumpărate imediat.

ScriptTransfer(i.apelant, i.fee, unitate)

Codul de mai jos rambursează taxa cheltuită utilizând fondurile contului inteligent. Pentru a vă proteja împotriva utilizării greșite a acestei funcții, trebuie să verificați dacă apelantul cheltuiește taxa în bunul potrivit și în limite rezonabile:

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
}

De asemenea, pentru a proteja împotriva risipei rău intenționate și fără sens a fondurilor, este necesară protecție împotriva apelurilor automate (PoW-captcha).

PoW-captcha

Însăși ideea de captcha proof-of-work nu este nouă și a fost deja implementată în diverse proiecte, inclusiv cele bazate pe WAVES. Ideea este că, pentru a realiza o acțiune care irosește resursele proiectului nostru, apelantul trebuie să-și cheltuiască și propriile resurse, ceea ce face un atac de epuizare a resurselor destul de costisitor. Pentru o validare foarte ușoară și cu costuri reduse că expeditorul tranzacției a rezolvat problema PoW, există o verificare a ID-ului tranzacției:

dacă take(toBase58String(i.transactionId), 3) != „123” atunci aruncă(„dovada muncii eșuate”) altfel

Pentru a efectua o tranzacție, apelantul trebuie să aleagă astfel de parametri, astfel încât codul său de bază58 (id) să înceapă cu numerele 123, care corespunde unei medii de câteva zeci de secunde de timp al procesorului și este în general rezonabil pentru sarcina noastră. Dacă este necesar un PoW mai simplu sau mai complex, atunci sarcina poate fi modificată cu ușurință într-un mod evident.

Interogați cheile de date după șablon

Pentru a utiliza blockchain-ul ca bază de date, este vital să aveți instrumente API pentru interogarea bazei de date ca un key-val folosind șabloane. Un astfel de set de instrumente a apărut la începutul lunii iulie 2019 ca parametru ?chibrituri la cererea REST API /addresses/data?matches=regexp. Acum, dacă trebuie să obținem mai mult de o cheie și nu toate cheile simultan din aplicația web, ci doar un grup, atunci putem face o selecție după numele cheii. De exemplu, în acest proiect, tranzacțiile de retragere sunt codificate ca

withdraw_${userAddress}_${txid}

care vă permite să obțineți o listă de tranzacții pentru retragerea de fonduri pentru orice adresă dată folosind șablonul:

?matches=withdraw_${userAddress}_.*

Acum să analizăm componentele soluției finite.

codul vuejs

Codul este o demonstrație de lucru, aproape de un proiect real. Implementează autentificarea prin Waves Keeper și lucrează cu biblioteca affiliate.js, cu ajutorul căreia înregistrează un utilizator în sistem, interogează datele tranzacției și, de asemenea, vă permite să retrageți fondurile câștigate în contul utilizatorului.

Program de afiliere descentralizat open source pe blockchain-ul Waves

Cod pe RIDE

Constă în funcții de înregistrare, fond și retragere.

Funcția de înregistrare înregistrează un utilizator în sistem. Are doi parametri: referer (adresa referer) și parametrul de sare neutilizat în codul funcției, care este necesar pentru a selecta id-ul tranzacției (sarcina PoW-captcha).

Funcția (ca și restul funcțiilor din acest proiect) folosește tehnica de împrumut, rezultatul funcției este finanțarea plății unei taxe pentru apelarea acestei funcție. Datorită acestei soluții, un utilizator care tocmai a creat un portofel poate lucra imediat cu sistemul și nu trebuie să fie nedumerit de problema achiziției sau primirii unui activ care îi permite să plătească o taxă de tranzacție.

Rezultatul funcției de înregistrare sunt două înregistrări:

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

Acest lucru permite căutări înainte și înapoi (recomandantul acestui utilizator și toate recomandările acestui utilizator).

Funcția de fond este mai mult un șablon pentru dezvoltarea funcționalității reale. În forma prezentată, preia toate fondurile transferate prin tranzacție și le distribuie în conturile de referință ale nivelului 1, 2, 3, în contul „cashback” și în contul „schimbare” (tot ce rămâne în timpul distribuirii către conturile anterioare ajunge aici).

Cashback este un mijloc de a stimula utilizatorul final să participe la sistemul de recomandare. Partea din comision plătită de sistem sub formă de „cashback” poate fi retrasă de utilizator în același mod ca recompensele pentru recomandări.

Când utilizați sistemul de trimitere, funcția de fond ar trebui să fie modificată, încorporată în logica principală a contului inteligent pe care va funcționa sistemul. De exemplu, dacă o recompensă de recomandare este plătită pentru un pariu făcut, atunci funcția de fond ar trebui să fie încorporată în logica în care este făcut pariul (sau este efectuată o altă acțiune țintă pentru care este plătită recompensa). Există trei niveluri de recompense de recomandare codificate în această funcție. Dacă doriți să faceți mai multe sau mai puține niveluri, atunci acest lucru este corectat și în cod. Procentul de recompensă este stabilit de constantele level1-level3, în cod este calculat ca suma * nivel / 1000, adică valoarea 1 corespunde cu 0,1% (aceasta poate fi modificată și în cod).

Apelul funcției modifică soldul contului și, de asemenea, creează înregistrări în scopul înregistrării formularului:

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

Adică ora tranzacției este ora blocului în care se află. Acest lucru este mai fiabil decât utilizarea ștampilei de timp din tranzacția în sine, mai ales că nu este disponibilă din apelabil.
Funcția de retragere retrage toate recompensele acumulate în contul utilizatorului. Creează intrări în scopuri de înregistrare:

# withdraw log: withdraw_user_txid=amount:timestamp

App

Partea principală a aplicației este biblioteca affiliate.js, care este o punte între modelele de date afiliate și API-ul WAVES NODE REST. Implementează un strat de abstractizare independent de cadru (poate fi folosit oricare). Funcțiile active (înregistrare, retragere) presupun că Waves Keeper este instalat în sistem, biblioteca în sine nu verifică acest lucru.

Implementeaza metode:

fetchReferralTransactions
fetchWithdrawTransactions
fetchMyBalance
fetchReferrals
fetchReferer
withdraw
register

Funcționalitatea metodelor este evidentă din nume, parametrii și datele returnate sunt descrise în cod. Funcția de înregistrare necesită comentarii suplimentare - începe ciclul de selecție a ID-ului tranzacției, astfel încât să înceapă la 123 - acesta este captcha PoW descris mai sus, care protejează împotriva înregistrărilor în masă. Funcția găsește o tranzacție cu id-ul necesar și apoi o semnează prin Waves Keeper.

Programul de afiliere DEX disponibil la GitHub.com.

Sursa: www.habr.com

Adauga un comentariu