1

I'm trying to build a DApp on Android with Geth 1.5.9. After some research and coding I managed to find the information to install/run a geth node and also create some accounts with Android Studio.

I followed more or less the instructions of the offical Wiki and the Devcon2 presentation - I know they are not up to date, but until now it was good enough for me.

Anyways, I would like to try out transaction now, so I tried to do a transaction from Account1 to Account2. So I went to Ropsten-Faucet and got some ether for both accounts and then tried to code the transaction method "sendTransaction", but I got some trouble in doing it right.

As you can see in the box below, I've got a error that the sender of the transaction is not set right.

03-09 16:03:36.542 24705-24766/ch.zhaw.zendrio V/MainActivity: Start startSync
03-09 16:03:36.544 24705-24766/ch.zhaw.zendrio I/MainActivity: Start Transaction
03-09 16:03:36.545 24705-24766/ch.zhaw.zendrio I/MainActivity: Account1: 0xfa1c40e42d7317cd2a1b9cc88c9182e3c5efda5d
03-09 16:03:36.546 24705-24766/ch.zhaw.zendrio I/MainActivity: Account2: 0x8a9519da1f03e1fd5a558a6d43dc4ba06f1f955d
03-09 16:03:36.546 24705-24766/ch.zhaw.zendrio I/MainActivity: Nonce used:0
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: Cost: 2
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: GasPrice: 1
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: Gas: 1
03-09 16:03:39.488 24705-24766/ch.zhaw.zendrio I/MainActivity: Nonce: 0
03-09 16:03:39.490 24705-24766/ch.zhaw.zendrio I/MainActivity: Value: 1
03-09 16:03:39.490 24705-24766/ch.zhaw.zendrio I/MainActivity: Sig-Hash Hex: 0x300eb1c450fe26f71e13bdbf099b8a70f3015e069ef1fd9e0598e6c21c0b4224
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio I/MainActivity: Hash Hex: 0xdf050dcf9f8e2f508addab5a0359923b0a15689184732b84b7f10e3994ce6f1f
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio I/MainActivity: Data-Length: 11
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio I/MainActivity: To: 0x8a9519da1f03e1fd5a558a6d43dc4ba06f1f955d
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio V/MainActivity: invalid transaction v, r, s values
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err: go.Universe$proxyerror: invalid transaction v, r, s values
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err:     at org.ethereum.geth.Transaction.getFrom(Native Method)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err:     at ch.zhaw.zendrio.view.activity.MainActivity.sendTransaction(MainActivity.java:136)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err:     at ch.zhaw.zendrio.view.activity.MainActivity.access$300(MainActivity.java:24)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err:     at ch.zhaw.zendrio.view.activity.MainActivity$2.run(MainActivity.java:88)
03-09 16:03:39.491 24705-24766/ch.zhaw.zendrio W/System.err:     at java.lang.Thread.run(Thread.java:761)

And thats where I'm stuck now for some days and I need some help from you guys.

I used the following test-accounts and the code below in the boxes:

  • Account1: 0xfa1c40e42d7317cd2a1b9cc88c9182e3c5efda5d
  • Account2: 0x8a9519da1f03e1fd5a558a6d43dc4ba06f1f955d

What might be my problems:

  1. Testnet-Node Syncing: Maybe I understood something wrong in connecting to ropsten-testnet when setting up the node. As far as my understanding goes I thought it is enough to change the EthereumNetworkId to 3 to connect to ropsten and use the default values for the rest of the node config. See "startNode" Method. But I think the sync is not working and I actually don't know why. If I use the mainnet I can see that the synronization start but not in the testnet. So what did I miss in the node-config?

    private Node startNode() throws Exception {
        final NodeConfig nodeConfig = new NodeConfig();
        nodeConfig.setEthereumNetworkID(3); // Is this enough to connect to Ropsten??
        Log.v(TAG, "Start Node");
        Node node = Geth.newNode(getFilesDir() + "/.ethereum", nodeConfig);
        node.start();
        final NodeInfo nodeInfo = node.getNodeInfo();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Show the config in the UI
                final TextView textbox = (TextView) findViewById(R.id.GethTextbox);
                textbox.append("My name: " + nodeInfo.getName() + "\n");
                textbox.append("My address: " + nodeInfo.getListenerAddress() + "\n");
                textbox.append("My protocols: " + nodeInfo.getProtocols() + "\n");
                textbox.append("My ID: " + nodeInfo.getID() + "\n");
                textbox.append("My ListenerPort: " + nodeInfo.getListenerPort() + "\n");
                textbox.append("My IP: " + nodeInfo.getIP() + "\n\n");
                textbox.append("NodeConfig: " + nodeConfig.toString() + "\n\n");
            }
        });
        return node;
    }

    private void startSync(Node node) throws Exception {
        //TODO Refactor/Delete
        Log.v(TAG, "Start startSync");
        ctx = new Context();
        final TextView blockTextBox = (TextView) findViewById(R.id.blockTextBox);
        ec = node.getEthereumClient();
        //blockTextBox.append("Latest block: " + ec.getBlockByNumber(ctx, -1).getNumber() + ", syncing...\n");
        NewHeadHandler handler = new NewHeadHandler() {
            @Override
            public void onError(String error) {
                Log.e(TAG, error);
            }

            @Override
            public void onNewHead(final Header header) {
                MainActivity.this.runOnUiThread(new Runnable() {
                    public void run() {
                        blockTextBox.append("#" + header.getNumber() + ": " + header.getHash().getHex().substring(0, 10) + "…\n");
                    }
                });
            }
        };
        ec.subscribeNewHead(ctx, handler, 16);
    }
  1. Signing the transaction: So I probably did also something wrong with the signing process and or the selected transaction values.
    • So the first problem I encounterd, was when I wanted to get a nonce. I'm actually not sure if I need to get it with ec.getPendingNonceAt(..) or if I can just set a random one, but what I know is, that when I use getPendingNonceAt(..) then it blockes my thread. Is that because I'm not synced? If I use a random nonce = 0 I get invalid transaction error. What probably should happen.
    • The second problem then was the signing itself with the keyStore.signTx(..) because it needs a BigInt as third parameter and I'm really sorry but I didn't find any reference for what the third parameter is needed. I even looked into the JavaScript and Ethereum-Go-Doc API's to find out for what this parameter could possible be. Please someone tell me or give me some JavaDoc.

    private void sendTransaction() throws Exception {
        Log.i(TAG,"Start Transaction");
        KeyStore keyStore = new KeyStore(this.getFilesDir() + "/keystore",
                Geth.StandardScryptN, Geth.StandardScryptP);
        Accounts accounts = keyStore.getAccounts();
        if(accounts.size() >= 2){
            account1 = accounts.get(0);
            account2 = accounts.get(1);
        }
        Log.i(TAG, "Account1: " + account1.getAddress().getHex()); //Sender
        Log.i(TAG, "Account2: " + account2.getAddress().getHex()); //Receiver

        BigInt value = Geth.newBigInt(1);
        BigInt gasLimit = Geth.newBigInt(0);
        BigInt gasPrice = Geth.newBigInt(0);
        String testData = "Hello World";
        byte[] data = testData.getBytes();

        long nonce = ec.getPendingNonceAt(ctx, account1.getAddress()); // 1. Blocks the Thread if used? Syncing maybe?
        //long nonce = 0x00;
        Log.i(TAG, "Nonce used:" + nonce);
        Transaction transaction = Geth.newTransaction(nonce, account2.getAddress(), value, gasLimit, gasPrice, data);

        keyStore.timedUnlock(account1, "test", 10000000);
        transaction = keyStore.signTx(account1, transaction, new BigInt(0)); // 2. Why BigInt needed?

        Log.i(TAG, "Cost: " + transaction.getCost());
        Log.i(TAG, "GasPrice: " + transaction.getGasPrice());
        Log.i(TAG, "Gas: " + transaction.getGas());
        Log.i(TAG, "Nonce: " + transaction.getNonce());
        Log.i(TAG, "Value: " + transaction.getValue());
        Log.i(TAG, "Sig-Hash Hex: " + transaction.getSigHash().getHex());
        Log.i(TAG, "Hash Hex: " + transaction.getHash().getHex());
        Log.i(TAG, "Data-Length: " + transaction.getData().length);
        Log.i(TAG, "To: " + transaction.getTo().getHex());
        Log.i(TAG, "Sender: " + transaction.getFrom().getHex()); // 3. Produces the Error-Output.

        ec.sendTransaction(ctx, transaction);
    }

Sorry for the long post and thanks for helping me!

1

I'm not certain, but there's potentially three issues:

  1. You'd need access to Ropsten's genesis block to sync properly, although I think geth should be able to do that for you, somehow. (It does on PC.) That said, Ropsten is more or less broken right now, due to attacks. You'd have better luck starting a private chain, as described here.

  2. The nonce must be precisely equal to the account's current nonce, or it won't be minable. If the accounts are new, this would ordinarily be zero. However, I believe testnet nonces start at a different number to avoid replay attacks. (Private testnets work as normal.)

  3. I'm guessing that the BigInt probably needs to be 3, due to this section in geth's code. I'm assuming this is because of replay attack prevention.

Finally (I think you'll encounter this next), your gas and gasPrice are both too low. gas needs to be at least 2300 (IIRC) to even execute a transaction. gasPrice is usually around 20 Gwei, and I'm assuming it's asking for the price in wei.

  • Thx, I will try this out – Tom Mar 13 '17 at 11:21
  • So first i tried to add the Genesis block to the nodeconfig. New the geth-log contains now the entry "Block synchronsation started", what is good I think, because now I get a none (0) via ec.getPendingNonceAt(..). I changed also the gas and gasPrice to the values you mentioned, but I still get the transaction error. – Tom Mar 13 '17 at 17:29
  • I also tried to do it with a Private network, but failed hard when it came to connect the Android Emulator to the network. I don't know why but my Android client could not connect to the miner or a node, even when I added them as bootnodes – Tom Mar 13 '17 at 17:31
  • Unfortunately, I'm not familiar with Android development, so I don't know how to help further. :( – Matthew Schmidt Mar 13 '17 at 21:07

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.