Åpen kildekode desentralisert tilknyttet program på Waves blockchain

Et desentralisert tilknyttet program basert på Waves blockchain, implementert som en del av et Waves Labs-tilskudd av Bettex-teamet.

Innlegget er ikke sponset! Programmet er åpen kildekode, bruk og distribusjon er gratis. Bruken av programmet stimulerer utviklingen av dApp-applikasjoner og fremmer generelt desentralisering, noe som er fordelaktig for alle brukere av nettverket.

Åpen kildekode desentralisert tilknyttet program på Waves blockchain

Den presenterte dApp for tilknyttede programmer er en mal for prosjekter som inkluderer affiliate som en del av funksjonaliteten deres. Koden kan brukes som en mal for kopiering, som et bibliotek, eller som et sett med ideer for teknisk implementering.

Funksjonsmessig er dette et ordinært affiliate-system som implementerer registrering hos referer, multi-level periodisering av vederlag for henvisninger og motivasjon for registrering i systemet (cashback). Systemet er en "ren" dApp, det vil si at nettapplikasjonen samhandler direkte med blokkjeden uten egen backend, database osv.

Det brukes teknikker som også kan være nyttige i mange andre prosjekter:

  • Ringe en smartkonto på kreditt med umiddelbar tilbakebetaling (på tidspunktet for samtalen er det ingen tokens på kontoen for å betale for samtalen, men de vises der som et resultat av samtalen).
  • PoW-captcha - beskyttelse mot høyfrekvente automatiserte oppkall av smartkontofunksjoner - lik captcha, men gjennom bevis for bruk av dataressurser.
  • Forespørsel om datanøkler etter mal.

Søknaden består av:

  • smart kontokode på ride4dapps-språket (som, som planlagt, er slått sammen til hovedsmartkontoen, som du må implementere tilknyttede funksjonalitet for);
  • js wrapper som implementerer et abstraksjonslag over WAVES NODE REST API;
  • kode på vuejs-rammeverket, som er et eksempel på bruk av biblioteket og RIDE-koden.

La oss beskrive alle de oppførte funksjonene.

Gjelder en smartkonto med umiddelbar tilbakebetaling

Å ringe InvokeScript krever betaling av et gebyr fra kontoen som starter transaksjonen. Dette er ikke et problem hvis du gjør et prosjekt for blokkjede-nerder som har et visst antall WAVES-tokens på kontoen sin, men hvis produktet er rettet mot massene, blir dette et alvorlig problem. Tross alt må brukeren sørge for kjøp av WAVES-tokens (eller en annen passende eiendel som kan brukes til å betale for transaksjoner), noe som øker den allerede betydelige terskelen for å gå inn i prosjektet. Vi kan distribuere eiendeler til brukere som får lov til å betale for transaksjoner og står overfor risikoen for misbruk når automatiserte systemer opprettes for å pumpe likvide eiendeler fra systemet vårt.

Det ville være veldig praktisk hvis det ville være mulig å kalle InvokeScript "på bekostning av mottakeren" (den smarte kontoen som skriptet er installert på), og denne muligheten eksisterer, men ikke på en åpenbar måte.

Hvis det i InvokeScript gjøres en ScriptTransfer til adressen til den som ringer, som kompenserer for tokens brukt på gebyret, vil en slik samtale lykkes, selv om det ikke var noen eiendeler på den oppringende kontoen på tidspunktet for samtalen. Dette er mulig fordi sjekken for tilstrekkelig med tokens gjøres etter at transaksjonen er kalt, og ikke før den, slik at det er mulig å foreta transaksjoner på kreditt, forutsatt at de umiddelbart innløses.

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

Koden nedenfor refunderer det brukte gebyret med smartkontomidler. For å beskytte mot misbruk av denne funksjonen, må du bruke en sjekk på at den som ringer bruker gebyret i riktig eiendel og innenfor rimelige grenser:

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
}

For å beskytte mot ondsinnet og meningsløs sløsing med midler, kreves beskyttelse mot automatisk anrop (PoW-captcha).

PoW-captcha

Selve ideen med proof-of-work captcha er ikke ny og har allerede blitt implementert i ulike prosjekter, inkludert de som er basert på WAVES. Poenget med ideen er at for å utføre en handling som sløser med prosjektets ressurser, må den som ringer også bruke sine egne ressurser, noe som gjør et ressursuttømmingsangrep ganske kostbart. For en veldig enkel og rimelig validering av at avsenderen av transaksjonen har løst PoW-problemet, er det en transaksjons-ID-sjekk:

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

For å gjennomføre en transaksjon må den som ringer velge slike parametere slik at dens base58-kode (id) begynner med tallene 123, som tilsvarer et gjennomsnitt på et par titalls sekunders prosessortid og generelt sett er rimelig for vår oppgave. Hvis det kreves en enklere eller mer kompleks PoW, kan oppgaven enkelt endres på en åpenbar måte.

Spør datanøkler etter mal

For å bruke blokkjeden som en database, er det viktig å ha API-verktøy for å spørre databasen som en nøkkelverdi ved hjelp av maler. Et slikt verktøysett dukket opp tidlig i juli 2019 som en parameter ?fyrstikker på REST API-forespørselen /adresser/data?matches=regexp. Nå, hvis vi trenger å hente mer enn én nøkkel og ikke alle nøkler på en gang fra nettapplikasjonen, men bare en gruppe, kan vi velge etter navnet på nøkkelen. For eksempel, i dette prosjektet er uttakstransaksjoner kodet som

withdraw_${userAddress}_${txid}

som lar deg få en liste over transaksjoner for uttak av midler for en gitt adresse ved å bruke malen:

?matches=withdraw_${userAddress}_.*

La oss nå analysere komponentene i den ferdige løsningen.

vuejs kode

Koden er en fungerende demo, nær et ekte prosjekt. Den implementerer pålogging gjennom Waves Keeper og jobber med affiliate.js-biblioteket, ved hjelp av dette registrerer den en bruker i systemet, spør etter transaksjonsdata, og lar deg også ta ut opptjente midler til brukerens konto.

Åpen kildekode desentralisert tilknyttet program på Waves blockchain

Kode på RIDE

Består av registrerings-, fond- og uttaksfunksjoner.

Registerfunksjonen registrerer en bruker i systemet. Den har to parametere: referer (referr's address) og saltparameteren som ikke brukes i funksjonskoden, som er nødvendig for å velge transaksjons-ID (PoW-captcha-oppgave).

Funksjonen (som resten av funksjonene i dette prosjektet) bruker låneteknikken, resultatet av funksjonen er å finansiere betalingen av et gebyr for å kalle denne funksjonen. Takket være denne løsningen kan en bruker som nettopp har opprettet en lommebok umiddelbart jobbe med systemet og trenger ikke å bli forvirret over spørsmålet om å anskaffe eller motta en eiendel som lar ham betale et transaksjonsgebyr.

Resultatet av registreringsfunksjonen er to poster:

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

Dette tillater oppslag fremover og bakover (henviser av den gitte brukeren og alle henvisninger fra den gitte brukeren).

Fondsfunksjonen er mer en mal for å utvikle reell funksjonalitet. I det presenterte skjemaet tar den alle midlene som er overført av transaksjonen og distribuerer dem til henvisningskontoene på 1., 2., 3. nivå, til "cashback"-kontoen og "change"-kontoen (alt som gjenstår under distribusjon til tidligere kontoer kommer her).

Cashback er et middel for å motivere sluttbrukeren til å delta i henvisningssystemet. Den delen av provisjonen som betales av systemet i form av "cashback" kan trekkes tilbake av brukeren på samme måte som belønninger for henvisninger.

Ved bruk av henvisningssystemet bør fondsfunksjonen modifiseres, innebygd i hovedlogikken til smartkontoen som systemet skal fungere på. For eksempel, hvis en henvisningsbelønning betales for et veddemål som er gjort, bør fondsfunksjonen bygges inn i logikken der innsatsen gjøres (eller en annen målhandling utføres som belønningen betales for). Det er tre nivåer av henvisningsbelønninger kodet inn i denne funksjonen. Ønsker du å lage flere eller færre nivåer, så er dette også rettet i koden. Belønningsprosenten er satt av nivå1-nivå3 konstantene, i koden beregnes den som beløp * nivå / 1000, det vil si at verdien 1 tilsvarer 0,1 % (dette kan også endres i koden).

Funksjonskallet endrer saldoen på kontoen og oppretter også oppføringer med det formål å logge skjemaet:

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

Det vil si at tidspunktet for transaksjonen er tidspunktet for blokken den befinner seg i. Dette er mer pålitelig enn å bruke tidsstemplet fra selve transaksjonen, spesielt siden det ikke er tilgjengelig fra den anropbare.
Uttaksfunksjonen trekker alle akkumulerte belønninger til brukerens konto. Oppretter oppføringer for loggingsformål:

# withdraw log: withdraw_user_txid=amount:timestamp

App

Hoveddelen av applikasjonen er affiliate.js-biblioteket, som er en bro mellom tilknyttede datamodeller og WAVES NODE REST API. Implementerer et rammeuavhengig abstraksjonslag (hvilket som helst kan brukes). Aktive funksjoner (registrere, trekke ut) forutsetter at Waves Keeper er installert i systemet, biblioteket selv sjekker ikke dette.

Implementerer metoder:

fetchReferralTransactions
fetchWithdrawTransactions
fetchMyBalance
fetchReferrals
fetchReferer
withdraw
register

Funksjonaliteten til metodene er tydelig fra navnene, parametrene og returdata er beskrevet i koden. Registerfunksjonen krever ytterligere kommentarer - den starter valgsyklusen for transaksjons-ID slik at den starter på 123 - dette er PoW captchaen beskrevet ovenfor, som beskytter mot masseregistreringer. Funksjonen finner en transaksjon med nødvendig ID, og ​​signerer den deretter gjennom Waves Keeper.

DEX-tilknyttede program tilgjengelig på GitHub.com.

Kilde: www.habr.com

Legg til en kommentar