«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, поскольку позволяет разработчикам создавать приложения нового типа, выходящие далеко за рамки всего, что мы видели раньше.