0

I've been learning about interacting with smart contracts through Android and the Web3j framework but have run into an issue.

I'm trying to mint an ERC721 token and send it to an address but it doesn't seem to be working. Whenever I try to invoke the method, it throws an exception and no token is created. Why isn't the token being generated?

Here's the Solidity code:

pragma solidity ^0.5.0;

import "../node_modules/@openzeppelin/contracts/token/ERC721/ERC721Full.sol";
import "../node_modules/@openzeppelin/contracts/drafts/Counters.sol";

 contract ExampleToken is ERC721Full {
     using Counters for Counters.Counter;
     Counters.Counter private _tokenIds;

     constructor() ERC721Full("ExampleToken", "EXT") public {
     }

     function mintUniqueToken(address _to, string memory _tokenURI) public returns (uint256) {
         _tokenIds.increment();

         uint256 newTokenId = _tokenIds.current();
         _mint(_to, newTokenId);
         _setTokenURI(newTokenId, _tokenURI);

         return newTokenId;

     }
 }

And here's the Java code:

private Web3j web3;
    private Credentials creds;
    private ExampleToken exampleContract;
    private String contractAddress;
    private DefaultGasProvider gasProvider;
    private String accountAddress;


    public EthNetwork() {
        web3 = Web3j.build(new HttpService(nodeURL));
        creds = Credentials.create(privateKey);
        contractAddress = erc721Address;
        gasProvider = new DefaultGasProvider();
        accountAddress = publicAccAddress;

        exampleContract = ExampleToken.load(contractAddress, web3, creds, gasProvider);
    }

    public String mintToken() throws Exception {
        TransactionReceipt transactionReceipt = exampleContract.mintUniqueToken(accountAddress, "EXT").send();
        String txHash = transactionReceipt.getTransactionHash();
        return txHash;
    }

Edit: Here's the result I get using printStackTrace() and more of the Java code. I should probably mention that I'm doing this on the Ropsten testnet and connecting via an Infura node.

W/System.err: android.os.NetworkOnMainThreadException
W/System.err:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:91)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
        at java.net.InetAddress.getAllByName(InetAddress.java:752)
        at okhttp3.Dns$1.lookup(Dns.java:40)
        at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
        at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
        at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:214)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
        at okhttp3.RealCall.execute(RealCall.java:77)
        at org.web3j.protocol.http.HttpService.performIO(HttpService.java:160)
        at org.web3j.protocol.Service.send(Service.java:42)
        at org.web3j.protocol.core.Request.send(Request.java:81)
        at org.web3j.tx.RawTransactionManager.getNonce(RawTransactionManager.java:95)
        at org.web3j.tx.RawTransactionManager.sendTransaction(RawTransactionManager.java:118)
        at org.web3j.tx.TransactionManager.executeTransaction(TransactionManager.java:75)
        at org.web3j.tx.ManagedTransaction.send(ManagedTransaction.java:114)
        at org.web3j.tx.Contract.executeTransaction(Contract.java:362)
        at org.web3j.tx.Contract.executeTransaction(Contract.java:345)
        at org.web3j.tx.Contract.executeTransaction(Contract.java:339)
        at org.web3j.tx.Contract.executeTransaction(Contract.java:334)
        at org.web3j.tx.Contract.lambda$executeRemoteCallTransaction$3$Contract(Contract.java:401)
W/System.err:     at org.web3j.tx.-$$Lambda$Contract$w6-chY5FF2Qs682sB2cKs6onFiM.call(lambda)
        at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:42)
        at com.quintus.labs.datingapp.Main.EthNetwork.mintToken(EthNetwork.java:48)
        at com.quintus.labs.datingapp.Main.MainActivity.LikeBtn(MainActivity.java:241)
        at java.lang.reflect.Method.invoke(Native Method)
        at android.view.View$DeclaredOnClickListener.onClick(View.java:4706)
        at android.view.View.performClick(View.java:5623)
        at android.view.View$PerformClick.run(View.java:22427)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6247)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
  • Can you post the exception you are getting as well as more of the java code (how are you creating a web3 object / the example contract). – Steven V Nov 30 '19 at 5:20
0

I figured it out. Turns out the problem was a NetworkOnMainThreadException.
Trying to invoke the mintToken() method by itself on the MainActivity class causes the exception to be thrown. So I fixed it by extending the EthNetwork class to include AsyncTask:

public class EthNetwork extends AsyncTask<Void, Void, String>

Next I created a method that would mint a token in the background:

protected String doInBackground (Void... params) {
        try {
            return mintToken();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

Then I used .execute() in MainActivity and the token was successfully minted:

EthNetwork contract = new EthNetwork();  
contract.execute();

The Documentation for Android development contains more details

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.