Learning Notes in Taifang: Operational Guidelines for Private Chain Building

Although Etaifang is a public chain system, we can run our private chain nodes by setting some parameters. Developing and testing on our private chain does not require synchronizing common chain data, nor spending money to buy Etai coin. It saves storage space and costs, and is flexible and convenient.This paper describes the steps for building a private chain using the get client, explains the meaning and function of the commands and options used in this process, and introduces some common functions in the Javascript Console of get.

Systems and Software

  • Ubuntu 16.04 64 bit
  • geth 1.5.6

Build Private Chain

I. Preparing Chuangshi Block Profile

Taifang supports custom Creation Blocks. To run the private chain, we need to define our own Creation Blocks. The Creation Block information is written in a JSON format configuration file.First, save the following to a JSON file, such as genesis.json.

{
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x400",
  "extraData"  : "0x0",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0xdeadbeefdeadbeef",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00",
  "alloc"      : {}
}

Initialization: Writing to the Creation Block

Once the Creation Block Profile is ready, to initialize the block chain, write the Creation Block information above into the block chain.First, create a new directory to store block chain data. Assuming the new data directory is ~/privatechain/data0 and genesis.json is stored in ~/privatechain, the directory structure should be as follows:

privatechain
├── data0
└── genesis.json

Next, enter privatechain and execute the initialization command:

$ cd privatechain
$ geth --datadir data0 init genesis.json

The main body of the above command is geth init, which means to initialize the block chain. The command can have options and parameters, where the--datadir option is followed by a directory name, where Data0 indicates that the specified data storage directory is data0, and genesis.json is the parameter of the init command.

Running the above command reads the genesis.json file and, depending on its contents, writes the Genesis blocks into the block chain.If you see the output below, the initialization is successful.

I0322 10:52:44.585282 cmd/geth/chaincmd.go:131] successfully wrote genesis block and/or chain rule set: b240e0678c2a8f87cf350225b528e3d97688aad6d4d84ee84e405c7fc9e37e4e

After successful initialization, the geth and keystore folders are generated in the data directory data0, where the directory structure is as follows:

privatechain
├── data0
│   ├── geth
│   │   └── chaindata
│   │       ├── 000002.log
│   │       ├── CURRENT
│   │       ├── LOCK
│   │       ├── LOG
│   │       └── MANIFEST-000003
│   └── keystore
└── genesis.json

Block data is stored in geth/chaindata, and private keys and addresses are stored in keystore.

3. Start Private Chain Nodes

Once initialization is complete, there is a private chain of your own, after which you can start your own private chain node and do something to start the node by typing the following command in the terminal:

$ geth --datadir data0 --networkid 1108 console

The principal part of the above command is the geth console, which means to start the node and enter the interactive console, --datadir option specifies using data0 as the data directory, --networkid option followed by a number, here 1108, which means specifying the network id of this private chain is 1108.The network id is used when connecting to other nodes. The network id of Taifang Public Network is 1. In order not to conflict with the public chain network, you should specify your own network id when running the private chain node.

After running the above command, the block chain node is started and enters the Javascript Console:

...
Welcome to the Geth JavaScript console!

instance: Geth/v1.5.6-stable/linux/go1.7.3
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 

This is an interactive Javascript execution environment in which Javascript code can be executed, where > is a command prompt.There are also some Javascript objects built into this environment to operate on Etaifang, which can be used directly.These objects include:

  • eth: Contains some methods related to manipulating block chains
  • net: Contains the following methods for viewing p2p network status
  • admin: contains some methods related to managing nodes
  • miner: Contains some ways to start and stop mining
  • Person: There are a few main ways to manage accounts
  • txpool: Contains some ways to view the pool of transactional memory
  • web3: contains the above objects, as well as some unit conversion methods

Explore Javascript Console

Once you enter the Etaifang Javascript Console, you can use its built-in objects to do a few things. These built-in objects provide many functions, such as viewing blocks and transactions, creating accounts, mining, sending transactions, deploying smart contracts, and so on.Following are some of the common functions described below, preceded by > to represent commands executed in the Javascript Console.

1. Create an account

You just built a private chain, you don't have your own account, you can verify it by entering eth.accounts in js console:

> eth.accounts
[]

Next, use the personal object to create an account:

> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0xc232e2add308136571bb8f9197ba4ae4e5ba9836"

You will be prompted to enter the password and confirm the password. The password will not be displayed. As long as you enter it, the newly created account address will be displayed.

You can create more than one account, so let's create one more:

> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0x814d39aa21f3eed069f2b21da7b5f857f7343afa"

Then you can see the two accounts you just created:

> eth.accounts
["0xc232e2add308136571bb8f9197ba4ae4e5ba9836", "0x814d39aa21f3eed069f2b21da7b5f857f7343afa"]

By default, the account is saved in the keystore folder in the data directory.Looking at the directory structure, we found two more files in the data0/keystore, which correspond to the two accounts just created. This is a text file in json format, which can be opened for viewing. It contains the information encrypted by the private key.

data0
├── geth
│   ├── chaindata
│   ├── LOCK
│   ├── nodekey
│   └── nodes
├── geth.ipc
├── history
└── keystore
    ├── UTC--2017-03-22T09-06-47.766993033Z--c232e2add308136571bb8f9197ba4ae4e5ba9836
    └── UTC--2017-03-22T09-09-42.041015656Z--814d39aa21f3eed069f2b21da7b5f857f7343afa

Tip: All commands can be auto-completed by pressing the Tab key.

2. View account balance

The eth object provides a way to view account balances:

> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
0

Currently, both accounts have an ET balance of 0. To make the account balance available, you can transfer it from another account or get an ET reward by digging.

3. Start-stop mining

Start mining by miner.start():

> miner.start(1)

The start parameter represents the number of threads used for mining.Start the Mining Society for the first time to generate the DAG files needed for mining. The process is a bit slow. When the progress reaches 100%, the mining will start and the screen will be brushed with the mining information.

If you want to stop mining, type miner.stop() in js console:

> miner.stop()

Note: The characters you enter will be washed out by the mining brush screen information. That's okay. As long as you enter the complete miner.stop() and return, you can stop mining.

Digging into a block will reward five ethernic coins, and the reward from mining will go to an account called a coinbase, which by default is the first account in the local account:

> eth.coinbase
"0xc232e2add308136571bb8f9197ba4ae4e5ba9836"

To get the mining reward into another account, set the other account to coinbase by miner.setEtherbase():

> miner.setEtherbase(eth.accounts[1])
true
> eth.coinbase
"0x814d39aa21f3eed069f2b21da7b5f857f7343afa"

There should be a balance in account 0 now:

> eth.getBalance(eth.accounts[0])
160000000000000000000

The return value of getBalance() is in wei, which is the smallest unit of ethernic currency, with one ethernic currency = 10 to the 18th power of wei.To see how many Etheric coins there are, you can convert the return value to Etheric coin using web3.fromWei():

> web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')
160

IV. Send Transactions

Currently, the balance of account one is 0:

> eth.getBalance(eth.accounts[1])
0

You can transfer five ethernic currencies from account 0 to account 1 by sending a transaction:

> amount = web3.toWei(5,'ether')
"5000000000000000000"
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})
Error: account is locked
    at web3.js:3119:20
    at web3.js:6023:15
    at web3.js:4995:36
    at <anonymous>:1:1

This is a mistake because the account is locked every other time. To send transactions, you must first unlock the account. Since we are sending transactions from account 0, we need to unlock account 0:

> personal.unlockAccount(eth.accounts[0])
Unlock account 0xc232e2add308136571bb8f9197ba4ae4e5ba9836
Passphrase: 
true

You can successfully unlock the account by entering the password you set when you created the account.Then send the transaction:

> amount = web3.toWei(5,'ether')
"5000000000000000000"
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})
I0322 19:39:36.300675 internal/ethapi/api.go:1047] Tx(0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825) to: 0x814d39aa21f3eed069f2b21da7b5f857f7343afa
"0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825"

At this point the transaction has been submitted to the block chain, returning the hash of the transaction, but not yet processed, which can be verified by looking at txpool:

> txpool.status
{
  pending: 1,
  queued: 0
}

There is a pending transaction, which indicates a transaction that has been submitted but not yet processed.

In order for the transaction to be processed, it must be mined.Here we start digging and wait until we reach a block before stopping:

> miner.start(1);admin.sleepBlocks(1);miner.stop();

When miner.stop() returns true, the number of pending transactions in txpool should be zero, indicating that the transaction has been processed:

> txpool.status
{
  pending: 0,
  queued: 0
}

At this time, the transaction has taken effect and the account should have received five tokens:

> web3.fromWei(eth.getBalance(eth.accounts[1]),'ether')
5

5. View transactions and blocks

The eth object encapsulates a way to view transaction and block information.

View the current total number of blocks:

> eth.blockNumber
33

View transactions through transaction hash:

> eth.getTransaction("0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825")
{
  blockHash: "0xf5d3da50065ce5793c9571a031ad6fe5f1af326a3c4fb7ce16458f4d909c1613",
  blockNumber: 33,
  from: "0xc232e2add308136571bb8f9197ba4ae4e5ba9836",
  gas: 90000,
  gasPrice: 20000000000,
  hash: "0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825",
  input: "0x",
  nonce: 0,
  r: "0x433fe5845391b6da3d8aa0d2b53674e09fb6126f0070a600686809b57e4ef77d",
  s: "0x6b0086fb76c46024f849141074a5bc79c49d5f9a658fd0fedbbe354889c34d8d",
  to: "0x814d39aa21f3eed069f2b21da7b5f857f7343afa",
  transactionIndex: 0,
  v: "0x1b",
  value: 5000000000000000000
}

View blocks by block number:

> eth.getBlock(33)
{
  difficulty: 132928,
  extraData: "0xd783010506846765746887676f312e372e33856c696e7578",
  gasLimit: 3244382,
  gasUsed: 21000,
  hash: "0xf5d3da50065ce5793c9571a031ad6fe5f1af326a3c4fb7ce16458f4d909c1613",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xc232e2add308136571bb8f9197ba4ae4e5ba9836",
  mixHash: "0x09849dff7c8b8467812fa80d1fa2a27bc61f1cf16d5b2c05a6ce1b77ee18f3f1",
  nonce: "0x5b3939449dbdbea0",
  number: 33,
  parentHash: "0xeca34637642f56f7cfe5b699031c7ddbc43aee00fb10c7f054e0a9719cf226da",
  receiptsRoot: "0xd5f5b7ee944e57cbff496f7bdda7ceffd5eedffe6d5be5320008190502adc07a",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 649,
  stateRoot: "0xc7add6b756980ab9e482766e455597ef1583e747ad62e2924a8e66c6f9170112",
  timestamp: 1490183209,
  totalDifficulty: 4358016,
  transactions: ["0x0c59f431068937cbe9e230483bc79f59bd7146edc8ff5ec37fea6710adcab825"],
  transactionsRoot: "0x7335a362b2c3925e7ba1b41bf7772aa9645a13d4f9c12edd5892b87887264232",
  uncles: []
}

There are more functions to explore by yourself...

6. Connect to other nodes

You can connect to other nodes through the admin.addPeer() method. To connect two nodes, you must ensure that the network is connected and specify the same networkid.

Assume that there are two nodes: Node 1 and Node 2, and both networkid s are 1108. You can connect from Node 1 to Node 2 by following the steps below.

The first thing to know is the enode information for Node 2, which is executed in the js console for Node 2:

> admin.nodeInfo.enode
"enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@[::]:30304"

Then execute admin.addPeer() in the js console of node one to connect to node two:

> admin.addPeer("enode://9e86289ea859ca041f235aed87a091d0cd594b377cbe13e1c5f5a08a8a280e62d4019ac54063ed6a1d0e3c3eaedad0b73c40b99a16a176993f0373ffe92be672@127.0.0.1:30304")

The parameter of addPeer() is the enode information of Node 2. Be careful to replace [:] in the enode with the IP address of Node 2.When the connection is successful, Node 2 starts synchronizing Node 1's blocks.Adn.peers allows you to view information about other nodes connected to, and net.peerCount allows you to see the number of nodes connected to.

In addition to the above method, you can also specify when you start a node that the--bootnodes option connects to other nodes.

Keywords: JSON Javascript network Ubuntu

Added by Mirage on Tue, 16 Jul 2019 20:29:39 +0300