How Create a Private Chain

ESC supports custom genesis blocks. In order to operate a private chain, we need to define our own genesis blocks where the information is written in a JSON configuration file. First, we save the following contents to a JSON file, such as genesis.json. The content of the JSON file is as follows:

{
  "config": {
    "chainId": 83,
    "homesteadBlock": 1,
    "eip150Block": 2,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 3,
    "eip158Block": 3,
    "byzantiumBlock": 4,
    "constantinopleBlock": 4,
    "petersburgBlock": 4,
    "istanbulBlock": 4,
    "pbftBlock":0,
    "preConnectOffset":5,
    "clique": {
      "period": 3,
      "epoch": 30000
    },
     "pbft":{
      "producers": [
          "03bfd8bd2b10e887ec785360f9b329c2ae567975c784daca2f223cb19840b51914",
          "0342eeb0d664e2507d732382c66d0eedbd0a0f989179fd33d71679aa607d5d3b57",
          "03b0a37c11d1dfa8622e3d64b9dfefee781c6eb8279fa28f0c723efbc7c67adcd8",
          "023288ae99c212b42e3ba9fa088f4578eb2c958a0c2293b900d4fdefd5e6c571ee",
          "02bd6d05a6d3d97ce3a1137f0d0c56c0d7f23c06fe04d7c85430780d440b64d88b",
          "031c0c22f6712324babd9443475c9120a51ac8813c446a84161b6b950e2c1bb0f5"
      ],
      "magic": 202000,
      "ip": "127.0.0.1",
      "dposport":0,
      "printlevel":0,
      "maxlogssize":0,
      "maxperlogsize":0,
      "maxnodeperhost":100
    }
  },

  "nonce": "0x0",
  "timestamp": "0x5d8adde5",
  "extraData": "0x000000000000000000000000000000000000000000000000000000000000000053781e106a2e3378083bdcede1874e5c2a7225f8d9758863f280c25b0d1f2f81705e3725ccd5ac49fd7f1f6e2c5157a33dda2e91f58f32862f864d709b170f914ef3541cd29ee672a11c56d4b96b4b6f8aef2209eab2f60bc13da5e669ad832709f5e71d05f9b7a73f6ba0298c5c1943204a6a54839166b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x2068F7700",
  "difficulty": "0x1",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {
    "0x4f2C793DB2163A7A081b984E6E8e2c504825668b": {
      "balance":"9999999999999999999999"
    }
  },
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}

ESC supports POA and DPOS consensus. If POA consensus is used, we do not need to configure PBFT field, but instead need to configure the account address of the node that participates in the consensus in extraData and configure the block period and epoch through CLIque. It's here where the configuration of DPOS is mainly introduced.

Exclusive Configuration of ESC

PbftBlock: the height of DPoS consensus is enabled. ESC starts as a POA consensus participation block and later becomes a DPoS consensus, so the height is increased. The default value of the private chain can be 0, indicating that only DPoS consensus is used.

PreConnectOffset: in order to better participate, consensus among all supernodes of DPoS consensus of ESC, Elastos also integrates with the direct network of Elastosmain chain except the P2P network. The field begins to build a direct network for several blocks before POA is converted to DPoS consensus. If only DPoS consensus is used, this field can be left unset. #### PBFT ESC DPoS consensus adopts the voting mechanism of PBFT, and the nodes that participate in the consensus can also be transmitted to the sidechain from the mainchain through SPV. Thus, producers in the PBFT field use the public key of the mainchain consensus node, which is also called node publickey.

l Producers are those participating in the node publickey list of consensus node. At least 6 nodes (namely 6 public keys) are required in the nodes because it should be greater than two-thirds before reaching consensus

l magic connects directly to the network magic

l ip connects directly to IP address of the local node

l dposport connects directly to network port

l Maxnodeperhost represents the maximum number of directly connected nodes supported by a node

Initializing Genesis Block and Configuration

./geth --datadir "./data"  init "../genesis.json"

The body of the above command is geth init, which initializes the blockchain, and the command can take options and arguments. The -datadir option is followed by a directory name, namely data showing that specified data storage directory is data. The genesis.json is the parameter of the init command.

When the above command is operated, it will read the genesis .json file and write the Genesis block to the blockchain based on its contents. If the sentence “Successfully wrote genesis state” is contained in the log information, the initialization was successful. The directory after the initialization is as follows:

Geth/ChainData stores block data, and keystore stores account data.

Next, GEth will run on this data directory, and the genesis block you defined will be used.

geth --datadir "./data"

Start the Bootnode

After all nodes create genesis blocks, the connection between different nodes needs to be established through a bootnode:

bootnode --genkey=boot.key
bootnode --nodekey=boot.key

After the bootnode is started, an enode URL is displayed. Other nodes can use the URL to connect it and exchange node P2P information. The enode URL is similar to the following contents:

enode://a487f2b8fc55e24221b1f42f1f3ca76d7270c2203e8ae412e59c98a90fbac4d4c71caacc86d4f0e2134148ede6c9e438d8d0daab287edbe65350c47bd170435a@127.0.0.1:0?discport=20630

Start all DPOS Supernodes

Unlike common ESC nodes, ESC supernodes require a keystore file of the Elastos mainchain. The general name is keystore.dat and the content is as follows:

{
    "Version":"1.0.0",
    "PasswordHash":"3180b4071170db0ae9f666167ed379f53468463f152e3c3cfb57d1de45fd01d6",
    "IV":"aa4413d74ca2e6583b1c4d24db37ce8f",
    "MasterKey":"32785b3fccf6a3f6d8c36829fec4ff90ceafb0b561d8358ef5734a55f3dc6594",
    "Account":[
        {
            "Address":"Ec12maDpgK1q6wvxhzWNV5WaPV5AFL6KSR",
            "ProgramHash":"21cebcb83c1527c3f69cc3b0992d9735dd8ee25b49",
            "RedeemScript":"2103bfd8bd2b10e887ec785360f9b329c2ae567975c784daca2f223cb19840b51914ac",
            "PrivateKeyEncrypted":"154781cefc098704b825918e5e303abdfc91c2b8aff0a1c55bd83f4bb96d139517ca732068ed9127d73beccc3d16712e605e3f2daaa48458006d715030373d5d0648326cbc4d715d2de9697f93210fb713ad940b247e739373ef4fb25a08a57b",
            "Type":"main-account"
        }
    ]
}

This file is the private key of the mainchain account, which is used for the super-node to sign the block proposal proposed by the on-duty node in the DPoS consensus process. A block will not generate unless there are more than two out of three signatures. Rather than ESC, the private key of the mainchain is used because the list of ESC supernodes is elected by voting on the mainchain and transmitted to the sidechain via SPV. However, the private key can be configured by itself.

Therefore, the supernode needs two account files, namely the keystore.dat for the consensus mainchain and ESC account file. The file is used to collect fees for packaging transactions.

With the two files ready, we can start the supernode.

The start command is as follows:

./geth --datadir "./data" \
      --mine \
      --rpc --rpcvhosts '*' --rpcaddr "127.0.0.1" --port 8111 --rpcport 6111 \
      --rpccorsdomain "*" \
      --rpcapi "personal,db,eth,net,web3,txpool,miner,admin" \
      --allow-insecure-unlock \
      --unlock "0x$(cat ./data/keystore/UTC* | jq -r .address)" \
      --password "./pass.txt" \
      --bootnodes "enode://a487f2b8fc55e24221b1f42f1f3ca76d7270c2203e8ae412e59c98a90fbac4d4c71caacc86d4f0e2134148ede6c9e438d8d0daab287edbe65350c47bd170435a@127.0.0.1:0?discport=20630"  \
      --pbft.net.address "127.0.0.1" --pbft.net.port 20020 \
      --pbft.keystore "./keystore.dat"
      --pbft.keystore.password "./ethdpos.txt" \

The point used in the start command is:

l --unlock identify the miner when the block is drawn

l --password the password used to unlock the account

l --bootnodes the enode URL of the bootnode is used to establish P2P with other nodes and then create a direct network.

l --pbft.net.address directly connect network local IP

l --pbft.net.port directly connect network local port

l --pbft.keystore Keystore. Dat file path of the main chain used for consensus signature

l --pbft.keystore.password decryption password of keystore.dat

Notes: --pbft.net.address and --pbft.net.port can also be set on the “IP” and “dPOsport” ports of the PBFT field in genesis .json, but only one will take effect.

The above parameters are examples - users can set specific contents according to their own needs.

After all the super-neednodes are started, if the P2P network and direct network are normally established, the consensus process will start, and a block will be produced every 5 seconds. At this point, the private chain completes construction.

Last updated