Po kilku dyskusjach na temat solidnego projektowania inteligentnych kontraktów i problemów w ostatnich dwóch artykułach (Tutaj i Tutaj), przyjrzymy się, jak możemy zintegrować inteligentne kontrakty z aplikacjami dla klientów korporacyjnych. Istnieje wiele technologii, które mogą wchodzić w interakcje z węzłem Ethereum (klient łańcucha blokowego Ethereum).

Podstawowa architektura EVM (maszyny wirtualnej ethereum), która uruchamia inteligentne kontrakty, polega na tym, że wszystkie wywołania kontraktu są wykonywane jako transakcja, w której eter wymagany do wykonania metody kontraktu jest przesyłany z adresu konta wywołującego na adres konta umowy. Kod kontraktu znajduje się w adresie kontraktu w łańcuchu bloków i oczekuje, że wywołania będą przychodzić jako transakcje przenoszące dane parametrów metody wraz z transakcją jako „wejście”. Aby włączyć standardowy format dla wszystkich klientów, nazwa metody i parametry muszą być zorganizowane w zalecanym formacie.

Wprowadzenie do klientów inteligentnych kontraktów Ethereum (biblioteka Web3js)

JSON-RPC

Standardowi klienci ethereum udostępniają interfejs do tworzenia RPC (Remote Procedure Call) z kodem kontraktu wdrożonym w łańcuchu bloków. Nazywa się to interfejsem RPC służącym jako żądania HTTP post na domyślnym porcie 8545 dla klienta go, c ++ i parzystości. Zwykle można to dostosować jako parametr polecenia lub właściwość pliku konfiguracyjnego:

–rpc –rpcaddr <ip> –rpcport <numer portu>

Format RPC zbudowany na popularnym JSON-RPC format. Format jest złożony, zwłaszcza w przypadku organizowania wartości parametrów na podstawie typów. Należy przestrzegać zalecanego schematu kodowania, zgodnie z definicją, z odpowiednim wypełnieniem, aby zapewnić, że EVM jest w stanie je zdekodować.

Ze względu na niskopoziomową złożoność formatu JSON_RPC dostępnych jest wiele bibliotek opakowujących, które upraszczają format wywołania. Najstarszy to wrapper JavaScript web3.js który działa w przeglądarce i instancji nodejs. Ta dyskusja nie ma na celu zastąpienia dokumentu referencyjnego dla wszystkich definicji API. Skorzystaj z powyższego linku, aby uzyskać informacje na temat konkretnych wywołań interfejsu API. Tutaj użyjemy określonego zestawu interfejsów API, aby utworzyć zalecenie dotyczące implementacji klienta opartego na przeglądarce dla inteligentnego kontraktu.

Zainstaluj web3.js

Aby zainstalować web3 jako węzeł, przeglądarkę lub pakiet meteor, postępuj zgodnie z instrukcją github powyżej. W przypadku zainstalowania modułu węzła z opcją -g, zostanie on zainstalowany w ścieżce / usr / lib / node_modules / web3. Upewnij się, że ten katalog istnieje z zależnościami w następującej strukturze (dotyczy to systemu operacyjnego Linux, z którym jest to testowane, zapoznaj się z dokumentacją nodejs specyficzną dla systemu operacyjnego dla ścieżki specyficznej dla systemu operacyjnego), jest to ważne dla środowiska uruchomieniowego nodejs, aby znaleźć wszystkie biblioteki.

/ usr / lib / node_modules / web3

├── bower.json

├── bundled.js

├── circle.yml

├── coder.js

├── dist

│ ├── web3.js

│ ├── web3.js.map

│ ├── web3-light.js

│ ├── web3-light.min.js

│ └── web3.min.js

├── przykład

│ ├── balance.html

│ ├── contract_array.html

│ ├── kontrakt.html

│ ├── event_inc.html

│ ├── icap.html

│ ├── namereg.html

│ └── node-app.js

├── gulpfile.js

├── index.js

├── lib

│ ├── kontrakty

│ │ ├── GlobalRegistrar.json

│ │ ├── ICAPRegistrar.json

│ │ └── SmartExchange.json

│ ├── solidność

│ │ ├── address.js

│ │ ├── bool.js

│ │ ├── bytes.js

│ │ ├── coder.js

│ │ ├── dynamicbytes.js

│ │ ├── formatatters.js

│ │ ├── int.js

│ │ ├── param.js

│ │ ├── real.js

│ │ ├── string.js

│ │ ├── type.js

│ │ ├── uint.js

│ │ └── ureal.js

│ ├── utils

│ │ ├── browser-bn.js

│ │ ├── browser-xhr.js

│ │ ├── config.js

│ │ ├── sha3.js

│ │ └── utils.js

│ ├── version.json

│ ├── web3

│ │ ├── allevents.js

│ │ ├── batch.js

│ │ ├── contract.js

│ │ ├── errors.js

│ │ ├── event.js

│ │ ├── extension.js

│ │ ├── filter.js

│ │ ├── formatatters.js

│ │ ├── function.js

│ │ ├── httpprovider.js

│ │ ├── iban.js

│ │ ├── ipcprovider.js

│ │ ├── jsonrpc.js

│ │ ├── method.js

│ │ ├── metody

│ │ │ ├── db.js

│ │ │ ├── eth.js

│ │ │ ├── net.js

│ │ │ ├── personal.js

│ │ │ ├── shh.js

│ │ │ ├── swarm.js

│ │ │ └── Waters.js

│ │ ├── namereg.js

│ │ ├── property.js

│ │ ├── requestmanager.js

│ │ ├── settings.js

│ │ ├── syncing.js

│ │ └── transfer.js

│ └── web3.js

├── LICENCJA

├── node_modules

│ ├── bignumber.js

│ │ ├── bignumber.js

│ │ ├── bignumber.js.map

│ │ ├── bignumber.min.js

│ │ ├── bower.json

│ │ ├── doc

│ │ │ └── API.html

│ │ ├── LICENCJA

│ │ ├── package.json

│ │ └── README.md

│ ├── crypto-js

│ │ ├── aes.js

│ │ ├── bower.json

│ │ ├── cipher-core.js

│ │ ├── CONTRIBUTING.md

│ │ ├── core.js

│ │ ├── crypto-js.js

│ │ ├── docs

│ │ │ └── QuickStartGuide.wiki

│ │ ├── enc-base64.js

│ │ ├── enc-hex.js

│ │ ├── enc-latin1.js

│ │ ├── enc-utf16.js

│ │ ├── enc-utf8.js

│ │ ├── evpkdf.js

│ │ ├── format-hex.js

│ │ ├── format-openssl.js

│ │ ├── hmac.js

│ │ ├── hmac-md5.js

│ │ ├── hmac-ripemd160.js

│ │ ├── hmac-sha1.js

│ │ ├── hmac-sha224.js

│ │ ├── hmac-sha256.js

│ │ ├── hmac-sha384.js

│ │ ├── hmac-sha3.js

│ │ ├── hmac-sha512.js

│ │ ├── index.js

│ │ ├── lib-typedarrays.js

│ │ ├── LICENCJA

│ │ ├── md5.js

│ │ ├── mode-cfb.js

│ │ ├── mode-ctr-gladman.js

│ │ ├── mode-ctr.js

│ │ ├── mode-ecb.js

│ │ ├── mode-ofb.js

│ │ ├── package.json

│ │ ├── pad-ansix923.js

│ │ ├── pad-iso10126.js

│ │ ├── pad-iso97971.js

│ │ ├── pad-nopadding.js

│ │ ├── pad-pkcs7.js

│ │ ├── pad-zeropadding.js

│ │ ├── pbkdf2.js

│ │ ├── rabbit.js

│ │ ├── rabbit-legacy.js

│ │ ├── rc4.js

│ │ ├── README.md

│ │ ├── ripemd160.js

│ │ ├── sha1.js

│ │ ├── sha224.js

│ │ ├── sha256.js

│ │ ├── sha384.js

│ │ ├── sha3.js

│ │ ├── sha512.js

│ │ ├── tripledes.js

│ │ └── x64-core.js

│ ├── utf8

│ │ ├── LICENSE-MIT.txt

│ │ ├── package.json

│ │ ├── README.md

│ │ └── utf8.js

│ ├── xhr2

│ │ ├── Cakefile

│ │ ├── CONTRIBUTING.md

│ │ ├── lib

│ │ │ ├── browser.js

│ │ │ └── xhr2.js

│ │ ├── LICENSE.txt

│ │ ├── package.json

│ │ ├── README.md

│ │ ├── src

│ │ │ ├── 000-xml_http_request_event_target.coffee

│ │ │ ├── 001-xml_http_request.coffee

│ │ │ ├── errors.coffee

│ │ │ ├── progress_event.coffee

│ │ │ └── xml_http_request_upload.coffee

│ │ └── test

│ │ ├── armatura

│ │ │ ├── hello.json

│ │ │ ├── hello.txt

│ │ │ └── xhr2.png

│ │ ├── html

│ │ │ └── browser_test.html

│ │ └── src

│ │ ├── events_test.coffee

│ │ ├── event_target_test.coffee

│ │ ├── headers_test.coffee

│ │ ├── pomocników

│ │ │ ├── browser_mocha_runner.coffee

│ │ │ ├── browser_mocha_setup.coffee

│ │ │ ├── setup.coffee

│ │ │ └── xhr_server.coffee

│ │ ├── nodejs_set_test.coffee

│ │ ├── redirect_test.coffee

│ │ ├── response_type_test.coffee

│ │ ├── responseurl_test.coffee

│ │ ├── send_test.coffee

│ │ ├── status_test.coffee

│ │ └── xhr_test.coffee

│ └── xmlhttprequest

│ ├── lib

│ │ └── XMLHttpRequest.js

│ ├── LICENCJA

│ ├── package.json

│ └── README.md

├── package-init.js

├── package.js

├── package.json

├── README.md

├── styleguide.md

└── przędza. Blok

Uruchom Nodejs Web3js

Nodejs to popularna platforma uruchomieniowa javascript po stronie serwera. Obsługuje wiele projektów oprogramowania pośredniego, sensowne jest umożliwienie nodejs interakcji z inteligentnymi kontraktami. Zapoznaj się z dokumentacją dotyczącą węzłów, aby dowiedzieć się, jak zainstalować nodejs na swojej platformie.

Aby przetestować instalację web3 w środowisku node. Zapisz poniższy kod w pliku js i przeprowadź go przez środowisko wykonawcze węzła. Upewnij się, że masz węzeł ethereum działający na komputerze lokalnym na porcie 8545 (lub zmień go na skonfigurowany – zapoznaj się z wcześniejszym artykułem na temat konfigurowania węzła prywatnego).

console.log ("startowy…");

var Web3 = require (‘/ usr / lib / node_modules / web3’);

web3 = nowy Web3 (nowy Web3.providers.HttpProvider (‘http: // localhost: 8545’));

console.log (web3.eth.accounts);

Jeśli nie ma problemu z instalacją, pojawi się następujący wynik:

local @ local-Lenovo-G50-70: / nodeinstall / node $ node eth.js

startowy…

[„0x81c95efa213ed798cc99e80f79eece314f76fbe8”]

local @ local-Lenovo-G50-70: / nodeinstall / node $

To jest drukowanie tablicy kont dostępnych w węźle ethereum. (Obecnie w tym przypadku jest tylko jeden) .

Wszystkie funkcje web3, które omówimy w kolejnych sekcjach, będą również dostępne w środowisku węzłów. Odtąd będziemy koncentrować się na uruchamianiu w przeglądarce, jeśli napotkasz jakieś konkretne problemy w swojej instancji węzła, skontaktuj się ze mną.

W przeglądarce działa Web3js

Web3 można zaimportować do kodu HTML przeglądarki, aby utworzyć interfejs użytkownika dla umów. To podejście nie jest zalecane, ponieważ nie będziesz udostępniać interfejsu RPC, aby komputer kliencki mógł się z nim połączyć. Zwykle aplikacja korporacyjna łączy się z węzłem Ethereum zamiast z przeglądarką. Dlatego nasz test z nodejs jest ważny. Istnieją inne starsze technologie, takie jak Java, które muszą łączyć się z inteligentnymi kontraktami ethereum. Istnieją sposoby tworzenia bibliotek opakowujących w każdej technologii, jeśli zastosujemy format JSON-RPC zgodnie z zaleceniami. Będziemy jednak trzymać się środowiska javascript w przeglądarce, aby zobaczyć wszystkie udogodnienia i funkcje, które zapewnia klient ethereum.

Zobaczmy prostą stronę HTML, która importuje web3 js i wykonuje proste wywołanie umowy.

&lt; html&gt;

&lt; głowa&gt;

&lt; tytuł&gt; Tester dla eth web3&lt; / tytuł&gt;

&lt; skrypt src ="https://static.blockgeeks.com/usr/lib/node_modules/web3/lib/web3.js"&gt;&lt; / skrypt&gt;

&lt; skrypt&gt;

&nbsp;

function start () {

var Web3 = require (‘web3’);

var web3 = nowy Web3 ();

web3.setProvider (new web3.providers.HttpProvider (‘http: // localhost: 8545’));

var abi = […];

var corecontractContract = web3.eth.contract (abi);

var corecontractContractInst = corecontractContract

.w (‘0x0e22a4f27c2fc3b47e66b70fada85e1c4ca33681’); console.log (corecontractContract.createCustomer (287187, ”custName”, 13243244,1213334));

}

&lt; / skrypt&gt;

&lt; / głowa&gt;

&lt; body onload ="początek();"&gt;

&lt; ciało&gt;

&lt; / html&gt;

Plik web3.js można zaimportować bezpośrednio z folderu lib wewnątrz instalacji modułu węzła. Zaleca się używanie wersji zminimalizowanej, ale do testów używam wersji rozszerzonej, aby móc debugować w bibliotece z poziomu przeglądarki. Proszę, nie kopiuj, wklejaj powyższego kodu bez zmiany kodu i dodaj ABI umowy i obiekt transakcji do wywołania metody createCustomer.

Umowa ABI

Powinniśmy szybko przejść segwayem, aby zrozumieć umowę ABI (Interfejs binarny aplikacji). Specyfikacja ABI kontraktu to tablica JSON zawierająca metodę kontraktu i zmienne podpisy. ABI definiuje kodowanie wymagane dla każdego typu parametru, ponieważ stanowi część danych wejściowych dla transakcji, która wyzwala metodę kontraktu.

Jak się przekonasz, w ostatnim artykule, w którym użyłeś przeglądarki Remix do skompilowania umowy, aplikacja ta utworzyła ABI. W przypadku kontraktu danych ABU wyglądało mniej więcej tak:

[{"stały":prawdziwe,"wejścia": [],"Nazwa":"liczyć","wyjścia": [{"Nazwa":"","rodzaj":"uint256"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [{"Nazwa":"kandydat","rodzaj":"adres"}, {"Nazwa":"metoda","rodzaj":"strunowy"}],"Nazwa":"isUserAuthorized","wyjścia": [{"Nazwa":"","rodzaj":"bool"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":prawdziwe,"wejścia": [{"Nazwa":"","rodzaj":"uint256"}],"Nazwa":"użytkowników","wyjścia": [{"Nazwa":"","rodzaj":"adres"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [],"Nazwa":"zabić","wyjścia": [],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [{"Nazwa":"użytkownik","rodzaj":"adres"}],"Nazwa":"Dodaj użytkownika","wyjścia": [],"płatny":prawdziwe,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [{"Nazwa":"kandydat","rodzaj":"adres"}, {"Nazwa":"metoda","rodzaj":"strunowy"}],"Nazwa":"isUser","wyjścia": [{"Nazwa":"","rodzaj":"bool"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":prawdziwe,"wejścia": [{"Nazwa":"ja","rodzaj":"uint256"}],"Nazwa":"getIthUser","wyjścia": [{"Nazwa":"","rodzaj":"adres"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [{"Nazwa":"indeks","rodzaj":"uint256"}, {"Nazwa":"Nazwa","rodzaj":"strunowy"}],"Nazwa":"updateCustomer","wyjścia": [],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [{"Nazwa":"ja","rodzaj":"uint256"}],"Nazwa":"deleteIthUser","wyjścia": [],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":prawdziwe,"wejścia": [],"Nazwa":"właściciel","wyjścia": [{"Nazwa":"","rodzaj":"adres"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [{"Nazwa":"indeks","rodzaj":"uint256"}, {"Nazwa":"status","rodzaj":"uint256"}],"Nazwa":"updateCustomerStatus","wyjścia": [],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":fałszywy,"wejścia": [{"Nazwa":"ID","rodzaj":"uint256"}, {"Nazwa":"Nazwa","rodzaj":"strunowy"}, {"Nazwa":"Data urodzenia","rodzaj":"uint256"}, {"Nazwa":"społeczny","rodzaj":"uint256"}],"Nazwa":"createCustomer","wyjścia": [],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":prawdziwe,"wejścia": [],"Nazwa":"getUserCount","wyjścia": [{"Nazwa":"","rodzaj":"uint256"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":prawdziwe,"wejścia": [{"Nazwa":"indeks","rodzaj":"uint256"}],"Nazwa":"getCustomer","wyjścia": [{"Nazwa":"ID","rodzaj":"uint256"}, {"Nazwa":"Nazwa","rodzaj":"strunowy"}, {"Nazwa":"Data urodzenia","rodzaj":"uint256"}, {"Nazwa":"społeczny","rodzaj":"uint256"}, {"Nazwa":"status","rodzaj":"uint256"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"stały":prawdziwe,"wejścia": [{"Nazwa":"ID","rodzaj":"uint256"}],"Nazwa":"getCustomerById","wyjścia": [{"Nazwa":"idRet","rodzaj":"uint256"}, {"Nazwa":"Nazwa","rodzaj":"strunowy"}, {"Nazwa":"Data urodzenia","rodzaj":"uint256"}, {"Nazwa":"społeczny","rodzaj":"uint256"}, {"Nazwa":"status","rodzaj":"uint256"}],"płatny":fałszywy,"rodzaj":"funkcjonować"}, {"anonimowy":fałszywy,"wejścia": [{"zindeksowane":fałszywy,"Nazwa":"typ wydarzenia","rodzaj":"strunowy"}, {"zindeksowane":fałszywy,"Nazwa":"ID","rodzaj":"uint256"}],"Nazwa":"Alarm","rodzaj":"zdarzenie"}, {"anonimowy":fałszywy,"wejścia": [{"zindeksowane":prawdziwe,"Nazwa":"przez","rodzaj":"adres"}, {"zindeksowane":prawdziwe,"Nazwa":"czas dostępu","rodzaj":"uint256"}, {"zindeksowane":fałszywy,"Nazwa":"metoda","rodzaj":"strunowy"}, {"zindeksowane":fałszywy,"Nazwa":"desc","rodzaj":"strunowy"}],"Nazwa":"LogAccess","rodzaj":"zdarzenie"}]

Jak widać ma metody z super kontraktu i aktualnego kontraktu z podpisem, parametrami i typami zwrotów. To musi zostać przekazane bezpośrednio jako tablica json do konstruktora kontraktu (abi) w celu utworzenia planu lub klasy kontraktu.

var abi = […];

var corecontractContract = web3.eth.contract (abi);

Ten mechanizm zapewnia, że ​​każda metoda może zostać wywołana bezpośrednio w wystąpieniu klasy kontraktu. Następna instrukcja tworzy instancję klasy kontraktowej corecontractContract

var corecontractContractInst = corecontractContract

.w (‘0x0e22a4f27c2fc3b47e66b70fada85e1c4ca33681’);

Teraz umowa jest powiązana z adresem, na którym „zainstalowany” jest kod umowy. Teraz możemy wywołać metody na kontrakcie.

corecontractContract.createCustomer (287187, ”custName”, 13243244,1213334);

To wywołanie zwróci skrót transakcji transakcji przesłanej do kontraktu.

Dodatkowe parametry:

Wraz z parametrem metody wywołanie umożliwia przekazanie dodatkowych parametrów niefunkcjonalnych w wywołaniu metody.

Obiekt transakcji (jest to kopia definicji obiektu transakcji w dokumencie referencyjnym z dodatkowymi komentarzami):

from: String – Adres konta wysyłającego. Używa web3.eth.default Account właściwość, jeśli nie została określona. Domyślna właściwość konta jest określana na etapie inicjalizacji jako web3.eth.defaultAccount = web3.eth.accounts [0]; Oznacza to, że będziemy używać pierwszego konta w tablicy kont, gaz potrzebny do transakcji jest odejmowany z tego konta.

to: String – (opcjonalne) Adres docelowy wiadomości, pozostawiony niezdefiniowany dla transakcji tworzenia kontraktu. Więc w naszym przypadku, gdy używamy obiektu transakcji do wywołań inteligentnych kontraktów, nie jest to potrzebne.

value: Number | String | BigNumber – (opcjonalne) Wartość przekazana w przypadku transakcji w Wei, a także dożycie, jeśli jest to transakcja polegająca na utworzeniu umowy. Ponieważ nie tworzymy umowy (została już wdrożona.

gas: Number | String | BigNumber – (opcjonalnie, domyślnie: To-Be-Determined) Ilość gazu do wykorzystania na potrzeby transakcji (zwrot niewykorzystanego gazu). Jest to ważne w naszym przypadku, ponieważ musimy przepuścić trochę gazu, aby metoda aktualizacji kontraktu uzyskać niezbędny gaz do zakończenia realizacji. Szacowany gaz według metody jest dostępny w aplikacji do remiksu, musimy użyć tej wartości podniesionej do liczby całkowitej, aby nasza transakcja nie zakończyła się niepowodzeniem z powodu błędu „za mało gazu”.

gasPrice: Number | String | BigNumber – (opcjonalne, domyślnie: To-Be-Determined) Cena gazu dla tej transakcji w wei, domyślnie średnia cena gazu sieciowego.

data: String – (opcjonalnie) albo plik ciąg bajtów zawierające powiązane dane komunikatu lub w przypadku transakcji tworzenia kontraktu kod inicjujący. Nie jest to potrzebne w naszym przypadku, ponieważ nie jest to wezwanie do wdrożenia.

nonce: Number – (opcjonalne) Liczba całkowita liczby jednorazowej. Pozwala to na nadpisanie własnych oczekujących transakcji, które używają tego samego numeru jednorazowego.

Umowa o stałej rozmowie Vs. Połączenie transakcyjne

Kontrakt może mieć dwa typy wywołań, jak zaimplementowano w jego kodzie solidności. Stałe wywołanie nie zmienia stanu kontraktu, tylko odczytuje łańcuch bloków i zwraca wartości, które filtruje zgodnie z jego logiką. Ten typ wywołania nie wymaga żadnych eterów do wykonania, więc nie musimy przekazywać żadnego parametru gas w naszym wywołaniu metody kontraktu. Np.

console.log (corecontractContractInst.getCustomer (0));

To zwróci tablicę BigNumbers dla uintów:

[BigNumber, "aCust", BigNumber, BigNumber, BigNumber]

Aby przekonwertować BigNumbers na dziesiętne, użyj narzędzia narzędzia toDecimal (BigNumber):

console.log (web3.toDecimal (corecontractContractInst.getCustomer (0) [0]));

To wywołanie nie tworzy transakcji w łańcuchu bloków.

Wywołanie transakcji ma na celu zaktualizowanie stanu umowy, na przykład utworzenie rekordu mapowania klienta tutaj w DataContract.

corecontractContract.createCustomer (287187, ”custName”, 13243244,1213334);

To wezwanie zakończy się transakcją i zużyje trochę gazu. Gaz może być dostarczony wraz z transakcją za pomocą obiektu transakcji:

console.log (corecontractContractInst.createCustomer (133423, ‘aCust’, 3334,454545), {gas: 20000});

Wartość 20000 jest tutaj dowolna, proszę użyć gazu oszacowanego na podstawie wykonania metody w aplikacji Remix. Jeśli ilość gazu jest niższa niż oczekiwana przez EVM, to pojawią się błędy:

Uncaught Error: Gaz transakcyjny jest za niski. Brakuje gazu, aby pokryć minimalny koszt transakcji (minimalny: 22680, dostał: 20000). Spróbuj zwiększyć dostarczany gaz.

w Object.InvalidResponse (web3.js: 3120)

na RequestManager.send (web3.js: 6043)

0});

Filtry:

Zdarzenia, które generujemy z kontraktu solidity można odsłuchać w warstwie Web3. Biblioteka podąża za mechanizmem odpytywania w celu wyszukania zdarzeń zarejestrowanych w łańcuchu bloków i przesyła je do warstwy web3, jeśli takie zostaną wygenerowane.

W kodzie ACLContract stworzyliśmy zdarzenia związane z kontrolą dostępu. Możemy słuchać zdarzeń generowanych z dowolnego wywołania klienta, subskrybując je za pomocą interfejsu API allEvents ().

var events = corecontractContractInst.allEvents ();

// obserwuj zmiany

events.watch (function (error, event) {

jeśli (! błąd)

console.log (JSON.stringify (zdarzenie));

});

Spowoduje to wyświetlenie takich zdarzeń:

{"adres":"0x969f563858ddef891e32de8d8c9232f6f74103d0","blockHash":"0x9c44f138a2f1b3aa4a6457252e62fff56257329d17261901048b1d50176e39b4","zablokuj numer": 47,"logIndex": 0,"transactionHash":"0xb4ca62b604c9cd43a0125703c07c8a1624963a8fd399b38f943357549f96c90a","transactionIndex": 0,"transactionLogIndex":"0x0","rodzaj":"zaminowany","zdarzenie":"LogAccess","argumenty": {"przez":"0x81c95efa213ed798cc99e80f79eece314f76fbe8","czas dostępu":"1494178629","metoda":"createCustomer","desc":"pomyślny dostęp"}}

{"adres":"0x969f563858ddef891e32de8d8c9232f6f74103d0","blockHash":"0x9c44f138a2f1b3aa4a6457252e62fff56257329d17261901048b1d50176e39b4","zablokuj numer": 47,"logIndex": 0,"transactionHash":"0xb4ca62b604c9cd43a0125703c07c8a1624963a8fd399b38f943357549f96c90a","transactionIndex": 0,"transactionLogIndex":"0x0","rodzaj":"zaminowany","zdarzenie":"LogAccess","argumenty": {"przez":"0x81c95efa213ed798cc99e80f79eece314f76fbe8","czas dostępu":"1494178629","metoda":"createCustomer","desc":"pomyślny dostęp"}}

Powyżej są dwa zdarzenia utworzone po dwukrotnym wywołaniu createCustomer. Możliwe jest odbieranie zdarzeń od jednego subskrybenta, podczas gdy wiele źródeł generuje zdarzenia za pomocą wywołań kontraktów za pośrednictwem wywołań JSON-RPC. Umożliwia to stworzenie jednej aplikacji do przechwytywania danych audytowych.

W powyższej dyskusji poruszyliśmy kilka podstawowych informacji o kliencie javascript. W następnym przyjrzymy się niektórym zaawansowanym koncepcjom, takim jak pisanie kodu testowego dla funkcji za pomocą biblioteki web3, tworzenie kompletnego Dapp, używanie struktury truflowej i nie tylko.

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me