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: 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// 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!