«1. Введение

Это руководство знакомит с Web3j, Java-реализацией популярной библиотеки абстракций Web3.

Web3j используется для взаимодействия с сетью Ethereum путем подключения к узлам Ethereum с использованием JSON-RPC или знакомых стандартов, таких как HTTP, WebSockets, IPC.

Ethereum — это отдельная тема, поэтому давайте сначала кратко рассмотрим, что это такое!

2. Ethereum

Ethereum — это (1) криптовалюта (символ токена ETH), (2) распределенный суперкомпьютер, (3) блокчейн и (4) сеть смарт-контрактов, написанная на Solidity.

Другими словами, Эфириум (сеть) управляется кучей подключенных серверов, называемых узлами, которые взаимодействуют в своего рода ячеистой топологии (технически это не совсем так, но достаточно близко, чтобы получить более четкое представление о том, как это происходит). все работает).

Web3j и его родительская библиотека под названием Web3 позволяют веб-приложениям подключаться к одному из этих узлов и, таким образом, отправлять транзакции Ethereum, которые, по сути, являются скомпилированными функциями смарт-контракта Solidity, которые ранее были развернуты в Ethereum. сеть. Для получения дополнительной информации о смарт-контрактах см. нашу статью об их создании и развертывании с помощью Solidity здесь.

Каждый узел транслирует свои изменения всем остальным узлам, чтобы можно было достичь консенсуса и проверки. Таким образом, каждый узел одновременно содержит всю историю блокчейна Ethereum, тем самым создавая избыточную резервную копию всех данных защищенным от несанкционированного доступа способом, а также посредством консенсуса и проверки всеми другими узлами в сети.\\

Подробнее подробную информацию об Ethereum смотрите на официальной странице.

3. Настройка

Чтобы использовать полный набор функций, предоставляемых Web3j, нам нужно сделать немного больше для настройки, чем обычно. Во-первых, Web3j поставляется в виде нескольких автономных модулей, каждый из которых может быть дополнительно добавлен к основной зависимости pom.xml:

<dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>3.3.1</version>
</dependency>

Обратите внимание, что команда Web3j предоставляет готовый Spring Boot Starter с некоторая конфигурация и ограниченная функциональность встроены прямо!

В этой статье мы сосредоточимся на основных функциях (включая то, как добавить Web3j в приложение Spring MVC, чтобы обеспечить совместимость с более широким спектром веб-приложений Spring).

Полный список этих модулей можно найти на Maven Central.

3.1. Компиляция контрактов: Truffle или Solc

Существует два основных способа компиляции и развертывания смарт-контрактов Ethereum (файлы .solc):

  1. The official Solidity compiler.
  2. Truffle (an abstraction suite for testing, deploying, and managing smart contracts).

В этой статье мы будем придерживаться Truffle. Truffle упрощает и абстрагирует процесс составления смарт-контрактов, их переноса и развертывания в сети. Он также является оболочкой компилятора Solc, что позволяет нам получить некоторый опыт работы с обоими.

Чтобы настроить Truffle:

$ npm install truffle -g
$ truffle version

Четыре ключевые команды, которые мы будем использовать для инициализации нашего проекта соответственно, компиляции нашего приложения, развертывания нашего приложения в блокчейне и его тестирования соответственно:

$ truffle init
$ truffle compile
$ truffle migrate
$ truffle test

Теперь , давайте рассмотрим простой пример:

pragma solidity ^0.4.17;

contract Example {
  function Example() {
    // constructor
  }
}

Который должен дать следующий ABI JSON при компиляции:

{
  "contractName": "Example",
  "abi": [
    {
      "inputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "constructor"
    }
  ],
  "bytecode": "0x60606040523415600e57600080fd5b603580601b6...,
  "deployedBytecode": "0x6060604052600080fd00a165627a7a72305...,
  //...
}

Затем мы можем использовать предоставленный байт-код и ABI в нашем приложении для взаимодействия с развернутыми контрактами!

3.2. Тестирование контрактов: Ganache

Один из самых простых способов работы с тестовой сетью Ethereum — запуск собственного сервера Ganache. Мы будем использовать готовое готовое решение, так как его проще всего установить и настроить. Он также предоставляет интерфейс и серверную оболочку для Ganache CLI, которая управляет Ganache изнутри.

Мы можем подключиться к нашему серверу Ganache по предоставленному по умолчанию URL-адресу: http://localhost:8545 или http://localhost:7545.

Существует несколько других популярных подходов к настройке тестовой сети, включая использование Meta-Mask, Infura или Go-Lang и Geth.

В этой статье мы остановимся на Ganache, поскольку настройка собственного экземпляра GoLang (и его настройка в качестве пользовательской тестовой сети) может быть довольно сложной задачей, а статус Meta-Mask в Chrome в настоящее время неясен.

«Мы можем использовать Ganache для сценариев ручного тестирования (при отладке или завершении нашего интеграционного тестирования) или использовать их для сценариев автоматического тестирования (на основе которых мы должны строить наши тесты, поскольку в таких обстоятельствах у нас может не быть доступных конечных точек).

4. Web3 и RPC

Web3 предоставляет фасад и интерфейс для простого взаимодействия с блокчейном Ethereum и серверными узлами Ethereum. Другими словами, Web3 облегчает взаимодействие между клиентами и блокчейном Ethereum посредством JSON-RPC. Web3J — это официальный Java-порт Web3.

Мы можем инициализировать Web3j для использования в нашем приложении, передав провайдера (например, конечную точку стороннего или локального узла Ethereum):

Web3j web3a = Web3j.build(new HttpService());
Web3j web3b = Web3j.build(new HttpService("YOUR_PROVIDER_HERE"));
Web3j myEtherWallet = Web3j.build(
  new HttpService("https://api.myetherapi.com/eth"));

Третий вариант показывает, как добавить сторонний провайдер (таким образом подключаясь к своему узлу Ethereum). Но у нас также есть возможность оставить опцию нашего провайдера пустой. В этом случае вместо этого будет использоваться порт по умолчанию (8545) на локальном хосте.

5. Основные методы Web3

Теперь, когда мы знаем, как инициализировать наше приложение для связи с блокчейном Ethereum, давайте рассмотрим несколько основных способов взаимодействия с блокчейном Ethereum.

Рекомендуется оборачивать ваши методы Web3 в CompleteableFuture для обработки асинхронного характера запросов JSON-RPC, отправляемых к настроенному вами узлу Ethereum.

5.1. Текущий номер блока

Мы можем, например, вернуть текущий номер блока:

public EthBlockNumber getBlockNumber() {
    EthBlockNumber result = new EthBlockNumber();
    result = this.web3j.ethBlockNumber()
      .sendAsync()
      .get();
    return result;
}

5.2. Учетная запись

Чтобы получить учетную запись указанного адреса:

public EthAccounts getEthAccounts() {
    EthAccounts result = new EthAccounts();
    result = this.web3j.ethAccounts()
        .sendAsync() 
        .get();
    return result;
}

5.3. Количество транзакций по счету

Чтобы получить количество транзакций по данному адресу:

public EthGetTransactionCount getTransactionCount() {
    EthGetTransactionCount result = new EthGetTransactionCount();
    result = this.web3j.ethGetTransactionCount(DEFAULT_ADDRESS, 
      DefaultBlockParameter.valueOf("latest"))
        .sendAsync() 
        .get();
    return result;
}

5.4. Баланс аккаунта

И, наконец, чтобы получить текущий баланс адреса или кошелька:

public EthGetBalance getEthBalance() {
    EthGetBalance result = new EthGetBalance();
    this.web3j.ethGetBalance(DEFAULT_ADDRESS, 
      DefaultBlockParameter.valueOf("latest"))
        .sendAsync() 
        .get();
    return result;
}

6. Работа с контрактами в Web3j

После того, как мы скомпилировали наш контракт Solidity с помощью Truffle, мы можем работать с наши скомпилированные бинарные интерфейсы приложений (ABI) с использованием автономного инструмента командной строки Web3j, доступного здесь, или в виде отдельного zip-файла здесь.

6.1. Магия CLI

Затем мы можем автоматически сгенерировать наши обертки смарт-контрактов Java (по сути, POJO, раскрывающие ABI смарт-контракта), используя следующую команду:

$ web3j truffle generate [--javaTypes|--solidityTypes] 
  /path/to/<truffle-smart-contract-output>.json 
  -o /path/to/src/main/java -p com.your.organisation.name

Выполнение следующей команды в корне проекта:

web3j truffle generate dev_truffle/build/contracts/Example.json 
  -o src/main/java/com/baeldung/web3/contract -p com.baeldung

сгенерировал наш примерный класс:

public class Example extends Contract {
    private static final String BINARY = "0x60606040523415600e576...";
    //...
}

6.2. Java POJO

Теперь, когда у нас есть обертка смарт-контракта, мы можем программно создать кошелек, а затем развернуть наш контракт по этому адресу:

WalletUtils.generateNewWalletFile("PASSWORD", new File("/path/to/destination"), true);
Credentials credentials = WalletUtils.loadCredentials("PASSWORD", "/path/to/walletfile");

6.3. Развернуть контракт

Example contract = Example.deploy(this.web3j,
  credentials,
  ManagedTransaction.GAS_PRICE,
  Contract.GAS_LIMIT).send();

Мы можем развернуть наш контракт следующим образом:

contractAddress = contract.getContractAddress();

И затем получить адрес:

6.4. Отправка транзакций

List inputParams = new ArrayList();
List outputParams = new ArrayList();
Function function = new Function("fuctionName", inputParams, outputParams);
String encodedFunction = FunctionEncoder.encode(function);

Чтобы отправить транзакцию с использованием функций нашего контракта, мы можем инициализировать функцию Web3j со списком входных значений и списком выходных параметров:

BigInteger nonce = BigInteger.valueOf(100);
BigInteger gasprice = BigInteger.valueOf(100);
BigInteger gaslimit = BigInteger.valueOf(100);

Transaction transaction = Transaction
  .createFunctionCallTransaction("FROM_ADDRESS", 
    nonce, gasprice, gaslimit, "TO_ADDRESS", encodedFunction);

EthSendTransaction transactionResponse = web3j.ethSendTransaction(transaction).sendAsync().get();
transactionHash = transactionResponse.getTransactionHash();

Затем мы можем инициализировать нашу транзакцию необходимым газом ( используется для выполнения транзакции) и параметры nonce:

Полный список функций смарт-контракта см. в официальной документации.

7. Заключение

Вот и все! Мы создали приложение Java Spring MVC с Web3j — пришло время блокчейна!