Clientes ligeros de Ethereum que utilizan Web3j

Parte superior de Java

Acabo de anunciar el nuevo curso Learn Spring , centrado en los fundamentos de Spring 5 y Spring Boot 2:

>> VER EL CURSO

1. Introducción

Este tutorial presenta Web3j, una implementación de Java de la popular biblioteca de abstracción Web3.

Web3j se usa para interactuar con la red Ethereum al conectarse a los nodos Ethereum usando JSON-RPC o estándares familiares como HTTP, WebSockets, IPC.

Ethereum es un tema en sí mismo, ¡así que primero echemos un vistazo rápido a lo que es!

2. Ethereum

Ethereum es una (1) criptomoneda (símbolo de token ETH), (2) supercomputadora distribuida, (3) blockchain y (4) red de contrato inteligente escrita en Solidity.

En otras palabras, Ethereum (la red ) es administrado por un grupo de servidores conectados llamados nodos que se comunican en una especie de topología de malla (técnicamente, esto no es exactamente cierto, pero lo suficientemente cerca como para obtener una comprensión más sólida de cómo funciona todo). .

Web3j , y su biblioteca principal llamada Web3 , permite que las aplicaciones web se conecten a uno de esos nodos y, por lo tanto, envíen transacciones de Ethereum , que son, para todos los efectos, funciones de contrato inteligente de Solidity compiladas que se han implementado previamente en la red Ethereum . Para obtener más información sobre contratos inteligentes, consulte nuestro artículo sobre cómo crearlos e implementarlos con Solidity aquí.

Cada nodo transmite sus cambios a todos los demás nodos para que se pueda lograr el consenso y la verificación. Por lo tanto, cada nodo contiene el historial completo de la cadena de bloques Ethereum simultáneamente , creando así una copia de seguridad redundante de todos los datos, a prueba de manipulaciones, y mediante consenso y verificación por parte de todos los demás nodos de la red . \

Para obtener información más detallada sobre Ethereum, consulte la página oficial.

3. Configurar

Para utilizar el conjunto completo de funciones proporcionadas por Web3j, tenemos que hacer un poco más de configuración de lo habitual. Primero, Web3j se suministra en varios módulos independientes, cada uno de los cuales se puede agregar opcionalmente a la dependencia principal pom.xml :

 org.web3j core 3.3.1  

Tenga en cuenta que el equipo de Web3j proporciona un Spring Boot Starter prediseñado con algunas configuraciones y funciones limitadas integradas.

Restringiremos nuestro enfoque a las funcionalidades centrales en este artículo (incluido cómo agregar Web3j a una aplicación Spring MVC, de modo que se obtenga compatibilidad con una gama más amplia de aplicaciones web Spring).

Puede encontrar una lista completa de estos módulos en Maven Central.

3.1. Compilación de contratos: trufa o solc

Hay dos formas principales de compilar e implementar contratos inteligentes de Ethereum ( archivos . Solc ):

  1. El compilador oficial de Solidity.
  2. Truffle (una suite de abstracción para probar, implementar y administrar contratos inteligentes).

Nos quedaremos con Truffle en este artículo. Truffle simplifica y abstrae el proceso de compilación de contratos inteligentes , migrarlos e implementarlos en una red. También envuelve el compilador de Solc permitiéndonos ganar algo de experiencia con ambos.

Para configurar Truffle:

$ npm install truffle -g $ truffle version

Cuatro comandos clave que usaremos para inicializar nuestro proyecto respectivamente, compilar nuestra aplicación, implementar nuestra aplicación en Blockchain y probarla respectivamente:

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

Ahora, repasemos un ejemplo simple:

pragma solidity ^0.4.17; contract Example { function Example() { // constructor } } 

Lo que debería producir el siguiente ABI JSON cuando se compila:

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

¡Entonces podemos usar el código de bytes proporcionado y ABI dentro de nuestra aplicación para interactuar con los contratos implementados!

3.2. Contratos de prueba: Ganache

Una de las formas más fáciles de trabajar con una red de prueba de Ethereum es lanzar su propio servidor Ganache. Usaremos la solución prediseñada y lista para usar, ya que es la más fácil de instalar y configurar. También proporciona una interfaz y un shell de servidor para Ganache CLI que controla Ganache bajo el capó.

Podemos conectarnos a nuestro servidor Ganache en la dirección URL proporcionada por defecto: // localhost: 8545 o // localhost: 7545.

Hay un par de otros enfoques populares para configurar una red de prueba, incluido el uso de Meta-Mask, Infura o Go-Lang y Geth.

Seguiremos con Ganache en este artículo, ya que configurar su propia instancia de GoLang (y configurarla como una red de prueba personalizada) puede ser bastante complicado y dado que el estado de Meta-Mask en Chrome es actualmente incierto.

Podemos usar Ganache para escenarios de prueba manual (al depurar o completar nuestras pruebas de integración) o usarlos para escenarios de prueba automatizados (sobre los cuales tenemos que construir nuestras pruebas ya que, en tales circunstancias, es posible que no tengamos los puntos finales disponibles).

4. Web3 y RPC

Web3 proporciona una fachada e interfaz para interactuar fácilmente con la cadena de bloques Ethereum y los nodos del servidor Ethereum. En otras palabras, Web3 facilita la intercomunicación entre los clientes y Ethereum Blockchain a través de JSON-RPC. Web3J es el puerto Java oficial de Web3.

Podemos inicializar Web3j para su uso dentro de nuestra aplicación pasando un proveedor (por ejemplo, el punto final de un nodo Ethereum local o de terceros):

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

The third option shows how to add in a third-party provider (thereby connecting with their Ethereum node). But we also have the option to leave our provider option empty. In that case, the default port will be used (8545) on localhost instead.

5. Essential Web3 Methods

Now that we know how to initialize our app to communicate with the Ethereum blockchain, let's look at a few, core, ways to interact with the Ethereum blockchain.

It's a good policy to wrap your Web3 methods with a CompleteableFuture to handle the asynchronous nature of JSON-RPC requests made to your configured Ethereum node.

5.1. Current Block Number

We can, for example, return the current block number:

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

5.2. Account

To get the account of a specified address:

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

5.3. Number of Account Transactions

To get the number of transactions of a given address:

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

5.4. Account Balance

And finally, to get the current balance of an address or wallet:

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

6. Working With Contracts in Web3j

Once we've compiled our Solidity contract using Truffle, we can work with our compiled Application Binary Interfaces (ABI) using the standalone Web3j command line tool available here or as a free-standing zip here.

6.1. CLI Magic

We can then automatically generate our Java Smart Contract Wrappers (essentially a POJO exposing the smart contract ABI) using the following command:

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

Running the following command in the root of the project:

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

generated our Example class:

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

6.2. Java POJO's

Now that we have our Smart Contract Wrapper, we can create a wallet programmatically and then deploy our contract to that address:

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

6.3. Deploy a Contract

We can deploy our contract like so:

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

And then get the address:

contractAddress = contract.getContractAddress();

6.4. Sending Transactions

To send a Transaction using the Functions of our Contract we can initialize a Web3j Function with a List of input values and a List of output parameters:

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

We can then initialize our Transaction with necessary gas (used to execute of the Transaction) and nonce parameters:

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

Para obtener una lista completa de las funcionalidades de los contratos inteligentes, consulte los documentos oficiales.

7. Conclusión

¡Eso es! Hemos configurado una aplicación Java Spring MVC con Web3j : ¡es hora de Blockchain!

Como siempre, los ejemplos de código utilizados en este artículo están disponibles en GitHub.

Fondo de Java

Acabo de anunciar el nuevo curso Learn Spring , centrado en los fundamentos de Spring 5 y Spring Boot 2:

>> VER EL CURSO