This post is part of the Infineon Blockchain Starter Kit road test.
Blockchain - outside of the bitcoin context - is new to me.
Follow along with me on this path to learn the technology....
Let's dive further into the example Android App "coinfinity". Retrieve crypto coin balance information from the Ethereum test network. |
Prerequisite: an Infinion Security 2Go smart card loaded with some Ethereum Ropsten test coins. See this post for instructions.
I'm picking up from where we left in the first part: Blockchain - Analyse the Infineon Android Demo App - part a: Detect Card.
You tapped the card to the back. It's detected and the 3 action buttons are enabled.
A little refresher of what first happened when the card was tapped:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // ... IsoDep isoDep = IsoDep.get(tag); // ... try { SharedPreferences pref = this.getSharedPreferences(PREFERENCE_FILENAME, Context.MODE_PRIVATE); pubKeyString = NfcUtils.readPublicKeyOrCreateIfNotExists(IsoTagWrapper.of(isoDep), pref.getInt(KEY_INDEX_OF_CARD, 1)).getPublicKeyInHexWithoutPrefix(); isoDep.close(); } catch (IOException | NfcCardException e) { // ... } // ... // use web3j to format this public key as ETH address ethAddress = Keys.toChecksumAddress(Keys.getAddress(pubKeyString));
At this point, the following info from your card / keys is known to the app:
private String pubKeyString; private String ethAddress;
Contact the Block Chain to Retrieve the Balance
Several blockchains support a web3j interface. So does the Etherium one.
In the previous blog (see snippet above) a web3j call was used to fetch the 20 byte address (checksummed address) from the public key.
But that's a utility call. It doesn't check your transactions.
Now we'll see how web3j can retrieve the card balance (the balance on the etherium address related to the card / key you tapped.
public void updateBalance() throws Exception { Log.d(TAG, "reading ETH balance.."); ethBalance = EthereumUtils.getBalance(ethAddress, UiUtils.getFullNodeUrl(this)); Log.d(TAG, String.format("reading ETH balance finished: %s", balance.toString())); }
The EthereumUtils class is the one that will call web3j.
The UiUtils class holds the URL for us. For the Ropsten network, this is https://ropsten.infura.io/v3/7b40d72779e541a498cb0da69aa418a2
This URL is built out of constants. I do not know what the 7b40d72779e541a498cb0da69aa418a2 value means.
private static final String HTTPS = "https://"; private static final String BASEURL = ".infura.io/v3/7b40d72779e541a498cb0da69aa418a2"; public static final String MAINNET_URI = HTTPS + "mainnet" + BASEURL; public static final String ROPSTEN_URI = HTTPS + "ropsten" + BASEURL;
I'm currently treating it as a magic value. I'll look it up when the need is there - or if you are interested maybe you can look it up and post in the comments.
public static EthBalanceBean getBalance(String ethAddress, String url) throws Exception { Web3j web3 = Web3jFactory.build(new HttpService(url)); BigInteger wei = getBalanceFromApi(web3, ethAddress, DefaultBlockParameterName.LATEST); if (wei == null) { wei = new BigInteger("0"); } BigDecimal ether = Convert.fromWei(wei.toString(), Convert.Unit.ETHER); BigInteger unconfirmedWei = getBalanceFromApi(web3, ethAddress, DefaultBlockParameterName.PENDING); if (unconfirmedWei == null) { unconfirmedWei = new BigInteger("0"); } unconfirmedWei = unconfirmedWei.subtract(wei); BigDecimal unconfirmedEther = Convert.fromWei(unconfirmedWei.toString(), Convert.Unit.ETHER); return new EthBalanceBean(wei, ether, unconfirmedWei, unconfirmedEther); }
private static BigInteger getBalanceFromApi(Web3j web3, String ethAddress, DefaultBlockParameterName defaultBlockParameterName) throws Exception { BigInteger wei = null; EthGetBalance ethGetBalance = web3 .ethGetBalance(ethAddress, defaultBlockParameterName) .sendAsync().get(); if (ethGetBalance != null) { wei = ethGetBalance.getBalance(); } return wei; }
Excuse me for not digging into the downstream code and that's template code. Easier for you to drill into it via Android Studio than for me to explain it.
Short story is that the web3j Request class is used to build the request and send it asynchronious.
This is the result:
This gets decoded using
BigInteger(value.substring(2), 16);
Resulting in: 59685000000000000
Format for Display on the App
That gets converted again:
BigDecimal ether = Convert.fromWei(wei.toString(), Convert.Unit.ETHER);
Prepared for display:
... and when the app refreshes its screen, the balance is shown:
I haven't shown the full trace here. Talking through it isn't half the value of stepping through it via Android Studio's debugger.
So I tried to stick to the process of getting the card info, create the web3j parameters for budget retrieval and parsing the results.
What you haven't seen is how web3j works internally to build the web call and get the async reply.
That's not blockchain related. I don't want to mix that into the discussion, yet wanted to show some of the intermediate variables for your understanding.
Enough hooks to go look into the code and APIs yourself.
Now that I revealed my Etherium address, feel free to try and fetch some of my balance, or donate some . It's Ropsten coins so they are free.
You can (in the true spirit of an open blockchain) see all transactions for that account. And that's one of the 255 keys on my Infineon 2Go smart card.
Top Comments