Здравствуйте, сколько стоит курс Работа с Ethereum? |
Обзор всех аспектов среды Solidity. Среда разработки Ethereum, Web3 и Truffle
Взаимодействие между контрактами и веб-сайтами
В этой лекции обсудим взаимодействие между сетью Ethereum и веб-сайтами посредством технологии web3. Среда Ethereum представляет собой блокчейн, единый счет, в который записаны все транзакции. Кроме того, есть виртуальные машины Ethereum, на которых приложение выполняется в виде кодов операций. Коды операций выглядят примерно так: PUSH 1 CALLDATALOAD и так далее. Среда Solidity переводит все эти коды операций в байткод Java. Доступны и другие языки, похожие на Solidity. Все они являются языками высокого уровня. Это напоминает работу на компьютере с компилятором C++ или C по сравнению с задачей команд через ассемблер.
Web3 работает с кодами RPC. Рассмотрим пример с узлом Geth или Ethereum-CPP. К ним может подключиться код web3.js. Также можно воспользоваться Ethereum-testRPC. Эти узлы предоставляют доступ к блокчейну. В языках HTML и JavaScript существует объект Web3.js. Здесь можно задать значение переменной web3.setProvider, указав в ней узел HTTP. С помощью протокола HTTP программа выполнит подключение к интерфейсу RPC. Например, адрес счета для зачисления эфира можно узнать с помощью функции web3.eth.coinbase, а баланс - с помощью web3.eth.getBalance.
В языке JavaScript можно работать с контрактами. Они создаются путем задания массива ABI и сообщения в web3, что контракт найден. Исполнение процедуры web3.eth.contract и сообщение массива ABI создаст объект MyContract. В реальности контракт воплощается после назначения ему адреса. Больше информации на эту тему можно почерпнуть из wiki-пространства Ethereum: https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethcontract.
Давайте подробнее разберем двоичный интерфейс приложения, или ABI. ABI всегда является массивом JSON.
В нашем примере массив содержит два элемента. Имя первого элемента - это send, что сообщает web3, что название функции, которую он будет вызывать - это send. Эта функция не является постоянной и насчитывает два входных параметра. Один из них относится к адресному типу и называется to, а другой - числового типа, uint256. Каких-либо выходных данных эта функция не предоставляет. Другой функцией является balance, она уже является постоянной, поэтому ее не нужно обсчитывать в блокчейне. У этой функции один входной параметр адресного типа, и один выходной - типа uint256. Этот двоичный интерфейс приложения сообщает web3.js, как взаимодействовать с двоичным кодом в блокчейне.
Теперь разберемся, как работает коммуникация.
За вызовами процедур стоит функция web3.eth.call. Она работает с объектом, который характеризуется адресом to и полем с данными data. Первые двадцать байт поля data предназначены для функции вызова call. Все остальные - это так называемый дополнительный параметр, обозначенный как padded. Его можно рассчитать вручную. Например, для объекта web3.sha3 вы сообщаете название функции, которую нужно вызвать. Придется обрезать имя до первых десяти символов, которые займут двадцать байт, и добавить нужные параметры в раздел padded. Узнать больше об этом можно в документации Solidity.
С этого момента будем работать исключительно с контрактами. Рассмотрим пример.
В прошлой лекции мы создали простой контракт с тремя функциями: getBalance, increaseBalance и decreaseBalance. В данном примере сфокусируемся на getBalance и increaseBalance, и вызовем их с веб-сайта. Для демонстрации будем использовать Ethereum Studio.
Давайте посмотрим, из чего состоит контракт.
Здесь есть переменная balance типа uint256, изначально равная нулю. Есть две функции для изменения баланса, increaseBalance и decreaseBalance, и одна постоянная функция getBalance для возврата величины баланса. Перезапустим режим песочницы для демонстрации работы контракта.
Этот запуск режима песочницы получил свой идентификатор и разместила контракт по следующему адресу.
Перейдем к каталогу web. В нем хранится другой каталог src и далее файл app.js, в котором расположен массив ABI.
Скопируем этот массив из контракта. Необходимо задать адрес песочницы.
После запуска кода будет создан объект HttpProvider. Эта операция выполняется вне виртуальной машины, и созданный объект доступен для других пользователей сети Ethereum.
Система выдала мне учетную запись. Теперь контракт размещается в сети по этому адресу, и с ним можно взаимодействовать разными способами: например, узнать баланс с помощью процедуры contract.getBalance, а затем преобразовать полученное большое число в строку с помощью расширения toString. Или можно увеличить баланс с помощью contract.increaseBalance, конечно, указав объем пополнения.
Поскольку эта функция не выполняется в реальном времени, придется подождать, пока транзакция не будет обсчитана сетью. Можно также вставить дополнительный код JavaScript, который будет выполнен вместе с обсчетом транзакции.
Перейдем в каталог web и подадим команду gulp для сборки реального приложения. Будет запущена процедура browserify и заданы следующие входные параметры. Результат сборки будет размещен в каталоге dist. Все необходимые библиотеки web3 и JavaScript тоже будут там.
Файл index.html был модифицирован. Текущий баланс будет отображаться с помощью демонстрации значения переменной contract_balance.
Также предусмотрена кнопка с событием при щелчке по ней - вызывается функция increaseContractBalance. Функциональность не очень высока, это все собрано в демонстрационных целях.
Я подключил к классу window функцию increaseContractBalance. Она подключается к консоли и вызывает функцию contract.increaseBalance с аргументом 4.
Затем она записывает в переменную contract_balance результат работы функции getTheBalanceFromTheContract. При первом запуске кода баланс контракта будет также отображен на веб-странице приложения.
Теперь запустим HTTP-сервер. Это позволит получать доступ к нашему контракту из внешнего мира. Скопируем адрес, вставим его в новой вкладке и сменим номер порта. При запуске кода будет выведен баланс, в настоящий момент равный нулю, как и в нашей песочнице.
При щелчке по кнопке Increase Balance баланс будет увеличен, затем будет вызвана функция getBalance, и текст, отображающий его величину, будет изменен. Теперь баланс равен четырем.