https://www.baeldung.com/web3j
1. Introduction
This tutorial introduces Web3j, a Java implementation of the popular Web3?abstraction library.
Web3j is used to interact with the Ethereum network by connecting to Ethereum nodes using?JSON-RPC?or familiar standards like HTTP, WebSockets, IPC.
Ethereum is a?whole topic unto itself so let’s first take a quick look at what it is!
2. Ethereum
Ethereum is a (1)?cryptocurrency?(token symbol?ETH), (2) distributed supercomputer, (3) blockchain, and (4) smart contract network written in?Solidity.
In other words, Ethereum (the?network) is run by a bunch of connected servers called?nodes?that communicate in a kind of mesh topology (technically, this is not exactly true but close enough to get a more solid understanding of how it all works).
Web3j, and its parent library called?Web3,?allows?web applications?to connect to one of those?nodes?and thereby submit Ethereum?transactions,which are, for all intents and purposes, compiled Solidity?smart contract?functionsthat have been previously deployed to the Ethereum?network. For more information on smart contracts see our article on creating and deploying them with Solidity?here.
Each Node broadcasts its changes to every other?node?so that consensus and verification can be achieved. Thus,?each?node?contains the entire history of the?Ethereum blockchain?simultaneously?thereby creating a redundant backup of all the data, in a tamper-proof way, and via consensus and verification by all the other?nodein the?network.\
For more detailed information on Ethereum, check out the?official page.
3. Set Up
To use the full suite of features provided by Web3j, we have to do a little bit more to get set up than usual. First, Web3j is supplied in several, free-standing, modules each of which can be optionally added to the corepom.xmldependency:
1
2
3
4
5
<dependency>
????<groupId>org.web3j</groupId>
????<artifactId>core</artifactId>
????<version>3.3.1</version>
</dependency>
Please note that?the team at Web3j provides a pre-built Spring Boot Starter with some configuration and limited functionality built right in!
We’ll restrict our focus to the core functionalities in this article (including how to add Web3j to a Spring MVC application, so compatibility with a wider-range of Spring webapps is obtained).
A full list of these modules can be found on?Maven Central.
3.1. Compiling Contracts: Truffle or Solc
There are two primary ways to compile and deploy Ethereum smart contracts (.solc?files):
The official?Solidity?compiler.
Truffle(an abstraction suite for testing, deploying, and managing smart contracts).
We’ll stick with Truffle in this article.?Truffle simplifies and abstracts the process of compiling smart contracts, migrating them, and deploying them to a network. It also wraps the?Solc?compiler letting us gain some experience with both.
To set up Truffle:
$ npm install truffle -g
$ truffle version
Four key commands we’ll use to initialize our project respectively, compile our app, deploy our app to the Blockchain, and test it respectively:
1
2
3
4
$ truffle init
$ truffle compile
$ truffle migrate
$ truffle test
Now, let’s go over a simple example:
1
2
3
4
5
6
7
pragma solidity ^0.4.17;
contract Example {
??function Example() {
????// constructor
??}
}
Which should yield the following ABI JSON when compiled:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
??"contractName": "Example",
??"abi": [
????{
??????"inputs": [],
??????"payable": false,
??????"stateMutability": "nonpayable",
??????"type": "constructor"
????}
??],
??"bytecode": "0x60606040523415600e57600080fd5b603580601b6...,
??"deployedBytecode": "0x6060604052600080fd00a165627a7a72305...,
??//...
}
We can then use the supplied bytecode and ABI within our application to interact with the deployed contracts!
3.2. Testing Contracts: Ganache
One of the easiest ways to work with an Ethereum testnet is to launch own?Ganache?server.?We’ll use the?pre-built, out-of-the-box, solution since it’s the easiest to set up and configure. It also provides an interface and server shell for Ganache CLI which drives Ganache under-the-hood.
We can connect to our Ganache server on the default supplied URL address:?http://localhost:8545 or http://localhost:7545.
There are a couple of other popular approaches to setting up a test network including using?Meta-Mask,?Infura, orGo-Lang and Geth.
We’ll stick with Ganache in this article since setting up your own GoLang?instance (and configuring it as a custom testnet) can be pretty tricky and since the status of Meta-Mask on Chrome is presently uncertain.
We can use Ganache for manual testing scenarios (when debugging or completing our integration testing) or use them for automated testing scenarios (which we have to build our tests around since, in such circumstances, we might not have the available endpoints).
4. Web3 and RPC
Web3 provides a facade and interface for interacting easily with the Ethereum blockchain and Ethereum server nodes. In other words,?Web3 facilitates intercommunication between clients and the Ethereum Blockchain?by way of JSON-RPC.?Web3J is the official Java port of?Web3.
We can initialize Web3j for use within our application by passing in a provider (e.g. – the endpoint of a third-party or local Ethereum node):
1
2
3
4
Web3j web3a = Web3j.build(newHttpService());
Web3j web3b = Web3j.build(newHttpService("YOUR_PROVIDER_HERE"));
Web3j myEtherWallet = Web3j.build(
??newHttpService("https://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:
1
2
3
4
5
6
7
publicCompletableFuture<EthBlockNumber> getBlockNumber() {
????EthBlockNumber result = newEthBlockNumber();
????result = this.web3j.ethBlockNumber()
??????.sendAsync()
??????.get();
????returnCompletableFuture.completedFuture(result);
}
5.2. Account
To get the?account of a specified address:
1
2
3
4
5
6
7
publicCompletableFuture<EthAccounts> getEthAccounts() {
????EthAccounts result = newEthAccounts();
????result = this.web3j.ethAccounts()
????????.sendAsync()
????????.get();
????returnCompletableFuture.completedFuture(result);
}
5.3. Number of Account Transactions
To get the?number of transactions of a given address:
1
2
3
4
5
6
7
8
publicCompletableFuture<EthGetTransactionCount> getTransactionCount() {
????EthGetTransactionCount result = newEthGetTransactionCount();
????result = this.web3j.ethGetTransactionCount(DEFAULT_ADDRESS,
??????DefaultBlockParameter.valueOf("latest"))
????????.sendAsync()
????????.get();
????returnCompletableFuture.completedFuture(result);
}
5.4. Account Balance
And finally, to get the?current balance of an address or wallet:
1
2
3
4
5
6
7
8
publicCompletableFuture<EthGetBalance> getEthBalance() {
????EthGetBalance result = newEthGetBalance();
????this.web3j.ethGetBalance(DEFAULT_ADDRESS,
??????DefaultBlockParameter.valueOf("latest"))
????????.sendAsync()
????????.get();
????returnCompletableFuture.completedFuture(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:
1
2
3
$ web3j truffle generate [--javaTypes|--solidityTypes]
??/path/to/<truffle-smart-contract-output>.json
??-o /path/to/src/main/java-p com.your.organisation.name
Running the following command in the root of the project:
1
2
web3j truffle generate dev_truffle/build/contracts/Example.json
??-o src/main/java/com/baeldung/web3/contract-p com.baeldung
generated our?Example?class:
1
2
3
4
publicclassExample extendsContract {
????privatestaticfinalString 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:
1WalletUtils.generateNewWalletFile("PASSWORD", newFile("/path/to/destination"), true);
1Credentials credentials = WalletUtils.loadCredentials("PASSWORD", "/path/to/walletfile");
6.3. Deploy A Contract
We can deploy our contract like so:
1
2
3
4
Example contract = Example.deploy(this.web3j,
??credentials,
??ManagedTransaction.GAS_PRICE,
??Contract.GAS_LIMIT).send();
And then get the address:
1contractAddress = contract.getContractAddress();
6.4. Sending Transactions
To send aTransaction?using the?Functions?of our?Contract?we? can initialize a Web3j?Function?with a?List?of input values and a?List?of output parameters:
1
2
3
4
List inputParams = newArrayList();
List outputParams = newArrayList();
Function function = newFunction("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:
1
2
3
4
5
6
7
8
9
10
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();
For a full list of smart contract functionalities see theofficial docs.
7. Conclusion
That’s it!?We’ve set up a Java Spring MVC app with Web3j?– it’s Blockchain time!
As always, the code examples used in this article are available over on?GitHub.