Clients Lighteum Ethereum utilisant Web3j

1. Introduction

Ce tutoriel présente Web3j, une implémentation Java de la célèbre bibliothèque d’abstractions Web3.

  • Web3j est utilisé pour interagir avec le réseau Ethereum en se connectant aux nœuds Ethereum à l’aide de JSON-RPC ** ou de normes connues telles que HTTP, WebSockets, IPC.

Ethereum est un sujet à part entière, jetons donc un coup d’œil sur ce qu’il en est!

2. Ethereum

Ethereum est un (1) cryptocurrency (symbole symbolique ETH ), (2) un superordinateur distribué, (3) une chaîne de chaînes et (4) un réseau de contrat intelligent écrit en Solidity.

En d’autres termes, Ethereum (le réseau) est géré par un groupe de serveurs connectés appelés nœuds, qui communiquent selon une sorte de topologie maillée (techniquement, ce n’est pas tout à fait vrai mais suffisamment proche pour permettre de mieux comprendre comment cela fonctionne). .

Web3j , et sa bibliothèque parente appelée Web3 , permettent à web applications de se connecter à l’un de ces nodes et de soumettre ainsi les transactions Ethereum , qui sont, à toutes fins utiles, compilées Solidity smart contract __functions au réseau Ethereum. Pour plus d’informations sur les contrats intelligents, consultez notre article sur leur création et leur déploiement avec Solidity ici .

Chaque nœud diffuse ses modifications sur tous les autres nœuds afin que le consensus et la vérification puissent être atteints. Ainsi, chaque noeud contient simultanément l’historique complet de la blockchain d’Ethereum , créant ainsi une sauvegarde redondante de toutes les données, de manière inviolable, et par consensus et vérification par tous les autres node du réseau .

Pour plus d’informations sur Ethereum, consultez la page official .

3. Installer

Pour utiliser la suite complète des fonctionnalités fournies par Web3j, nous devons faire un peu plus pour configurer que d’habitude. Tout d’abord, Web3j est fourni dans plusieurs modules autonomes, chacun d’eux pouvant éventuellement être ajouté à la dépendance principale pom.xml :

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

Veuillez noter que l’équipe de Web3j fournit un démarreur Spring Boot pré-construit avec une configuration et des fonctionnalités limitées intégrées!

Dans cet article, nous nous limiterons aux principales fonctionnalités (notamment comment ajouter Web3j à une application Spring MVC afin d’obtenir la compatibilité avec un plus grand nombre d’applications Web Spring).

Une liste complète de ces modules est disponible à l’adresse Maven. Central .

3.1. Compilation de contrats: Truffe ou Solc

Il existe deux méthodes principales pour compiler et déployer des contrats intelligents Ethereum (fichiers . solc ):

  1. L’officiel

Solidity compilateur.

  1. Truffle (une suite d’abstraction

pour tester, déployer et gérer des contrats intelligents).

Nous allons nous en tenir à la truffe dans cet article. Truffle simplifie et simplifie le processus de compilation des contrats intelligents , de leur migration et de leur déploiement sur un réseau. Il englobe également le compilateur Solc , nous permettant d’acquérir une expérience des deux.

Pour configurer Truffle:

$ npm installer truffle -g
version truffe

Quatre commandes clés que nous utiliserons pour initialiser notre projet, compiler notre application, la déployer dans la chaîne de blocs et la tester:

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

Voyons maintenant un exemple simple:

pragma solidity ^0.4.17;

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

Ce qui devrait donner le JSON ABI suivant lors de la compilation:

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

Nous pouvons ensuite utiliser le bytecode et l’ABI fournis dans notre application pour interagir avec les contrats déployés!

3.2. Contrats d’essais: Ganache

  • L’un des moyens les plus simples de travailler avec un réseau de test Ethereum est de lancer son propre serveur Ganache . ** Nous utiliserons le logiciel pré-construit et prêt à l’emploi, C’est la solution la plus facile à configurer et à configurer. Il fournit également une interface et un shell de serveur pour Ganache CLI qui permettent à Ganache de fonctionner correctement.

Nous pouvons nous connecter à notre serveur Ganache à l’adresse URL fournie par défaut: http://localhost : 8545 ou http://localhost : 7545.

Il existe quelques autres approches populaires pour mettre en place un réseau de test, y compris Meta-Mask , Infura ou Go-Lang and Geth .

Nous nous en tiendrons à Ganache dans cet article car la configuration de votre propre instance GoLang (et sa configuration en tant que réseau de test personnalisé) peut s’avérer assez délicate et le statut de Meta-Mask sur Chrome étant actuellement incertain.

Nous pouvons utiliser Ganache pour des scénarios de tests manuels (lors du débogage ou de la fin de nos tests d’intégration) ou pour des scénarios de tests automatisés (sur lesquels nous devons construire nos tests car, dans de telles circonstances, nous pourrions ne pas disposer des points de terminaison disponibles).

4. Web3 et RPC

Web3 fournit une façade et une interface permettant d’interagir facilement avec les nœuds de serveur Ethereum blockchain et Ethereum. En d’autres termes, Web3 facilite l’intercommunication entre les clients et la Ethercha Blockchain via JSON-RPC. Web3J est le port Java officiel de Web3 . .

Nous pouvons initialiser Web3j pour une utilisation dans notre application en transmettant un fournisseur (par exemple, le point de terminaison d’un nœud Ethereum local ou tiers):

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

La troisième option montre comment ajouter un fournisseur tiers (en se connectant ainsi à son nœud Ethereum). Mais nous avons également la possibilité de laisser notre option de fournisseur vide. Dans ce cas, le port par défaut sera utilisé ( 8545 ) sur localhost à la place de _. _

5. Méthodes Web3 essentielles

Maintenant que nous savons initialiser notre application pour communiquer avec la blockchain Ethereum, examinons quelques méthodes principales permettant d’interagir avec la blockchain Ethereum.

C’est une bonne politique que d’envelopper vos méthodes Web3 avec un CompleteableFuture afin de gérer la nature asynchrone des requêtes JSON-RPC adressées à votre nœud Ethereum configuré.

5.1. Numéro de bloc actuel

Nous pouvons, par exemple, renvoyer le numéro de bloc actuel :

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

5.2. Compte

Pour obtenir le compte d’une adresse spécifiée :

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

5.3. Nombre de transactions de compte

Pour obtenir le nombre de transactions d’une adresse donnée :

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. Solde du compte

Et enfin, pour obtenir le solde actuel d’une adresse ou d’un portefeuille:

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

6. Travailler avec des contrats dans Web3j

Une fois que nous avons compilé notre contrat Solidity avec Truffle, nous pouvons utiliser nos interfaces binaires Application compilées ( ABI ) à l’aide de l’outil de ligne de commande Web3j autonome disponible à l’adresse https://docs.web3j.io/command line.html zip libre debout here .

6.1. CLI Magic

Nous pouvons ensuite générer automatiquement nos wrappers de contrat Java Smart (essentiellement un POJO exposant le ABI de contrat intelligent) à l’aide de la commande suivante:

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

Exécuter la commande suivante à la racine du projet:

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

généré notre __Example __class:

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

6.2. POJO Java

Maintenant que nous avons notre Smart Contract Wrapper , nous pouvons créer un portefeuille par programmation, puis déployer notre contrat à cette adresse :

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

6.3. Déployer un contrat

Nous pouvons déployer notre contrat comme suit:

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

Et puis obtenir l’adresse:

contractAddress = contract.getContractAddress();

6.4. Envoi de transactions

Pour envoyer une transaction en utilisant les fonctions de notre contrat, nous pouvons initialiser une fonction Web3j avec une liste de valeurs d’entrée et une liste de paramètres de sortie:

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

Nous pouvons ensuite initialiser notre Transaction avec les paramètres nécessaires gas (utilisés pour exécuter du Transaction ) et 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();

Pour obtenir une liste complète des fonctionnalités des contrats intelligents, consultez la page documents officiels .

7. Conclusion

C’est tout! Nous avons configuré une application Java Spring MVC avec Web3j - il est temps de passer au bloc!

Comme toujours, les exemples de code utilisés dans cet article sont disponibles sur GitHub .