
Hallo allerseits!
Im ersten Teil haben wir uns eingehend mit dem Erstellen und Arbeiten mit dApp (dezentrale Anwendung) in der Waves RIDE IDE befasst .
Testen wir jetzt ein kleines Beispiel .
Stufe 3. Testen des dApp-Kontos

Welche Probleme treten bei Alice dApp Account sofort auf?
Erstens:
Boob und Cooper können versehentlich mit einer normalen Überweisungstransaktion Geld an dApp senden und können daher nicht mehr darauf zurückgreifen.
Zweitens:
Wir beschränken Alice nicht darauf, Geld ohne die Zustimmung von Boob und / oder Cooper abzuheben. Achten Sie darauf, dass alle Transaktionen von Alice ausgeführt werden.
Drittens:
Jeder kann alle Vorgänge von einem Alice-Konto aus ausführen, indem er einfach seinen publicKey in die Transaktion einfügt :
const unsignedTransferTx = transfer({ amount: 1, recipient: '3P6fVra21KmTfWHBdib45iYV6aFduh4WwC2',
Leider können Sie mit Waves Smart-Verträgen eingehende Transaktionen auf Ihrem Konto noch nicht blockieren, sodass Boob und Cooper ihre ausgehenden Transaktionen selbst kontrollieren müssen.
Beheben wir den 2. und 3. Platz, indem wir Alice für alle Transaktionen außer SetScriptTransaction deaktivieren und den Rest deaktivieren, indem wir den PublicKey in @Verifier angeben. Das heißt, wir erlauben Alice als dApp-Entwickler nur, einen Smart-Vertrag für eine Weile zu aktualisieren / korrigieren.
Ja, Alice kann das Skript jederzeit aktualisieren, um mehr Rechte zu erhalten und die Gelder der „Benutzer“ zu verwalten. Dies kann jedoch nur sie, und alle Benutzer sehen den Moment nicht autorisierter Vertragsänderungen und können Maßnahmen ergreifen. Solange jedoch andere Transaktionen als invokeScript nicht blockiert sind, muss Alice den Clients vertrauen.
Stellen Sie das korrigierte Skript bereit:
@Verifier(tx) func verify() = { match tx { case d: SetScriptTransaction => sigVerify(tx.bodyBytes, tx.proofs[0], base58'x51ySWMyhE8G2AqJqmDpe3qoQM2aBwmieiJzZLK33JW') case _ => true }
Wir versuchen, Münzen mit dApp Alice und ihrer Unterschrift abzuheben. Wir bekommen den Fehler:

Wir versuchen, uns durch Rückzug zurückzuziehen:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"withdraw",args:[{type:"integer", value: 1000000}]}, payment: []}))
Das Skript funktioniert und mit dem 2. Punkt haben wir es herausgefunden!
Stufe 4. Wir erstellen DAO mit Abstimmung
Leider bietet die RIDE-Sprache noch keine Möglichkeit, mit Sammlungen (Wörterbücher, Wörterbücher, Iteratoren, Reduzierer usw.) zu arbeiten. Für alle Operationen mit flachen Schlüsselwertsammlungen können wir jedoch ein System für die Arbeit mit Zeichenfolgen bzw. mit Schlüsseln und deren Entschlüsselung entwerfen.
Strings sind sehr einfach zu verketten, Strings können nach Index aufgeteilt werden.
Wir haben alles, was Sie brauchen, um komplexe DAO-dApp- Logik zu schreiben!
DatentransaktionenDatentransaktionen:
„Die maximale Größe eines Schlüssels beträgt 100 Zeichen. Ein Schlüssel kann beliebige Unicode-Codepunkte enthalten, einschließlich Leerzeichen und anderer nicht druckbarer Symbole. String-Werte haben ein Limit von 32.768 Bytes und die maximale Anzahl möglicher Einträge in Datentransaktionen beträgt 100. Insgesamt beträgt die maximale Größe einer Datentransaktion etwa 140 KB - als Referenz fast genau die Länge von Shakespeares Stück 'Romeo und Julia'. ”
Erstellen Sie ein DAO mit den folgenden Bedingungen:
Damit ein Startup finanziert werden kann, benötigt der Aufruf von getFunds () die Unterstützung von mindestens 2 Teilnehmern - DAO-Investoren. Es wird möglich sein, genau so viel abzuheben, wie der von den Eigentümern des DAO angegebene Gesamtbetrag.
Lassen Sie uns 3 Arten von Schlüsseln erstellen und Logik für die Arbeit mit Guthaben in 2 neuen Funktionen hinzufügen. Vote und getFunds:
xx ... xx _ia = Investoren, verfügbares Guthaben (Abstimmung, Einzahlung, Auszahlung)
xx ... xx _sv = Startups, Anzahl der Stimmen (Abstimmung, getFunds)
xx ... xx _sf = Startups, Anzahl der Stimmen (Abstimmung, getFunds)
xx ... xx = öffentliche Adresse (35 Zeichen)
Beachten Sie bei der Abstimmung, dass wir mehrere Felder gleichzeitig aktualisieren mussten:
WriteSet([DataEntry(key1, value1), DataEntry(key2, value2)]),
Mit WriteSet können wir innerhalb einer invokeScript- Transaktion mehrere Datensätze gleichzeitig erstellen .
So sieht es im DAO-dApp-Schlüsselwertspeicher aus, nachdem Bob und Cooper ihre Einlagen aufgefüllt haben:

Die Einzahlungsfunktion hat sich geringfügig geändert:

Jetzt kommt der wichtigste Moment in den Aktivitäten des DAO - die Abstimmung für Finanzierungsprojekte.
Bob stimmt für Nelis 500.000 Wavelets-Projekt:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"vote",args:[{type:"integer", value: 500000}, {type:"string", value: "3MrXEKJr9nDLNyVZ1d12Mq4jjeUYwxNjMsH"}]}, payment: []}))
Abstimmungsfunktionscode:
@Callable(i) func vote(amount: Int, address: String) = { let currentKey = toBase58String(i.caller.bytes) let xxxInvestorBalance = currentKey + "_" + "ib" let xxxStartupFund = address + "_" + "sf" let xxxStartupVotes = address + "_" + "sv" let flagKey = address + "_" + currentKey let flag = match getInteger(this, flagKey) { case a:Int => a case _ => 0 } let currentAmount = match getInteger(this, xxxInvestorBalance) { case a:Int => a case _ => 0 } let currentVotes = match getInteger(this, xxxStartupVotes) { case a:Int => a case _ => 0 } let currentFund = match getInteger(this, xxxStartupFund) { case a:Int => a case _ => 0 } if (amount <= 0) then throw("Can't withdraw negative amount") else if (amount > currentAmount) then throw("Not enough balance!") else if (flag > 0) then throw("Only one vote per project is possible!") else WriteSet([ DataEntry(xxxInvestorBalance, currentAmount - amount), DataEntry(xxxStartupVotes, currentVotes + 1), DataEntry(flagKey, 1), DataEntry(xxxStartupFund, currentFund + amount) ]) }
Im Data Warehouse sehen wir alle notwendigen Einträge für die Neli-Adresse:

Cooper stimmte auch für das Neli-Projekt.

Werfen wir einen Blick auf den Funktionscode von getFunds . Neli muss mindestens 2 Stimmen sammeln, um Geld vom DAO abheben zu können.

Neli wird die Hälfte des ihr anvertrauten Betrags abheben:
broadcast(invokeScript({dappAddress: address(env.accounts[1]), call:{function:"getFunds",args:[{type:"integer", value: 500000}]}, payment: []}))

Sie hat Erfolg, das heißt, das DAO funktioniert!
Wir haben uns den Prozess der Erstellung eines DAO in der Sprache von RIDE4DAPPS angesehen .
In den folgenden Abschnitten werden wir uns eingehender mit Code-Refactoring und Falltests befassen.
Vollversion des Codes in Waves RIDE IDE:
# In this example multiple accounts can deposit their funds to DAO and safely take them back, no one can interfere with this. # DAO participants can also vote for particular addresses and let them withdraw invested funds then quorum has reached. # An inner state is maintained as mapping `address=>waves`. # https:
Erster Teil
Github-Code
Wellen FAHRT IDE
Ankündigung des Grant-Programms