Leichte Ethereum-Clients, die Web3j verwenden

1. Einführung

In diesem Lernprogramm wird Web3j vorgestellt, eine Java-Implementierung der beliebten Web3-Abstraktionsbibliothek.

  • Web3j wird für die Interaktion mit dem Ethereum-Netzwerk verwendet, indem über JSON-RPC ** oder bekannte Standards wie HTTP, WebSockets, IPC eine Verbindung zu Ethereum-Knoten hergestellt wird.

Ethereum ist ein Thema für sich, also werfen wir zunächst einen Blick darauf, was es ist!

2. Äther

Ethereum ist ein (1) cryptocurrency (Tokensymbol ETH ), (2) verteilter Supercomputer, (3) Blockchain und (4) in __Solidity geschriebenes intelligentes Vertragsnetzwerk.

Mit anderen Worten, Ethereum (das Netzwerk ) wird von einer Reihe verbundener Server namens nodes ausgeführt, die in einer Art Netztopologie kommunizieren. .

Web3j und seine übergeordnete Bibliothek mit dem Namen Web3 ermöglichen es web-Anwendungen , sich mit einem dieser nodes zu verbinden und dadurch Ethereum -Transaktionen zu übergeben, , die für alle Absichten und Zwecke kompilierte Solidity smart contract functions sind, die zuvor bereitgestellt wurden zum Ethereum network . Weitere Informationen zu intelligenten Verträgen finden Sie in unserem Artikel zum Erstellen und Bereitstellen dieser Verträge mit Solidity hier .

Jeder Knoten sendet seine Änderungen an jeden anderen Knoten, so dass Konsens und Verifizierung erzielt werden können. Somit enthält jeder node die gesamte Historie des Ethereum blockchain gleichzeitig , wodurch eine redundante Sicherung aller Daten auf manipulationssichere Weise und durch Konsens und Überprüfung durch alle anderen node im network erstellt wird.

Weitere Informationen zu Ethereum finden Sie auf der Seite official .

3. Konfiguration

Um die vollständige Palette an Funktionen von Web3j nutzen zu können, müssen wir uns etwas mehr als üblich einrichten. Zunächst wird Web3j in mehreren freistehenden Modulen geliefert, die jeweils optional zur Kernabhängigkeit pom.xml hinzugefügt werden können:

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

Bitte beachten Sie, dass das Team von Web3j einen vorgefertigten Spring Boot Starter mit einiger Konfiguration und eingeschränkter Funktionalität enthält!

Wir beschränken uns auf die Kernfunktionalitäten in diesem Artikel (einschließlich des Hinzufügens von Web3j zu einer Spring MVC-Anwendung, sodass Kompatibilität mit einer größeren Bandbreite von Spring-Webanwendungen erzielt wird).

Eine vollständige Liste dieser Module finden Sie unter https://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22core%22%20AND%20g%3A%22org.web3j%22 Zentral].

3.1. Vertragserstellung: Truffle oder Solc

Es gibt zwei Hauptmethoden zum Kompilieren und Bereitstellen von intelligenten Ethereum-Verträgen (. solc -Dateien):

  1. Das offizielle

Solidity Compiler.

  1. Truffle (eine Abstraktions-Suite)

zum Testen, Bereitstellen und Verwalten von intelligenten Verträgen).

Wir bleiben in diesem Artikel bei Truffle. Truffle vereinfacht und abstrahiert das Kompilieren von intelligenten Verträgen , deren Migration und Bereitstellung in einem Netzwerk. Es schließt auch den Solc -Compiler ein, sodass wir mit beiden Erfahrungen sammeln können.

So richten Sie Trüffel ein:

$ npm install truffle -g
$ Trüffelversion

Vier wichtige Befehle, mit denen wir unser Projekt initialisieren bzw. kompilieren, unsere App für die Blockchain bereitstellen und jeweils testen:

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

Gehen wir nun ein einfaches Beispiel durch:

pragma solidity ^0.4.17;

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

Welches sollte beim Kompilieren den folgenden ABI-JSON ergeben:

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

Wir können dann den gelieferten Bytecode und die ABI in unserer Anwendung verwenden, um mit den bereitgestellten Verträgen zu interagieren!

3.2. Testverträge: Ganache

  • Eine der einfachsten Möglichkeiten, um mit einem Ethereum-Testnetz zu arbeiten, besteht darin, einen eigenen Ganache -Server zu starten. ** Wir verwenden den vorgefertigten, sofort einsatzbereiten Lösung, da es am einfachsten einzurichten und zu konfigurieren ist. Es bietet auch eine Schnittstelle und eine Server-Shell für Ganache CLI, die Ganache unter die Haube treiben.

Wir können eine Verbindung zu unserem Ganache-Server unter der standardmäßig angegebenen URL-Adresse herstellen: http://localhost : 8545 oder http://localhost : 7545.

Es gibt eine Reihe weiterer populärer Ansätze zum Einrichten eines Testnetzwerks, z. B. Meta-Mask , https://web3j.readthedocs.io/de/latest/infura.html oder Go-Lang and Geth .

Wir werden uns in diesem Artikel an Ganache halten, da das Einrichten einer eigenen GoLang-Instanz (und das Konfigurieren als benutzerdefiniertes Testnetz) ziemlich kompliziert sein kann und der Status von Meta-Mask in Chrome derzeit unsicher ist.

Wir können Ganache für manuelle Testszenarien verwenden (beim Debuggen oder Durchführen unserer Integrationstests) oder für automatisierte Testszenarien (um die wir unsere Tests herumbauen müssen, da uns unter solchen Umständen möglicherweise keine verfügbaren Endpunkte zur Verfügung stehen).

4. Web3 und RPC

Web3 bietet eine Fassade und eine Schnittstelle für die einfache Interaktion mit den Ethereum-Blockchain- und Ethereum-Serverknoten. Mit anderen Worten, Web3 erleichtert die Kommunikation zwischen Clients und der Ethereum Blockchain über JSON-RPC. ** Web3J ist der offizielle Java-Port von https://github.com/ethereum/web3.js

Wir können Web3j für die Verwendung in unserer Anwendung initialisieren, indem Sie einen Provider (z. B. den Endpunkt eines Drittanbieter- oder lokalen Ethereum-Knotens) übergeben:

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

Die dritte Option zeigt, wie ein Drittanbieter hinzugefügt wird (wodurch eine Verbindung zu seinem Ethereum-Knoten hergestellt wird). Wir haben aber auch die Möglichkeit, unsere Provider-Option leer zu lassen. In diesem Fall wird der Standardport ( 8545 ) anstelle von localhost verwendet. _. _

5. Wesentliche Web3-Methoden

Nun, da wir wissen, wie Sie unsere App für die Kommunikation mit der Ethereum-Blockkette initialisieren, wollen wir uns einige Kernmöglichkeiten der Interaktion mit der Ethereum-Blockchain ansehen.

Es ist eine gute Richtlinie, Ihre Web3-Methoden mit CompleteableFuture zu umschließen, um die asynchronen Anforderungen von JSON-RPC-Anforderungen an Ihren konfigurierten Ethereum-Knoten zu behandeln.

5.1. Aktuelle Blocknummer

Wir können zB die aktuelle Blocknummer zurückgeben :

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

5.2. Konto

So erhalten Sie das Konto einer angegebenen Adresse :

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

5.3. Anzahl der Kontotransaktionen

So ermitteln Sie die Anzahl der Transaktionen einer bestimmten Adresse :

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. Kontostand

Und schließlich, um den aktuellen Kontostand einer Adresse oder Brieftasche zu erhalten:

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

6. Arbeiten mit Verträgen in Web3j

Nachdem wir unseren Solidity-Vertrag mit Truffle erstellt haben, können wir mit unseren kompilierten Application Binary Interfaces ( ABI ) mit dem eigenständigen Web3j-Befehlszeilentool ( https://docs.web3j.io/command line.html[hier]) oder als freistehende zip https://github.com/web3j/web3j/releases/download/v3.3.1/web3j-3.3.1.zip hier].

6.1. CLI Magic

Wir können dann automatisch unsere Java Smart Contract Wrapper (im Wesentlichen ein POJO, das die intelligente Vertrags-ABI verfügbar macht) mithilfe des folgenden Befehls generieren:

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

Führen Sie den folgenden Befehl im Stammverzeichnis des Projekts aus:

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

generierte unsere __Example __class:

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

6.2. Java POJOs

Jetzt, da wir unseren Smart Contract Wrapper haben, können wir eine Brieftasche programmgesteuert erstellen und unseren Vertrag an diese Adresse weiterleiten

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

6.3. Einen Vertrag bereitstellen

Wir können unseren Vertrag so einsetzen:

Example contract = Example.deploy(this.web3j,
  credentials,
  ManagedTransaction.GAS__PRICE,
  Contract.GAS__LIMIT).send();

Und dann die Adresse bekommen:

contractAddress = contract.getContractAddress();

6.4. Senden von Transaktionen

Um eine Transaction mit den Functions unseres Contract zu senden, können Sie eine Web3j Function mit einer List von Eingabewerten und einer List von Ausgabeparametern initialisieren:

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

Wir können dann unsere Transaction mit den notwendigen gas (zur Ausführung der Transaction ) und nonce-Parametern initialisieren:

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

Eine vollständige Liste der intelligenten Vertragsfunktionalitäten finden Sie unter https://docs.web3j.io/transactions.html (Offizielle Dokumente).

7. Fazit

Das ist es! Wir haben eine Java Spring MVC-App mit Web3j eingerichtet - die Zeit der Blockchain

Die in diesem Artikel verwendeten Codebeispiele sind wie immer unter GitHub verfügbar.