Interacting with Ethereum Smart Contracts from Android

Usually when you want to interact with smart contracts you need to download the whole ethereum blockchain and keep your local node synchronized. As of writing the blockchain takes up more than 80GB of space on my computer. This might make sense on a desktop computer but is less reasonable on a mobile device.

One way to go around this limitation is to use a service like Infura. Infura allows you to connect to a remote ethereum node and execute transactions without having to worry about maintaining and synchronizing your local node.

To be able to transact with the smart contract from native Java code I used a library called Web3j. Web3j provides you with utilities for generating smart contract java wrappers and a complete implementation of Ethereum’s JSON-RPC client API over HTTP and IPC. It provides more features but these were the important ones for this “Android Ethereum hello world” example.

The example smart contract I want to interact with is a Greeter. It stores a greeting message on the blockchain which can be read or updated. It looks like this:

contract greeter is mortal {
    /* define variable greeting of the type string */
    string greeting;

    /* this runs when the contract is executed */
    function greeter(string _greeting) public {
        greeting = _greeting;
    }

    /* change greeting */
    function changeGreeting(string _greeting) public {
        greeting = _greeting;
    }

    /* main function */
    function greet() constant returns (string) {
        return greeting;
    }
}

 

To be able to create the wrappers we first have to compile this smart contract like so

solc greeter.sol --bin --abi --optimize -o <output-dir>/

 

To generate the wrappers you run

web3j solidity generate /path/to/<smart-contract>.bin /path/to/<smart-contract>.abi -o /path/to/src/main/java -p com.your.organisation.name

 

Java part

First we need to get a web3 instance for the ethereum blockchain interaction.
It will look like this

InfuraHttpService infuraHttpService = new InfuraHttpService(url);
Web3j web3j = Web3jFactory.build("https://ropsten.infura.io/YOUR_API_KEY");

 

Now we can read from the contract which is almost instantaneous.

Greeter greeter = Greeter.load(greeterContractAddress, web3j, credentials, gasPrice, gasLimit);
Future<Utf8String> greeting = greeter.greet();
Utf8String greetingUtf8 = greeting.get();
String result = greetingUtf8.getValue();

 

Transactions are not instantaneous and may take a few minutes to be validated.

Greeter greeter = Greeter.load(greeterContractAddress, web3j, credentials, gasPrice, gasLimit);
TransactionReceipt transactionReceipt = greeter.changeGreeting(new Utf8String(greetingToWrite)).get(timeout);
String result = "Successful transaction. Gas used: " + transactionReceipt.getGasUsed();

 

Full working example can be found on github.

This Post Has 8 Comments

  1. Hey Ondrej Bendo,

    Thanks for your tutorial. It was pretty insightful. Although when I run your code, I get an error when pressing the “Get Greeting”.
    It’s an IndexOutOfBounds. To be specific,

    java.lang.IndexOutOfBoundsException: Index: 0
    at java.util.Collections$EmptyList.get

    I looked it up here: https://github.com/web3j/web3j/issues/179
    In their case, they were using .deploy() and didn’t place their initial Wei value to 0.

    Just wondering if you came across it during your debugging.
    Cheers,

    1. Hi Vik,
      To run the code you have to modify it with your own information.
      Make sure to search for YOUR_PRIVATE_KEY and YOUR_API_KEY.
      Replace YOUR_PRIVATE_KEY with your ethereum account private key.
      Replace YOUR_API_KEY with the api key you get after registering on the Infura website.

  2. Hi ,

    Nice article! one question though, how are you creating the wallet on the device( public+private key). Infura doesnt support personal apis.

    Thanks and Regards
    Amit

    1. For this project I just created an account with mist.

      1. Hi Ondrej, great article and example code. Any mobile app will need the user’s private key to pay for blockchain updates, not one that we’ve given it. What’s the best way to get access to (or ask the user to create) their private key? Is there a java library for this or a wallet with a well documented API?

  3. Hi This is a great article , but I don’t actually get where did you get your eth wallet. I am trying to access mine in metamask, is there a way?

  4. Hey I am getting a Client Connection Exception, can you help me with that. (error reading smart contract)

Leave a Reply

Close Menu