1. Обзор
Возможность запуска смарт-контрактов
— вот что сделало блокчейн Ethereum таким популярным и прорывным.
Прежде чем мы объясним, что такое смарт-контракт, давайте начнем с определения блокчейна
:
Блокчейн — это общедоступная база данных, в которой хранится постоянная запись цифровых транзакций. Он работает как система транзакций без доверия, структура, в которой люди могут совершать одноранговые транзакции без необходимости доверять третьей стороне или друг другу.
Давайте посмотрим, как мы можем создавать смарт-контракты на Ethereum с надежностью:
2. Эфириум
Ethereum — это платформа, которая позволяет людям эффективно писать децентрализованные приложения с использованием технологии блокчейн.
Децентрализованное приложение ( Dapp
) — это инструмент, с помощью которого люди и организации, находящиеся на разных сторонах взаимодействия, могут собираться вместе без какого-либо централизованного посредника. Ранние примеры Dapps включают BitTorrent (обмен файлами) и биткойн (валюта).
Мы можем описать Ethereum как блокчейн со встроенным языком программирования.
2.1. Виртуальная машина Ethereum (EVM)
С практической точки зрения EVM можно рассматривать как большую децентрализованную систему, содержащую миллионы объектов, называемых учетными записями
, которые могут поддерживать внутреннюю базу данных, выполнять код и общаться друг с другом.
Первый тип учетной записи, вероятно, наиболее знаком обычному пользователю, использующему сеть. Его имя — EOA
(внешняя учетная запись); он используется для передачи значения (например, эфира ) и управляется закрытым ключом.
С другой стороны, есть еще один тип счета, который является контрактом.
Давайте продолжим и посмотрим, о чем идет речь:
3. Что такое смарт-контракт?
Смарт-контракт
— это автономный скрипт, обычно написанный на Solidity, скомпилированный в двоичный файл
или JSON и развернутый по определенному адресу
в блокчейне
. Точно так же, как мы можем вызвать конкретную конечную точку URL-адреса RESTful API для выполнения некоторой логики через HttpRequest
, мы можем аналогичным образом выполнить развернутый смарт-контракт
по определенному адресу
, отправив правильные данные вместе с необходимым Ethereum для вызова развернутого и скомпилированная функция
Solidity .
С точки зрения бизнеса это означает, что функции смарт-контрактов
могут быть изначально монетизированы (аналогично функции AWS Lambda, которая позволяет пользователям платить за вычислительный цикл
, а не за экземпляр
). Важно отметить, что запуск функций смарт-контракта
не требует затрат на Ethereum.
Проще говоря, мы можем рассматривать смарт-контракт
как набор кода, хранящегося в сети блокчейн, который определяет условия, с которыми соглашаются все стороны, использующие контракт.
Это позволяет разработчикам создавать вещи, которые еще не были изобретены. Подумайте об этом на секунду — здесь нет необходимости в посреднике, а также нет риска контрагента. Мы можем создавать новые рынки, хранить реестры долгов или обещаний и быть уверенными, что у нас есть консенсус сети, которая проверяет транзакции.
Любой может развернуть смарт-контракт в децентрализованной базе данных за плату, пропорциональную размеру хранилища содержащего его кода. Узлы, желающие использовать смарт-контракт, должны каким-то образом указать результат своего участия остальной части сети.
3.1. Солидность
Основным языком, используемым в Ethereum, является Solidity — язык, похожий на Javascript, разработанный специально для написания смарт-контрактов. Solidity имеет статическую типизацию, поддерживает наследование, библиотеки и сложные определяемые пользователем типы среди других функций.
Компилятор Solidity превращает код в байт-код EVM, который затем может быть отправлен в сеть Ethereum в качестве транзакции развертывания. Такие развертывания требуют более значительных комиссий за транзакции, чем взаимодействия со смарт-контрактами, и их должен оплачивать владелец контракта.
4. Создание смарт-контракта с Solidity
Первая строка в контракте Solidity устанавливает версию исходного кода. Это делается для того, чтобы контракт не повел себя внезапно по-другому с новой версией компилятора.
pragma solidity ^0.4.0;
В нашем примере имя контракта — Greeting
, и, как мы видим, его создание похоже на создание класса в Java или другом объектно-ориентированном языке программирования:
contract Greeting {
address creator;
string message;
// functions that interact with state variables
}
В этом примере мы объявили две переменные состояния: Creator
и message
. В Solidity мы используем тип данных с именем address
для хранения адресов учетных записей.
Далее нам нужно инициализировать обе переменные в конструкторе.
4.1. Конструктор
Мы объявляем конструктор, используя ключевое слово function
, за которым следует имя контракта (точно так же, как в Java).
Конструктор — это специальная функция, которая вызывается только один раз при первом развертывании контракта в блокчейне Ethereum. Мы можем объявить только один конструктор для контракта:
function Greeting(string _message) {
message = _message;
creator = msg.sender;
}
Мы также вводим исходную строку _message
в качестве параметра в конструктор и устанавливаем ее в переменную состояния сообщения .
Во второй строке конструктора мы инициализируем переменную создателя
значением msg.sender
. Причина, по которой нет необходимости внедрять msg
в конструктор, заключается в том, что msg
— это глобальная переменная, предоставляющая конкретную информацию о сообщении, такую как адрес учетной записи, отправившей его.
Потенциально мы могли бы использовать эту информацию для реализации контроля доступа к определенным функциям.
4.2. Методы установки и получения
Наконец, мы реализуем методы установки и получения сообщения:
function greet() constant returns (string) {
return message;
}
function setGreeting(string _message) {
message = _message;
}
Вызов функции приветствия
просто вернет текущее сохраненное сообщение.
Мы используем ключевое слово константы
, чтобы указать, что эта функция не изменяет состояние контракта и не инициирует запись в блокчейн.
Теперь мы можем изменить значение состояния в контракте, вызвав функцию setGreeting
. Любой может изменить значение, просто вызвав эту функцию. Этот метод не имеет возвращаемого типа, но принимает в качестве параметра тип String .
Теперь, когда мы создали наш первый смарт-контракт, следующим шагом будет его развертывание в блокчейне Ethereum, чтобы каждый мог его использовать. Мы можем использовать Remix , которая в настоящее время является лучшей онлайн-средой разработки, и ее легко использовать.
5. Взаимодействие со смарт-контрактом
Для взаимодействия со смарт-контрактом в децентрализованной сети (блокчейн) нам необходимо иметь доступ к одному из клиентов.
Есть два способа сделать это:
- запускаем клиент сами
- подключиться к удаленному узлу с помощью сервиса типа Infura .
Infura — самый простой вариант, поэтому мы запросим токен бесплатного доступа . После регистрации нам нужно выбрать URL-адрес тестовой сети Rinkeby: «https://rinkeby.infura.io/<токен>».
Чтобы иметь возможность совершать транзакции со смарт-контрактом из Java, нам нужно использовать библиотеку под названием Web3j . Вот зависимость Maven:
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.3.1</version>
</dependency>
И в Градле:
compile ('org.web3j:core:3.3.1')
Прежде чем приступить к написанию кода, нам нужно сделать несколько вещей.
5.1. Создание кошелька
Web3j позволяет нам использовать некоторые его функции из командной строки:
- Создание кошелька
- Управление паролями кошелька
- Перевод средств с одного кошелька на другой
- Создание оболочек функций смарт-контракта Solidity
Инструменты командной строки можно получить в виде zip-файла/tarball со страницы релизов репозитория проекта в разделе загрузок или для пользователей OS X через homebrew:
brew tap web3j/web3j
brew install web3j
Чтобы сгенерировать новый кошелек Ethereum, мы просто вводим в командной строке следующее:
$ web3j wallet create
Он запросит у нас пароль и место, где мы можем сохранить наш кошелек. Файл находится в формате Json, и главное, что нужно помнить, это адрес Ethereum.
Мы будем использовать его на следующем шаге для запроса эфира.
5.2. Запрос эфира в тестовой сети Ринкеби
Мы можем запросить бесплатный эфир здесь . Чтобы злоумышленники не исчерпали все доступные средства, они просят нас предоставить общедоступную ссылку на одну публикацию в социальной сети с нашим адресом Ethereum.
Это очень простой шаг, почти мгновенно они предоставляют эфир, чтобы мы могли запустить тесты.
5.3. Создание оболочки смарт-контракта
Web3j может автоматически генерировать код оболочки смарт-контрактов для развертывания и взаимодействия со смарт-контрактами, не покидая JVM.
Чтобы сгенерировать код оболочки, нам нужно скомпилировать наш смарт-контракт. Мы можем найти инструкцию по установке компилятора здесь . Оттуда мы вводим в командной строке следующее:
$ solc Greeting.sol --bin --abi --optimize -o <output_dir>/
Последний создаст два файла: Greeting.bin
и Greeting.abi.
Теперь мы можем сгенерировать код оболочки с помощью инструментов командной строки web3j:
$ web3j solidity generate /path/to/Greeting.bin
/path/to/Greeting.abi -o /path/to/src/main/java -p com.your.organisation.name
Теперь у нас будет класс Java для взаимодействия с контрактом в нашем основном коде.
6. Взаимодействие со смарт-контрактом
В нашем основном классе мы начинаем с создания нового экземпляра web3j для подключения к удаленным узлам в сети:
Web3j web3j = Web3j.build(
new HttpService("https://rinkeby.infura.io/<your_token>"));
Затем нам нужно загрузить файл нашего кошелька Ethereum:
Credentials credentials = WalletUtils.loadCredentials(
"<password>",
"/path/to/<walletfile>");
Теперь давайте развернем наш смарт-контракт:
Greeting contract = Greeting.deploy(
web3j, credentials,
ManagedTransaction.GAS_PRICE, Contract.GAS_LIMIT,
"Hello blockchain world!").send();
Развертывание контракта может занять некоторое время в зависимости от работы в сети. После развертывания мы можем захотеть сохранить адрес, по которому был развернут контракт. Мы можем получить адрес таким образом:
String contractAddress = contract.getContractAddress();
Все транзакции, совершенные с контрактом, можно увидеть в URL-адресе: « https://rinkeby.etherscan.io/address/<contract_address>».
С другой стороны, мы можем изменить значение смарт-контракта, выполняющего транзакцию:
TransactionReceipt transactionReceipt = contract.setGreeting("Hello again").send();
Наконец, если мы хотим просмотреть новое сохраненное значение, мы можем просто написать:
String newValue = contract.greet().send();
7. Заключение
В этом руководстве мы увидели, что Solidity — это язык программирования со статической типизацией, предназначенный для разработки смарт-контрактов, работающих на EVM.
Мы также создали прямой контракт с этим языком и увидели, что он очень похож на другие языки программирования.
Смарт - контракт
— это просто фраза, используемая для описания компьютерного кода, который может облегчить обмен ценностями. При работе на блокчейне смарт-контракт становится самодействующей компьютерной программой, которая автоматически запускается при выполнении определенных условий.
В этой статье мы увидели, что возможность запуска кода в блокчейне является основным отличием Ethereum, поскольку позволяет разработчикам создавать приложения нового типа, которые выходят далеко за рамки всего, что мы видели раньше.
Как всегда, образцы кода можно найти на GitHub .