4

When I trying to unlock the account with personalUnlockAccount.accountUnlocked() method of PersonalUnlockAccount class of web3j library, it's giving NullPointerException even if I am entering right password.

Please point out the wrong doing, I am committing in the below code.

package com.kaushik.blockchain;

import java.io.IOException;
import java.math.BigInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.protocol.admin.Admin;
import org.web3j.protocol.admin.methods.response.PersonalUnlockAccount;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;

public class MainTransferApp {
    private static final Logger log =
            LoggerFactory.getLogger(MainTransferApp.class);
    public static void main(String[] args) throws Exception {
        new MainTransferApp().run();
    }
    private void run() throws IOException, InterruptedException {
        String from = "0xe8fbbddf73c128e50f824ec6af65cb15c237fe58";
        String to =   "0x288a49996ae58aa9999389912cba8cf908a0990e";
        Admin web3j = Admin.build(new HttpService());
        //web3j
        log.info("Connected to Ethereum client version: "
                + web3j.web3ClientVersion().send().getWeb3ClientVersion());
        PersonalUnlockAccount personalUnlockAccount = web3j.personalUnlockAccount(from, "passPhrase").send();
        log.info("Unlocked: "+personalUnlockAccount.accountUnlocked());
        if(personalUnlockAccount.accountUnlocked()){
        EthGetTransactionCount transactionCount = 
                web3j.ethGetTransactionCount(from, DefaultBlockParameterName.LATEST).send();
        BigInteger value = Convert.toWei("45.0", Convert.Unit.ETHER).toBigInteger();
        Transaction transaction = Transaction.createEtherTransaction(from, 
                transactionCount.getTransactionCount(), 
                BigInteger.valueOf(10000), BigInteger.valueOf(4500000), 
                to, value);
        EthSendTransaction response = web3j.ethSendTransaction(transaction).send();
        if (response.getError() != null) {
            log.info("Transaction error: {}", response.getError().getMessage());
        }
        log.info("Transaction: {}", response.getResult());
        EthGetTransactionReceipt receipt = 
                web3j.ethGetTransactionReceipt(response.getTransactionHash()).send();
        if (receipt.getTransactionReceipt().isPresent()) {
            TransactionReceipt r = receipt.getTransactionReceipt().get();
            log.info("Tx receipt: from={}, to={}, gas={}, cumulativeGas={}", r.getFrom(), r.getTo(), r.getGasUsed().intValue(), r.getCumulativeGasUsed().intValue());
        }
        Thread.sleep(5000);
        EthGetBalance balance = web3j.ethGetBalance(from, DefaultBlockParameterName.LATEST).send();
        log.info("Balance: address={}, amount={}", from, balance.getBalance().longValue());
        balance = web3j.ethGetBalance(to, DefaultBlockParameterName.LATEST).send();
        log.info("Balance: address={}, amount={}", to, balance.getBalance().longValue());
        }else{
            log.info("Error occurred while unlocking account");
        }

    }
}

Now this is the error I am getting. Please help me out.

[main] INFO com.kaushik.blockchain.MainTransferApp - Connected to Ethereum client version: Geth/nodeSOL/v1.8.13-stable-225171a4/windows-amd64/go1.10.3
[main] INFO com.kaushik.blockchain.MainTransferApp - Unlocked: null
Exception in thread "main" java.lang.NullPointerException
    at com.kaushik.blockchain.MainTransferApp.run(MainTransferApp.java:35)
    at com.kaushik.blockchain.MainTransferApp.main(MainTransferApp.java:24)

Please suggest me the other way around. In my project, I want to send from address and password from the UI. Is there any other approach, I can go with, which should be easy from user perspective?

kaushik_pm
  • 353
  • 2
  • 13
  • 1
    What is the command used to launch geth? Is the personal api enabled? – Ismael Aug 29 '18 at 17:46
  • 1
    @Ismael I am using the below command. geth --datadir=E:/BC_Private/node1 --networkid 2061 --port 30304 --nodiscover --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --ipcpath=E:/BC_Private/node1/geth.ipc --mine --minerthreads 1 --gasprice "10000" --etherbase 0xd0831f602d3e10c2c4442918abb0a84cef5582f5 --targetgaslimit "5800000"--verbosity 3 console – kaushik_pm Aug 29 '18 at 19:10
  • 1
    From this answer https://ethereum.stackexchange.com/a/1414 you need explicitely enable it for RPC with --rpcapi "db,eth,net,web3,personal". – Ismael Aug 29 '18 at 19:25
  • 1
    @Ismael If I am not using this flag, it means by default it will have "db,eth,net,web3,personal". Isn't it? Please clarify my doubt. – kaushik_pm Aug 29 '18 at 19:31
  • 2
    For security reason personal is not enabled in RPC you have to explicitely enable it. – Ismael Aug 29 '18 at 19:34
  • 1
    @Ismael I will try this solution and update you. :) – kaushik_pm Aug 29 '18 at 19:40
  • 1
    I have the same issue. personal is clearly enabled in --rpcapi , using the java script client attach option confirms this where personal.unlockAccount returns true with same address and pass option, However null is returned from the API call using web3j... Any solution appreciated – Abelgo Sep 08 '18 at 09:54
  • 1
    @Abelgo Try these all flag explicitly --rpcapi "db,eth,net,web3,personal". Or share your code. – kaushik_pm Sep 10 '18 at 13:16
  • 1
    I enabled trace logging in the web3j java library. My conclusion is. The calls work the account is unlocked and Json RPC correct responce logged. However web3j is broken it still returns null regardless. I also tested using IPC where personal should be enabled by default .. same result, web3j seems to be broken here. – Abelgo Sep 10 '18 at 22:24
  • 1
    There is also a method to unlock and send in the same transaction. see "personal_sendTransaction" will save the unlock step. org.web3j.protocol.core.methods.request.Transaction txn = org.web3j.protocol.core.methods.request.Transaction.createEtherTransaction(eth_address, nonce.incrementAndGet(), gassPrice, gassLimit, toAddress, value); EthSendTransaction sentTXN = node_admin.personalSendTransaction(txn, this.getPrivateKey() ).send(); – Abelgo Sep 10 '18 at 22:52
  • 1
    Can you unlock your account inside geth ? – alper Sep 10 '18 at 22:52

2 Answers2

1

I need to explicitly use the personal api for RPC. Using this flag worked for me.

--rpcapi "db,eth,net,web3,personal"

Thanks @Ismael for the help.

kaushik_pm
  • 353
  • 2
  • 13
1

Some more insight. I seems to be getting some inconsistent results here. In this code segment the RawResponce is null however the boolean is returned correctly.

                LOG.info("CALLING UNLOCK !!");
                PersonalUnlockAccount ok = RPC_ADMIN.personalUnlockAccount(HOT_WALLET, ac.getPrivateKey(), ACCOUNT_UNLOCK_SECONDS).send();
                LOG.info("RAW RESPONCE IS: " + ok.getRawResponse());
                LOG.info( "BOOLEAN IS:"  +  ok.accountUnlocked().toString());

10:35:42.550 [main] INFO com.abelgo.eth.EthAdaptor - CALLING UNLOCK !! 10:35:42.552 [main] DEBUG org.web3j.protocol.ipc.IpcService - >> {"jsonrpc":"2.0","method":"personal_unlockAccount","params":["0xf1b0725bd64cbe62a5160357d53e92c54788f2e5","-SECRET-",7],"id":13} 10:35:43.245 [main] DEBUG org.web3j.protocol.ipc.IpcService - << {"jsonrpc":"2.0","id":13,"result":true}

10:35:43.247 [main] INFO com.abelgo.eth.EthAdaptor - RAW RESPONCE IS: null 10:35:43.247 [main] INFO com.abelgo.eth.EthAdaptor - BOOLEAN IS:true

Abelgo
  • 121
  • 3