«1. Обзор
Возможность запуска смарт-контрактов — вот что сделало блокчейн Ethereum таким популярным и прорывным.
Прежде чем мы объясним, что такое смарт-контракт, давайте начнем с определения блокчейна:
Blockchain is a public database that keeps a permanent record of digital transactions. It operates as a trustless transactional system, a framework in which individuals can make peer-to-peer transactions without needing to trust a third party or one another.
Давайте посмотрим, как мы можем надежно создавать смарт-контракты на Ethereum:
2. Ethereum
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. Solidity
Основным языком, используемым в 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
}
«
«В этом примере мы объявили две переменные состояния: создатель и сообщение. В Solidity мы используем тип данных с именем address для хранения адресов учетных записей.
Далее нам нужно инициализировать обе переменные в конструкторе.
4.1. Конструктор
Мы объявляем конструктор, используя ключевое слово function, за которым следует имя контракта (точно так же, как в Java).
function Greeting(string _message) {
message = _message;
creator = msg.sender;
}
Конструктор — это специальная функция, которая вызывается только один раз при первом развертывании контракта в блокчейне Ethereum. Мы можем объявить только один конструктор для контракта:
Мы также вводим исходную строку _message в качестве параметра в конструктор и устанавливаем ее в переменную состояния сообщения.
Во второй строке конструктора мы инициализируем переменную создателя значением, называемым msg.sender. Причина, по которой нет необходимости внедрять msg в конструктор, заключается в том, что msg — это глобальная переменная, предоставляющая конкретную информацию о сообщении, такую как адрес учетной записи, отправившей его.
Потенциально мы могли бы использовать эту информацию для реализации контроля доступа к определенным функциям.
4.2. Методы установки и получения
function greet() constant returns (string) {
return message;
}
function setGreeting(string _message) {
message = _message;
}
Наконец, мы реализуем методы установки и получения для сообщения:
Вызов функции приветствия просто вернет сохраненное в данный момент сообщение. Мы используем ключевое слово константы, чтобы указать, что эта функция не изменяет состояние контракта и не инициирует запись в блокчейн.
Теперь мы можем изменить значение состояния в контракте, вызвав функцию setGreeting. Любой может изменить значение, просто вызвав эту функцию. Этот метод не имеет возвращаемого типа, но принимает в качестве параметра тип String.
Теперь, когда мы создали наш первый смарт-контракт, следующим шагом будет его развертывание в блокчейне Ethereum, чтобы каждый мог его использовать. Мы можем использовать Remix, которая в настоящее время является лучшей онлайн-IDE, и ее легко использовать.
5. Взаимодействие со смарт-контрактом
Для взаимодействия со смарт-контрактом в децентрализованной сети (блокчейне) нам необходимо иметь доступ к одному из клиентов.
-
Есть два способа сделать это:
запустить клиент, самостоятельно подключиться к удаленному узлу, используя такой сервис, как Infura.
Infura — самый простой вариант, поэтому мы запросим токен бесплатного доступа. После регистрации нам нужно выбрать URL-адрес тестовой сети Rinkeby: «https://rinkeby.infura.io/\u003ctoken\u003e».
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.3.1</version>
</dependency>
Чтобы иметь возможность совершать транзакции со смарт-контрактом из Java, нам нужно использовать библиотеку под названием Web3j. Вот зависимость Maven:
compile ('org.web3j:core:3.3.1')
И в Gradle:
Прежде чем приступить к написанию кода, нам нужно сделать несколько вещей.
5.1. Создание кошелька
-
Web3j позволяет нам использовать некоторые его функции из командной строки:
Создание кошелька Управление паролем кошелька Перенос средств из одного кошелька в другой Генерация обёрток функций смарт-контракта Solidity
brew tap web3j/web3j
brew install web3j
Инструменты командной строки могут быть полученный в виде zip-файла/tarball со страницы релизов репозитория проекта в разделе загрузок или для пользователей OS X через доморощенный:
$ web3j wallet create
Чтобы сгенерировать новый кошелек Ethereum, мы просто набираем в командной строке следующее :
Он запросит у нас пароль и место, где мы можем сохранить наш кошелек. Файл находится в формате Json, и главное, что нужно помнить, это адрес Ethereum.
Мы будем использовать его на следующем шаге для запроса эфира.
5.2. Запрос эфира в тестовой сети Ринкеби
Мы можем запросить бесплатный эфир здесь. Чтобы злоумышленники не исчерпали все доступные средства, они просят нас предоставить общедоступную ссылку на одну публикацию в социальной сети с нашим адресом Ethereum.
Это очень простой шаг, почти мгновенно они предоставляют эфир, чтобы мы могли запустить тесты.
5.3. Создание оболочки смарт-контракта
Web3j может автоматически генерировать код оболочки смарт-контракта для развертывания и взаимодействия со смарт-контрактами, не покидая JVM.
$ solc Greeting.sol --bin --abi --optimize -o <output_dir>/
«Чтобы сгенерировать код оболочки, нам нужно скомпилировать наш смарт-контракт. Мы можем найти инструкцию по установке компилятора здесь. Оттуда мы набираем в командной строке следующее:
$ web3j solidity generate /path/to/Greeting.bin
/path/to/Greeting.abi -o /path/to/src/main/java -p com.your.organisation.name
Последнее создаст два файла: Greeting.bin и Greeting.abi. Теперь мы можем сгенерировать код оболочки с помощью инструментов командной строки web3j:
Теперь у нас будет класс Java для взаимодействия с контрактом в нашем основном коде.
6. Взаимодействие со смарт-контрактом
Web3j web3j = Web3j.build(
new HttpService("https://rinkeby.infura.io/<your_token>"));
В нашем основном классе мы начинаем с создания нового экземпляра web3j для подключения к удаленным узлам в сети:
Credentials credentials = WalletUtils.loadCredentials(
"<password>",
"/path/to/<walletfile>");
Now let’s deploy our smart contract:
Greeting contract = Greeting.deploy(
web3j, credentials,
ManagedTransaction.GAS_PRICE, Contract.GAS_LIMIT,
"Hello blockchain world!").send();
Затем нам нужно загрузить файл нашего кошелька Ethereum :
String contractAddress = contract.getContractAddress();
Развертывание контракта может занять некоторое время в зависимости от работы в сети. После развертывания мы можем захотеть сохранить адрес, по которому был развернут контракт. Мы можем получить адрес следующим образом:
Все транзакции, совершенные с контрактом, можно увидеть в URL-адресе: «https://rinkeby.etherscan.io/address/\u003ccontract_address\u003e».
TransactionReceipt transactionReceipt = contract.setGreeting("Hello again").send();
С другой стороны, мы можем изменить значение смарт-контракта, выполняющего транзакцию:
String newValue = contract.greet().send();
Наконец, если мы хотим просмотреть новое сохраненное значение, мы можем просто написать:
7. Заключение
В этом руководстве мы увидели, что Solidity — это язык программирования со статической типизацией, предназначенный для разработки смарт-контрактов, работающих на EVM.
Мы также создали прямой контракт с этим языком и увидели, что он очень похож на другие языки программирования.
Смарт-контракт — это просто фраза, используемая для описания компьютерного кода, который может облегчить обмен ценностями. При работе на блокчейне смарт-контракт становится самодействующей компьютерной программой, которая автоматически запускается при выполнении определенных условий.
В этой статье мы увидели, что возможность запускать код в блокчейне является основным отличием Ethereum, поскольку позволяет разработчикам создавать приложения нового типа, выходящие далеко за рамки всего, что мы видели раньше.