07 Mar 2017, 19:20 by CodeOoze
A brief introduction to deploying smart contracts on a private blockchain with truffle and geth.
Previously we went through setting up an Ethereum development environment with truffle and testrpc, and deploying a simple smart contract written in Solidity. Now we will take it a step further using truffle
and geth
to deploy a smart contract on a private blockchain. First, we will use geth
to start a single node running locally on Ubuntu, then we’ll use truffle
to deploy our smart contract.
For these steps I’m running Ubuntu 16 in VirtualBox on Windows 10, as described here.
Check out these previous articles which describe setting up the dev environment and other tools I’ll be using:
If you’re using Atom on Windows 10, the following articles may be useful for editing files on a remote Ubuntu server:
First we need to install geth
on our Ubuntu machine. These steps are from the documentation: https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Ubuntu
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
That’s the basic geth
install done.
Next we need to initialise the private blockchain with a genesis block.
The article article at the link below has a good explanation of this process. The geth
steps are a bit out of date, but the surrounding explanations are still valuable.
https://souptacular.gitbooks.io/ethereum-tutorials-and-tips-by-hudson/content/private-chain.html
Let’s go through it quickly:
Create a new directory to work from, then create the genesis.json
file.
mkdir geth && cd geth
mkdir privchain
touch genesis.json
Edit the genesis.json
file and type or paste the following:
{
"nonce": "0x0000000000220042",
"timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x0",
"gasLimit": "0x8000000",
"difficulty": "0x400",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333",
"alloc": {
}
}
Now we’re ready to initialise the blockchain. Note that some of the tools we’re using are bleeding edge, and evolving quickly. As a result, information quickly goes out of date. I found this guide very useful and it seems current at the time of writing: http://mlgblockchain.com/ethereum-private-network.html
To initialise the blockchain. open a new terminal and enter
geth --datadir privchain init genesis.json
Output:
...WARNING: No etherbase set and no accounts found as default
...Allotted 128MB cache and 1024 file handles to /home/someone/privchain/geth/chaindata
...closed db:/home/someone/privchain/geth/chaindata
...Allotted 128MB cache and 1024 file handles to /home/someone/privchain/geth/chaindata
...successfully wrote genesis block and/or chain rule set: 6650a0ac6c5e805475...
This should generate a new folder privchain
with stuff inside it.
Next we use geth
to start the first node on our private network. Since this is a private blockchain, it will be the only node for now.
Type the following to start the node using the initialised genesis block:
geth --port 3000 --networkid 58342 --nodiscover --datadir="privchain" --maxpeers=0 --autodag \
--rpc --rpcport 8545 --rpcaddr 127.0.0.1 --rpccorsdomain "*" --rpcapi "eth,net,web3" \
--ipcapi "eth,net,web3"
--rpcapi "eth,net,web3"
is required for geth attach
to work (we’ll use this shortly)
--rpcport 8545
is to be consistent with ethereumjs-testrpc, and make integration with truffle
easier
--rpcapi "eth,net,web3"
is required for web3 to work in truffle
Read more about the geth
command line options here: https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options
After starting the geth
node you should see something like IPC endpoint opened: /home/someone/privchain/geth.ipc
Next we attach to the geth console. Open a new terminal window and type:
geth attach ipc://home/someone/privchain/geth.ipc
Then create an account to use
> personal.newAccount('password')
Lastly, verify the new account is your default.
> personal.listAccounts
> web3.eth.coinbase
These two commands should both return the same address, which should match the account created in the previous step.
For this step I’ll assume you already have a truffle project with a contract you’d like to deploy (if not, check out my earlier article). Before we can actually deploy the contract, there are a few things we need to do first (these are the sorts of things testrpc
usally takes care of for us).
If we were to open a new terminal, cd
to our truffle project, and run truffle migrate
, we’d probably get an error:
Deploying Migrations...
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: authentication needed: password or unlock
We need to unlock the account so truffle can deploy the contract. Refer also http://ethereum.stackexchange.com/questions/11908/account-is-locked-after-running-truffle-migrate-command
In the geth
console, enter the following to unlock the default account, ensuring to replace password
with the value entered when the account was created previously.
> personal.unlockAccount(web3.eth.coinbase, "password", 15000)
But still, if we were to run truffle compile
again, we’d probably get another error:
Deploying Migrations...
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: Insufficient funds for gas * price + value
We seem to be making progress, and this error indicates we don’t have any ether at our default address. We can start mining briefly on our private network to create some Ether. Type the following into the geth
console.
> miner.start()
Now back in the first terminal, where we started the geth
node, you should start to see output like:
Generating DAG for epoch 0 (size 1073739904) (000000000000000000000000000000000000000...)
...Generating DAG: 0%
...Generating DAG: 1%
...Generating DAG: 2%
This could take a while to run, but you can pass the time by reading about the DAG:
Also note that if you’re running your geth
node for extended periods of time, i.e longer than 30000 blocks, using --autodag
to enable automatic DAG pregeneration can help speed things up.
Eventually you’ll see the mining start:
...Generating DAG: 100%
...Done generating DAG for epoch 0, it took 8m16.297777249s
...