Wednesday, March 01, 2017

The method personal_unlockAccount does not exist/is not available

Wow, it's been almost 5 long years since I wrote a blog post... Life is busy at Microsoft, mostly in the IoT space but I am back, and I am back for good reason. I felt the need to document my learnings on Blockchain (the technology bitcoin is based on), because there does not seem to be a whole lot of technical information out there right now when you run into problems.

(Skip to the section "The Fix" if you know the background to this problem, as per the title)

If you are new to Blockchain (when I use the word chain from here on in, it means the same thing as Blockchain), then I suggest ramping up using this link. I will write many other introductory posts to Blockchain often specifically focused at running on Azure but for now back to the topic of this post: The method personal_unlockAccount does not exist/is not available. If you are using the Nethereum SDK to connect to your chain, the exception you will get back is: Nethereum.JsonRpc.Client.RpcResponseException.

Before you can write to the chain, that is publish a smartcontract, create an account etc. you have to "unlock" the account that you are using to write to the chain. This problem is very specific to the Ethereum Blockchain and by default the transaction nodes running Ethereum will be locked down, meaning you cannot remote RPC into the transaction nodes. Of course you can attach to the geth process on each node and unlock the accounts this way but to do it programmatically, please continue to read the rest of this post. In Azure we use the Golang implementation (called geth).

This problem you may be getting is also independent on the client library you are using and there are many out there. I am actually using Nethereum - a .NET implementation of the client, you can get that here: https://github.com/Nethereum/Nethereum If you like JavaScript then the web3 client library may interest you instead.

The fix
SSH/RDP into one of your transaction nodes on the Ethereum network, this needs to be done on every transaction node within the network.

Edit file: /home//start-private-blockchain.sh from below (line 54):

nohup geth --datadir $GETH_HOME -verbosity $VERBOSITY --bootnodes $BOOTNODE_URLS --maxpeers $MAX_PEERS --nat none --networkid $NETWORK_ID --identity $IDENTITY $MINE_OPTIONS $FAST_SYNC --rpc --rpcaddr "$IPADDR" --rpccorsdomain "*" >> $GETH_LOG_FILE_PATH 2>&1 &

To this:

nohup geth --datadir $GETH_HOME -verbosity $VERBOSITY --bootnodes $BOOTNODE_URLS --maxpeers $MAX_PEERS --nat none --networkid $NETWORK_ID --identity $IDENTITY $MINE_OPTIONS $FAST_SYNC --rpc --rpcaddr "$IPADDR" --rpccorsdomain "*" --rpcapi "eth,net,web3,admin,personal" >> $GETH_LOG_FILE_PATH 2>&1 &

Notice the additional parameter that has been added to the above command: --rpcapi "eth,net,web3,admin,personal". This will enable all the API's over the RCP JSON protocol which is what the Ethereum clients use to unlock accounts etc. The Ubuntu image in Azure does not enable these API's by default which is why we need to turn them on here. You need to do this for every transaction node within your Ethereum network.

Now reboot your OS by running command:

$sudo reboot



To test if this worked, you can try to run some code against this transaction node, for example try creating an account, or run the following command:

ps aux | grep geth

If all worked well, then you should get something back that looks like the below (notice the additional rpcapi parameter):

geth --datadir /home/simon/.ethereum -verbosity 4 --bootnodes enode://_mynode_and_IP/port --bootnodes enode://_mybootnodes_and_port_ --maxpeers 25 --nat none --networkid _my_id_ --identity bled72mw2-tx0 --fast --rpc --rpcaddr _myinternal_IP_ --rpccorsdomain "*" --rpcapi "eth,net,web3,admin,personal"

Hopefully this worked for you and happy Blockchaining!

10 comments:

Prashant Rai said...

Hi Simon - Its a great port and helped me lot. Few queries.

I have created private blockchain on Azure using "Consortium Blockchain Network solution template" and through its admin page I am able to transfer 1000 Eth for any account. Same I am also able to do using Metamask so:

1. why its not working when I am trying same using "Nethereum - a .NET implementation of the client" OR Web3.. why do I need to enable personal api into transaction node.
2. Before starting transfer - Is it mandatory to unlock account?
3. Before starting transfer - Is it mandatory to stop mining?

Thanks for your response in advance.

Kind Regards,
Prashant Rai

Simon Hart said...

Hi, I'm glad it helped.

I think the reason transferring Ether via the web application worked is because it is not using the rcpapi or could be because the web application is on the same network as the transaction nodes - there is no firewall/Azure load balancer in the way or VIP to cross.

When you enable rpcapi, does Nethereum work? I too have used Nethereum with great success.

Cheers
Simon

Prashant Rai said...

Thanks for your response.

I also thought the reason for transferring Ether via the web application worked because web application is on the same network as the transaction nodes. But I am not able to figure out how actually its working with Metamask utility which is installed as plugin into my local browser and its accessing blockchain using rcpapi only.

Also would like to have your thought on:
1. Before starting transfer - Is it mandatory to unlock account?
2. Before starting transfer - Is it mandatory to stop mining?

Kind Regards,
Prashant Rai

The Great Mind said...

Hi Simon, this is an excellent post. But unfortunately, after sudo reboot, geth is not starting on its own. I had to manually start geth console with other params. I couldnt start geth with the shell start-private-blockchain.sh ./genesis.json . Can you please help

Simon Hart said...

I am not sure how Metamask worked for use, I don't use it.

Yes you need to unlock the account from which you want to send Ether. You don't need to stop mining to transfer Ether.

Cheers
Simon

Simon Hart said...

Hi

Can you please post your start-private-blockchain.sh script.

Cheers
Simon

Unknown said...

Hi

I am just wondering how you ssh into a transaction node on azure? I have the same exact error.

Thank you

Unknown said...

Very helpful! thanks a lot!

Simon Hart said...

@Terance

You need to find your load-balancer or public IP within your Blockchain resource group. Take that IP, then use a SSH client connecting over port 3000 (default) we then have a port forwarding rule that maps 3000 to 22 defined within the load-balancer.

If running on Windows, you can use Putty - a UI SSH client or use mobaxterm or if you use Git on Windows, you will get a bash emulator that has a ssh client installed. If Linux then use bash.

Cheers
Simon

AmrikMahal said...

Thank you Simon. That helped me.
I am running local node and here is the command if it helps others.

geth --dev --rpc --mine --rpcapi "eth,web3,personal,net,miner,admin,debug"