Kontrakty Ethereum Oracle: konfiguracja i orientacja

Opublikowany: 2022-03-11

Inteligentne kontrakty Ethereum to coś więcej niż tylko „nowa gorąca rzecz”. Wierzę, że oni (lub coś z nimi powiązane) są w stanie zmienić sposób, w jaki ludzie prowadzą ze sobą interesy w nadchodzącej nowej erze Internetu. Czas pokaże, czy tak jest.

Jest to pierwszy z trzyczęściowego artykułu na temat rozwoju inteligentnych kontraktów Ethereum za pomocą Solidity, w szczególności badającego wykorzystanie kontraktów z tak zwanymi „wyroczniami” – które są w zasadzie kontraktami, które pompują dane do blockchaina do wykorzystania przez inne inteligentne kontrakty.

  • Część 1: Wprowadzenie do programowania z Truffle i konfiguracja projektu do dalszych eksperymentów
  • Część 2: Zagłębianie się w kod w celu głębszego zbadania
  • Część 3: Konceptualne omówienie wyroczni z inteligentnymi kontraktami

Celem tej pierwszej części serii nie jest zagłębianie się w koncepcję kontraktów wyroczni, stojącą za nimi filozofię, ani nawet bardzo głęboko w to, czym one są; celem tej części naszego samouczka dotyczącego wyroczni Ethereum jest po prostu:

  • Przygotuj się do budowania inteligentnych kontraktów z Truffle.
  • Zbuduj projekt inteligentnego kontraktu, który posłuży nam w częściach 2 i 3.
  • Przedstaw kilka pojęć związanych z inteligentnymi kontraktami Ethereum i kodowaniem inteligentnych kontraktów.
  • Wprowadź cykl kompilacji/uruchomienia/debugowania za pomocą Truffle i inteligentnych kontraktów.

Definicja: Wyrocznia. Sposób dla inteligentnych kontraktów na dostęp do danych ze świata poza łańcuchem bloków. Same wyrocznie, będące rodzajem inteligentnych kontraktów, pobierają dane ze świata zewnętrznego i umieszczają je w łańcuchu bloków, aby inne inteligentne kontrakty mogły je wykorzystać.

Pierwsza część tego artykułu będzie dotyczyć konfiguracji ze wszystkimi warunkami wstępnymi. Następnie założymy jedną umowę Ethereum i przetestujemy ją za pomocą Truffle. Na koniec oddzielimy wyrocznię od klienta i wspólnie je przetestujemy.

Wymagania Systemowe

  • Każdy główny system operacyjny będzie działał, chociaż niektóre elementy instalacji i konfiguracji będą oczywiście różnić się w różnych systemach. Zrobiłem to wszystko na Ubuntu Linux (16.04). Nie miałem też problemów z konfiguracją środowiska w systemie Windows. Nie próbowałem Maca, chociaż zdaję sobie sprawę, że często robię to również na Macu.
  • Nie jest konieczne uruchomienie pełnego węzła eth; użyjemy Truffle, który ma własną sieć testową. Jeśli wiesz trochę o tym, co robisz, możesz użyć dowolnej innej sieci testowej; Lokalna sieć testowa Truffle jest po prostu najłatwiejszą i najbardziej dostępną dla celów tego samouczka.

Wymagania dotyczące wiedzy

  • Podstawowa wiedza na temat działania blockchain
  • Zrozumienie, czym jest inteligentny kontrakt oparty na blockchain
  • Przydadzą się podstawowe, światowe doświadczenia związane z tworzeniem inteligentnych kontraktów, ale nie są konieczne, jeśli jesteś mądry i ambitny. (I wiem, że jesteś!)

Ta seria artykułów może służyć jako pierwsze wprowadzenie do inteligentnych kontraktów, ale bardzo szybko przechodzi w bardziej zaawansowane koncepcje. Jeśli to Twój pierwszy samouczek dotyczący inteligentnego kontraktu, przygotuj się na szybkie wznoszenie się na wysokość. Jeśli czujesz się pewnie, świetnie; jeśli nie, możesz najpierw uzyskać prostszy samouczek typu „hello world” lub dwa. Na początek sprawdź jeden z poprzednich artykułów o Ethereum i Cryptozombie.

Zastrzeżenie: Przestrzeń inteligentnych kontraktów, będąc tak nowa, szybko się zmienia. Funkcje składni Solidity, które były nowe w momencie pisania tego artykułu, mogą być przestarzałe lub przestarzałe do czasu, gdy to czytasz. Wersje Getha mogły pojawiać się i odchodzić. Solidity zawsze dodaje nowe funkcje językowe i odrzuca stare. Obecnie trwają prace nad wieloma nowymi funkcjami. Bądź więc przygotowany, jeśli to konieczne, aby dostosować informacje zawarte w tym artykule do nowego krajobrazu przyszłości; jeśli poważnie myślisz o nauce rozwoju inteligentnych kontraktów, to wierzę w ciebie.

Opis przykładowej aplikacji

Zastosowanie: Użytkownicy obstawiają mecze bokserskie.

  • Użytkownik może wyciągnąć listę meczów bokserskich z możliwością obstawiania.
  • Użytkownik może wybrać mecz i postawić na zwycięzcę.
  • Użytkownik może postawić dowolną kwotę powyżej określonego minimum.
  • Jeśli typ użytkownika przegrywa, użytkownik traci całą kwotę zakładu.
  • Jeśli typ użytkownika wygrywa, użytkownik otrzymuje część puli w oparciu o wielkość swojego zakładu i całkowitą kwotę zakładu na przegranego meczu, po tym jak dom (właściciel kontraktu) zabierze niewielki procent wygranych .

Co to jest wyrocznia Ethereum?

Inteligentne kontrakty to wciąż coś nowego; jeszcze nie weszły do ​​głównego nurtu, a tak wiele aspektów ich działania nie zostało jeszcze wypracowanych i ustandaryzowanych. Pokrótce wyjaśnię impuls stojący za ideą „wyroczni” – i bądź cierpliwy; zajmiemy się tym bardziej szczegółowo w dalszej części.

Inżynieria kontraktu blockchain nie przypomina programowania aplikacji klient-serwer. Ważną różnicą jest to, że dane, z którymi współpracuje kontrakt, muszą już znajdować się w łańcuchu bloków. Nie ma wywoływania z łańcucha bloków. Nie tylko nie jest obsługiwany przez język, ale także nie jest obsługiwany przez paradygmat blockchain. Kontrakt może przyjmować zakłady w postaci waluty opartej na Ethereum, przechowywać je w kontrakcie i przekazywać na właściwe adresy portfela zgodnie z formułą, gdy zostanie ogłoszony zwycięzca meczu. Ale skąd kontrakt zna zwycięzcę? Nie może wysyłać zapytań do interfejsu API REST ani niczego w tym rodzaju. Może używać tylko danych, które już znajdują się w łańcuchu bloków! Wiele przypadków użycia inteligentnych kontraktów napotyka podobny problem — są one poważnie ograniczone, chyba że mogą wchodzić w interakcje ze światem poza łańcuchem bloków.

Jeśli umowa może wchodzić w interakcje tylko z danymi w łańcuchu bloków, oczywistym rozwiązaniem jest wstrzyknięcie niezbędnych danych do łańcucha bloków. I tym właśnie jest wyrocznia. Wyrocznia to kolejna umowa, która wstrzykuje dane do łańcucha bloków, umożliwiając innym kontraktom ich wykorzystanie. Chociaż może to rodzić pytania dotyczące zaufania i nieufności, po prostu zaakceptuj na razie, że tym właśnie jest wyrocznia. W części 3 tej serii omówimy te niuanse. W naszym przykładowym przypadku użycia wyrocznią będzie kontrakt, który wstrzykuje dane do łańcucha bloków, dotyczące (a) dostępnych dopasowań i (b) tego, kto wygrał te dopasowania, gdy już zostanie podjęta decyzja.

Konfigurowanie środowiska programistycznego Ethereum

W przypadku podstawowej konfiguracji zainstalujemy:

  • Geth (na razie opcjonalnie)
  • Trufla
  • Ganache CLI (opcjonalnie)
  • Środowisko programistyczne (opcjonalnie)

Ten artykuł nie ma miejsca, aby być pełnym przewodnikiem po konfiguracji środowiska, ale działa tylko jako przybliżony przewodnik. Jest to jednak w porządku, ponieważ istnieje już wiele bardziej kompletnych przewodników po konfiguracji dla konkretnego systemu operacyjnego, a Internet tak naprawdę nie potrzebuje nowego. Poprowadzę cię więc szybko ścieżką i wskażę ci zasoby, aby uzyskać więcej szczegółów w razie potrzeby. Przygotuj się na instalację wymagań i wymagań wstępnych zgodnie z wymaganiami Twojego systemu i zgodnie z zaleceniami Google.

Ilustracja procesu kontraktów Oracle

Zainstaluj Getha (opcjonalnie)

Zrzut ekranu instalacji Geth Kliknij, aby zobaczyć obraz w pełnym rozmiarze.

Geth to Go-ethereum, podstawowe oprogramowanie Ethereum; chociaż nie jest to wcale konieczne do tego ćwiczenia, każdy niedoszły programista Ethereum powinien go mieć i być z nim zaznajomiony. Będzie to konieczne, jeśli kiedykolwiek zamierzasz wdrożyć swój inteligentny kontrakt w działającej sieci Ethereum.

  • http://www.talkcrypto.org/blog/2018/01/23/what-is-geth/
  • https://github.com/ethereum/go-ethereum/wiki/Instrukcje-instalacji-dla-Ubuntu
  • https://github.com/ethereum/go-ethereum/wiki/Instrukcje-instalacji-dla-Windows

Zainstaluj trufle

Zrzut ekranu instalacji Truffle Kliknij, aby zobaczyć obraz w pełnym rozmiarze.

Truffle to główna rzecz, której będziemy używać do rozwoju, i absolutnie jest to wymóg dla tego przewodnika. Znajdź i postępuj zgodnie z instrukcjami dla swojego systemu operacyjnego, aby zainstalować Truffle. Poniżej znajduje się kilka linków, które, miejmy nadzieję, pomogą.

  • https://truffleframework.com/docs/truffle/getting-started/installation
  • https://github.com/trufflesuite/trufla
  • https://truffleframework.com/tutorials/how-to-install-truffle-and-testrpc-on-windows-for-blockchain-development

Zainstaluj Ganache CLI (opcjonalnie)

Zrzut ekranu instalacji Ganache CLI Kliknij, aby zobaczyć obraz w pełnym rozmiarze.

Polecam zainstalowanie Ganache CLI, aby używać go jako innego narzędzia testowego, chociaż tak naprawdę nie użyjemy go w naszym samouczku. To opcjonalne.

https://github.com/trufflesuite/ganache-cli

Środowisko programistyczne Ethereum

Byłoby więcej niż możliwe zrobienie tego całego samouczka za pomocą dowolnego prostego edytora tekstu, takiego jak Notepad ++, gedit, vi lub dowolnego wybranego edytora tekstu lub IDE. Osobiście używam Visual Studio Code z następującymi rozszerzeniami:

  • Solidność
  • Rozszerzona solidność
  • Motyw ikony materiału

Uwaga: rozszerzenia nie są wymagane — po prostu zapewniają lepsze środowisko kodowania.

Konfigurowanie kodu

Konfiguracja projektu

Truffle to bardzo wygodne narzędzie do kompilowania inteligentnych kontraktów, migrowania ich do łańcucha bloków, a także zapewnia narzędzia programistyczne i debugujące. Aby zintegrować się z Truffle, konieczna będzie konfiguracja niektórych projektów. Teraz skonfigurujemy powłokę dla naszego projektu, zarówno w Truffle, jak iw strukturze katalogów. Usiądź wygodnie, na razie postępuj zgodnie z instrukcjami i ciesz się.

Utwórz katalog do przechowywania całego kodu; nazwij to wyrocznią-przykład .

Wewnątrz katalogu głównego utwórz dwa podkatalogi, ponieważ ostatecznie projekt będzie składał się z dwóch podprojektów. Utwórz katalogi:

  • /przykład-wyroczni/klient
  • /przykład-wyroczni/wyrocznia

Wejdź do folderu klienta, bo to pierwszy projekt, który będziemy rozwijać. Otwórz okno terminala (wiersz poleceń) w folderze /oracle-example/client .

Uruchom polecenie truffle init .

Zauważ, że wśród wielu utworzonych plików są trufle-config.js i trufle.js . Nie potrzebujemy ich obu, więc usuń truffle-config.js (aby uniknąć zamieszania i bałaganu).

Musimy wyedytować truffle.js , aby wskazać Truffle we właściwym kierunku do testowania. Zastąp zawartość truffle.js następującą treścią:

 module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" // Match any network id } } };

https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/truffle.js

Zauważ, że init Truffle utworzył katalog o nazwie migracje ( oracle-example/client/migrations ). Wewnątrz tego folderu powinien znajdować się plik o nazwie 1_initial_migration.js .

Dodaj kolejny plik w katalogu migracji i nazwij go 2_deploy_contracts.js , o następującej treści:

 var BoxingBets = artifacts.require("BoxingBets"); module.exports = function(deployer) { deployer.deploy(BoxingBets); };

https://github.com/jrkosinski/oracle-example/tree/part1-step1

Dodawanie kodu

Teraz, gdy nie ma już prostej konfiguracji, zaczynamy kodowanie. Pamiętaj, ta część artykułu to wciąż wprowadzenie i konfiguracja, więc dość szybko przejdziemy przez kod. Zajmiemy się bardziej szczegółowymi objaśnieniami kodu w części 2 i bardziej szczegółowym omówieniem architektury i koncepcji w części 3. To powiedziawszy, szybko dotkniemy kilku podstawowych koncepcji widocznych w kodzie. Śledź uważnie, aby nadążyć.

Pełny kod tego kroku w procesie jest dostępny na GitHub: https://github.com/jrkosinski/oracle-example/tree/part1-step1

Kontrakty w Solidności

„Kontrakt” w Solidity jest z grubsza analogiczny do klasy w innych językach obiektowych. Sam język porównywany był m.in. do Golanga i JavaScriptu. Niektóre inne konstrukcje językowe w Solidity — których przykłady przedstawimy później — to modyfikatory, biblioteki i interfejsy. W przypadku umów obsługiwane jest dziedziczenie (w tym dziedziczenie wielokrotne). Pliki kontraktów Solidity mają rozszerzenie .sol.

Interfejs Oracle

Dodaj ten plik do swojego projektu: /oracle-example/client/contracts/OracleInterface.sol

https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/contracts/OracleInterface.sol

Zrzut ekranu interfejsu Oracle Kliknij, aby zobaczyć obraz w pełnym rozmiarze.

Normalnie interfejs wyroczni byłby właśnie tym — interfejsem. W tej pierwszej iteracji jest to po prostu prosta klasa zawarta w projekcie Solidity, na razie jako symbol zastępczy. Przeniesiemy go w następnym kroku, po pomyślnym skompilowaniu i uruchomieniu umowy na Truffle. Po późniejszej konwersji tego do rzeczywistego interfejsu, implementacje funkcji będą puste.

Umowa z klientem

Dodaj ten plik do swojego projektu: /oracle-example/client/contracts/BoxingBets.sol

https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/contracts/BoxingBets.sol

Jest to umowa, która wykorzystuje dane o meczach bokserskich, pozwala użytkownikom wyszukiwać dostępne mecze i stawiać na nie zakłady. W późniejszych iteracjach obliczy i wypłaci wygrane.

Kompilowanie i uruchamianie

Teraz zobaczymy, czy za pierwszym razem wszystko ułożyło się dobrze!

Kompiluj i migruj kontrakt

Otwórz terminal w folderze /oracle-example/client/

Skompiluj kod za pomocą tego polecenia:

 truffle compile 
Zrzut ekranu przedstawiający kompilację i migrację umowy Kliknij, aby zobaczyć obraz w pełnym rozmiarze.
Drugi zrzut ekranu przedstawiający kompilację i migrację umowy Kliknij, aby zobaczyć obraz w pełnym rozmiarze.

Alternatywnie: użyj mojego skryptu powłoki recompile.sh (https://github.com/jrkosinski/oracle-example/tree/part1-step1/client/recompile.sh).

Zwróć uwagę, że zobaczysz wiele ostrzeżeń, ponieważ nasz kod nie jest jeszcze w ostatecznej formie!

Otwórz konsolę programistyczną Truffle:

 truffle develop

Teraz, w konsoli programisty Truffle, przeprowadź migrację do sieci testowej:

 truffle(develop)> migrate

Uruchom umowę

W monicie konsoli deweloperskiej wprowadź następujący wiersz kodu:

 truffle(develop)> BoxingBets.deployed().then(inst => { instance = inst })

Teraz „instancja” jest zmienną, która odnosi się do kontraktu BoxingBets i może być używana do wywoływania jej metod publicznych.

Przetestuj go za pomocą następującego polecenia:

 truffle(develop)> instance.test(3, 4)

Zwróć uwagę, że w BoxingBets.sol umieściliśmy publiczną funkcję „testową”. Dodaje do siebie wszystkie dwie liczby, które do niego przekażesz, aby pokazać, że kontrakt wykonuje kod i że możemy go wywołać z konsoli programistycznej Truffle. Jeśli otrzymamy odpowiedź, która wygląda na rozsądną (patrz poniżej), to nasza praca tutaj jest skończona (przynajmniej na razie).

Oddziel wyrocznię Ethereum

Jeśli do tej pory wszystko się udało, to już garb. Następną rzeczą, którą zrobimy, jest oddzielenie kontraktu wyroczni od kontraktu BoxingBets. W rzeczywistości umowa wyroczni będzie istniała niezależnie od umowy klienta w łańcuchu bloków, więc będziemy musieli być w stanie:

Schemat procesów kontraktowych ethereum oracle

  • Utwórz wystąpienie za pomocą adresu blockchain.
  • Dynamicznie zmieniaj adres wyroczni, którego umowa klienta używa do odwoływania się do wyroczni.

Krótko mówiąc, teraz zamierzamy podzielić wyrocznię i klienta na dwie oddzielne jednostki kontraktowe blockchain i sprawić, by ze sobą rozmawiali. Klient utworzy instancję wyroczni według adresu i wywoła ją.

Umowa z klientem

Po pierwsze, zmienimy kontrakt klienta (klienta), aby odwoływał się do dynamicznego interfejsu do wyroczni, a nie do konkretnej klasy. Następnie upewnimy się, że tworzy instancję wyroczni z umowy zewnętrznej.

Przejdź do /oracle-example/client/contracts/OracleInterface.sol . Jak zauważyliśmy wcześniej, obecnie nie jest to interfejs, ale zamierzamy go stworzyć. Zastąp to, co tam jest, zawartością:

https://github.com/jrkosinski/oracle-example/tree/part1-step2/client/contracts/OracleInterface.sol

 pragma solidity ^0.4.17; contract OracleInterface { enum MatchOutcome { Pending, //match has not been fought to decision Underway, //match has started & is underway Draw, //anything other than a clear winner (eg cancelled) Decided //index of participant who is the winner } function getPendingMatches() public view returns (bytes32[]); function getAllMatches() public view returns (bytes32[]); function matchExists(bytes32 _matchId) public view returns (bool); function getMatch(bytes32 _matchId) public view returns ( bytes32 id, string name, string participants, uint8 participantCount, uint date, MatchOutcome outcome, int8 winner); function getMostRecentMatch(bool _pending) public view returns ( bytes32 id, string name, string participants, uint participantCount, uint date, MatchOutcome outcome, int8 winner); function testConnection() public pure returns (bool); function addTestData() public; }

W BoxingBets.sol zamierzamy zastąpić ten wiersz:

 OracleInterface internal boxingOracle = new OracleInterface();

Z tymi dwiema liniami:

 address internal boxingOracleAddr = 0; OracleInterface internal boxingOracle = OracleInterface(boxingOracleAddr);

Teraz chcemy dynamicznego ustawienia adresu wyroczni oraz funkcji, którą możemy wywołać, aby znaleźć aktualny adres wyroczni. Dodaj te dwie funkcje do BoxingBets.sol :

 /// @notice sets the address of the boxing oracle contract to use /// @dev setting a wrong address may result in false return value, or error /// @param _oracleAddress the address of the boxing oracle /// @return true if connection to the new oracle address was successful function setOracleAddress(address _oracleAddress) external onlyOwner returns (bool) { boxingOracleAddr = _oracleAddress; boxingOracle = OracleInterface(boxingOracleAddr); return boxingOracle.testConnection(); } /// @notice gets the address of the boxing oracle being used /// @return the address of the currently set oracle function getOracleAddress() external view returns (address) { return boxingOracleAddr; }

I na koniec, do testowania połączenia między klientem a wyrocznią, możemy zastąpić funkcję test w BoxingBets funkcją do testowania połączenia wyroczni:

 /// @notice for testing; tests that the boxing oracle is callable /// @return true if connection successful function testOracleConnection() public view returns (bool) { return boxingOracle.testConnection(); }

Na własność

Zauważ, że po definicji setOracleAddress występuje modyfikator onlyOwner . Ogranicza to możliwość wywołania tej funkcji przez kogokolwiek innego niż właściciel kontraktu, nawet jeśli funkcja jest publiczna. To nie jest funkcja językowa. Daje nam to umowa Ownable, która jest usuwana z biblioteki kontraktów Solidity firmy OpenZeppelin. Omówimy to szczegółowo w części 2, ale aby ułatwić korzystanie z modyfikatora onlyOwner , musimy wprowadzić kilka zmian:

Skopiuj Ownable.sol z https://github.com/jrkosinski/oracle-example/tree/part1-step2/client/contracts/Ownable.sol do /oracle-example/client/contracts/ .

Dodaj odniesienie do niego na górze BoxingBets.sol , na przykład:

 import "./Ownable.sol";

(Możesz dodać go tuż pod wierszem, który importuje OracleInterface.sol .)

Zmodyfikuj deklarację kontraktu BoxingBets, aby dziedziczyła po Ownable, z tego:

 contract BoxingBets {

Do tego:

 contract BoxingBets is Ownable {

I powinniśmy być gotowi. Pełny kod jest tutaj na wypadek zgubienia się: https://github.com/jrkosinski/oracle-example/tree/part1-step2/client/contracts

Kontrakty Oracle

Organizować coś

Teraz, gdy kontrakt BoxingBets próbuje odnosić się do całkowicie oddzielnej umowy (czyli wyroczni) według adresu, naszym następnym zadaniem jest stworzenie tego kontraktu wyroczni. Więc teraz stworzymy cały oddzielny projekt, który będzie zawierał kontrakt z wyrocznią. Jest to zasadniczo ta sama konfiguracja, którą już zrobiliśmy dla projektu umowy z klientem; czyli przygotowanie Truffle do kompilacji i rozwoju.

Powinieneś już mieć folder o nazwie /oracle-example/oracle/ , który utworzyliśmy w poprzednim kroku (lub jeśli nie, śmiało utwórz ten pusty katalog teraz). Otwórz terminal w tym katalogu.

  • Uruchom polecenie truffle init .
  • Usuń /oracle-example/oracle/truffle-config.js .
  • Edytuj /oracle-example/oracle/truffle.js w ten sposób:
 module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" // Match any network id } } };

Zobacz przykład tutaj: https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/truffle.js

Wewnątrz /oracle-example/oracle/migrations/ utwórz plik o nazwie 2_deploy_contracts.js o następującej treści:

 var BoxingOracle = artifacts.require("BoxingOracle"); module.exports = function(deployer) { deployer.deploy(BoxingOracle); };

Zobacz przykład tutaj: https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/migrations/2_deploy_contracts.js

Kod Oracle

W tym kroku po prostu skopiuj następujące trzy pliki z https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/contracts/ do folderu /oracle-example/oracle/contracts/ :

  • BoxingOracle.sol: główny kontrakt z wyrocznią.
  • Ownable.sol: dla funkcji tylko dla właściciela, jak już użyliśmy w umowie z klientem.
  • DateLib.sol: biblioteka dat. Przyjrzymy się temu bardziej szczegółowo w części 2 tej serii.

Testowanie Wyroczni

Teraz, w obecnej iteracji projektu, naprawdę musimy dokładnie przetestować naszą inteligentną wyrocznię kontraktową, ponieważ będzie to nasza baza, na której zbudujemy resztę projektu. Tak więc, teraz, gdy skonfigurowaliśmy projekt oracle i skopiowaliśmy kod, będziemy chcieli:

  • Skompiluj wyrocznię.
  • Upewnij się, że wyrocznia działa.
  • Uruchom kilka funkcji w konsoli Truffle, aby upewnić się, że wyrocznia działa zgodnie z oczekiwaniami.

Kompiluj i migruj Oracle

Nadal w terminalu otwartym na /oracle-example/oracle/ uruchom następujące polecenia. Ponownie, te kroki są identyczne z tym, co już zrobiliśmy, aby skompilować i przeprowadzić migrację kontraktu klienta.

 truffle compile

Alternatywnie: użyj mojego skryptu powłoki recompile.sh (https://github.com/jrkosinski/oracle-example/tree/part1-step2/oracle/recompile.sh).

Otwórz konsolę programistyczną Truffle:

 truffle develop

Przejdź do sieci testowej:

 truffle(develop)> migrate

Uruchom i przetestuj Oracle

Wciąż w konsoli programistycznej Truffle wprowadź to, aby przechwycić użyteczny wskaźnik do kontraktu Oracle:

 truffle(develop)> BoxingOracle.deployed().then(inst => { instance = inst })

Teraz możemy (i powinniśmy) uruchomić zestaw testów naszego kontraktu Oracle, aby go przetestować. Spróbuj uruchomić następujące polecenia, każde po kolei, i sprawdź wyniki.

 truffle(develop)> instance.testConnection() ... truffle(develop)> instance.getAllMatches() ... truffle(develop)> instance.addTestData() ... truffle(develop)> instance.getAllMatches() ...

W tym miejscu zachęcamy do przejrzenia kodu Oracle, zobaczenia, jakie są dostępne metody publiczne, przeczytania komentarzy w kodzie i wymyślenia kilku własnych testów do uruchomienia (i uruchomienia ich tutaj, w konsoli, jako pokazane powyżej).

Testowanie i debugowanie

Teraz jesteśmy gotowi na ostateczny test: aby sprawdzić, czy umowa klienta może wywołać umowę Oracle, która jest już na blockchainie, a następnie pobrać i wykorzystać jej dane. Jeśli to wszystko działa, to mamy parę klient-wyrocznia, której możemy użyć do dalszych eksperymentów. Nasze kroki, aby przeprowadzić test end-to-end:

  • Skompiluj i uruchom kontrakt wyroczni
  • Skompiluj i uruchom umowę z klientem
  • Uzyskaj adres umowy z wyrocznią
  • Ustaw adres wyroczni w umowie z klientem
  • Dodaj dane testowe do umowy z wyrocznią
  • Sprawdź, czy możemy pobrać te dane w umowie z klientem

Otwórz dwa okna terminala:

  • Jeden w /oracle-example/klient/
  • A drugi w /oracle-example/oracle/

Sugeruję pozostawienie otwartego /oracle-example/client/ po lewej stronie i /oracle-example/oracle/ po prawej stronie, a następnie śledź je uważnie, aby uniknąć zamieszania.

Skompiluj i uruchom kontrakt Oracle

Wykonaj następujące polecenia w terminalu /oracle-example/oracle/ :

 bash recompile.sh truffle develop truffle(develop)> migrate truffle(develop)> BoxingOracle.deployed().then(inst => { instance = inst })

Skompiluj i uruchom umowę z klientem

Wykonaj następujące polecenia w terminalu /oracle-example/client/ :

 bash recompile.sh truffle develop truffle(develop)> migrate truffle(develop)> BoxingBets.deployed().then(inst => { instance = inst })

Uzyskaj adres kontraktu Oracle

Wykonaj następujące polecenie, aby Truffle w terminalu /oracle-example/oracle/ :

 truffle(develop)> instance.getAddress()

Skopiuj adres będący wynikiem tego wywołania; i użyj go w następnym kroku.

Ustaw adres Oracle w umowie klienta

Wykonaj następujące polecenie, aby truflować w terminalu /oracle-example/client/ :

 truffle(develop)> instance.setOracleAddress('<insert address here, single quotes included>')

I przetestuj to:

 truffle(develop)> instance.testOracleConnection()

Jeśli dane wyjściowe to true , możemy zacząć.

Sprawdź, czy możemy odzyskać te dane w umowie z klientem

Wykonaj następujące polecenie, aby truflować w terminalu /oracle-example/client/ :

 truffle(develop)> instance.getBettableMatches()

Powinien zwrócić pustą tablicę, ponieważ żadne dane testowe nie zostały jeszcze dodane do strony Oracle.

Wykonaj następujące polecenie, aby truffle w terminalu /oracle-example/oracle/ , aby dodać dane testowe:

 truffle(develop)> instance.addTestData()

Wykonaj następującą komendę, aby truffle w terminalu /oracle-example/client/ , aby sprawdzić, czy możemy pobrać nowo dodane dane testowe od klienta:

 truffle(develop)> instance.getBettableMatches()

Teraz, jeśli weźmiesz poszczególne adresy z tablicy zwróconej przez getBettableMatches() i podłączysz je do getMatch() .

W tym miejscu zachęcamy do przejrzenia kodu klienta, zobaczenia, jakie metody publiczne są dostępne, przeczytania komentarzy w kodzie i wymyślenia kilku własnych testów do uruchomienia (i uruchomienia ich tutaj, w konsoli, jako nad).

Zakończenie części pierwszej

Nasze wyniki z tego ćwiczenia są ograniczone, ale tak samo było z naszymi celami, aby utrzymać realistyczne tempo. Nasz klient nie ma jeszcze możliwości przyjmowania zakładów, obsługiwania funduszy, dzielenia wygranych itp. To, co mamy – poza zdobytą wiedzą i doświadczeniem – to:

  • W większości funkcjonalna inteligentna wyrocznia kontraktowa
  • Klient, który może łączyć się z wyrocznią i wchodzić z nią w interakcję
  • Ramy dalszego rozwoju i uczenia się

A to nie jest takie złe jak na krótki artykuł.

W drugiej części tej serii zagłębimy się głębiej w kod i przyjrzymy się niektórym funkcjom, które są unikalne dla rozwoju inteligentnych kontraktów, a także niektórym funkcjom językowym, które są specyficzne dla Solidity. Wiele rzeczy, które zostały właśnie pominięte w tej części, zostanie wyjaśnionych w następnej.

W trzeciej części tej serii omówimy nieco filozofię i projektowanie inteligentnych kontraktów, w szczególności w odniesieniu do ich wykorzystania z wyroczniami.

Dalsze opcjonalne kroki

Eksperymentowanie w pojedynkę to dobry sposób na naukę. Oto kilka prostych sugestii, jeśli zastanawiasz się nad sposobami rozszerzenia tego samouczka w celu uzyskania większej wiedzy (żadne z poniższych nie zostanie omówione w częściach 2 i 3):

  • Wdróż kontrakty w Ganache (dawniej testrpc) i uruchom te same testy, aby zweryfikować funkcję.
  • Wdróż kontrakty w sieciach testowych ropsten lub rinkeby i uruchom te same testy, aby zweryfikować funkcję.
  • Zbuduj interfejs web3js dla wyroczni lub klienta (lub obu).

Powodzenia. W razie jakichkolwiek pytań proszę o kontakt. Nie mogę zagwarantować szybkiej odpowiedzi, ale zrobię co w mojej mocy.