Cum se scrie un contract inteligent WebAssembly în rețeaua Ontology? Partea 1: Rugina

Cum se scrie un contract inteligent WebAssembly în rețeaua Ontology? Partea 1: Rugina

Tehnologia Ontology Wasm reduce costul migrării contractelor inteligente dApp cu o logică complexă de afaceri către blockchain, îmbogățind astfel foarte mult ecosistemul dApp.

în prezent Ontologie Wasm Suportă simultan atât dezvoltarea Rust, cât și C++. Limbajul Rust acceptă mai bine Wasm, iar bytecode-ul generat este mai simplu, ceea ce poate reduce și mai mult costul apelurilor contractuale. Asa de, cum să folosiți Rust pentru a dezvolta un contract pe rețeaua Ontology?

Dezvoltarea unui contract WASM cu Rust

Creați un contract

încărcătură este un instrument bun de creare a proiectelor și de gestionare a pachetelor pentru dezvoltarea Rust, care ajută dezvoltatorii să organizeze mai bine interacțiunea dintre codul și bibliotecile terțe. Pentru a crea un nou contract Ontology Wasm, pur și simplu rulați următoarea comandă:

Cum se scrie un contract inteligent WebAssembly în rețeaua Ontology? Partea 1: Rugina

Structura proiectului pe care o generează:

Cum se scrie un contract inteligent WebAssembly în rețeaua Ontology? Partea 1: Rugina

Fișierul Cargo.toml este folosit pentru a configura informațiile de bază ale proiectului și informațiile dependente de bibliotecă. Secțiunea [lib] a fișierului trebuie să fie setată la crate-type = ["cdylib"]. Fișierul lib.rs este folosit pentru a scrie codul logic al contractului. În plus, trebuie să adăugați parametri de dependență la secțiunea [dependențe] din fișierul de configurare Cargo.toml:

Cum se scrie un contract inteligent WebAssembly în rețeaua Ontology? Partea 1: Rugina

Cu această dependență, dezvoltatorii pot apela interfețe care interacționează cu blockchain-ul Ontology și instrumente precum parametrul de serializare.

Funcția de înscriere a contractului

Fiecare program are o funcție de intrare, ca și funcția principală pe care o vedem de obicei, dar contractul nu are o funcție principală. Când un contract Wasm este dezvoltat folosind Rust, funcția de invocare implicită este utilizată ca funcție de intrare pentru a utiliza contractul. Numele unei funcții în Rust va fi neclar când se compilează codul sursă Rust în bytecode care poate fi executat de o mașină virtuală. Pentru a împiedica compilatorul să genereze cod redundant și pentru a reduce dimensiunea contractului, funcția de invocare adaugă adnotarea #[no_mangle].

Cum obține funcția de invocare parametrii pentru a executa o tranzacție?

Biblioteca ontio_std oferă o funcție runtime::input() pentru a obține parametrii pentru a executa o tranzacție. Dezvoltatorii pot folosi ZeroCopySource pentru a deserializa matricea de octeți rezultată. În care prima matrice de octeți citiți este numele metodei invoke, urmat de parametrii metodei.

Cum se returnează rezultatul executării contractului?

Funcția runtime::ret furnizată de biblioteca ontio_std returnează rezultatul execuției unei metode.

Funcția de invocare finalizată arată astfel:

Cum se scrie un contract inteligent WebAssembly în rețeaua Ontology? Partea 1: Rugina

Serializarea și deserializarea datelor contractului

În procesul de dezvoltare a contractelor, dezvoltatorii se confruntă întotdeauna cu probleme cu serializarea și deserializarea, în special cu modul de stocare a unui tip de date struct în baza de date și cum să deserializeze o matrice de octeți citită din baza de date pentru a obține un tip de date struct.

Biblioteca ontio_std oferă interfețe de decodor și codificator pentru serializarea și deserializarea datelor. Câmpurile unei structuri implementează, de asemenea, interfețele decodorului și codificatorului, astfel încât structura să poată fi serializată și deserializată. Instanțele clasei Sink sunt necesare atunci când sunt serializate diferite tipuri de date. O instanță a clasei Sink are un buf de câmp de tip set care stochează datele de tip octet, iar toate datele serializate sunt stocate în buf.

Pentru date cu lungime fixă ​​(de exemplu: octet, u16, u32, u64, etc.), datele sunt convertite direct într-o matrice de octeți și apoi stocate în buf; pentru datele de lungime nefixă, lungimea trebuie serializată mai întâi, apoi Ddata (de exemplu, numere întregi fără semn de dimensiune necunoscută, inclusiv u16, u32 sau u64 etc.).

Deserializarea este exact opusul. Pentru fiecare metodă de serializare, există o metodă de deserializare corespunzătoare. Deserializarea necesită utilizarea instanțelor clasei Source. Această instanță de clasă are două câmpuri buf și pos. Buf este folosit pentru a stoca datele care urmează să fie deserializate și pos este folosit pentru a stoca poziția curentă de citire. Când un anumit tip de date este citit, dacă îi cunoașteți lungimea, îl puteți citi direct, pentru date de lungime necunoscută - citiți mai întâi lungimea, apoi citiți conținutul.

Accesați și actualizați datele din lanț

ontologie-wasm-cdt-rugina - a încapsulat o metodă operațională de lucru cu datele din lanț, care este convenabilă pentru dezvoltatori să implementeze operațiuni precum adăugarea, ștergerea, modificarea și interogarea datelor în lanț, după cum urmează:

  • baza de date::get(cheie) - este folosit pentru a solicita date din lanț, iar cheia solicită implementarea interfeței AsRef;
  • baza de date::put(cheie, valoare) - folosit pentru stocarea datelor în rețea. Key solicită implementarea interfeței AsRef, iar value solicită implementarea interfeței Encoder;
  • baza de date::delete(cheie) - este folosit pentru a elimina datele din lanț, iar cheia solicită implementarea interfeței AsRef.

Testarea contractelor

Atunci când metodele unui contract sunt implementate, avem nevoie de acces la datele din lanț și avem nevoie de o mașină virtuală adecvată pentru a executa bytecode-ul contractului, așa că în general este necesar să implementăm contractul pe lanț pentru testare. Dar această metodă de testare este problematică. Pentru a facilita testarea contractelor de către dezvoltatori, biblioteca ontio_std oferă un modul simulat pentru testare. Acest modul oferă o simulare a datelor din circuit, facilitând pentru dezvoltatori testarea unitară a metodelor din contract. Pot fi găsite exemple specifice aici.

Depanare contract

console::debug(msg) afișează informații de depanare în timpul depanării unui contract. Informațiile mesajului vor fi adăugate la fișierul jurnal al nodului. O condiție prealabilă este să setați nivelul fișierului jurnal în modul de depanare atunci când rulează nodul de testare Ontology local.

runtime::notify(msg) afișează informațiile corespunzătoare de depanare în timp ce contractul este depanat. Această metodă va stoca informațiile introduse în lanț și poate fi interogată din lanț folosind metoda getSmartCodeEvent.

Articolul a fost tradus de editorii Hashrate&Shares în special pentru OntologyRussia. clic

Ești dezvoltator? Alăturați-vă comunității noastre tehnologice la Discordie. De asemenea, aruncați o privire la Centrul pentru dezvoltatori pe site-ul nostru web, unde puteți găsi instrumente pentru dezvoltatori, documentație și multe altele.

ontologie

Sursa: www.habr.com

Adauga un comentariu