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
{
"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 andp
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.