Why Infura
Last year I published a tutorial helping you get started with the development of smart contracts and using them from java applications. In those tutorials, I’ve described how to use parity as the Ethereum client. Exactly this setup we’ve used also in our own project “Value Manifesto”. But a couple of weeks ago we’ve decided to switch the Ethereum client from parity to Infura. This gives me an opportunity to extend my tutorial with new information.
One of the reasons for changing the Ethereum client is as follows: maintaining your own Ethereum node can give you headaches. First of all, you need to keep your parity version up to date as it’s being continuously improved and adapted to the changes happening on the Ethereum blockchain.
Also, you need to pay for a hard disk with enough space (in our case a volume in the AWS environment) where the Ethereum database is stored. Actually this was not a huge issue, because we believe in decentralization and would like to maintain our own node, contributing to the growing power of the Ethereum network. But unfortunately due to some political and commercial reasons the development team of parity decided to source out parity to the community.
Of course, you never know, probably it will be a positive change! But when your live system with active customers is based on a component where future development and support are not clear, you start to think about alternatives. And thus we’ve decided to switch to Infura.
Infura is a cloud-based solution offered by the global blockchain company ConsenSys. You don’t need to start your own Ethereum node, you can access the blockchain via Infura APIs. They have flexible pricing with a free tier that is perfectly fine for our needs.
Migration from parity to Infura
It’s not rocket science to switch from parity to Infura if you are using web3j library as we do. The main differences between using both clients are:
– Infura is maintaining Ethereum nodes for you in their cloud. You call them via remote APIs. So no need to install anything locally and to wait until your local node is synchronized with Ethereum’s testnet or mainnet database
– the only thing you need to store locally are key files of your accounts, either for your own smart contract owner account or for your users. E.g. if you are creating Ethereum accounts on behalf of your users and keep their private keys, you will need to take care of this. But that’s not the topic of this tutorial, so let’s continue with the steps needed to setup and use Infura for calling your smart contract.
Step 1. Register on Infura
Register an account at https://infura.io/ and create a project there following the instructions.
In your Infura project dashboard, you will see your Project ID and Project Secret.
Project ID will be the part of URL when calling Infura, e.g. mainnet.infura.io/v3/<YOUR-PROJECT-ID> for mainnet or rinkeby.infura.io/v3/<YOUR-PROJECT-ID> for the rinkeby testnet
And Project Secret is your API key which needs to be kept secret and non-readable by humans. Project Secret is not mandatory for API calls by default. It’s a very good idea to make it mandatory. You can enable it in your project’s settings under Security. Please check also, whether whitelisting of origins, contract addresses and user agents is applicable for you. There cannot be “too much” security, especially important are proper security settings when you are not only playing with test apps but going to launch a production system.
Step 2. Implement Infura client
In the java service class where we use the parity client to call our smart contract (see the part II of my tutorial) we just need to switch to the Infura client instead.
As we would like to use our Project Secret for a proper authentication the creation of the Infura client is a bit more verbose.
First we create a HttpService and add the authorization header with our Project Secret to it. If you’ve enabled mandatory Project Secret and don’t provide it, you will get an error saying:
org.web3j.protocol.exceptions.ClientConnectionException: Invalid response received: 403; {"jsonrpc":"2.0","error":{"code":-32002,"message":"rejected due to project ID settings"}}
We will be using rinkeby as tesnet:
final String url = "https://rinkeby.infura.io/v3/<YOUR-PROJECT-ID>";
final HttpService httpService = new HttpService(url);
final String auth = StringUtils.EMPTY + ":" + <YOUR-PROJECT-SECRET>);
final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
final String authHeader = "Basic " + new String(encodedAuth);
httpService.addHeader(HttpHeaders.AUTHORIZATION, authHeader);
Now we can create an Infura client using this HttpService:
final Web3j infuraClient = Web3j.build(httpService);
The remaining steps for loading Credentials from the keyfile, loading and calling your smart contract stays actually the same as described in part II of the tutorial. However, we could make a small improvement when loading the smart contract. Instead of providing fixed values for gas price and gas limit we can provide our own implementation of a GasProvider.
The beauty of this version lies in that you can either use the default implementation StaticGasProvider with fixed values for gas price and gas limit like before. Or you can implement your own dynamic GasProvider that calculates gas price and gas limit per smart contract function. For the StaticGasProvider it would look as follows:
final BigInteger gasPrice = BigInteger.valueOf(2200000);
final BigInteger gasLimit = BigInteger.valueOf(4300000);
final ContractGasProvider gasProvider = new StaticGasProvider(gasPrice, gasLimit);
final Ownable contract = Ownable.load(smartContractAddress, infuraClient, credentials, gasProvider);
Step 3. Remove parity
When you’ve implemented and tested your Infura client, you can stop and remove your parity instance and free some disk space removing unneeded parity files and the local Ethereum database.
That’s it!
Hope this was helpful. Happy coding!