Jak napisać smart kontrakt WebAssembly w sieci Ontology? Część 1: Rdza

Jak napisać smart kontrakt WebAssembly w sieci Ontology? Część 1: Rdza

Technologia Ontology Wasm zmniejsza koszty migracji inteligentnych kontraktów dApp ze złożoną logiką biznesową do łańcucha bloków, tym samym znacznie wzbogacając ekosystem dApp.

Teraz Ontologia Wasm Jednocześnie obsługuje zarówno programowanie w języku Rust, jak i C++. Język Rust lepiej obsługuje Wasm, a generowany kod bajtowy jest prostszy, co może jeszcze bardziej obniżyć koszty połączeń kontraktowych. Więc, jak wykorzystać Rust do opracowania kontraktu w sieci Ontology?

Opracowanie kontraktu WASM z Rust

Utwórz umowę

Ładunek to dobre narzędzie do tworzenia projektów i zarządzania pakietami dla rozwoju Rust, które pomaga programistom lepiej zorganizować interakcję kodu i bibliotek innych firm. Aby utworzyć nowy kontrakt Ontology Wasm, po prostu uruchom następujące polecenie:

Jak napisać smart kontrakt WebAssembly w sieci Ontology? Część 1: Rdza

Struktura projektu, którą generuje:

Jak napisać smart kontrakt WebAssembly w sieci Ontology? Część 1: Rdza

Plik Cargo.toml służy do konfigurowania podstawowych informacji o projekcie i informacji o bibliotekach zależnych. Sekcja [lib] pliku musi być ustawiona na crate-type = ["cdylib"]. Plik lib.rs służy do zapisywania kodu logiki kontraktu. Ponadto należy dodać parametry zależności do sekcji [dependencies] pliku konfiguracyjnego Cargo.toml:

Jak napisać smart kontrakt WebAssembly w sieci Ontology? Część 1: Rdza

Dzięki tej zależności programiści mogą wywoływać interfejsy, które wchodzą w interakcje z łańcuchem blokowym Ontology i narzędziami, takimi jak parametr serializacji.

Funkcja wprowadzania umów

Każdy program ma funkcję wejściową, taką jak główna funkcja, którą zwykle widzimy, ale umowa nie ma głównej funkcji. Kiedy kontrakt Wasm jest tworzony przy użyciu Rust, domyślna funkcja invoke jest używana jako funkcja wejściowa do korzystania z kontraktu. Nazwa funkcji w Rust będzie niejasna podczas kompilowania kodu źródłowego Rust do kodu bajtowego, który może być wykonywany przez maszynę wirtualną. Aby uniemożliwić kompilatorowi generowanie nadmiarowego kodu i zmniejszyć rozmiar kontraktu, funkcja invoke dodaje adnotację #[no_mangle].

W jaki sposób funkcja invoke pobiera parametry do wykonania transakcji?

Biblioteka ontio_std udostępnia funkcję runtime::input(), która pobiera parametry potrzebne do wykonania transakcji. Deweloperzy mogą używać ZeroCopySource do deserializacji wynikowej tablicy bajtów. W którym pierwsza tablica odczytanych bajtów to nazwa metody invoke, po której następują parametry metody.

W jaki sposób zwracany jest wynik realizacji umowy?

Funkcja runtime::ret udostępniana przez bibliotekę ontio_std zwraca wynik wykonania metody.

Gotowa funkcja invoke wygląda następująco:

Jak napisać smart kontrakt WebAssembly w sieci Ontology? Część 1: Rdza

Serializacja i deserializacja danych kontraktu

W procesie opracowywania kontraktów programiści zawsze napotykają problemy z serializacją i deserializacją, w szczególności z tym, jak przechowywać dane typu struct w bazie danych i jak deserializować tablicę bajtów odczytaną z bazy danych, aby uzyskać typ danych struct.

Biblioteka ontio_std udostępnia interfejsy dekodera i kodera do serializacji i deserializacji danych. Pola struktury implementują również interfejsy dekodera i kodera, dzięki czemu struktura może być serializowana i deserializowana. Wystąpienia klasy Sink są wymagane w przypadku serializacji różnych typów danych. Instancja klasy Sink ma pole typu set buf, które przechowuje dane typu bajtowego, a wszystkie serializowane dane są przechowywane w buf.

W przypadku danych o stałej długości (np. byte, u16, u32, u64 itd.) dane są bezpośrednio konwertowane na tablicę bajtów, a następnie przechowywane w buf; w przypadku danych o nieokreślonej długości długość musi być najpierw serializowana, a następnie Ddata (na przykład liczby całkowite bez znaku o nieznanym rozmiarze, w tym u16, u32 lub u64 itp.).

Deserializacja jest dokładnym przeciwieństwem. Dla każdej metody serializacji istnieje odpowiednia metoda deserializacji. Deserializacja wymaga użycia instancji klasy Source. Ta instancja klasy ma dwa pola buf i poz. Buf służy do przechowywania danych do deserializacji, a pos służy do przechowywania bieżącej pozycji odczytu. Kiedy odczytywany jest określony typ danych, jeśli znasz ich długość, możesz je odczytać bezpośrednio, w przypadku danych o nieznanej długości — najpierw przeczytaj długość, a następnie przeczytaj zawartość.

Dostęp i aktualizacja danych w łańcuchu

ontologia-wasm-cdt-rust - hermetyzował metodę operacyjną do pracy z danymi w łańcuchu, która jest wygodna dla programistów do implementacji operacji, takich jak dodawanie, usuwanie, zmiana i odpytywanie danych w łańcuchu w następujący sposób:

  • baza danych::pobierz(klucz) - służy do żądania danych z łańcucha i żądań kluczowych implementacji interfejsu AsRef;
  • baza danych::put(klucz, wartość) - służy do przechowywania danych w sieci. Key żąda implementacji interfejsu AsRef, a value żąda implementacji interfejsu Encoder;
  • baza danych::usuń(klucz) - służy do usuwania danych z łańcucha, a klucz żąda implementacji interfejsu AsRef.

Testowanie kontraktu

Gdy implementowane są metody kontraktu, potrzebujemy dostępu do danych w łańcuchu i potrzebujemy odpowiedniej maszyny wirtualnej do wykonania kodu bajtowego kontraktu, więc generalnie konieczne jest wdrożenie kontraktu w łańcuchu do testowania. Ale ta metoda testowania jest problematyczna. Aby ułatwić programistom testowanie kontraktów, biblioteka ontio_std udostępnia próbny moduł do testowania. Ten moduł zapewnia symulację danych w obwodzie, ułatwiając programistom testowanie jednostkowe metod zawartych w kontrakcie. Można znaleźć konkretne przykłady tutaj.

Debugowanie kontraktu

console::debug(msg) wyświetla informacje debugowania podczas debugowania kontraktu. Informacje msg zostaną dodane do pliku dziennika węzła. Warunkiem wstępnym jest ustawienie poziomu pliku dziennika na tryb debugowania, gdy uruchomiony jest lokalny węzeł testowy Ontologii.

runtime::notify(msg) wyprowadza odpowiednie informacje debugowania podczas debugowania kontraktu. Ta metoda przechowuje informacje wprowadzone do łańcucha i może być wyszukiwana z łańcucha za pomocą metody getSmartCodeEvent.

Artykuł został przetłumaczony przez redakcję Hashrate&Shares specjalnie dla OntologyRussia. płakać

jesteś programistą? Dołącz do naszej społeczności technicznej pod adresem Discord. Także przyjrzyj się Centrum programistów na naszej stronie internetowej, gdzie można znaleźć narzędzia dla programistów, dokumentację i nie tylko.

Ontologia

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

Dodaj komentarz