Cum să construiți, să implementați și să testați Waves RIDE dApp
Buna ziua! În acest articol vă voi arăta cum să scrieți și să rulați o aplicație dApp obișnuită pe un nod Waves. Să ne uităm la instrumentele, metodele și un exemplu de dezvoltare necesare.
Schema de dezvoltare pentru dApps și aplicațiile obișnuite este aproape aceeași:
Scrierea codului
Scrierea testelor automate
Lansați aplicația
Testăm
Instrumente
1. docker pentru a rula nodul și Waves Explorer
Dacă nu doriți să porniți un nod, puteți sări peste acest pas. La urma urmei, există o rețea de testare și experimentală. Dar fără a vă implementa propriul nod, procesul de testare poate dura.
Veți avea nevoie în mod constant de conturi noi cu jetoane de testare. Robinetul de rețea de testare transferă 10 UNDURI la fiecare 10 minute.
Timpul mediu de blocare în rețeaua de testare este de 1 minut, în nod – 15 secunde. Acest lucru este vizibil mai ales atunci când o tranzacție necesită confirmări multiple.
Memorarea în cache agresivă este posibilă pe nodurile de testare publice.
De asemenea, pot fi temporar indisponibile din cauza întreținerii.
De acum înainte voi presupune că lucrați cu propriul nod.
Instalați Surfboard, un instrument care vă permite să rulați teste pe un nod existent.
npm install -g @waves/surfboard
3. Plugin Visual Studio Code
Acest pas este opțional dacă nu sunteți un fan al IDE-urilor și preferați editorii de text. Toate instrumentele necesare sunt utilitare de linie de comandă. Dacă utilizați vim, acordați atenție pluginului vim-ride.
Descărcați și instalați codul Visual Studio: https://code.visualstudio.com/
Deschideți VS Code și instalați pluginul waves-ride:
docker run -d -e API_NODE_URL=http://localhost:6869 -e NODE_LIST=http://localhost:6869 -p 3000:8080 wavesplatform/explorer
Deschideți un browser și accesați http://localhost:3000. Veți vedea cât de repede este construit un circuit de nod local gol.
Waves Explorer afișează o instanță de nod local
Structura RIDE și instrumentul pentru placă de surf
Creați un director gol și rulați comanda în el
surfboard init
Comanda inițializează un director cu structura proiectului, aplicații „hello world” și teste. Dacă deschideți acest folder cu VS Code, veți vedea:
Surfboard.config.json
Sub folderul ./ride/ veți găsi un singur fișier wallet.ride - directorul în care se află codul dApp. Vom analiza pe scurt dApps în blocul următor.
Sub folderul ./test/ veți găsi un fișier *.js. Testele sunt stocate aici.
./surfboard.config.json – fișier de configurare pentru rularea testelor.
Envs este o secțiune importantă. Fiecare mediu este configurat astfel:
Punctul final API REST al nodului care va fi folosit pentru a lansa dApp și CHAIN_ID-ul rețelei.
Expresie secretă pentru un cont cu jetoane care vor fi sursele jetoanelor dvs. de testare.
După cum puteți vedea, surfboard.config.json acceptă mai multe medii în mod implicit. Valoarea implicită este mediul local (cheia defaultEnv este un parametru modificabil).
Aplicație demo pentru portofel
Această secțiune nu este o referință la limbajul RIDE. Mai degrabă, o privire asupra aplicației pe care o implementăm și o testăm pentru a înțelege mai bine ce se întâmplă în blockchain.
Să ne uităm la o aplicație demo simplă Wallet. Oricine poate trimite jetoane la o adresă dApp. Îți poți retrage doar WAVE-urile. Două funcții @Callable sunt disponibile prin InvokeScriptTransaction:
deposit()care necesită o plată atașată în WAVES
withdraw(amount: Int)care returnează jetoane
De-a lungul ciclului de viață dApp, structura (adresă → sumă) va fi menținută:
Acțiune
Stare rezultată
inițială
gol
Alice depune 5 UNDURI
alice-adresă → 500000000
Bob depune 2 VALURI
alice-adresă → 500000000
bob-adresă → 200000000
Bob retrage 7 VALURI
NEGAT!
Alice retrage 4 VALURI
alice-adresă → 100000000
bob-adresă → 200000000
Iată codul pentru a înțelege pe deplin situația:
# In this example multiple accounts can deposit their funds and safely take them back. No one can interfere with this.
# An inner state is maintained as mapping `address=>waves`.
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
@Callable(i)
func deposit() = {
let pmt = extract(i.payment)
if (isDefined(pmt.assetId))
then throw("works with waves only")
else {
let currentKey = toBase58String(i.caller.bytes)
let currentAmount = match getInteger(this, currentKey) {
case a:Int => a
case _ => 0
}
let newAmount = currentAmount + pmt.amount
WriteSet([DataEntry(currentKey, newAmount)])
}
}
@Callable(i)
func withdraw(amount: Int) = {
let currentKey = toBase58String(i.caller.bytes)
let currentAmount = match getInteger(this, currentKey) {
case a:Int => a
case _ => 0
}
let newAmount = currentAmount - amount
if (amount < 0)
then throw("Can't withdraw negative amount")
else if (newAmount < 0)
then throw("Not enough balance")
else ScriptResult(
WriteSet([DataEntry(currentKey, newAmount)]),
TransferSet([ScriptTransfer(i.caller, amount, unit)])
)
}
@Verifier(tx)
func verify() = false
Pluginul VSCode acceptă compilarea continuă în timpul editării unui fișier. Prin urmare, puteți monitoriza oricând erorile în fila PROBLEME.
Dacă doriți să utilizați un editor de text diferit la compilarea fișierului, utilizați
surfboard compile ride/wallet.ride
Aceasta va scoate o serie de coduri RIDE compilate base64.
Scriptul de testare pentru „wallet.ride”
Să ne uităm la fișier de testare. Funcționat de cadrul JavaScript Mocha. Există o funcție „Înainte” și trei teste:
„Înainte” finanțează mai multe conturi prin MassTransferTransaction, compilează scriptul și îl implementează în blockchain.
„Poate depune” trimite o tranzacție InvokeScript în rețea, activând funcția de depozit () pentru fiecare dintre cele două conturi.
„Nu se poate retrage mai mult decât a fost depus” teste că nimeni nu poate fura jetoanele altora.
Cecurile „Poate depune” că retragerile sunt procesate corect.
Rulați teste de la Surfboard și analizați rezultatele în Waves Explorer
Pentru a rula testul, alergați
surfboard test
Dacă aveți mai multe scripturi (de exemplu, aveți nevoie de un script de implementare separat), puteți rula
surfboard test my-scenario.js
Surfboard va colecta fișierele de testare în folderul ./test/ și va rula scriptul pe nodul care este configurat în surfboard.config.json. După câteva secunde vei vedea ceva de genul:
wallet test suite
Generating accounts with nonce: ce8d86ee
Account generated: foofoofoofoofoofoofoofoofoofoofoo#ce8d86ee - 3M763WgwDhmry95XzafZedf7WoBf5ixMwhX
Account generated: barbarbarbarbarbarbarbarbarbar#ce8d86ee - 3MAi9KhwnaAk5HSHmYPjLRdpCAnsSFpoY2v
Account generated: wallet#ce8d86ee - 3M5r6XYMZPUsRhxbwYf1ypaTB6MNs2Yo1Gb
Accounts successfully funded
Script has been set
√ Can deposit (4385ms)
√ Cannot withdraw more than was deposited
√ Can withdraw (108ms)
3 passing (15s)
Ura! Testele trecute. Acum să aruncăm o privire la ceea ce se întâmplă când utilizați Waves Explorer: uitați-vă la blocuri sau lipiți una dintre adresele de mai sus în căutare (de exemplu, corespunzătoare wallet#. Acolo puteți găsi istoricul tranzacțiilor, starea dApp, fișierul binar decompilat.
Waves Explorer. O aplicație care tocmai a fost implementată.
Configurarea Waves Keeper pentru a funcționa cu un nod local
2. Importați o frază secretă cu jetoane pentru rețea? Pentru simplitate, utilizați sămânța inițială a nodului dvs.: waves private node seed with waves tokens. Abordare: 3M4qwDomRabJKLZxuXhwfqLApQkU592nWxF.