Pod koniec 2017 roku świat oszalał na punkcie kryptowalut. Wartość Bitcoina (BTC) i Ether (ETH) osiągnęła astronomiczne kwoty. Ludzie, którzy nigdy nie inwestowali, nagle kompulsywnie zaczęli kupować i sprzedawać kryptowaluty na giełdach. Jednak dla mnie największym odkryciem związanym z kryptowalutami jest blockchain — technologia, na której oparte są Bitcoiny, Ether i inne; technologia, która może zmienić nasze finanse, politykę (np. system głosowania w wyborach) i oczywiście systemy IT. Blockchain pozwala nam tworzyć aplikacje, które nie zależą od żadnej organizacji ani nie mają scentralizowanej struktury.


Kuba Wilczek. Ruby on Rails developer w krakowskim software house Nopio. Momentami front-end developer, zdarzyło mu się też w przeszłości pisać w Javie i C++. Od niedawna zafascynowany Blockchainem i to temu tematowi poświęca najwięcej uwagi, eksperymentując, prezentując, wertując artykuły i pisząc własne. Jego hobby jest triathlon – w wolnym czasie biega, pływa lub jeździ na rowerze.


Ten tutorial pokazuje, jak pracować z blockchainem przy użyciu języka Ruby i jak stworzyć zdecentralizowaną aplikację opartą na Ruby on Rails. Nie obejmuje on szerokiej wiedzy o blockchainie, a jedynie wprowadzenie, które pomaga zrozumieć, jak on działa i jak zaprojektować architekturę dApp.

Zdecentralizowana aplikacja

Zanim zaczniemy wdrażać naszą aplikację, musimy zrozumieć różnicę pomiędzy scentralizowaną aplikacją, a systemem opartym na blockchainie. W standardowym przypadku główna część to serwer, który przechowuje kod aplikacji i łączy się z bazą danych, która przechowuje wszystkie niezbędne informacje. Użytkownik wchodzi w interakcję z aplikacją za pośrednictwem interfejsu użytkownika, który jest częścią serwera lub jest z nim ściśle związany.

W zdecentralizowanej aplikacji nie mamy strony serwera, ponieważ nie chcemy przechowywać żadnych danych na podatnych na ataki serwerach. Kod jest przechowywany w blockchainie, a użytkownicy łączą się bezpośrednio z nim za pośrednictwem interfejsu użytkownika. Wszystkie działania, takie jak tworzenie i podpisywanie transakcji, powinny być wykonywane po stronie klienta. Interfejs umożliwia tylko wołanie metod smart contractów. Aplikacja po stronie klienta musi znać adres zdeployowanego kontraktu w blockchainie.

Ok… dlaczego w tym tutorialu skoncentrowałem się na tym, jak połączyć blockchain z Ruby on Rails? Czy nie wspomniałem tylko, że zdecentralizowane aplikacje nie zawierają serwera? Tak, to prawda. Dlaczego to robimy? Ponieważ… możemy. Wszystko sprowadza się do bezpieczeństwa i roli jaką odgrywa w naszym systemie.

Kiedy korzystasz tylko z interfejsu do transakcji z blockchain, nie przesyłasz swojego klucza prywatnego — korzystając z serwera musisz przekazać go za pomocą formularza. Tak samo logujemy się przecież do banku — dlaczego więc powiedziałem, że jest to niebezpieczne? Różnica polega na tym, że bank jest zaufaną instytucją, dodaje poczucie odpowiedzialności do twoich transakcji. Kiedy mamy do czynienia z dApp, tak naprawdę nie wiesz, co stanie się z kluczem, który wysyłasz.

Tworzenie aplikacji

W tym tutorialu stworzymy aplikację do głosowania, co zamawiamy dzisiaj na lunch. Przeanalizujmy wymagania:

  • Administrator powinien mieć możliwość tworzenia głosowań, wybierania, którzy użytkownicy mogą głosować i typy posiłków, na które należy głosować.
  • Użytkownicy mogą głosować (tylko raz) i wyświetlać wyniki. Każdy użytkownik jest zobowiązany do posiadania konta na blockchain (portfela).

Zanim zabierzemy się do pisania kodu, musimy się przygotować. Aby przetestować i skonfigurować naszą aplikację, musimy uruchomić node’a na naszym komputerze. Wybrałem parity, ponieważ jest obsługiwane przez ethereum.rb — gem, którego użyjemy, a także ma wbudowany interfejs do interakcji z blockchainem. W repozytorium ethereum.rb GitHub można znaleźć szczegółowe instrukcje dotyczące instalacji parity:

https://github.com/EthWorks/ethereum.rb/blob/master/PREREQUISITES.md#installing-prerequisites

Aby uruchomić dev (lokalny) blockchain wpisujemy w konsolę parity –chain = dev. Następnie wchodzimy na localhost:8180 i sprawdzamy czy wyświetlił się interfejs parity. W aplikacji będziemy potrzebować dwóch portfeli dla konta administratora i użytkownika. Można je utworzyć za pomocą interfejsu parity. Aby uzyskać klucz prywatny, przejdź do menedżera konta, wybierz konto i kliknij ‘Eksportuj’. Wyeksportowane zostaną dane portfela w postaci pliku JSON.

Aby zaszyfrować klucz, wystarczy wpisać w konsole rails następującą komendę:

Bardzo ważne jest, aby przechowywać klucz prywatny w bezpiecznym miejscu! Tak, wiem, że to instancja DEV i nie ma ryzyka, ale warto od początku wdrożyć dobre nawyki, by później nie martwić się, że przez pomyłkę podzieliło się swój prawdziwy klucz prywatny.

Po skonfigurowaniu środowiska stworzymy smart contract, który jest głównym elementem każdej zdecentralizowanej aplikacji blockchain. Nie chcę skupiać się tutaj na implementacji smart contractów, ponieważ w Internecie można znaleźć wiele artykułów i tutoriali na ten temat. Na oficjalnej stronie Ethereum można również przeczytać dokumentację Solidity z przykładami.

Kod

Nasza umowa, VotingContract, przechowuje dwie mapy (hashe w Ruby):

  • Licznik głosów na posiłki.
  • Flaga, czy dany użytkownik już głosował (nie zezwalamy na więcej niż jeden głos).

Zawiera również listę dostępnych posiłków oraz użytkowników dopuszczonych do głosowania, oba są ustawiane w konstruktorze.

Mamy dwie główne metody: jedna do głosowania i jedna do pobierania wyników, a także modyfikatory używane do sprawdzenia, czy użytkownicy mogą brać udział w głosowaniu i jeszcze nie zagłosowali. Zazwyczaj kontrakt należy umieścić w folderze app/contracts/ w naszej aplikacji.

Zajmijmy się Ruby

Wreszcie możemy przejść do kodowania w Rubym! Z gemów do obsługi Ethereum w rubym wybrałem ethereum.rb. To mój osobisty wybór, być może przyciągnęła mnie liczba gwiazdek na GitHubie. 😉

Ten gem pozwala nam wykonywać podstawowe działania na kontrakcie w blockchainie. Dodatkowo wykorzystamy eth gem, który pomaga tworzyć i podpisywać transakcje.

Aby używać gemów dodaj je do Gemfile i uruchom instalację pakietów.

Szkielet aplikacji

Potrzebujemy dwóch modeli w naszej aplikacji o nazwie: User i Voting.

W przypadku pierwszego polecam utworzyć go za pomocą devise’a, a następnie dodać pole wallet_address, które powinno zostać uzupełniane podczas rejestracji. Admina możemy stworzyć dodając pole admin do naszego modelu i ustawić go jako true w konsoli.

Model Voting będzie przechowywać informacje o utworzonych głosowaniach: adres smart contractu oraz posiłki, które możemy wybrać podczas głosowania. User i Voting są połączone relacją wiele do wielu: wielu użytkowników może brać udział w wielu głosowaniach.

Pełny kod tej aplikacji znajduje się w repozytorium na GitHub:

https://github.com/nopio/ethereum_voting_example

Zabawa z blockchainem

Po utworzeniu szkieletu aplikacji zastanówmy się nad akcjami, które należy wykonać aby zdeployować i korzystać z kontraktu.

Ponieważ nie można zmienić smart contractu po jego zapisaniu w blockchainie, wszystkie dane muszą zostać ustawione, zanim to nastąpi. Dlatego, gdy administrator tworzy głosowanie, musi najpierw wybrać użytkowników i posiłki. Po utworzeniu i wrzuceniu smart contactu w blockchain musimy przechowywać jego adres w naszej lokalnej bazie danych. Przechowywanie tego adresu jest ważne, ponieważ będzie on dla nas odwołaniem do blockchaina, dzięki czemu możemy dokonać transakcji i pobrać dane zapisane w smart contract, takie jak liczba głosów.

Aby wdrożyć contract, musimy zrobić kilka rzeczy:

1. Utworzyć Ethereum :: Contract z parametrami: file — ścieżka naszego pliku kontraktu (ethereum.rb pozwala na utworzenie umowy z abi, więc zamiast do pliku kontraktu możemy przekazać ścieżkę do pliku abi).

2. Następny krok to utworzenie transakcji i podpisanie jej za pomocą klucza prywatnego (użytkownika dokonującego transakcji).

3. Wreszcie, wrzucamy nasz smart contract do chaina. Używamy funkcji deploy_and_wait, która czeka, aż blok w blockchainie zostanie wykopany. W naszym przypadku zaleca się użycie tej funkcji w celu uzyskania adresu kontraktu. Proces ten może zająć dużo czasu podczas interakcji z prawdziwą, produkcyjną siecią, w związku z tym chcielibyśmy, aby na produkcji działał on w tle.

4. Mamy już nasz kontrakt w blockchainie — dobra robota. Możemy teraz wywoływać jego metody i dokonywać transakcji. Wywołanie metod (widokowych, kiedy pobieramy dane) jest bardzo proste. Wystarczy, że stworzymy instancję kontraktu z adresem w blockchainie i wywołamy funkcję total_votes_for, która zwraca liczbę głosów na dany posiłek. Zauważ, że w definicji kontraktu znajduje się funkcja totalVotesFor (camel case), ale dzięki gemowi ethereum.rb, który używamy jej w postaci snake case.

Jedyna różnica między wywoływaniem transakcji polega na tym, że każda transakcja powinna być podpisana przez użytkownika. Podobnie do deployowania umowy tworzymy instancję kontraktową i podpisujemy ją. Następnie możemy wykonać transakcji i zagłosować na konkretny posiłek.

Podsumowanie

Stworzyliśmy prostą aplikację do głosowania, wykorzystującą Ruby on Rails i blockchain. Działa i wygląda dobrze, ale jak wspomniałem wcześniej, nie jest doskonała i nie jest zgodna z dobrymi praktykami działania na blockchainie. Tworząc bezpieczną aplikację w Rubym powinniśmy unikać tworzenia aplikacji blockchainowej z przetwarzaniem po stronie serwera! Więc dlaczego zrobiłem ten tutorial? Dlaczego ktoś stworzył ten gem?

Są co najmniej dwa przypadki użycia dla tego rodzaju aplikacji. W naszej pracy jest wiele aplikacji, które tworzymy wewnętrznie dla naszej firmy, przyjaciół itp. Jeśli ufasz instytucji, która jest odpowiedzialna za aplikację, dobrym pomysłem może być utworzenie go w Ruby ​​– jest po prostu łatwiej. Co więcej, użyjmy specjalnych portfeli z małą ilością ETH, a może z tokenami (specjalne tokeny tylko dla twojej firmy, instytucji, niektórych grup), abyśmy nie stracili zbyt wielu oszczędności.

Drugim pomysłem na wykorzystanie tych technologii jest stworzenie interfejsu do tworzenia i wdrażania smart contractów, jako administrator w naszej aplikacji. W tym podejściu tylko jedna osoba ma dostęp do aplikacji, więc jest odpowiedzialna za aplikację i swój klucz prywatny. Jest to łatwiejszy sposób niż użycie wiersza poleceń, zwłaszcza gdy trzeba sparametryzować każdą umowę, a osoba, która to robi, nie jest zaznajomiona z technikami technicznymi.

Myślę, że masz także wiele sposobów, aby zachować bezpieczeństwo. Mam nadzieję, że zdobyta tutaj wiedza pomoże ci zrozumieć, jak działają aplikacje blockchain i aplikacje zdecentralizowane.

Jeśli masz jakieś pytania odnośnie tego tutoriala — nie wahaj się, pisz w komentarzu!


Wszystkim zainteresowanym blockchainem polecamy tekst pt. Blockchain nie zna pojęcia czasu. Trzeba to zmienić.

Zdjęcie główne artykułu pochodzi z pexels.com.

Zapraszamy do dyskusji
Nie ma więcej wpisów

Send this to a friend