Hyperledger Besu: How to Create an Ethereum Genesis File
Setting up a private network or joining a public network requires an Ethereum node to create a new blockchain. Whether it is a private or public network, each node/validator will have a full copy of the blockchain. In order to build this copy, the node/validator has to have instructions on how to build the first block and the subsequent blocks in the chain. In this article, we are going to walk through the components of a genesis file, within the context of using Hyperledger Besu as the client for our network. These concepts are applicable to all Ethereum clients.
The first block in a blockchain is called the genesis block. Ethereum mainnet鈥檚 genesis block 鈥 block 0 鈥 was mined on July 30, 2015. In order to join or create any network, the data for the genesis block must be included. Therefore, the genesis file defines the data that is in the first block of a blockchain, as well as rules for the blockchain itself. If a new node or validator attempts to join the blockchain, it will use the genesis file as the starting point in recreating the history of the chain in order to synchronize with the existing network.
The genesis file for Ethereum mainnet, along with the supported testnets, is included in the download of Besu. When creating a private network, a custom genesis file must be provided. The genesis file is a JSON formatted file. It looks like the below:
{
聽聽鈥渃onfig鈥: {
聽聽聽聽鈥渃hainId鈥: 2018,
聽聽聽聽鈥渕uirglacierblock鈥: 0,
聽聽聽聽鈥渋bft2鈥: {
聽聽聽聽聽聽鈥渂lockperiodseconds鈥: 2,
聽聽聽聽聽聽鈥渆pochlength鈥: 30000,
聽聽聽聽聽聽鈥渞equesttimeoutseconds鈥: 4
聽聽聽聽}
聽聽},
聽聽鈥渘once鈥: 鈥0x0鈥,
聽聽鈥渢imestamp鈥: 鈥0x58ee40ba鈥,
聽聽鈥渆xtraData鈥: 鈥0xf83ea00000000000000000000000000000000000000000000000000000000000000000d5949811ebc35d7b06b3fa8dc5809a1f9c52751e1deb808400000000c0鈥,
聽聽鈥済asLimit鈥: 鈥0x1fffffffffffff鈥,
聽聽鈥渄ifficulty鈥: 鈥0x1鈥,
聽聽鈥渕ixHash鈥: 鈥0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365鈥,
聽聽鈥渃oinbase鈥: 鈥0x0000000000000000000000000000000000000000鈥,
聽聽鈥渁lloc鈥: {
聽聽聽聽鈥9811ebc35d7b06b3fa8dc5809a1f9c52751e1deb鈥: {
聽聽聽聽聽聽鈥渂alance鈥: 鈥0xad78ebc5ac6200000鈥
聽聽聽聽}
聽聽}
}
In this specific example, the genesis file is for an IBFT 2.0 private network.聽
{
聽聽鈥渃onfig鈥: {
聽聽聽聽鈥渃hainId鈥: 2018,
鈥渕uirglacierblock鈥: 0,
聽聽聽聽鈥渋bft2鈥: {
聽聽聽聽聽聽鈥渂lockperiodseconds鈥: 2,
聽聽聽聽聽聽鈥渆pochlength鈥: 30000,
聽聽聽聽聽聽鈥渞equesttimeoutseconds鈥: 4
聽聽聽聽}
The config key section contains the following information about the blockchain
鈥渃hainId鈥: 2018
The chainId controls the transaction signature process, providing a unique identifier to allow for the hashing of signed transactions to only work on the network associated with the corresponding chainId. Ethereum Improvement Proposal 155 (EIP-155) provides more information on the relationale behind the chainID. Most chainIDs match the networkID of the network. In this case, 2018 refers to the chainID associated with a development chain. For a list of the network and chain IDs, please see the Documentation.
鈥渕uirglacierblock鈥: 0,
This field is called a 鈥渕ilestone block鈥. Muir glacier refers to a specific network upgrade that occurred at block 9,200,000 on Ethereum mainnet. For private networks, like the one that is being created in this example, the name of the latest milestone block can be listed, and set to be the genesis block. Here you can see a continuously updated list of network upgrades and the associated blocks for Ethereum.
鈥渋bft2鈥:
This specifies that the consensus protocol for the blockchain is IBFT 2.0. The options available for specifying the consensus mechanism are available in the documentation, with an overview of the proof-of-authority (PoA) consensus protocols available here. Within the specification, the following three fields are provided:
鈥渂lockperiodseconds鈥: 2,
The minimum block time, in seconds. In this case, after two seconds, a new block will be proposed by the network with transactions stored in the memory pool packaged and distributed to the network.
鈥渆pochlength鈥: 30000,
The number of blocks at which to reset all votes. The votes refer to validators voting to add or remove validators to the network. In this case, after 30,000 blocks are created, this IBFT 2.0 network will discard all pending votes collected from received blocks. Existing proposals remain in effect and validators re-add their vote the next time they create a block.
鈥渞equesttimeoutseconds鈥: 4
The time by which a new block must be proposed or else a new validator will be assigned by the network. If a validator goes down, the request time out ensures that the proposal of a new block passes on to another validator. The request time out seconds should be set to be double the minimum block time (blockperiodseconds), hence why it is 4.
The second section, starting with 鈥渘once鈥: 鈥0x0鈥,聽 contains information about the genesis block
聽鈥渘once鈥: 鈥0x0鈥,
聽聽鈥渢imestamp鈥: 鈥0x58ee40ba鈥,
聽聽鈥渆xtraData鈥: 鈥0xf83ea00000000000000000000000000000000000000000000000000000000000000000d5949811ebc35d7b06b3fa8dc5809a1f9c52751e1deb808400000000c0鈥,
聽聽鈥済asLimit鈥: 鈥0x1fffffffffffff鈥,
聽聽鈥渄ifficulty鈥: 鈥0x1鈥,
聽聽鈥渕ixHash鈥: 鈥0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365鈥,
聽聽鈥渃oinbase鈥: 鈥0x0000000000000000000000000000000000000000鈥,
聽聽鈥渁lloc鈥: {
聽聽聽聽鈥9811ebc35d7b06b3fa8dc5809a1f9c52751e1deb鈥: {
聽聽聽聽聽聽鈥渂alance鈥: 鈥0xad78ebc5ac6200000鈥
聽聽聽聽}
聽聽}
}
聽鈥渘once鈥: 鈥0x0鈥,
The number used once aka nonce, that is a part of the blockheader for the first block. Set to 0x0.
聽聽鈥渢imestamp鈥: 鈥0x58ee40ba鈥,
The creation date and time of the block. Often it can be set to 0x0, but as long as it is any value in the past, it will work. In this case 0x58ee40ba is a hexadecimal which converts to 1492009146 and represents Wed Apr 12 2017 14:59:06 GMT+0000
聽聽鈥渆xtraData鈥: 鈥0xf83ea00000000000000000000000000000000000000000000000000000000000000000d5949811ebc35d7b06b3fa8dc5809a1f9c52751e1deb808400000000c0鈥,
Extra data is a recursive length prefix (RLP) encoded string (which is space efficient) containing the validator addresses of the IBFT 2.0 private network. The validator addresses are unique to the validators, so if there are four validators are the start of the network, this field should contain a list of their addresses. Instructions on how to create an RLP using Besu can be found here.
聽聽鈥済asLimit鈥: 鈥0x1fffffffffffff鈥,
The block gas limit, which is the total gas limit for all transactions included in a block. It defines how large the block size can be for the block, and is represented by an hexadecimal string. For this network, the gas limit is the maximum size, and is therefore a 鈥渇ree gas network鈥
聽聽鈥渄ifficulty鈥: 鈥0x1鈥,
The difficulty of creating a new block. Represented as a hexadecimal string, the difficulty is set to 1, effectively the lowest difficulty.
聽鈥渕ixHash鈥: 鈥0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365鈥,
The mixHash is the unique identifier for the block, which for this genesis file is 0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365
鈥渃oinbase鈥: 鈥0x0000000000000000000000000000000000000000鈥,
The network coinbase account, which is where all block rewards for this network will be paid. In this case it is to 0x0000000000000000000000000000000000000000, which is sometimes called address(0) or the zero address.
鈥渁lloc鈥: {
聽聽聽聽鈥9811ebc35d7b06b3fa8dc5809a1f9c52751e1deb鈥: {
聽聽聽聽聽聽鈥渂alance鈥: 鈥0xad78ebc5ac6200000鈥
The alloc field creates an address on our network, which is sometimes also referred to as an externally owned account, as it is an account not associated with a smart contract (referred to as a contract account). The number starting with 鈥98鈥 is the public key of the address. The balance can be passed in as a decimal OR a hexadecimal (like it has in this case and corresponds to 200 ETH, or 2*10^20 Wei). The balance is always in Wei, or 10^-18 Ether.
A Second Genesis File
Below we provide another genesis file with a different consensus mechanism, Clique PoA, and different information. Take a look below and see what values stick out. This is the genesis file for the chain that you can build in the ConsenSys Quorum quickstart:
{
聽聽鈥渃onfig鈥:{
聽聽聽聽鈥渃hainId鈥:1337,
聽聽聽聽鈥渕uirglacierblock鈥: 0,
聽聽聽聽鈥渃lique鈥:{
聽聽聽聽聽聽鈥渂lockperiodseconds鈥:15,
聽聽聽聽聽聽鈥渆pochlength鈥:30000
聽聽聽聽}
聽聽},
聽聽鈥渃oinbase鈥:鈥0x0000000000000000000000000000000000000000鈥,
聽聽鈥渄ifficulty鈥:鈥0x1鈥,
鈥渆xtraData鈥:鈥0x00000000000000000000000000000000000000000000000000000000000000004592c8e45706cc08b8f44b11e43cba0cfc5892cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000鈥,
聽聽鈥済asLimit鈥:鈥0xa00000鈥,聽 鈥渕ixHash鈥:鈥0x0000000000000000000000000000000000000000000000000000000000000000鈥,
聽聽鈥渘once鈥:鈥0x0鈥,
聽聽鈥渢imestamp鈥:鈥0x5c51a607鈥,
聽聽鈥渁lloc鈥: {
聽聽聽聽鈥渇e3b557e8fb62b89f4916b721be55ceb828dbd73鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥0xad78ebc5ac6200000鈥
聽聽聽聽},
聽聽聽聽鈥627306090abaB3A6e1400e9345bC60c78a8BEf57鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥渃87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥90000000000000000000000鈥
聽聽聽聽},
聽聽聽聽鈥渇17f52151EbEF6C7334FAD080c5704D77216b732鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥渁e6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥90000000000000000000000鈥
聽聽聽聽}
聽聽},
聽聽鈥渘umber鈥:鈥0x0鈥,
聽聽鈥済asUsed鈥:鈥0x0鈥,
鈥減arentHash鈥:鈥0x0000000000000000000000000000000000000000000000000000000000000000鈥
}
Once again, we will look at the fields and explain them.聽
{
聽聽鈥渃onfig鈥:{
聽聽聽聽鈥渃hainId鈥:1337,
聽聽聽聽鈥渃onstantinoplefixblock鈥: 0,
聽聽聽聽鈥渃lique鈥:{
聽聽聽聽聽聽鈥渂lockperiodseconds鈥:15,
聽聽聽聽聽聽鈥渆pochlength鈥:30000
聽聽聽聽}
聽聽}
The config key section contains the following information about the blockchain
鈥渃hainId鈥: 1337
In this case. 1337 refers to a local chainID. MetaMask, a self-custodial wallet, and Ganache, which is Truffle鈥檚 Private Blockchain App, both use this as the local chain ID, and so to follow convention, in this genesis file we are doing the same. For a list of the network and chain IDs, please see the Documentation.
鈥渕uirglacierblock鈥: 0,
Once again, we have set the milestone block to Muir Glacier. Something to note 鈥撀 The 鈥渕ilestone block鈥 could be for this configuration file, which is something you may see in some tutorials. For example, if we saw constantinopleBlock鈥: 0, this refers to a specific network upgrade that occurred at block 7,280,000 on Ethereum mainnet. For private networks, like the one that is being created in this example, the name of the latest milestone block can be listed, and set to be the genesis block. Here you can see a continuously updated list of network upgrades and the associated blocks for Ethereum.
鈥渃lique鈥:
This specifies that the consensus protocol for the blockchain is Clique. The options available for specifying the consensus mechanism are available in the documentation, with an overview of the proof-of-authority (PoA) consensus protocols available here. Within the specification, the following two fields are provided:
鈥渂lockperiodseconds鈥: 15,
The minimum block time, in seconds. In this case, after 15 seconds, a new block will be proposed by the network. Given this genesis file is modeled after the testnet, it is made to approximate the minimum blocktime of mainnet, which is 15 seconds.
鈥渆pochlength鈥: 30000,
The number of blocks at which to reset all votes. The votes refer to validators voting to add or remove validators to the network. In this case, after 30,000 blocks are created, this Clique network will discard all pending votes collected from received blocks. Existing proposals remain in effect and validators re-add their vote the next time they create a block.
Starting at the coinbase we now have the information available in the genesis block
鈥渃oinbase鈥:鈥0x0000000000000000000000000000000000000000鈥,
聽聽鈥渄ifficulty鈥:鈥0x1鈥,
聽聽鈥渆xtraData鈥:鈥0x00000000000000000000000000000000000000000000000000000000000000004592c8e45706cc08b8f44b11e43cba0cfc5892cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000鈥,
聽聽鈥済asLimit鈥:鈥0xa00000鈥,
聽聽鈥渕ixHash鈥:鈥0x0000000000000000000000000000000000000000000000000000000000000000鈥,
聽聽鈥渘once鈥:鈥0x0鈥,
聽聽鈥渢imestamp鈥:鈥0x5c51a607鈥,
聽聽鈥渁lloc鈥: {
聽聽聽聽鈥渇e3b557e8fb62b89f4916b721be55ceb828dbd73鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥0xad78ebc5ac6200000鈥
聽聽聽聽},
聽聽聽聽鈥627306090abaB3A6e1400e9345bC60c78a8BEf57鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥渃87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥90000000000000000000000鈥
聽聽聽聽},
聽聽聽聽鈥渇17f52151EbEF6C7334FAD080c5704D77216b732鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥渁e6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥90000000000000000000000鈥
聽聽聽聽}
聽聽}
鈥渃oinbase鈥: 鈥0x0000000000000000000000000000000000000000鈥,聽
The coinbase account, which is where all block rewards for this network will be paid. In this case it is to 0x0000000000000000000000000000000000000000, which is sometimes called address(0) or the zero address.
聽聽鈥渄ifficulty鈥: 鈥0x1鈥,
The difficulty of creating a new block. Represented as a hexadecimal string, the difficulty is set to 1, effectively the lowest difficulty.
鈥渆xtraData鈥:鈥0x00000000000000000000000000000000000000000000000000000000000000004592c8e45706cc08b8f44b11e43cba0cfc5892cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000鈥,
Extra data is a recursive length prefix (RLP) encoded string (which is space efficient) containing the validator address of the Clique private network, which in this case is 4592c8e45706cc08b8f44b11e43cba0cfc5892cb. Instructions on how to create an RLP using Besu can be found here and how to add additional addresses for a Clique network with additional signers can be found here.
鈥済asLimit鈥: 鈥0xa00000鈥,
The block gas limit, which is the total gas limit for all transactions included in a block. It defines how large the block size can be for the block, and is represented by an hexadecimal string. For this network, the gas limit is聽
聽鈥渕ixHash鈥:鈥0x0000000000000000000000000000000000000000000000000000000000000000鈥,
The mixHash is the unique identifier for the block, which for this genesis file is 0x0000000000000000000000000000000000000000000000000000000000000000
鈥渘once鈥: 鈥0x0鈥,
聽聽鈥渢imestamp鈥: 鈥0x5c51a607鈥,
In this case 0x5c51a607 is a hexadecimal which converts to 1548854791 and represents Wed Jan 30 2019 13:26:31 GMT+0000.
鈥渁lloc鈥: {
聽聽聽聽鈥渇e3b557e8fb62b89f4916b721be55ceb828dbd73鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥0xad78ebc5ac6200000鈥
聽聽聽聽},
聽聽聽聽鈥627306090abaB3A6e1400e9345bC60c78a8BEf57鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥渃87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥90000000000000000000000鈥
聽聽聽聽},
聽聽聽聽鈥渇17f52151EbEF6C7334FAD080c5704D77216b732鈥: {
聽聽聽聽聽聽鈥減rivateKey鈥: 鈥渁e6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f鈥,
聽聽聽聽聽聽鈥渃omment鈥: 鈥減rivate key and this comment are ignored.聽 In a real chain, the private key should NOT be stored鈥,
聽聽聽聽聽聽鈥渂alance鈥: 鈥90000000000000000000000鈥
聽聽聽聽}
The alloc field creates three addresses on our network, The balance can be passed in as a decimal (like the second and third account, which are both 900 ETH, or 2*10^20 Wei) OR a hexadecimal (like the first account, which is 200 ETH, or 2*10^20 Wei). The balance is always in Wei, or 10^-18 Ether.
Deploying Your Genesis File
Once you have created your genesis file, you will save it within the directory where your blockchain networks files will be kept. Do not save it within any of the Node or data folders, but rather at the top level. When it is time to start your network, you will use the flag
鈥揼enesis-file=../genesis.json
To start up your network using the genesis file use the following command:
besu鈥揼enesis-file=../genesis.json
For more information, please see the Documentation.
In the next article in this series, we will explore two advanced features for using a genesis file as part of a private network 鈥 how to deploy a smart contract within a genesis file and how to ensure the genesis file is appropriately tuned for the desired performance.