This is a series of blogs about how to develop dApps on Ethereum.

We developed a proof-of-concept example of lending platform on blockchain.
You can check live demo here.
* this is just a proof of concept example…

Last time we covered client side. If you’re interested, please check part 1.

This time we’re going to cover topics like…

  • Setup Ethereum private network
  • A bit about IPFS
  • Sign a message on a client and decode the message on a server


Setup Ethereum private network.

Create a couple of accounts

You need a couple of addresses (accounts) before setting up a network.

geth account new --datadir ./data
> <address #1>
geth account new --datadir ./data
> <address #2>
geth account new --datadir ./data
> <address #3>

You can check files associated to the accounts you just created at ./data/keystore directory.
We use the addresses later. Please take a note.

Setup initial json file to generate genesis block

Now you can prepare a setting json file to generate a genesis block of a private network. To do so, let’s use the command line tool called puppeth.
Puppeth is installed with Geth.

You can choose 2 things, consensus algorithm and speed of mining.

For consensus algorithm we have 2 options, proof of work and proof of authority. Proof of work is the most popular consensus algorithm but require huge computation power. If I chose POW, my mac would roar. So my choice was POA. With POA we can give special power to a specific address to mine.

We don’t need consensus for prototyping and I really don’t want to waste power.

And I also chose 5 seconds for mining time (default 15secs may be too slow…)

But to tell the truth, any network works.

| Welcome to puppeth, your Ethereum private network manager |
|                                                           |
| This tool lets you create a new Ethereum network down to  |
| the genesis block, bootnodes, miners and ethstats servers |
| without the hassle that it would normally entail.         |
|                                                           |
| Puppeth uses SSH to dial in to remote servers, and builds |
| its network components out of Docker containers using the |
| docker-compose toolset.                                   |

Please specify a network name to administer (no spaces, please)
> ratel_network_demo

What would you like to do? (default = stats)
 1. Show network stats
 2. Configure new genesis
 3. Track new remote server
 4. Deploy network components
> 2

Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 2

How many seconds should blocks take? (default = 15)
> 5

Which accounts are allowed to seal? (mandatory at least one)
> 0x<address #1>
> 0x

Which accounts should be pre-funded? (advisable at least one)
> 0x<address #1>
> 0x<address #2>
> 0x

Specify your chain/network ID if you want an explicit one (default = random)

Anything fun to embed into the genesis block? (max 32 bytes)

What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
> 2

 1. Modify existing fork rules
 2. Export genesis configuration
> 2

Which file to save the genesis into? (default = ratel_network_demo.json)

Create a genesis block

geth --datadir ./data init ratel_network_demo.json

start private network

RPC should be running at is only for testing purpose.

nohup geth --datadir ./data --nodiscover --networkid <Your network ID> --rpc --rpcapi db,eth,net,web3,personal,miner,admin --cache=128 --rpcport 8545 --rpcaddr --rpccorsdomain "*" &

start geth console to start mining

geth attach

unlock the main account and start mining.

web3.personal.unlockAccount(web3.eth.accounts[0], <your password>, 0)

That’s it.

Start IPFS

IPFS is a decentralized file system. As of January 2018, IPFS is the only working system which is actively used by developers. There are competitors like Ethereum’s Swarm. But non of them are ready even for prototyping this kind of applications.

Install IPFS

IPFS has good documents, please follow the install section for your environment.

Start IPFS instance on background mode

Once you installed IPFS, let’s start it.

nohup ipfs daemon --enable-pubsub-experiment &

Sign message on client and get address on Server

Finally we can write node scripts to verify message from clients.

Sign a message on a client

There are 6 steps to generate signature string. I use ethereum-util node module, which is a library to do low-level ethereum things easily, to sign a message because for me ethereum-util is easy to use. But you can use other libraries of course.

As you notice, I use many libraries, some of which have overlapping features. But because Ethereum eco system is in infancy, none of tools are perfect. That’s why I use multiple tolls to develop dApps.

  1. get private key
  2. make the private key buffer
  3. take a sha3 hash of the buffer
  4. make the sha3 hash buffer
  5. sign the buffer with ethereumjs-util module
  6. generate a signature string
import EthUtil from 'ethereumjs-util'
// client side
wallet.keyFromPassword( password, (err, pwDerivedKey) => {
  if (err) {
// get private key
  const pKey = wallet.exportPrivateKey( address, pwDerivedKey )
// make the private key buffer
  const pKeyx = new Buffer(pKey, 'hex');
// take a sha3 hash of the buffer
  const messageHash = web3.utils.sha3(message)
// make the sha3 hash buffer
  const messageHashx = new Buffer(messageHash.substr(2), 'hex');
// sign the buffer with ethereumjs-util module
  const signedMessage = EthUtil.ecsign(messageHashx, pKeyx)
// generate a signature string
  const signatureString = EthUtil.toRpcSig(signedMessage.v, signedMessage.r, signedMessage.s).toString('hex')

In Ethereum development, we use buffer many times.

If you’re person like me, who have used high level languages like Python, Swift, and Javascript, it may take time to get used to buffer things.

Send the signature to server

Next step is to send the signature string, message hash, and singer address to the server.

  signatureString: signatureString,
  messageHash: messageHash,
  signer: signer

Verify the singer on client side

I use node express as http server.

There are a couple of steps in server side too but I think it’s simpler than client side.

  1. receive valuables from client
  2. create buffer of message hash
  3. decode signagure
  4. recover address
// sever side
import EthUtil from 'ethereumjs-util'
// req come from express...
const signatureString = req.body.signatureString
const messageHash = req.body.messageHash
const signer = req.body.signer
// create buffer of message hash
const messageHashx = new Buffer(messageHash.substr(2), 'hex');
// decode signature
const sigDecoded = EthUtil.fromRpcSig(signatureString)
// recover address
const recoveredPub = EthUtil.ecrecover(messageHashx, sigDecoded.v, sigDecoded.r, sigDecoded.s)
// change it to familiar format
const recoveredAddress = "0x"+EthUtil.pubToAddress(recoveredPub).toString('hex')
if (recoveredAddress === signer) {
} else {
  console.log("Not Okay")

That’s it.
Now we can sign message on client and verify the message on server.

By the way why do we have to send message to server?

Good question!

In most case client can talk to blockchain directly but there are a few scenarios we want to delegate actions to server.

  • Execute a specific task which have to be done by an authorized address
  • Send transaction without letting end users pay.
  • When you have something you want to do on server

This is called oracle in blockchain world. There are many other cases which is also called oracle, but I use term, oracle, almost equivalent to API for blockchain.


We covered topics like setting up a private blockchain, start a IPFS server, and how to sign message and verify address.

We didn’t use the private network and IPFS this time.
Sorry about that. we will use them at the next blog.

At next blog, I will cover smart contracts and explain how we use blockchain and IPFS on server.

If you are interested in our project, please visit our website. and source code is here on github.


Also published on Medium.

Related posts:

Subscribe To Our Newsletter

Join our mailing list to receive the latest news and updates from our team.

You have Successfully Subscribed!

%d bloggers like this: