Ein dezentralisiertes Affiliate-Programm auf der Waves-Blockchain, realisiert im Rahmen eines Grants von Waves Labs durch das Team von Bettex.
Der Beitrag ist keine Werbung! Das Programm ist Open Source, seine Nutzung und Verbreitung sind kostenlos. Der Einsatz des Programms fördert die Entwicklung von dApp-Anwendungen und trägt insgesamt zur Dezentralisierung bei, was jedem Nutzer des Netzwerks zugutekommt.

Die vorgestellte dApp für Affiliate-Programme ist eine Vorlage für Projekte, die Affiliate-Mechanismen als Teil ihrer Funktionalität integrieren. Der Code kann als Vorlage zum Kopieren, als Bibliothek oder als Ideenset für technische Umsetzungen verwendet werden.
In Bezug auf die Funktionalität handelt es sich um ein gewöhnliches Affiliate-System, das die Registrierung mit Angabe des Referrers, multi-level Belohnungen für Empfehlungen und Anreize zur Registrierung im System (Cashback) umsetzt. Das System ist eine „reine“ dApp, das heißt, die Webanwendung interagiert direkt mit der Blockchain, ohne einen eigenen Backend-Server oder eine Datenbank.
Techniken werden verwendet, die auch in vielen anderen Projekten nützlich sein können:
- Ein sofortiger Kreditabruf für ein Smart-Konto, ohne dass zu Beginn Token zur Bezahlung des Abrufs auf dem Konto vorhanden sind – diese werden während des Abrufs generiert.
- PoW-Captcha – ein Schutz gegen hochfrequente automatisierte Abrufe von Smart-Konto-Funktionen – ähnlich einer Captcha, aber basierend auf dem Nachweis der Nutzung von Rechenressourcen.
- Anfrage an die Schlüsseldaten nach Vorlage.
Die Anwendung besteht aus:
- dem Smart-Kontocode in der Sprache ride4dapps (der konzipiert wurde, um in das Haupt-Smart-Konto integriert zu werden, für das die Affiliate-Funktionalität implementiert werden muss);
- einer js-Hülle, die eine Abstraktionsschicht über das WAVES NODE REST API bereitstellt;
- Code im vuejs-Framework, der ein Beispiel für die Verwendung der Bibliothek und des RIDE-Codes darstellt.
Wir beschreiben alle genannten Eigenschaften.
Ein sofortiger Kreditabruf für ein Smart-Konto
Der Aufruf von InvokeScript erfordert eine Gebühr vom kontoauslösenden Transaktionskonto. Das ist kein Problem, wenn Sie ein Projekt für Blockchain-Enthusiasten machen, die einige WAVES-Token auf ihrem Konto haben. Wenn das Produkt jedoch für die breite Masse gedacht ist, wird dies zu einem ernsthaften Problem. Der Nutzer muss sich um den Kauf von WAVES-Token (oder einem anderen passenden Asset, mit dem Transaktionen bezahlt werden können) kümmern, was die ohnehin schon hohe Einstiegshürde für das Projekt erhöht. Wir könnten den Nutzern ein Asset zur Verfügung stellen, mit dem sie Transaktionen bezahlen können, und uns dem Risiko uneingemessener Verwendung aussetzen, wenn automatisierte Systeme eingerichtet werden, um liquide Assets aus unserem System abzuziehen.
Es wäre sehr praktisch, wenn man den InvokeScript-Aufruf "auf Kosten des Empfängers" (des Smart-Accounts, auf dem das Skript installiert ist) durchführen könnte, und eine solche Möglichkeit besteht, wenn auch nicht offensichtlich.
Wenn innerhalb von InvokeScript ein ScriptTransfer an die aufrufende Adresse erfolgt, der die ausgegebenen Tokens für die Gebühr kompensiert, wird dieser Aufruf erfolgreich sein, selbst wenn zum Zeitpunkt des Aufrufs auf dem aufrufenden Konto keine Assets vorhanden sind. Dies ist möglich, da die Prüfung, ob genügend Tokens vorhanden sind, nach dem Transaktionsaufruf und nicht davor erfolgt, sodass Transaktionen auf Kredit durchgeführt werden können, sofern sie sofort ausgeglichen werden.
ScriptTransfer(i.caller, i.fee, unit)
Der folgende Code erstattet die für die Gebühr ausgegebenen Mittel aus dem Smart-Account. Um einen Missbrauch dieser Möglichkeit zu verhindern, ist es notwendig zu überprüfen, dass der Aufrufer die Gebühr im richtigen Asset und in angemessenen Grenzen ausgibt:
func checkFee(i:Invocation) = {
if i.fee > maxFee then throw("unvernünftige hohe Gebühr") else
if i.feeAssetId != unit then throw("Die Gebühr muss in WAVES sein") else true
}Um sich auch gegen böswillige und sinnlose Mittelverschwendung abzusichern, ist ein Schutz vor automatischen Aufrufen erforderlich (PoW-Captcha)
PoW-Captcha
Die Grundidee der Proof-of-Work-Captcha ist nicht neu und wurde bereits in verschiedenen Projekten umgesetzt, darunter solche, die auf WAVES basieren. Der Gedanke dahinter ist, dass derjenige, der eine ressourcenverbrauchende Aktion durchführen möchte, auch eigene Ressourcen aufbringen muss, was Angriffe zur Erschöpfung von Ressourcen kostspielig macht. Für die einfache und kostengünstige Validierung, dass der Absender der Transaktion die PoW-Aufgabe gelöst hat, gibt es die Überprüfung der Transaktions-ID:
if take(toBase58String(i.transactionId), 3) != “123” then throw(“proof of work failed”) else
Um eine Transaktion durchzuführen, muss der Aufrufende Parameter wählen, sodass der Base58-Code (ID) mit den Ziffern 123 beginnt, was im Durchschnitt einige Dutzend Sekunden an Prozessorzeit entspricht und insgesamt für unsere Aufgabe sinnvoll ist. Wenn ein einfacherer oder schwierigerer PoW erforderlich ist, kann die Aufgabe auf offensichtliche Weise leicht angepasst werden.
Anfrage an die Daten Schlüssel nach dem Muster
Um die Blockchain als Datenbank nutzen zu können, ist es entscheidend, API-Tools für Anfragen an die Datenbank nach Schlüssel-Wert-Paaren gemäß Mustern zu haben. Ein solches Toolset wurde Anfang Juli 2019 in Form eines Parameters eingeführt ?matches für die REST API-Anfrage /addresses/data?matches=regexp. Wenn wir aus der Webanwendung nicht einen Schlüssel und nicht alle Schlüssel gleichzeitig, sondern nur eine bestimmte Gruppe abrufen müssen, können wir nach dem Schlüsselnamen filtern. Zum Beispiel werden in diesem Projekt die Auszahlungs Transaktionen in folgender Form kodiert
withdraw_${userAddress}_${txid}, was es ermöglicht, eine Liste von Auszahlungs Transaktionen für jede gegebene Adresse nach diesem Muster zu erhalten:
?matches=withdraw_${userAddress}_.*Jetzt werden wir die Komponenten der fertigen Lösung analysieren.
Code in vuejs
Der Code ist eine funktionierende Demonstration, die einem realen Projekt nahekommt. Er implementiert den Zugang über Waves Keeper und die Arbeit mit der Bibliothek affiliate.js, mithilfe derer er den Benutzer im System registriert, Transaktionsdaten abfragt und es ermöglicht, die verdienten Gelder auf das Benutzerkonto auszuzahlen.

Code in RIDE
Besteht aus den Funktionen register, fund und withdraw.
Die Funktion register registriert einen Benutzer im System. Sie hat zwei Parameter: referer (Adresse des Referrers) und einen in der Funktionslogik nicht verwendeten Parameter salt, der für die Bestimmung der Transaktions-ID benötigt wird (Aufgabe der PoW-Captcha).
Die Funktion (wie auch die anderen Funktionen in diesem Projekt) verwendet eine Technik zur verzögerten Ausführung. Das Ergebnis dieser Funktion ist die Finanzierung der Gebührenzahlung für den Aufruf dieser Funktion. Mit dieser Lösung kann der Benutzer, der gerade eine Wallet erstellt hat, sofort mit dem System arbeiten, ohne sich Gedanken darüber machen zu müssen, wie er ein Asset erwerben oder erhalten kann, um die Transaktionsgebühr zu bezahlen.
Das Ergebnis der Registrierung besteht aus zwei Einträgen:
${owner}_referer = referer
${referer}_referral_${owner} = ownerDies ermöglicht sowohl direkte als auch umgekehrte Suchen (den Referrer dieses Nutzers und alle Referral-Links dieses Nutzers).
Die Funktion fund dient eher als Vorlage zur Entwicklung des tatsächlichen Funktionsumfangs. In der vorliegenden Form nimmt sie alle durch die Transaktion übertragenen Mittel und verteilt sie auf die Konten der Referrer der Stufen 1, 2 und 3, auf das "Cashback"-Konto und das "Wechselgeld"-Konto (hier gelangen alle Beträge hin, die nach der Verteilung auf die vorherigen Konten übrig bleiben).
Cashback ist ein Anreiz für Endbenutzer, an einem Empfehlungsprogramm teilzunehmen. Der ausgezahlte Teil der Provision, der als „Cashback“ bezeichnet wird, kann vom Benutzer in der gleichen Weise abgehoben werden wie die Belohnungen für Empfehlungen.
Bei Verwendung des Empfehlungsprogramms sollte die Funktion fund angepasst und in die Hauptlogik des Smart Accounts integriert werden, in dem das System betrieben wird. Wenn beispielsweise die Empfehlungsentlohnung für eine platzierte Wette gezahlt wird, sollte die Funktion fund in die Logik integriert werden, wo die Wette platziert wird (oder eine andere zielgerichtete Handlung durchgeführt wird, für die eine Entlohnung gezahlt wird). In dieser Funktion sind drei Ebenen der Empfehlungsbelohnungen kodiert. Falls mehr oder weniger Ebenen benötigt werden, kann dies ebenfalls im Code angepasst werden. Der Provisionsprozentsatz wird durch die Konstanten level1-level3 festgelegt, im Code wird er wie folgt berechnet: amount * level / 1000, was bedeutet, dass der Wert 1 0,1 % entspricht (dies kann ebenfalls im Code geändert werden).
Der Aufruf der Funktion ändert das Guthaben des Kontos und erstellt auch Protokolle für Logging-Zwecke in folgendem Format:
fund_address_txid = address:owner:inc:level:timestamp
Um den Timestamp (aktuelle Zeit) zu erhalten, wird folgende Verbindung verwendet
func getTimestamp() = {
let block = extract(blockInfoByHeight(height))
toString(block.timestamp)
} Das bedeutet, dass die Transaktionszeit — die Zeit des Blocks ist, in dem sie sich befindet. Dies ist zuverlässiger, als den Timestamp aus der Transaktion selbst zu verwenden, zumal dieser nicht aus callable verfügbar ist.
Die Funktion withdraw hebt alle angesammelten Belohnungen auf das Benutzerkonto ab. Sie erstellt Einträge für Logging-Zwecke:
# withdraw log: withdraw_user_txid=amount:timestampgenerierten Wortliste wurde sichergestellt.
Der Hauptteil der Anwendung — die Bibliothek affiliate.js, die als Brücke zwischen den Datenmodellen affiliate und dem WAVES NODE REST API dient. Sie implementiert eine abstrahierte Ebene, die unabhängig vom Framework ist (kann mit jedem verwendet werden). Die aktiven Funktionen (register, withdraw) setzen voraus, dass Waves Keeper im System installiert ist, die Bibliothek überprüft dies jedoch nicht.
Implementiert Methoden:
fetchReferralTransactions
fetchWithdrawTransactions
fetchMyBalance
fetchReferrals
fetchReferer
withdraw
registerDie Funktionalität der Methoden ist aus den Namen ersichtlich, Parameter und Rückgabewerte sind im Code beschrieben. Die Funktion „register“ benötigt zusätzliche Kommentare – sie startet einen Prozess zur Ermittlung der Transaktions-ID, die bei 123 beginnen soll – dies ist die oben beschriebene PoW-Captcha, die vor Massenregistrierungen schützt. Die Funktion findet die Transaktion mit der benötigten ID und signiert sie dann über Waves Keeper.
Das DEX-Partnerprogramm ist verfügbar auf .
Quelle: habr.com
