Przewodnik po zdarzeniach i dziennikach w inteligentnych kontraktach Ethereum

blog 1AktualnościDevelopersEnterpriseBlockchain ExplainedWydarzenia i konferencjePrasaBiuletyny

Zapisz się do naszego newslettera.

Adres e-mail

Szanujemy twoją prywatność

HomeBlogBlockchain Development

Przewodnik po zdarzeniach i dziennikach w inteligentnych kontraktach Ethereum

Techniczne wprowadzenie do przypadków użycia zdarzeń i dzienników w łańcuchu blokowym Ethereum z przykładowym kodem autorstwa Josepha Chowa 6 czerwca 2016 r. Opublikowane 6 czerwca 2016 r.

ConsenSys Signal przewodnik po zdarzeniach i dziennikach w ethereum smart contract hero

Zdarzenia i dzienniki są ważne w Ethereum, ponieważ ułatwiają komunikację między inteligentnymi kontraktami a ich interfejsami użytkownika. W tradycyjnym programowaniu WWW odpowiedź serwera jest dostarczana w wywołaniu zwrotnym do frontendu. W Ethereum, gdy transakcja jest wydobywana, inteligentne kontrakty mogą emitować zdarzenia i zapisywać dzienniki w łańcuchu bloków, które frontend może następnie przetworzyć. Istnieją różne sposoby adresowania zdarzeń i dzienników. W tym wprowadzeniu technicznym wyjaśniono niektóre źródła nieporozumień związanych ze zdarzeniami i przykładowy kod do pracy z nimi.

Wydarzenia mogą być mylące, ponieważ można ich używać na różne sposoby. Wydarzenie dla jednego może nie wyglądać jak wydarzenie dla innego. Istnieją 3 główne przypadki użycia zdarzeń i dzienników:

  1. Inteligentna umowa zwraca wartości dla interfejsu użytkownika
  2. Asynchroniczne wyzwalacze z danymi
  3. Tańsza forma przechowywania

Terminologia między zdarzeniami a dziennikami jest kolejnym źródłem nieporozumień i zostanie to wyjaśnione w trzecim przypadku użycia.

1) Wartości zwrotów Smart Contract dla interfejsu użytkownika

Najprostszym zastosowaniem zdarzenia jest przekazanie wartości zwracanych z umów do interfejsu aplikacji. Aby to zilustrować, oto problem:

kontrakt PrzykładContract {// niektóre zmienne stanu … function foo (int256 _value) zwraca (int256) {// manipuluj stanem … return _value; }} Język kodu: JavaScript (javascript)

Zakładając, że exampleContract jest instancją ExampleContract, frontendu używającego web3.js, może uzyskać wartość zwracaną przez symulację wykonania kontraktu:

var returnValue = exampleContract.foo.call (2); console.log (returnValue) // 2Code language: JavaScript (javascript)

Jednak gdy web3.js przesyła wywołanie umowy jako transakcję, nie może uzyskać wartości zwracanej [1]:


var returnValue = exampleContract.foo.sendTransaction (2, {from: web3.eth.coinbase}); console.log (returnValue) // transakcja hashCode język: JavaScript (javascript)

Wartość zwracana metody sendTransaction jest zawsze skrótem utworzonej transakcji. Transakcje nie zwracają wartości kontraktu do frontendu, ponieważ transakcje nie są natychmiast wydobywane i uwzględniane w łańcuchu bloków.

Zalecanym rozwiązaniem jest użycie wydarzenia i jest to jeden z zamierzonych celów wydarzeń.

kontrakt ExampleContract {zdarzenie ReturnValue (adres indeksowany _from, int256 _value); funkcja foo (int256 _value) zwraca (int256) {ReturnValue (msg.sender, _value); return _value; }} Frontend może wtedy uzyskać zwracaną wartość: var exampleEvent = exampleContract.ReturnValue ({_ from: web3.eth.coinbase}); exampleEvent.watch (function (err, result) {if (err) {console.log (err) return;} console.log (result.args._value) // sprawdź, czy result.args._from to web3.eth.coinbase następnie // wyświetl wynik.args._value w interfejsie użytkownika i wywołaj // exampleEvent.stopWatching ()}) exampleContract.foo.sendTransaction (2, {from: web3.eth.coinbase}) Język kodu: JavaScript (javascript)

Kiedy transakcja wywołująca foo zostanie wydobyta, wywołanie zwrotne wewnątrz zegarka zostanie wyzwolone. To skutecznie pozwala frontendowi uzyskać wartości zwracane z foo.

2) Asynchroniczne wyzwalacze z danymi

Wartości zwracane są minimalnym przypadkiem użycia dla zdarzeń, a zdarzenia można ogólnie uznać za wyzwalacze asynchroniczne z danymi. Gdy kontrakt chce uruchomić frontend, kontrakt emituje zdarzenie. Ponieważ frontend obserwuje zdarzenia, może podejmować działania, wyświetlać komunikat itp. Przykład tego znajduje się w następnej sekcji (interfejs użytkownika można zaktualizować, gdy użytkownik dokona wpłaty).

3) Tańsza forma przechowywania

Trzeci przypadek użycia różni się znacznie od tego, co zostało omówione, i polega na używaniu wydarzeń jako znacznie tańszej formy przechowywania. W maszynie wirtualnej Ethereum (EVM) i Żółty papier Ethereum, zdarzenia są nazywane dziennikami (istnieją kody operacyjne LOG). Mówiąc o przechowywaniu, z technicznego punktu widzenia dokładniejsze byłoby stwierdzenie, że dane mogą być przechowywane w dziennikach, a nie w zdarzeniach. Jednak kiedy przekraczamy poziom protokołu, dokładniejsze jest stwierdzenie, że kontrakty emitują lub wyzwalają zdarzenia, na które frontend może reagować. Za każdym razem, gdy zdarzenie jest emitowane, odpowiednie dzienniki są zapisywane w łańcuchu bloków. Terminologia między zdarzeniami a dziennikami jest kolejnym źródłem nieporozumień, ponieważ kontekst decyduje, który termin jest dokładniejszy.

Kłody zostały zaprojektowane jako forma przechowywania, która kosztuje znacznie mniej gazu niż przechowywanie kontraktowe. Dzienniki zasadniczo [2] kosztują 8 gazu za bajt, podczas gdy przechowywanie kontraktowe kosztuje 20 000 gazu za 32 bajty. Chociaż dzienniki oferują gigantyczne oszczędności na gazie, dzienniki nie są dostępne w żadnej umowie [3].

Niemniej jednak istnieją przypadki użycia dzienników jako taniego magazynu zamiast wyzwalaczy dla interfejsu użytkownika. Odpowiednim przykładem dla logów jest przechowywanie danych historycznych, które mogą być renderowane przez frontend.

Giełda kryptowalut może chcieć pokazać użytkownikowi wszystkie depozyty, które dokonała na giełdzie. Zamiast przechowywać te szczegóły depozytu w umowie, znacznie tańsze jest przechowywanie ich jako dzienników. Jest to możliwe, ponieważ giełda potrzebuje stanu salda użytkownika, który przechowuje w magazynie kontraktowym, ale nie musi znać szczegółów historycznych depozytów.

kontrakt CryptoExchange {zdarzenie Depozyt (uint256 indeksowany _market, adres indeksowany _sender, uint256 _amount, uint256 _time); funkcja depozytu (uint256 _amount, uint256 _market) zwraca (int256) {// dokonaj wpłaty, zaktualizuj saldo użytkownika itp. Depozyt (_market, msg.sender, _amount, teraz); } Język kodu: JavaScript (javascript)

Załóżmy, że chcemy zaktualizować interfejs użytkownika, gdy użytkownik dokonuje wpłat. Oto przykład użycia zdarzenia (Depozyt) jako asynchronicznego wyzwalacza z danymi (_market, msg.sender, _amount, now). Załóżmy, że cryptoExContract jest instancją CryptoExchange:

var depositEvent = cryptoExContract.Deposit ({_ sender: userAddress}); depositEvent.watch (function (err, result) {if (err) {console.log (err) return;} // dołącz szczegóły result.args do UI}) Język kodu: JavaScript (javascript)

Poprawa wydajności pobierania wszystkich zdarzeń dla użytkownika jest powodem indeksowania parametru _sender do zdarzenia: zdarzenie Depozyt (indeksowany przez uint256 _market, indeksowany adresowo _sender, uint256 _amount, uint256 _time).

Domyślnie nasłuchiwanie zdarzeń rozpoczyna się tylko w momencie tworzenia wystąpienia zdarzenia. Podczas pierwszego ładowania interfejsu użytkownika nie ma żadnych depozytów do dołączenia. Chcemy więc pobrać zdarzenia od bloku 0 i jest to robione poprzez dodanie parametru fromBlock do zdarzenia.

var depositEventAll = cryptoExContract.Deposit ({_ sender: userAddress}, {fromBlock: 0, toBlock: ‘latest’}); depositEventAll.watch (function (err, result) {if (err) {console.log (err) return;} // dołącz szczegóły result.args do UI}) Język kodu: JavaScript (javascript)

Gdy interfejs użytkownika jest renderowany, należy wywołać metodę depositEventAll.stopWatching ().

Poza – parametry indeksowane

Indeksować można do 3 parametrów. Na przykład proponowany standard tokena ma: Transfer zdarzenia (adres indeksowany _od, adres indeksowany _do, wartość_uint256). Oznacza to, że frontend może skutecznie po prostu obserwować transfery tokenów, które są:

  • wysłane przez tokenContract.Transfer ({_ from: senderAddress})
  • lub odebrane przez adres tokenContract.Transfer ({_ to: receiverAddress})
  • lub wysłane przez adres na określony adres tokenContract.Transfer ({_ from: senderAddress, _to: receiverAddress})

Wniosek

Przedstawiono trzy przypadki użycia dla wydarzeń. Po pierwsze, użycie zdarzenia do prostego pobrania wartości zwracanej z funkcji kontraktu wywołanej za pomocą sendTransaction (). Po drugie, użycie zdarzenia jako asynchronicznego wyzwalacza z danymi, który może powiadomić obserwatora, na przykład interfejs użytkownika. Po trzecie, wykorzystanie zdarzenia do zapisywania dzienników w łańcuchu bloków jako tańszej formy przechowywania. W tym wprowadzeniu pokazano niektóre z Pszczoła do pracy z wydarzeniami. Tam są inne podejścia do pracy ze zdarzeniami, dziennikami i potwierdzeniami, a te tematy mogą zostać omówione w przyszłych artykułach.

Podziękowania dla Aarona Davisa, Vincenta Gariepy i Josepha Lubina za opinie na temat tego artykułu.

Bibliografia

[1] web3.js może obserwować, czy transakcja zostanie uwzględniona w łańcuchu bloków, a następnie odtworzyć transakcję w instancji EVM, aby uzyskać wartość zwracaną, ale jest to znaczna ilość logiki do dodania do web3.js [2] Koszty gazu wynoszą 375 dla operacji LOG i 375 gazu na temat, ale gdy przechowywanych jest wiele bajtów, koszty te stanowią nieznaczną część całkowitego kosztu przechowywania. [3] Dowody Merkle dla logów są możliwe, więc jeśli podmiot zewnętrzny dostarczy umowę z takim dowodem, umowa może zweryfikować, czy dziennik faktycznie istnieje w łańcuchu bloków.

Chcesz, aby przewodniki programisty trafiały prosto do Twojej skrzynki odbiorczej?

Subskrybuj biuletyn dla programistów ConsenSys

Biuletyn Zapisz się do naszego newslettera, aby otrzymywać najnowsze wiadomości o Ethereum, rozwiązania dla przedsiębiorstw, zasoby dla programistów i nie tylko.Jak zbudować udany produkt BlockchainWebinar

Jak zbudować udany produkt Blockchain

Jak skonfigurować i uruchomić węzeł EthereumWebinar

Jak skonfigurować i uruchomić węzeł Ethereum

Jak zbudować własny interfejs API EthereumWebinar

Jak zbudować własny interfejs API Ethereum

Jak stworzyć token społecznościowyWebinar

Jak stworzyć token społecznościowy

Korzystanie z narzędzi bezpieczeństwa w tworzeniu inteligentnych kontraktówWebinar

Korzystanie z narzędzi bezpieczeństwa w tworzeniu inteligentnych kontraktów

Przyszłość finansów, aktywów cyfrowych i DeFiWebinar

Przyszłość finansów: aktywa cyfrowe i DeFi

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me
Like this post? Please share to your friends:
Adblock
detector
map