Decentralizovaný pridružený program s otvoreným zdrojom na blockchaine Waves

Decentralizovaný pridružený program na blockchaine Waves, implementovaný ako súčasť grantu Waves Labs tímom Bettex.

Príspevok nie je reklama! Program je open source, jeho používanie a distribúcia sú bezplatné. Používanie programu stimuluje vývoj aplikácií dApp a vo všeobecnosti podporuje decentralizáciu, z ktorej profituje každý používateľ internetu.

Decentralizovaný pridružený program s otvoreným zdrojom na blockchaine Waves

Prezentovaný dApp pre affiliate programy je šablónou pre projekty, ktoré zahŕňajú affiliate programy ako súčasť ich funkčnosti. Kód možno použiť ako šablónu na kopírovanie, ako knižnicu alebo ako súbor nápadov na technickú realizáciu.

Funkčne ide o bežný affiliate systém, ktorý implementuje registráciu s odporúčateľom, viacúrovňové pripisovanie odmien za odporúčanie a motiváciu k registrácii do systému (cashback). Systém je „čistý“ dApp, to znamená, že webová aplikácia interaguje priamo s blockchainom bez toho, aby mala vlastný backend, databázu atď.

Použité techniky, ktoré môžu byť užitočné aj v mnohých iných projektoch:

  • Zadlženie smart účtu s okamžitým splatením (v čase hovoru nie sú na účte žiadne tokeny na zaplatenie hovoru, ale objavujú sa tam ako výsledok hovoru).
  • PoW-captcha - ochrana proti vysokofrekvenčným automatickým volaniam na funkcie smart účtu - obdoba captcha, ale prostredníctvom dôkazu o využití výpočtových zdrojov.
  • Dopyt na dátové kľúče pomocou šablóny.

Aplikácia pozostáva z:

  • kód inteligentného účtu v jazyku ride4dapps (ktorý je podľa plánu zlúčený do hlavného inteligentného účtu, pre ktorý je potrebné implementovať pridruženú funkcionalitu);
  • js wrapper, ktorý implementuje úroveň abstrakcie cez WAVES NODE REST API;
  • kód na frameworku vuejs, čo je príklad použitia knižnice a kódu RIDE.

Poďme popísať všetky uvedené funkcie.

Volanie na inteligentný účet na dlh s okamžitým splatením

Volanie InvokeScript vyžaduje zaplatenie poplatku z účtu, ktorý iniciuje transakciu. To nie je problém, ak robíte projekt pre blockchainových geekov, ktorí majú na svojom účte určité množstvo tokenov WAVES, ale ak je produkt zameraný na použitie širokou verejnosťou, stáva sa to vážnym problémom. Užívateľ sa totiž musí postarať o nákup tokenov WAVES (alebo iného vhodného aktíva, ktorým je možné platiť za transakcie), čo zvyšuje už aj tak značnú bariéru vstupu do projektu. Môžeme distribuovať aktívum používateľom, ktorí budú môcť platiť za transakcie a čeliť riziku ich zneužitia, keď sa vytvoria automatizované systémy na odčerpanie likvidných aktív z nášho systému.

Bolo by veľmi výhodné, keby bolo možné volať InvokeScript „na náklady príjemcu“ (inteligentného účtu, na ktorom je skript nainštalovaný), a takáto možnosť, aj keď nie očividne, existuje.

Ak v rámci InvokeScript vykonáte ScriptTransfer na adresu volajúceho, čím sa kompenzujú vynaložené tokeny poplatkov, potom bude takýto hovor úspešný, aj keď v čase hovoru neboli na volajúcom účte žiadne aktíva. Je to možné, pretože kontrola dostatočného množstva tokenov sa vykonáva po vyvolaní transakcie, a nie pred ňou, takže transakcie môžu byť uskutočnené na úver s výhradou okamžitého splatenia.

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

Nižšie uvedený kód prepláca vynaložený poplatok pomocou prostriedkov inteligentného účtu. Na ochranu pred zneužitím tejto funkcie je potrebné použiť kontrolu, či volajúci minie poplatok v požadovanom aktíve a v rozumných medziach:

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
}

Na ochranu pred zlomyseľným a nezmyselným plytvaním finančnými prostriedkami je tiež potrebná automatická ochrana hovorov (PoW-captcha).

PoW-captcha

Samotná myšlienka proof-of-work captcha nie je nová a už bola implementovaná v rôznych projektoch, vrátane projektov realizovaných na báze WAVES. Myšlienka je taká, že na vykonanie akcie, ktorá spotrebuje zdroje nášho projektu, musí volajúci minúť aj svoje vlastné zdroje, čo značne predražuje útok na vyčerpanie zdrojov. Pre veľmi jednoduché a lacné overenie, že odosielateľ transakcie vyriešil problém PoW, existuje kontrola ID transakcie:

if take(toBase58String(i.transactionId), 3) != “123” then throw(”proof of work failed”) else

Na uskutočnenie transakcie si volajúci musí zvoliť také parametre, aby jeho základný58 kód (id) začínal číslicami 123, čo v priemere zodpovedá niekoľkým desiatkam sekúnd procesorového času a je vo všeobecnosti rozumné pre našu úlohu. Ak je potrebný jednoduchší alebo zložitejší PoW, potom sa úloha dá ľahko upraviť zrejmým spôsobom.

Dopyt na dátové kľúče pomocou šablóny

Aby bolo možné použiť blockchain ako databázu, je nevyhnutné mať nástroje API na dopytovanie databázy ako kľúč-val na základe šablón. Takáto sada nástrojov sa objavila začiatkom júla 2019 vo forme parametra ?zápasy pri požiadavke REST API /addresses/data?matches=regexp. Teraz, ak potrebujeme získať viac ako jeden kľúč z webovej aplikácie a nie všetky kľúče naraz, ale iba nejakú skupinu, potom môžeme vykonať výber podľa názvu kľúča. Napríklad v tomto projekte sú transakcie výberu kódované ako

withdraw_${userAddress}_${txid}

čo vám umožňuje získať zoznam transakcií na výber finančných prostriedkov pre akúkoľvek danú adresu pomocou šablóny:

?matches=withdraw_${userAddress}_.*

Teraz sa pozrime na komponenty hotového riešenia.

Vuejsov kód

Kód je pracovné demo blízke skutočnému projektu. Implementuje prihlásenie cez Waves Keeper a spolupracuje s knižnicou affiliate.js, pomocou ktorej eviduje používateľa v systéme, zisťuje údaje o transakciách a umožňuje aj výber zarobených prostriedkov na účet používateľa.

Decentralizovaný pridružený program s otvoreným zdrojom na blockchaine Waves

Kód pre RIDE

Pozostáva z funkcií registra, fondu a výberu.

Funkcia registra zaregistruje používateľa v systéme. Má dva parametre: referer (adresa referera) a parameter salt, ktorý sa nepoužíva v kóde funkcie, ktorý je potrebný na výber ID transakcie (úloha PoW-captcha).

Funkcia (rovnako ako ostatné funkcie z tohto projektu) využíva techniku ​​dlhového volania, výsledkom funkcie je financovanie úhrady poplatku za volanie tejto funkcie. Vďaka tomuto riešeniu môže používateľ, ktorý si práve vytvoril peňaženku, okamžite pracovať so systémom a nemusí sa starať o nákup alebo prijatie aktíva, ktoré mu umožňuje zaplatiť transakčný poplatok.

Výsledkom funkcie registrácie sú dva záznamy:

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

To umožňuje dopredné a spätné vyhľadávanie (sprostredkovateľ daného používateľa a všetky odporúčania daného používateľa).

Funkcia fondu je skôr šablónou pre vývoj reálnej funkcionality. Vo svojej prezentovanej forme vezme všetky prostriedky prevedené transakciou a rozdelí ich na účty sprostredkovateľov úrovne 1, 2, 3, na účet „cashback“ a účet „zmeny“ (všetko, čo zostane pri rozdelení na predchádzajúci účty idú sem).

Cashback je prostriedkom motivácie koncového užívateľa k účasti v systéme odporúčaní. Používateľ si môže časť provízie vyplatenej systémom stiahnuť formou „cashbacku“ rovnakým spôsobom ako odmeny za odporúčania.

Pri používaní systému odporúčaní by sa funkcia fondu mala upraviť a integrovať do hlavnej logiky inteligentného účtu, na ktorom bude systém fungovať. Ak sa napríklad za uskutočnenú stávku vypláca odmena za odporúčanie, potom by mala byť funkcia fondu zabudovaná do logiky, v ktorej sa stávka podáva (alebo sa vykonáva iná cielená akcia, za ktorú sa odmena vypláca). Do tejto funkcie sú zakódované tri úrovne odmien za odporúčanie. Ak potrebujete urobiť viac alebo menej úrovní, je to tiež opravené v kóde. Percento odmeny je nastavené konštantami level1-level3, v kóde je vypočítané ako množstvo * úroveň / 1000, to znamená, že hodnota 1 zodpovedá 0,1% (dá sa to zmeniť aj v kóde).

Vyvolaním funkcie sa zmení zostatok na účte a tiež sa vytvoria záznamy na účely prihlásenia do formulára:

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

To znamená, že čas transakcie je čas bloku, v ktorom sa nachádza. Je to spoľahlivejšie ako použitie časovej pečiatky zo samotnej transakcie, najmä preto, že nie je dostupná z volaného.
Funkcia výberu zobrazuje všetky nahromadené odmeny na účet používateľa. Vytvára záznamy na účely protokolovania:

# withdraw log: withdraw_user_txid=amount:timestamp

Aplikácia

Hlavnou časťou aplikácie je knižnica affiliate.js, ktorá je mostom medzi affiliate dátovými modelmi a WAVES NODE REST API. Implementuje úroveň abstrakcie nezávislú od rámca (môže byť použitá akákoľvek). Aktívne funkcie (registrácia, stiahnutie) predpokladajú, že v systéme je nainštalovaný Waves Keeper, samotná knižnica to nekontroluje.

Implementuje metódy:

fetchReferralTransactions
fetchWithdrawTransactions
fetchMyBalance
fetchReferrals
fetchReferer
withdraw
register

Funkčnosť metód je zrejmá z názvov, parametre a vrátené dáta sú popísané v kóde. Funkcia registra si vyžaduje ďalšie komentáre – spustí cyklus výberu id transakcie tak, aby začínala na 123 – ide o vyššie popísanú PoW-captcha, ktorá chráni pred hromadnými registráciami. Funkcia nájde transakciu s požadovaným ID a potom ju podpíše cez Waves Keeper.

Partnerský program DEX je dostupný na GitHub.com.

Zdroj: hab.com

Pridať komentár