This document describes the tool to create the genesis block as well as to print its contents.
The tool supports two modes, make-genesis
and print-genesis
.
The latter simply prints the contents of the genesis block. The former is used to collect a number of files into a single genesis block that can be used to start the node.
The input to this command are the genesis parameters, genesis accounts, update keys, cryptographic parameters and anonymity revokers and identity providers.
The following options are supported (note that in contrast to many other command-line tools, parameters must be given without any space, e.g., you must write --identity-providers=foo.json
and not --identity-providers foo.json
):
--identity-providers=
must be a file with the identity providers that need to be included in genesis. The format of this file is
{
"v": 0,
"value": {
"0": ip_info_0
"1": ip_info_1
"2": ip_info_2
...
}
}
where each ip_info_i
is the public information about the identity provider. This is the same format as the one generated by the keygen
tool and looks as follows.
{
"ipIdentity": 2,
"ipDescription": {
"name": "identity_provider-2",
"url": "",
"description": ""
},
"ipVerifyKey": "...",
"ipCdiVerifyKey": "..."
}
Note that it is important to ensure that the key, e.g, "2"
, matches the ipIdentity
field.
--anonymity-revokers=
must be a file with the initial anonymity revokers. The format of this file is
{
"v": 0,
"value": {
"1": ar_info_1,
"2": ar_info_2,
"3": ar_info_3
}
}
where each ar_info_i
is the public information about the anonymity revoker. This is the same format as the one generated by the keygen
tool and looks as follows
{
"arIdentity": 1,
"arDescription": {
"name": "AR-1",
"url": "url",
"description": "description"
},
"arPublicKey": "..."
}
Note that it is important to ensure that the key, e.g., "1"
in the anonymity-revokers file matches the arIdentity
field.
--crypto-params=
must be a file containing cryptographic parameters of the chain. This file must be of the following format
{
"v": 0,
"value": {
"onChainCommitmentKey": "...",
"bulletproofGenerators": "...",
"genesisString": "Stagenet 2021-04-26 genesis."
}
}
-- --accounts=
is the file containing the list of accounts in genesis with their initial stake, and whether they are a baker or not. The file must contain a JSON list of account
structures where each account structure has the format
{
"accountThreshold": 1, // number of credentials that need to sign valid transactions
"address": "33aAwqhbFU1teSpLtan34zTox7gYBmjUSRiZKEv4tKd2wkEbhw", // address of the account, derived from the first credential
"balance": "3500000000000", // initial amount of GTU on the account
"credentials": { // all credentials on the account. This must be non-empty and can have up to 255 credentials. They can be either initial or normal.
"v": 0,
"value": {
"0": {
"contents": {
"arData": {
"1": {
"encIdCredPubShare": "a462a8c7f51a39f80879a2050afbb1526a63c3f086802a92ade03cac2acd6deca1883f7becfa8a88df7700efaee009e89112b8cbbde11594fec7f0a8f02fabb312f6b84b9eef1bd3b23c884d9c4985afde9799a9411d8a3183e38d2316f21024"
}
},
"commitments": {
"cmmAttributes": {
},
"cmmCredCounter": "a22b0c5a53feae56c1d50390a661f08e3943094b74c0270c1ec04548bb4ba5a3a077ce5278907bd3f80b58e7f10dc6ad",
"cmmIdCredSecSharingCoeff": [
"82a0a718cbe26cf6f40250e34bb1440c334b96ca0b4854a07e680c529b2b94a766b56b41f8708db290f7b694d4354de0"
],
"cmmMaxAccounts": "ac2896ca35e6cb58764d76159e21002ad11f95cd83bcdf26bb35cf066a83d8380f95cb454e69f65ba3b53dc419b39fbb",
"cmmPrf": "a27fe6a729c0f43c1910b9886b021ac4a565c0f00e90d2cb2c026a6662c49041a6962fa0afaad8064bf7e5dfe53f2471"
},
"credId": "8f52879bef78c1cda1770c4e2b5eb73a693bb7e20a0d36e5290f4a565b9e2b15af19e0e1c20b05db7826490fef4daf9d",
"credentialPublicKeys": {
"keys": {
"0": {
"schemeId": "Ed25519",
"verifyKey": "43a4c70601d0039334be253527b029e99542d84cbd8e70698672ade950c87dd2"
}
},
"threshold": 1
},
"ipIdentity": 0,
"policy": {
"createdAt": "202104",
"revealedAttributes": {
},
"validTo": "202204"
},
"revocationThreshold": 1
},
"type": "normal"
}
}
},
"baker": { // this field is optional. If it is present the account will be a baker registered in genesis.
"bakerId": 0, // the id of the baker. This is defined by the account address and the order in the list of genesis accounts. The genesis tool checks that the id corresponds to the account address.
"aggregationVerifyKey": "88c83de6ba981856a8cdbc0d0f1151782145d75983f8eb88a41b54e75e763fd8188770c158c9643922712ff7c162189208631e2821419028233019965d6814f6b6fcfdc674f3295f12dfe832a8a8d799016ad0fbf584af4fdd2b4caef4872ef7",
"electionVerifyKey": "1deea65af31f2af7fac549c70091d03f00a2c2b013658a95e749b0868af57b37",
"restakeEarnings": false, // whether the baker should automatically restake rewards or not
"signatureVerifyKey": "deb8f7e3cf890af1f890cda8cacf5cac389e9ccdeb9331a89af7376762e5af0d",
"stake": "3000000000000" // initial stake of the baker.
}
}
The order of the accounts in the list is significant. The recommendation is to make the list such that the initial segment contains all the bakers, followed by any other accounts.
--update-keys=
contains the authorization structures for various kinds of updates. The format is
{
"rootKeys": {
"keys": [
{
"schemeId": "Ed25519",
"verifyKey": "57d47b4a1803d8c6a9b779f015c72e7b33791adf5303c3bd822b84c5258e6bb3"
},
...
],
"threshold": 3
},
"level1Keys": { // all the level 1 keys
"keys": [
{
"schemeId": "Ed25519",
"verifyKey": "c208c35a0cdb17df3451e7d0cb32dc31bb2a198723be3392efe098aa3052d655"
},
...
],
"threshold": 3
},
"level2Keys": {
"keys": [
{
"schemeId": "Ed25519",
"verifyKey": "3a8bc441dfc90ac88bd606b3bb1c465c12a09d6679ca2f33c2a89da0e005a16a"
},
...
],
"emergency": { // emergency update access structure
"authorizedKeys": [0,1,2], // the numbers in this list are indices into the array of `level2Keys.keys`
"threshold": 3
},
"protocol": { // access structure for protocol updates
"authorizedKeys": [...],
"threshold": 2
},
"electionDifficulty": {
"authorizedKeys": [...],
"threshold": 3
},
"euroPerEnergy": {
"authorizedKeys": [...],
"threshold": 2
},
"microGTUPerEuro": {
"authorizedKeys": [11],
"threshold": 1
},
"addAnonymityRevoker": {
"authorizedKeys": [...],
"threshold": 3
},
"addIdentityProvider": {
"authorizedKeys": [...],
"threshold": 3
},
"poolParameters": {
"authorizedKeys": [...],
"threshold": 3
},
"foundationAccount": {
"authorizedKeys": [...],
"threshold": 3
},
"mintDistribution": {
"authorizedKeys": [...],
"threshold": 3
},
"paramGASRewards": {
"authorizedKeys": [...]
"threshold": 3
},
"transactionFeeDistribution": {
"authorizedKeys": [...],
"threshold": 3
},
"cooldownParameters": { // For protocol version 4 onwards
"authorizedKeys": [...],
"threshold": 3
},
"timeParameters": { // For protocol version 4 onwards
"authorizedKeys": [...],
"threshold": 3
}
}
}
The names of the different fields should make clear what the autorization structure is for.
- genesis-parameters file. This is a JSON files specifying the remaining genesis parameters. It must be of the following format
{
"v": 2,
"value": {
"genesisTime": 1619442000000, // milliseconds since the unix epoch
"slotDuration": 250, // slot duration in milliseconds
"leadershipElectionNonce": "5bb78b5f359007c9532e17e474ff188c30bbd999147f6721d870f7ab2004e438",
"epochLength": 14400, // epoch length in slots
"maxBlockEnergy": 3000000,
"finalizationParameters": {
"minimumSkip": 0,
"committeeMaxSize": 1000,
"waitingTime": 100, // in milliseconds
"ignoreFirstWait": true,
"skipShrinkFactor": 0.5,
"skipGrowFactor": 2,
"delayShrinkFactor": 0.5,
"delayGrowFactor": 2,
"allowZeroDelay": true
},
"chainParameters": {
"electionDifficulty": 0.025,
"euroPerEnergy": 0.000001,
"microGTUPerEuro": 100000000,
"bakerCooldownEpochs": 1,
"accountCreationLimit": 10,
"foundationAccount": "4NyqjcJwKAckGE3gMGDJeqcyLZQxtfnDFTdvg74xYUU8myQTrB",
"minimumThresholdForBaking": "300000000000", // microGTU
"rewardParameters": {
"mintDistribution": {
"mintPerSlot": 0.0000000007555665,
"bakingReward": 0.6,
"finalizationReward": 0.3
},
"transactionFeeDistribution": {
"baker": 0.45,
"gasAccount": 0.45
},
"gASRewards": {
"baker": 0.25,
"finalizationProof": 0.005,
"accountCreation": 0.002,
"chainUpdate": 0.005
}
}
}
}
}
All parameters apart from genesis.json
are optional and their values can be specified directly in genesis.json
.
--identity-providers
flag can be replaced by a fieldidentityProviders
ingenesis.json
. The format of the value of this field is the same as decribed above, apart from the outer versioning wrapper, i.e., it has to be an object of the form{ "0": ip_info_0 "1": ip_info_1 "2": ip_info_2 ... }
--anonymity-revokers
flag can be replaced by a fieldanonymityRevokers
with the same considerations as theidentityProviders
field.--crypto-params
flag can be replaced by a fieldcryptographicParameters
with the same considerations as the above two fields--accounts
flag can be replaced by a fieldinitialAccount
with the same structure as the structure of the file described above, i.e., array of genesis accounts.--update-keys
flag can be replaced by a fieldupdateKeys
with the same structure as the structure of the file described above.
If both the field in genesis.json
and a flag are present, the priority goes to the file specified by the flag.
An example invocation of the tool in the make-genesis
mode is
$ genesis make-genesis\
--identity-providers=ips.json\
--anonymity-revokers=ars.json\
--crypto-params=global.json\
--accounts=initial-accounts.json\
--update-keys=update-keys.json\
genesis-parameters.json\
genesis.dat
Where all files apart from genesis.dat
are input files, and genesis.dat
is the output file. This file can be used to start a node.
In addition to genesis.dat
the tool will produce a file genesis_hash
which contains the hash of the genesis block. This can be used to start a bootstrapper.
print-genesis
mode
This simply prints the contents of the genesis block in human readable format. The tool can be invoked as
$ genesis print-genesis genesis.dat