Легкие клиенты Ethereum, использующие Web3j

1. Вступление

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

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

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

2. Ethereum

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

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

Web3j и его родительская библиотека Web3 позволяют web Applications подключаться к одному из этих nodes и, таким образом, отправлять транзакции Ethereum , которые для всех намерений и целей являются скомпилированными Solidity smart contract functions , которые были ранее развернуты в Эфириум network__. Для получения дополнительной информации о смарт-контрактах см. Нашу статью о создании и развертывании их с помощью ссылки Solidity:/smart-contract-ethereum-solidity[здесь].

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

Для получения более подробной информации об Ethereum посетите страницу official .

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 Центральная .

3.1. Составление договоров: трюфель или солк

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

, Официальный

Solidity компилятор.

, Truffle (набор абстракций

для тестирования, развертывания и управления смарт-контрактами).

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

Чтобы настроить трюфель:

$ npm установить трюфель -g
трюфельная версия

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

$ 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 and 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 ) на localhost вместо _. _

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

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

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

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

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

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

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

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

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

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

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

public CompletableFuture<EthGetTransactionCount> getTransactionCount() {
    EthGetTransactionCount result = new EthGetTransactionCount();
    result = this.web3j.ethGetTransactionCount(DEFAULT__ADDRESS,
      DefaultBlockParameter.valueOf("latest"))
        .sendAsync()
        .get();
    return CompletableFuture.completedFuture(result);
}

5.4. Баланс

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

public CompletableFuture<EthGetBalance> getEthBalance() {
    EthGetBalance result = new EthGetBalance();
    this.web3j.ethGetBalance(DEFAULT__ADDRESS,
      DefaultBlockParameter.valueOf("latest"))
        .sendAsync()
        .get();
    return CompletableFuture.completedFuture(result);
}

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

После того, как мы скомпилировали наш контракт Solidity с использованием Truffle, мы можем работать с нашими скомпилированными Application Binary Interfaces ( ABI ), используя автономный инструмент командной строки Web3j, доступный here или как автономный почтовый индекс here .

6.1. CLI Magic

Затем мы можем автоматически генерировать наши Java Smart Contract Wrappers (по сути, 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

сгенерировал наш __Example __class:

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

6.2. Java POJO

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

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. Отправка транзакций

Чтобы отправить Transaction с помощью Functions нашего Contract , мы можем инициализировать Function Web3j с List входных значений и List выходных параметров:

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

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

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();

Полный список функциональных возможностей смарт-контрактов см. В official docs .

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

Это оно! Мы создали приложение Java Spring MVC с Web3j - сейчас самое время Blockchain!

Как всегда, примеры кода, используемые в этой статье, доступны на GitHub .