Zdecentralizowany program partnerski typu open source na blockchainie Waves

Zdecentralizowany program partnerski na blockchainie Waves, realizowany w ramach grantu Waves Labs przez zespół Bettex.

Post nie ma charakteru reklamy! Program ma charakter open source, jego użytkowanie i dystrybucja są bezpłatne. Korzystanie z programu stymuluje rozwój aplikacji dApp i ogólnie sprzyja decentralizacji, na której zyskuje każdy użytkownik Internetu.

Zdecentralizowany program partnerski typu open source na blockchainie Waves

Prezentowana dApp dla programów partnerskich jest szablonem dla projektów, które w ramach swojej funkcjonalności uwzględniają afiliację. Kod może służyć jako szablon do kopiowania, jako biblioteka lub jako zbiór pomysłów do technicznego wdrożenia.

Pod względem funkcjonalności jest to zwykły system partnerski, który realizuje rejestrację z osobą polecającą, wielopoziomowe naliczanie nagród za poleconych oraz motywację do rejestracji w systemie (cashback). System jest „czystym” dApp, czyli aplikacja internetowa wchodzi w bezpośrednią interakcję z blockchainem, bez posiadania własnego backendu, bazy danych itp.

Zastosowane techniki, które mogą być przydatne także w wielu innych projektach:

  • Zadłużenie inteligentnego konta z natychmiastową spłatą (w momencie połączenia na koncie nie znajdują się tokeny umożliwiające opłacenie połączenia, ale pojawiają się one tam w wyniku połączenia).
  • PoW-captcha - ochrona przed automatycznymi wywołaniami o wysokiej częstotliwości do funkcji konta inteligentnego - analogicznie do captcha, ale poprzez dowód wykorzystania zasobów obliczeniowych.
  • Zapytanie o klucze danych przy użyciu szablonu.

Aplikacja składa się z:

  • kod konta inteligentnego w języku ride4dapps (który zgodnie z planem jest scalony z głównym kontem inteligentnym, dla którego należy wdrożyć funkcjonalność afiliacyjną);
  • js wrapper implementujący poziom abstrakcji poprzez API REST WAVES NODE;
  • kod na frameworku vuejs, który jest przykładem wykorzystania biblioteki i kodu RIDE.

Opiszmy wszystkie wymienione funkcje.

Wywołanie inteligentnego konta dla zadłużenia z natychmiastową spłatą

Wywołanie InvokeScript wymaga uiszczenia opłaty z rachunku inicjującego transakcję. Nie stanowi to problemu, jeśli robisz projekt dla maniaków blockchaina, którzy mają na swoim koncie określoną ilość tokenów WAVES, ale jeśli produkt jest przeznaczony do użytku przez ogół społeczeństwa, staje się to poważnym problemem. Przecież użytkownik musi zadbać o zakup tokenów WAVES (lub innego odpowiedniego aktywa, którym można zapłacić za transakcje), co zwiększa i tak już znaczną barierę wejścia do projektu. Możemy dystrybuować aktywa wśród użytkowników, którzy będą mogli płacić za transakcje i stawić czoła ryzyku ich niewłaściwego wykorzystania, gdy tworzone będą zautomatyzowane systemy w celu wypompowywania płynnych aktywów z naszego systemu.

Byłoby bardzo wygodnie, gdyby istniała możliwość wywołania InvokeScriptu „na koszt odbiorcy” (inteligentnego konta, na którym zainstalowany jest skrypt) i taka możliwość, choć nie w oczywisty sposób, istnieje.

Jeśli w InvokeScript wykonasz ScriptTransfer na adres dzwoniącego, co rekompensuje wydane tokeny opłaty, to takie połączenie zakończy się sukcesem, nawet jeśli w momencie połączenia nie było żadnych środków na koncie wywołującym. Jest to możliwe, ponieważ sprawdzenie wystarczającej liczby tokenów następuje po wywołaniu transakcji, a nie przed nią, dzięki czemu można dokonywać transakcji na kredyt, z zastrzeżeniem natychmiastowej spłaty.

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

Poniższy kod zwraca poniesioną opłatę przy użyciu środków z konta inteligentnego. Aby zabezpieczyć się przed niewłaściwym wykorzystaniem tej funkcji, należy sprawdzić, czy osoba dzwoniąca wydała opłatę w wymaganym aktywze i w rozsądnych granicach:

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
}

Ponadto, aby chronić przed złośliwym i bezsensownym marnowaniem środków, wymagana jest automatyczna ochrona połączeń (PoW-captcha).

PoW-captcha

Sam pomysł captcha proof-of-work nie jest nowy i został już wdrożony w różnych projektach, także tych realizowanych w oparciu o WAVES. Pomysł jest taki, że aby wykonać akcję pochłaniającą zasoby naszego projektu, wywołujący musi także wydać własne zasoby, co sprawia, że ​​atak polegający na wyczerpaniu zasobów jest dość kosztowny. Aby bardzo łatwo i tanio sprawdzić, czy nadawca transakcji rozwiązał problem PoW, istnieje możliwość sprawdzenia identyfikatora transakcji:

if take(toBase58String(i.transactionId), 3) != „123” then rzut(„dowód wykonania pracy nie powiódł się”) else

Aby przeprowadzić transakcję, osoba wywołująca musi tak dobrać takie parametry, aby jej kod base58 (id) zaczynał się od cyfr 123, co odpowiada średnio kilkudziesięciu sekundom czasu procesora i jest w zasadzie rozsądne dla naszego zadania. Jeśli potrzebny jest prostszy lub bardziej złożony PoW, zadanie można łatwo zmodyfikować w oczywisty sposób.

Zapytanie o klucze danych przy użyciu szablonu

Aby wykorzystać blockchain jako bazę danych, niezbędne jest posiadanie narzędzi API umożliwiających odpytywanie bazy danych w formie klucza-vala w oparciu o szablony. Taki zestaw narzędzi pojawił się na początku lipca 2019 roku w postaci parametru ?mecze na żądanie API REST /addresses/data?matches=regexp. Teraz, jeśli potrzebujemy uzyskać więcej niż jeden klucz z aplikacji internetowej i nie wszystkie klucze na raz, ale tylko jakąś grupę, możemy dokonać selekcji według nazwy klucza. Na przykład w tym projekcie transakcje wypłat są kodowane jako

withdraw_${userAddress}_${txid}

co pozwala na uzyskanie zestawienia transakcji wypłaty środków dla dowolnego adresu za pomocą szablonu:

?matches=withdraw_${userAddress}_.*

Przyjrzyjmy się teraz elementom gotowego rozwiązania.

Kod Vuejsa

Kod jest działającym demo zbliżonym do prawdziwego projektu. Realizuje logowanie poprzez Waves Keeper i współpracuje z biblioteką partnerską.js, za pomocą której rejestruje użytkownika w systemie, odpytuje dane transakcyjne, a także umożliwia wypłatę zarobionych środków na konto użytkownika.

Zdecentralizowany program partnerski typu open source na blockchainie Waves

Kod dla RIDE

Składa się z funkcji rejestracji, gromadzenia środków i wypłat.

Funkcja rejestru rejestruje użytkownika w systemie. Posiada dwa parametry: referer (adres referer) oraz parametr salt, który nie jest używany w kodzie funkcji, a który jest niezbędny do wybrania identyfikatora transakcji (zadanie PoW-captcha).

Funkcja (podobnie jak inne funkcje z tego projektu) wykorzystuje technikę wezwania długu, efektem działania funkcji jest sfinansowanie zapłaty opłaty za wywołanie tej funkcji. Dzięki temu rozwiązaniu użytkownik, który właśnie założył portfel, może od razu pracować z systemem i nie musi się martwić o zakup czy otrzymanie aktywa, które pozwoli mu uiścić opłatę transakcyjną.

Wynikiem funkcji rejestracji są dwa rekordy:

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

Umożliwia to wyszukiwanie do przodu i do tyłu (strona polecająca danego użytkownika i wszystkie polecenia danego użytkownika).

Funkcja funduszu jest raczej szablonem do opracowania prawdziwej funkcjonalności. W przedstawionej formie pobiera wszystkie środki przekazane w ramach transakcji i rozdziela je na konta polecających poziomów 1, 2, 3, na konto „cashback” i konto „zmiana” (wszystko, co pozostaje po rozdysponowaniu do poprzednich konta znajdują się tutaj).

Cashback to sposób na zmotywowanie użytkownika końcowego do wzięcia udziału w systemie poleceń. Użytkownik może wypłacić część zapłaconej przez system prowizji w formie „cashbacku” w taki sam sposób, jak nagrody za polecenia.

W przypadku korzystania z systemu poleceń należy zmodyfikować funkcję funduszu i zintegrować ją z główną logiką konta inteligentnego, na którym system będzie działał. Na przykład, jeśli za postawiony zakład wypłacana jest nagroda za polecenie, wówczas funkcja funduszu powinna zostać wbudowana w logikę, w której zostaje postawiony zakład (lub wykonywana jest inna ukierunkowana akcja, za którą wypłacana jest nagroda). W tej funkcji zakodowane są trzy poziomy nagród za polecenie. Jeśli chcesz utworzyć więcej lub mniej poziomów, jest to również poprawione w kodzie. Procent nagrody jest ustalany przez stałe Level1-Level3; w kodzie jest obliczany jako ilość * poziom / 1000, czyli wartość 1 odpowiada 0,1% (można to również zmienić w kodzie).

Wywołanie funkcji powoduje zmianę salda rachunku, a także powoduje utworzenie zapisów do logowania w formularzu:

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

Oznacza to, że czasem transakcji jest czas bloku, w którym się ona znajduje. Jest to bardziej niezawodne niż użycie znacznika czasu z samej transakcji, zwłaszcza że nie jest on dostępny z poziomu wywołania.
Funkcja wypłaty wyświetla wszystkie zgromadzone nagrody na koncie użytkownika. Tworzy wpisy do celów logowania:

# withdraw log: withdraw_user_txid=amount:timestamp

Aplikacja

Główną częścią aplikacji jest biblioteka partners.js, która stanowi pomost pomiędzy modelami danych afiliacyjnych, a API REST WAVES NODE. Implementuje poziom abstrakcji niezależny od frameworka (można użyć dowolnego). Aktywne funkcje (rejestracja, wycofywanie) zakładają, że w systemie jest zainstalowany Waves Keeper, sama biblioteka tego nie sprawdza.

Implementuje metody:

fetchReferralTransactions
fetchWithdrawTransactions
fetchMyBalance
fetchReferrals
fetchReferer
withdraw
register

Funkcjonalność metod wynika z nazw, parametry i zwracane dane są opisane w kodzie. Funkcja rejestru wymaga dodatkowego komentarza - rozpoczyna cykl wyboru identyfikatora transakcji tak, aby zaczynał się od 123 - jest to opisana powyżej PoW-captcha, która chroni przed masowymi rejestracjami. Funkcja wyszukuje transakcję o wymaganym identyfikatorze, a następnie podpisuje ją za pomocą Waves Keeper.

Program partnerski DEX jest dostępny pod adresem GitHub.com.

Źródło: www.habr.com

Dodaj komentarz