Skip to content

Genesis Block

The genesis block is the first block in your blockchain. It's never empty, even if configs/peer/genesis.json is. Here's an example:

Genesis Block Example: alice@wonderland
json
{
  "transactions": [
    [
      {
        "Register": {
          "Domain": {
            "id": "wonderland",
            "logo": null,
            "metadata": {
              "key": {
                "String": "value"
              }
            }
          }
        }
      },
      {
        "Register": {
          "Account": {
            "id": "alice@wonderland",
            "signatories": [
              "ed01207233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0"
            ],
            "metadata": {
              "key": {
                "String": "value"
              }
            }
          }
        }
      },
      {
        "Register": {
          "Account": {
            "id": "bob@wonderland",
            "signatories": [
              "ed01207233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0"
            ],
            "metadata": {
              "key": {
                "String": "value"
              }
            }
          }
        }
      },
      {
        "Register": {
          "AssetDefinition": {
            "id": "rose#wonderland",
            "value_type": "Numeric",
            "mintable": "Infinitely",
            "logo": null,
            "metadata": {}
          }
        }
      },
      {
        "Register": {
          "Domain": {
            "id": "garden_of_live_flowers",
            "logo": null,
            "metadata": {}
          }
        }
      },
      {
        "Register": {
          "Account": {
            "id": "carpenter@garden_of_live_flowers",
            "signatories": [
              "ed01207233BFC89DCBD68C19FDE6CE6158225298EC1131B6A130D1AEB454C1AB5183C0"
            ],
            "metadata": {}
          }
        }
      },
      {
        "Register": {
          "AssetDefinition": {
            "id": "cabbage#garden_of_live_flowers",
            "value_type": "Numeric",
            "mintable": "Infinitely",
            "logo": null,
            "metadata": {}
          }
        }
      },
      {
        "Mint": {
          "Asset": {
            "object": "13",
            "destination_id": "rose##alice@wonderland"
          }
        }
      },
      {
        "Mint": {
          "Asset": {
            "object": "44",
            "destination_id": "cabbage#garden_of_live_flowers#alice@wonderland"
          }
        }
      },
      {
        "Transfer": {
          "Domain": {
            "source_id": "genesis@genesis",
            "object": "wonderland",
            "destination_id": "alice@wonderland"
          }
        }
      },
      {
        "Grant": {
          "PermissionToken": {
            "object": {
              "definition_id": "CanSetParameters",
              "payload": null
            },
            "destination_id": "alice@wonderland"
          }
        }
      },
      {
        "NewParameter": "?MaxTransactionsInBlock=512"
      },
      {
        "NewParameter": "?BlockTime=2000"
      },
      {
        "NewParameter": "?CommitTimeLimit=4000"
      },
      {
        "NewParameter": "?TransactionLimits=4096,4194304_TL"
      },
      {
        "NewParameter": "?WSVDomainMetadataLimits=1048576,4096_ML"
      },
      {
        "NewParameter": "?WSVAssetDefinitionMetadataLimits=1048576,4096_ML"
      },
      {
        "NewParameter": "?WSVAccountMetadataLimits=1048576,4096_ML"
      },
      {
        "NewParameter": "?WSVAssetMetadataLimits=1048576,4096_ML"
      },
      {
        "NewParameter": "?WSVTriggerMetadataLimits=1048576,4096_ML"
      },
      {
        "NewParameter": "?WSVIdentLengthLimits=1,128_LL"
      },
      {
        "NewParameter": "?ExecutorFuelLimit=55000000"
      },
      {
        "NewParameter": "?ExecutorMaxMemory=524288000"
      },
      {
        "NewParameter": "?WASMFuelLimit=55000000"
      },
      {
        "NewParameter": "?WASMMaxMemory=524288000"
      },
      {
        "Register": {
          "Role": {
            "id": "ALICE_METADATA_ACCESS",
            "permissions": [
              {
                "definition_id": "CanRemoveKeyValueInAccount",
                "payload": {
                  "account_id": "alice@wonderland"
                }
              },
              {
                "definition_id": "CanSetKeyValueInAccount",
                "payload": {
                  "account_id": "alice@wonderland"
                }
              }
            ]
          }
        }
      }
    ]
  ],
  "executor_file": "./executor.wasm"
}

The genesis account is specified in the peer configuration file, configs/peer/config.json. This is the account that will submit the genesis block. The genesis account is like a super user account that has elevated privileges, but only during the genesis round. The genesis account should be signed by one of the peers, or, in other words, it should have the public key of this peer.

If you look at the example of a genesis block above, you will see that it contains instructions for registering a new domain (wonderland), two new accounts (alice@wonderland and bob@wonderland), a new asset (rose#wonderland) and a Mint instruction for this asset, as well as several permission tokens and roles. Both new accounts are signed with the ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0 public key.

Note

Iroha is case-sensitive, meaning that Alice@wonderland is different from alice@wonderland. It should go without saying that alice@wonderland is not the same as alice@looking_glass either, since these accounts belong to different domains, wonderland and looking_glass.

The accounts registered in the genesis block are just new accounts. As we said above, the genesis account is determined in the peer configuration. However, you can use the matching signature for the genesis account and for a new account in the genesis block. Since the genesis account only has privileges during the genesis round, it won't be a security issue.

You can generate the default genesis block or create a custom one.

If you need to recommit a genesis block, remove the previously stored blocks, then restart the Docker container. The new genesis block will be automatically recommited upon container restart.

Generation

You can add various instructions to the genesis block, such as registering new accounts or assets, as well as minting assets. You can also register permission tokens and roles, as well as grant them to the registered accounts.

Generate default genesis block

You can use kagami to generate the default genesis block:

  • Generate a genesis block in JSON format:

    bash
    $ kagami genesis
  • Generate a genesis block in JSON format and write the output to the specified file:

    bash
    $ kagami genesis > genesis.json
  • Generate a synthetic genesis block in JSON format and write the n domains, m accounts per domain and p assets per domain:

    bash
    $ kagami genesis --synthetic --domains n --accounts-per-domain m --assets-per-domain p

The genesis block should be located in configs/peer/genesis.json.

Configuration

As we already explained, genesis account is specified in the peer configuration file, configs/peer/config.json. You can use the same configuration file to fine-tune other genesis block configurations.