web3j is a lightweight, reactive, type safe Java and Android library for integrating with clients (nodes) on the Ethereum network:
This allows you to work with the Ethereum blockchain, without the additional overhead of having to write your own integration code for the platform.
The Java and the Blockchain talk provides an overview of blockchain, Ethereum and web3j.
- Complete implementation of Ethereum's JSON-RPC client API over HTTP and IPC
- Ethereum wallet support
- Auto-generation of Java smart contract wrappers to create, deploy, transact with and call smart contracts from native Java code
- Reactive-functional API for working with filters
- Support for Parity's Personal, and Geth's Personal client APIs
- Support for Infura, so you don't have to run an Ethereum client yourself
- Comprehensive integration tests demonstrating a number of the above scenarios
- Command line tools
- Android compatible
- Support for JP Morgan's Quorum via web3j-quorum
It has seven runtime dependencies:
- RxJava for its reactive-functional API
- Apache HTTP Client
- Jackson Core for fast JSON serialisation/deserialisation
- Bouncy Castle (Spongy Castle for Android) and Java Scrypt for crypto
- JavaPoet for generating smart contract wrappers
- Jnr-unixsocket for *nix IPC
Full project documentation is available at Read the Docs.
You can help fund the development of web3j by donating to the following wallet addresses:
| Ethereum | 0x2dfBf35bb7c3c0A466A6C48BEBf3eF7576d3C420 |
| Bitcoin | 1DfUeRWUy4VjekPmmZUNqCjcJBMwsyp61G |
Commercial support and training is available from blk.io.
Add the relevant dependency to your project:
Java 8:
<dependency> <groupId>org.web3j</groupId> <artifactId>core</artifactId> <version>2.3.1</version> </dependency>Android:
<dependency> <groupId>org.web3j</groupId> <artifactId>core-android</artifactId> <version>2.2.1</version> </dependency>Java 8:
compile ('org.web3j:core:2.3.1')Android:
compile ('org.web3j:core-android:2.2.1')Start up an Ethereum client if you don't already have one running, such as Geth:
$ geth --rpcapi personal,db,eth,net,web3 --rpc --testnetOr Parity:
$ parity --chain testnetOr use Infura, which provides free clients running in the cloud:
Web3jweb3 = Web3j.build(newInfuraHttpService("https://morden.infura.io/your-token"));For further information refer to Using Infura with web3j
To send asynchronous requests using a Future:
Web3jweb3 = Web3j.build(newHttpService()); // defaults to http://localhost:8545/Web3ClientVersionweb3ClientVersion = web3.web3ClientVersion().sendAsync().get(); StringclientVersion = web3ClientVersion.getWeb3ClientVersion();To use an RxJava Observable:
Web3jweb3 = Web3j.build(newHttpService()); // defaults to http://localhost:8545/web3.web3ClientVersion().observable().subscribe(x ->{StringclientVersion = x.getWeb3ClientVersion(); ... });To send synchronous requests:
Web3jweb3 = Web3j.build(newHttpService()); // defaults to http://localhost:8545/Web3ClientVersionweb3ClientVersion = web3.web3ClientVersion().send(); StringclientVersion = web3ClientVersion.getWeb3ClientVersion();Note: for Android use:
Web3jweb3 = Web3jFactory.build(newHttpService()); // defaults to http://localhost:8545/ ...web3j also supports fast inter-process communication (IPC) via file sockets to clients running on the same host as web3j. To connect simply use the relevent IpcService implemntation instead of HttpService when you create your service:
// OS X/Linux/Unix:Web3jweb3 = Web3j.build(newUnixIpcService("/path/to/socketfile")); ... // WindowsWeb3jweb3 = Web3j.build(newWindowsIpcService("/path/to/namedpipefile")); ...Note: IPC is not currently available on web3j-android.
web3j functional-reactive nature makes it really simple to setup observers that notify subscribers of events taking place on the blockchain.
To receive all new blocks as they are added to the blockchain:
Subscriptionsubscription = web3j.blockObservable(false).subscribe(block ->{... });To receive all new transactions as they are added to the blockchain:
Subscriptionsubscription = web3j.transactionObservable().subscribe(tx ->{... });To receive all pending transactions as they are submitted to the network (i.e. before they have been grouped into a block together):
Subscriptionsubscription = web3j.pendingTransactionObservable().subscribe(tx ->{... });Or, if you'd rather replay all blocks to the most current, and be notified of new subsequent blocks being created:
There are a number of other transaction and block replay Observables described in the docs.
Topic filters are also supported:
EthFilterfilter = newEthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, <contract-address>) .addSingleTopic(...)|.addOptionalTopics(..., ...)|...; web3j.ethLogObservable(filter).subscribe(log ->{... });Subscriptions should always be cancelled when no longer required:
subscription.unsubscribe();Note: filters are not supported on Infura.
For further information refer to Filters and Events and the Web3jRx interface.
web3j provides support for both working with Ethereum wallet files (recommended) and Ethereum client admin commands for sending transactions.
To send Ether to another party using your Ethereum wallet file:
Web3jweb3 = Web3j.build(newHttpService()); // defaults to http://localhost:8545/Credentialscredentials = WalletUtils.loadCredentials("password", "/path/to/walletfile"); TransactionReceipttransactionReceipt = Transfer.sendFunds( web3, credentials, "0x...", BigDecimal.valueOf(1.0), Convert.Unit.ETHER);Or if you wish to create your own custom transaction:
Web3jweb3 = Web3j.build(newHttpService()); // defaults to http://localhost:8545/Credentialscredentials = WalletUtils.loadCredentials("password", "/path/to/walletfile"); // get the next available nonceEthGetTransactionCountethGetTransactionCount = web3j.ethGetTransactionCount( address, DefaultBlockParameterName.LATEST).sendAsync().get(); BigIntegernonce = ethGetTransactionCount.getTransactionCount(); // create our transactionRawTransactionrawTransaction = RawTransaction.createEtherTransaction( nonce, <gasprice>, <gaslimit>, <toAddress>, <value>); // sign & send our transactionbyte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); StringhexValue = Hex.toHexString(signedMessage); EthSendTransactionethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get(); // ...Although it's far simpler using web3j's Java smart contract wrappers.
Using an Ethereum client's admin commands (make sure you have your wallet in the client's keystore):
Parityparity = Parity.build(newHttpService()); // defaults to http://localhost:8545/PersonalUnlockAccountpersonalUnlockAccount = parity.personalUnlockAccount("0x000...", "a password").sendAsync().get(); if (personalUnlockAccount.accountUnlocked()){// send a transaction, or use parity.personalSignAndSendTransaction() to do it all in one }web3j can auto-generate smart contract wrapper code to deploy and interact with smart contracts without leaving Java.
To generate the wrapper code, compile your smart contract:
$ solc <contract>.sol --bin --abi --optimize -o <output-dir>/Then generate the wrapper code using web3j's Command line tools:
web3j solidity generate /path/to/<smart-contract>.bin /path/to/<smart-contract>.abi -o /path/to/src/main/java -p com.your.organisation.nameOr in code:
org.web3j.codegen.SolidityFunctionWrapperGenerator /path/to/<smart-contract>.bin /path/to/<smart-contract>.abi -o /path/to/src/main/java -p com.your.organisation.nameNow you can create and deploy your smart contract:
Web3jweb3 = Web3j.build(newHttpService()); // defaults to http://localhost:8545/Credentialscredentials = WalletUtils.loadCredentials("password", "/path/to/walletfile"); YourSmartContractcontract = YourSmartContract.deploy( <web3j>, <credentials>, GAS_PRICE, GAS_LIMIT, <initialEtherValue>, <param1>, ..., <paramN>).get(); // constructor paramsOr use an existing:
YourSmartContractcontract = YourSmartContract.load( "0x<address>", <web3j>, <credentials>, GAS_PRICE, GAS_LIMIT);To Transact with a smart contract:
TransactionReceipttransactionReceipt = contract.someMethod( newType(...), ...).get();To call a smart contract:
Typeresult = contract.someMethod(newType(...), ...).get();For more information refer to the documentation.
A web3j fat jar is distributed with each release providing command line tools. The command line tools allow you to use some of the functionality of web3j from the command line:
- Wallet creation
- Wallet password management
- Transfer of funds from one wallet to another
- Generate Solidity smart contract function wrappers
Please refer to the documentation for further information.
In the Java 8 build:
- web3j provides type safe access to all responses. Optional or null responses are wrapped in Java 8's Optional type.
- Async requests are handled using Java 8's CompletableFutures.
In both the Java 8 and Andriod builds:
- Quantity payload types are returned as BigIntegers. For simple results, you can obtain the quantity as a String via Response.getResult().
- Geth
- Parity
You can run the integration test class CoreIT to verify clients.
For a .NET implementation, check out Nethereum.
For a pure Java implementation of the Ethereum client, check out EthereumJ and the work of Ether.Camp.
web3j includes integration tests for running against a live Ethereum client. If you do not have a client running, you can exclude their execution as per the below instructions.
To run a full build including integration tests:
$ ./gradlew checkTo run excluding integration tests:
$ ./gradlew -x integrationTest check- The Nethereum project for the inspiration
- Othera for the great things they are building on the platform
- Finhaus guys for putting me onto Nethereum
- bitcoinj for the reference Elliptic Curve crypto implementation
- Everyone involved in the Ethererum project and its surrounding ecosystem
- And of course the users of the library, who've provided valuable input & feedback - @ice09, @adridadou, @nickmelis, @basavk, @kabl, @MaxBinnewies, @vikulin, @sullis, @vethan, @h2mch, @mtiutin, @fooock, @ermyas, @danieldietrich, @matthiaszimmermann, @ferOnti, @fraspadafora, @bigstar119, @gagarin55, @thedoctor, @tramonex-nate, @ferOnti
