# Jormungandr User Guide

Welcome to the Jormungandr User Guide.

Jormungandr is a node implementation, written in rust, with the initial aim to support the Ouroboros type of consensus protocol.

A node is a participant of a blockchain network, continuously making, sending, receiving, and validating blocks. Each node is responsible to make sure that all the rules of the protocol are followed.

## Mythology

Jörmungandr refers to the Midgard Serpent in Norse mythology. It is a hint to Ouroboros, the Ancient Egyptian serpent, who eat its own tail, as well as the IOHK paper on proof of stake.

# General Concepts

This chapter covers the general concepts of the blockchain, and their application in the node, and is followed by the node organisation and the user interaction with it.

# Blockchain concepts

## Time

Slots represent the basic unit of time in the blockchain, and at each slot a block could be present.

Consecutive slots are grouped into epochs, which have updatable size defined by the protocol.

## Fragments

Fragments are part of the blockchain data that represent all the possible events related to the blockchain health (e.g. update to the protocol), but also and mainly the general recording of information like transactions and certificates.

## Blocks

Blocks represent the spine of the blockchain, safely and securely linking blocks in a chain, whilst grouping valid fragments together.

Blocks are composed of 2 parts:

• The header
• The content

The header link the content with the blocks securely together, while the content is effectively a sequence of fragments.

## Blockchain

The blockchain is the general set of rules and the blocks that are periodically created. Some of the rules and settings, can be changed dynamically in the system by updates, while some other are hardcoded in the genesis block (first block of the blockchain).

    +-------+      +-------+
|Genesis+<-----+Block 1+<--- ....
|Header |      |Header |
+---+---+      +---+---+
|              |
+---v---+      +---v---+
|Genesis|      |Block 1|
|Content|      |Content|
+-------+      +-------+


## Consensus

The node currently support the following consensus protocol:

• Ouroboros BFT (OBFT)
• Ouroboros Genesis-Praos

Ouroboros BFT is a simple Byzantine Fault Tolerant (BFT) protocol where the block makers is a known list of leaders that successively create a block and broadcast it on the network.

Ouroboros Genesis Praos is a proof of stake (PoS) protocol where the block maker is made of a lottery where each stake pool has a chance proportional to their stake to be elected to create a block. Each lottery draw is private to each stake pool, so that the overall network doesn't know in advance who can or cannot create blocks.

In Genesis-Praos slot time duration is constant, however the frequency of creating blocks is not stable, since the creation of blocks is a probability that is linked to the stake and consensus_genesis_praos_active_slot_coeff.

Note: In Genesis-Praos, if there is no stake in the system, no blocks will be created anymore starting with the next epoch.

## Leadership

The leadership represent in abstract term, who are the overall leaders of the system and allow each individual node to check that specific blocks are lawfully created in the system.

The leadership is re-evaluated at each new epoch and is constant for the duration of an epoch.

## Leader

Leader are an abstraction related to the specific actor that have the ability to create block; In OBFT mode, the leader just the owner of a cryptographic key, whereas in Genesis-Praos mode, the leader is a stake pool.

## Transaction

Transaction forms the cornerstone of the blockchain, and is one type of fragment and also the most frequent one.

Transaction is composed of inputs and outputs; On one side, the inputs represent coins being spent, and on the other side the outputs represent coins being received.

    Inputs         Alice (80$) Bob (20$)
\             /
\           /
-----------
B - Account with 0$=> Account B has no stake  The account might have a bigger stake than what it actually contains, since it could also have associated UTXOs, and this case is covered in the next section. ## Stake in the UTXO Model UTXO are represented by two kind of addresses: • single address: those type of address have no stake associated • group address: those types of address have an account associated which receive the stake power of the UTXOs value For example with the following utxos:  UTXO1 60$ (single address) => has stake of 0

UTXO2 50$(group address A) \ ->- A - Account with 10$ => Account A has stake of 100
UTXO3 40$(group address A) / UTXO4 20$ (group address B) -->- B - Account with 5$=> Account B has stake of 25  ## Stake pool Stake pool are the trusted block creators in the genesis-praos system. A pool is declared on the network explicitely by its owners and contains, metadata and cryptographic material. Stake pool has no stake power on their own, but participants in the network delegate their stake to a pool for running the operation. ## Stake Delegation Stake can and need to be delegated to stake pool in the system. They can change over time with a publication of a new delegation certificate. Delegation certificate are a simple declaration statement in the form of:  Account 'A' delegate to Stake Pool 'Z'  Effectively it assign the stake in the account and its associated UTXO stake to the pool it delegates to until another delegation certificate is made. # Node organisation ## Secure Enclave The secure enclave is the component containing the secret cryptographic material, and offering safe and secret high level interfaces to the rest of the node. ## Network The node's network is 3 components: • Intercommunication API (GRPC) • Public client API (REST) • Control client API (REST) ### Intercommunication API (GRPC) This interface is a binary, efficient interface using the protobuf format and GRPC standard. The protobuf files of types and interfaces are available in the source code. The interface is responsible to communicate with other node in the network: • block sending and receiving • fragments (transaction, certificates) broadcast • peer2peer gossip ### Public API REST This interface is for simple queries for clients like: • Wallet Client & Middleware • Analytics & Debugging tools • Explorer it's recommended for this interface to not be opened to the public. TODO: Add a high level overview of what it does ### Control API REST This interface is not finished, but is a restricted interface with ACL, to be able to do maintenance tasks on the process: • Shutdown • Load/Retire cryptographic material TODO: Detail the ACL/Security measure # Quickstart The rust node comes with tools and help in order to quickly start a node and connect to the blockchain. It is compatible with most platforms and it is pre-packaged for some of them. Here we will see how to install jormungandr and its helper jcli and how to connect quickly to a given blockchain. There are three posible ways you can start jormungandr. ## As a passive node in an existing network As described here. The passive Node is the most common type of Node on the network. It can be used to download the blocks and broadcast transactions to peers, but it doesn't have cryptographic materials or any mean to create blocks. This type of nodes are mostly used for wallets, explorers or relays. ## As a node generating blocks in an existing network The network could be running either bft or genesis consensus. In the former case the node must have the private key of a registered as a slot leader, while for the latter the private keys of a registered stake pool are needed. More information here ## Creating your own network This is similar to the previous case, but configuring a genesis file is needed. Consult the Advanced section for more information on this procedure. The software is bundled with 2 different command line software: 1. jormungandr: the node; 2. jcli: Jormungandr Command Line Interface, the helpers and primitives to run and interact with the node. # Installation ## From a release This is the recommended method. Releases are all available here. ## From source Jormungandr's code source is available on github. Follow the instructions to build the software from sources. # Help and auto completion All commands come with usage help with the option --help or -h. For jcli, it is possible to generate the auto completion with: jcli auto-completion bash${HOME}/.bash_completion.d


Supported shells are: bash, fish, zsh, powershell and elvish.

Note: Make sure ${HOME}/.bash_completion.d directory previously exists on your HD. In order to use auto completion you still need to: source${HOME}/.bash_completion.d/jcli.bash


You can also put it in your ${HOME}/.bashrc. In order to start the node, you first need to gather the blockchain information you need to connect to. 1. the hash of the genesis block of the blockchain, this will be the source of truth of the blockchain. It is 64 hexadecimal characters. 2. the trusted peers identifiers and access points. These information are essentials to start your node in a secure way. The genesis block is the first block of the blockchain. It contains the static parameters of the blockchain as well as the initial funds. Your node will utilise the Hash to retrieve it from the other peers. It will also allows the Node to verify the integrity of the downloaded genesis block. The trusted peers are the nodes in the public network that your Node will trust in order to initialise the Peer To Peer network. # The node configuration Your node configuration file may look like the following: Note This config shouldn't work as it is, the ip address and port for the trusted peer should be those of an already running node. Also, the public_address ('u.x.v.t') should be a valid address (you can use an internal one, eg: 127.0.0.1). Furthermore, you need to have permission to write in the path specified by the storage config. storage: "/mnt/cardano/storage" rest: listen: "127.0.0.1:8443" p2p: trusted_peers: - id: 1 address: "/ip4/104.24.28.11/tcp/8299" public_address: "/ip4/u.v.x.y/tcp/8299" topics_of_interest: messages: low blocks: normal  Description of the fields: • storage: (optional) Path to the storage. If omitted, the blockchain is stored in memory only. • log: (optional) Logging configuration: • level: log messages minimum severity. If not configured anywhere, defaults to "info". Possible values: "off", "critical", "error", "warn", "info", "debug", "trace". • format: Log output format, plain or json. • output: Log output destination. Possible values are: • stdout: standard output • stderr: standard error • syslog: syslog (only available on Unix systems) • journald: journald service (only available on Linux with systemd, (if jormungandr is built with the systemd feature) • gelf: Configuration fields for GELF (Graylog) network logging protocol (if jormungandr is built with the gelf feature): • backend: hostname:port of a GELF server • log_id: identifier of the source of the log, for the host field in the messages. • rest: (optional) Configuration of the REST endpoint. • listen: address:port to listen for requests • pkcs12: (optional) Certificate file • p2p: P2P network settings • trusted_peers: (optional) the list of nodes to connect to in order to bootstrap the P2P topology (and bootstrap our local blockchain); • public_id: (optional) the public identifier sent to the other nodes in the P2P network. If not set it will be randomly generated. • public_address: multiaddr string specifying address of the P2P service. This is the public address that will be distributed to other peers of the network that may find interest in participating to the blockchain dissemination with the node. • topics_of_interest: The dissemination topics this node is interested to hear about: • messages: Transactions and other ledger entries. Typical setting for a non-mining node: low. For a stakepool: high; • blocks: Notifications about new blocks. Typical setting for a non-mining node: normal. For a stakepool: high; # Starting the node jormungandr --config config.yaml --genesis-block-hash 'abcdef987654321....'  The 'abcdef987654321....' part refers to the hash of the genesis, that should be given to you from one of the peers in the network you are connecting to. In case you have the genesis file (for example, because you are creating the network) you can get this hash with jcli. cat block-0 | jcli genesis hash  or, in case you only have the yaml file cat genesis.yaml | jcli genesis encode | jcli genesis hash  It is possible to query the node via its REST Interface. In the node configuration, you have set something like: # ... rest: listen: "127.0.0.1:8443" #...  This is the REST endpoint to talk to the node, to query blocks or send transaction. It is possible to query the node stats with the following end point: curl http://127.0.0.1:8443/api/v0/node/stats  The result may be: {"blockRecvCnt":120,"txRecvCnt":92,"uptime":245}  THE REST API IS STILL UNDER DEVELOPMENT Please note that the end points and the results may change in the future. To see the whole Node API documentation, click here # How to start a node as a leader candidate ## Gathering data Like in the passive node case, two things are needed to connect to an existing network 1. the hash of the genesis block of the blockchain, this will be the source of truth of the blockchain. It is 64 hexadecimal characters. 2. the trusted peers identifiers and access points. The node configuration could be the same as that for running a passive node. There are some differences depending if you are connecting to a network running a genesis or bft consensus protocol. ### Connecting to a genesis blockchain #### Registering a stake pool In order to be able to generate blocks in an existing genesis network, a registered stake pool is needed. #### Creating the secrets file Put the node id and private keys in a yaml file in the following way: ##### Example filename: node_secret.yaml genesis: sig_key: Content of stake_pool_kes.prv file vrf_key: Content of stake_pool_vrf.prv file node_id: Content of stake_pool.id file  #### Starting the node jormungandr --genesis-block-hash asdf1234... --config config.yaml --secret node_secret.yaml  The 'asdf1234...' part should be the actual block0 hash of the network ### Connecting to a BFT blockchain In order to generate blocks, the node should be registered as a slot leader in the network and started in the following way. ## The secret file Put secret key in a yaml file, e.g. node_secret.yaml as follows: bft: signing_key: ed25519_sk1kppercsk06k03yk4qgea....  where signing_key is a private key associated to the public id of a slot leader. ### Starting the node jormungandr --genesis-block asdf1234... --config node.config --secret node_secret.yaml  The 'asdf1234...' part should be the actual block0 hash of the network This chapter covers the node documentation, necessary to have a working system. It covers the network, logging and storage parameters. The node configuration uses the YAML format. This is an example of a configuration file: storage: "/tmp/storage" log: level: debug format: json p2p: trusted_peers: - id: 1 address: "/ip4/104.24.28.11/tcp/8299" - id: 2 address: "/ip4/104.24.29.11/tcp/8299" public_address: "/ip4/127.0.0.1/tcp/8080" topics_of_interest: messages: low blocks: normal  The following options are available in the log section: • level: log messages minimum severity. If not configured anywhere, defaults to "info". Possible values: "off", "critical", "error", "warn", "info", "debug", "trace". • format: log output format - plain or json. • output: log output - stdout, stderr, syslog (Unix only), or journald (Linux with systemd only, must be enabled during compilation). There's 2 differents network interfaces which are covered by their respective section: rest: ... p2p: ...  ## REST interface configuration • listen: listen address • pkcs12: certificate file (optional) ## P2P configuration • trusted_peers: (optional) the list of nodes to connect to in order to bootstrap the p2p topology (and bootstrap our local blockchain); • public_id: (optional) the public identifier send to the other nodes in the p2p network. If not set it will be randomly generated. • public_address: the address to listen from and accept connection from. This is the public address that will be distributed to other peers of the network that may find interest into participating to the blockchain dissemination with the node; • topics_of_interest: the different topics we are interested to hear about: • messages: notify other peers this node is interested about Transactions typical setting for a non mining node: "low". For a stakepool: "high"; • blocks: notify other peers this node is interested about new Blocs. typical settings for a non mining node: "normal". For a stakepool: "high"; # jcli This is the node command line helper. It is mostly meant for developers and stake pool operators. It allows offline operations: • generating cryptographic materials for the wallets and stake pools; • creating addresses, transactions and certificates; • prepare a new blockchain and it allows simple interactions with the node: • query stats; • send transactions and certificates; • get raw blocks and UTxOs. # cryptographic keys There are multiple type of key for multiple use cases. typeusage Ed25519Signing algorithm for Ed25519 algorithm Ed25519Bip32Related to the HDWallet, Ed25519 Extended with chain code for derivation derivation Ed25519ExtendedRelated to Ed25519Bip32 without the chain code SumEd25519_12For stake pool, necessary for the KES Curve25519_2HashDHFor stake pool, necessary for the VRF There is a command line parameter to generate this keys: $ jcli key generate --type=Ed25519
ed25519_sk1cvac48ddf2rpk9na94nv2zqhj74j0j8a99q33gsqdvalkrz6ar9srnhvmt


and to extract the associated public key:

$echo ed25519_sk1cvac48ddf2rpk9na94nv2zqhj74j0j8a99q33gsqdvalkrz6ar9srnhvmt | jcli key to-public ed25519_pk1z2ffur59cq7t806nc9y2g64wa60pg5m6e9cmrhxz9phppaxk5d4sn8nsqg  # Address Jormungandr comes with a separate CLI to create and manipulate addresses. This is useful for creating addresses from their components in the CLI, for debugging addresses and for testing. ## Display address info To display an address and verify it is in a valid format you can utilise: $ jcli address info ta1svy0mwwm7mdwcuj308aapjw6ra4c3e6cygd0f333nvtjzxg8ahdvxlswdf0
discrimination: testing
public key: ed25519e_pk1pr7mnklkmtk8y5tel0gvnksldwywwkpzrt6vvvvmzus3jpldmtpsx9rnmx


or for example:

$jcli address \ info \ ca1qsy0mwwm7mdwcuj308aapjw6ra4c3e6cygd0f333nvtjzxg8ahdvxz8ah8dldkhvwfghn77se8dp76uguavzyxh5cccek9epryr7mkkr8n7kgx discrimination: production public key: ed25519_pk1pr7mnklkmtk8y5tel0gvnksldwywwkpzrt6vvvvmzus3jpldmtpsx9rnmx group key: ed25519_pk1pr7mnklkmtk8y5tel0gvnksldwywwkpzrt6vvvvmzus3jpldmtpsx9rnmx  ## Creating an address Each command following allows to create addresses for production and testing chains. For chains, where the discrimination is testing, you need to use the --testing flag. There's 3 types of addresses: • Single address : A simple spending key. This doesn't have any stake in the system • Grouped address : A spending key attached to an account key. The stake is automatically • Account address : An account key. The account is its own stake ### Address for UTxO You can create a single address (non-staked) using the spending public key for this address utilising the following command: $ jcli address \
single ed25519e_pk1jnlhwdgzv3c9frknyv7twsv82su26qm30yfpdmvkzyjsdgw80mfqduaean
ca1qw207ae4qfj8q4yw6v3ned6psa2r3tgrw9u3y9hdjcgj2p4pcaldyukyka8


To add the staking information and make a group address, simply add the account public key as a second parameter of the command:

$jcli address \ single \ ed25519_pk1fxvudq6j7mfxvgk986t5f3f258sdtw89v4n3kr0fm6mpe4apxl4q0vhp3k \ ed25519_pk1as03wxmy2426ceh8nurplvjmauwpwlcz7ycwj7xtl9gmx9u5gkqscc5ylx ca1q3yen35r2tmdye3zc5lfw3x992s7p4dcu4jkwxcda80tv8xh5ym74mqlzudkg42443nw08cxr7e9hmcuzals9ufsa9uvh723kvteg3vpvrcxcq  ### Address for Account To create an account address you need the account public key and run: $ jcli address \
account ed25519_pk1c4yq3hflulynn8fef0hdq92579n3c49qxljasrl9dnuvcksk84gs9sqvc2
ca1qhz5szxa8lnujwva8997a5q42nckw8z55qm7tkq0u4k03nz6zc74ze780qe


### changing the address prefix

You can decide to change the address prefix, allowing you to provide more enriched data to the user. However, this prefix is not forwarded to the node, it is only for UI/UX.

$jcli address \ account \ --prefix=address_ \ ed25519_pk1yx6q8rsndawfx8hjzwntfs2h2c37v5g6edv67hmcxvrmxfjdz9wqeejchg address_1q5smgquwzdh4eyc77gf6ddxp2atz8ej3rt94nt6l0qes0vexf5g4cw68kdx  # transaction Tooling for offline transaction creation and signing. jcli transaction  Those familiar with cardano-cli transaction builder will see resemblance in jcli transaction. There is a couple of commands that can be used to: 1. prepare a transaction: • new create a new empty transaction; • add-input • add-account • add-output 2. finalize the transaction for signing: 3. create witnesses and add the witnesses: • make-witness • add-witness 4. seal the transaction, ready to send to the blockchain There are also functions to help decode and display the content information of a transaction: • info • id to get the Transaction ID of the transaction • to-message to get the hexadecimal encoded message, ready to send with cli rest message # Examples The following example focuses on using an utxo as input, the few differences when transfering from an account will be pointed out when necessary. There is also a script here to send a transaction from a faucet account to a specific address which could be used as a reference. Let's use the following utxo as input and transfer 50 lovelaces to the destination address ## Input utxo FieldValue UTXO's transaction ID55762218e5737603e6d27d36c8aacf8fcd16406e820361a8ac65c7dc663f6d1c UTXO's output index0 associated addressca1q09u0nxmnfg7af8ycuygx57p5xgzmnmgtaeer9xun7hly6mlgt3pjyknplu associated value100 ## Destination address address: ca1qvnr5pvt9e5p009strshxndrsx5etcentslp2rwj6csm8sfk24a2wlqtdj6 ## Create a staging area jcli transaction new > tx  ## Add input For the input, we need to reference the uxto with the UTXO's transaction ID and UTXO'S output index fields and we need to specify how much coins are there with the associated value field. ### Example - UTXO address as Input jcli transaction add-input 55762218e5737603e6d27d36c8aacf8fcd16406e820361a8ac65c7dc663f6d1c 0 100 --staging tx  ### Example - Account address as Input If the input is an account, the command is slightly different jcli transaction add-account account_address account_funds --staging tx  ## Add output For the output, we need the address we want to transfer to, and the amount. jcli transaction add-output ca1qvnr5pvt9e5p009strshxndrsx5etcentslp2rwj6csm8sfk24a2wlqtdj6 50 --staging tx  ## Add fee and change address We want to get the change in the same address that we are sending from (the associated address of the utxo). We also specify how to compute the fees. You can leave out the --fee-constant 5 --fee-coefficient 2 part if those are both 0. jcli transaction finalize ca1q09u0nxmnfg7af8ycuygx57p5xgzmnmgtaeer9xun7hly6mlgt3pjyknplu --fee-constant 5 --fee-coefficient 2 --staging tx  Now, if you run jcli transaction info --fee-constant 5 --fee-coefficient 2 --staging tx  You should see something like this Transaction 0df39a87d3f18a188b40ba8c203f85f37af665df229fb4821e477f6998864273' (finalizing) Input: 100 Output: 89 Fees: 11 Balance: 0 - 55762218e5737603e6d27d36c8aacf8fcd16406e820361a8ac65c7dc663f6d1c:0 100 + ca1qvnr5pvt9e5p009strshxndrsx5etcentslp2rwj6csm8sfk24a2wlqtdj6 50 + ca1q09u0nxmnfg7af8ycuygx57p5xgzmnmgtaeer9xun7hly6mlgt3pjyknplu 39  ## Sign the transaction ### Make witness For signing the transaction, you need the private key associated with the input address (the one that's in the utxos) and the hash of the genesis block of the network you are connected to. The genesis' hash is needed for ensuring that the transaction cannot be re-used in another blockchain and for security concerns on offline transaction signing, as we are signing the transaction for the specific blockchain started by this block0 hash. The following command takes the private key in the key.prv file and creates a witness in a file named witness in the current directory. jcli transaction make-witness --genesis-block-hash abcdef987654321... --type utxo txid witness key.prv  #### Account input When using an account as input, the command takes account as the type and an additional parameter: --account-spending-counter, that should be increased every time the account is used as input. e.g. jcli transaction make-witness --genesis-block-hash abcdef987654321... --type account --account-spending-counter 0 witness key.prv  ### Add witness jcli transaction add-witness witness --staging tx  ## Send the transaction jcli transaction seal --staging tx  jcli transaction to-message --staging tx > txmsg  Send it using the rest api jcli rest v0 message post -f txmsg --host http://127.0.0.1:8443/api  ## Checking if the transaction was accepted You can check if the transaction was accepted by checking the node logs, for example, if the transaction is accepted jcli rest v0 message logs -h http://127.0.0.1:8443/api --- - fragment_id: d6ef0b2148a51ed64531efc17978a527fd2d2584da1e344a35ad12bf5460a7e2 last_updated_at: "2019-06-11T15:38:17.070162114Z" received_at: "2019-06-11T15:37:09.469101162Z" received_from: Rest status: InABlock: "4.707"  Where the InABlock status means that the transaction was accepted in the block with date "4.707". The status here could also be: Pending: if the transaction is received and is pending being added in the blockchain (or rejected). or Rejected: with an attached message of the reason the transaction was rejected. # certificate Tooling for offline transaction creation ## Builder Builds a signed certificate. The process can be split into steps on the first step certificate is created. jcli certificate new stake-pool-registration \ --vrf-key <vrf-public-key> --kes-key <kes-public-key> \ [--owner <owner-public-key>] \ --serial <node-serial> \ <output-file>  if output-file is omited result will be written to stdout. Once certificate is ready you must sign it with the private keys of all the owners: jcli certificate sign <key> <input-file> <output-file>  # Genesis Tooling for working with a genesis file # Usage jcli genesis [subcommand]  ## Subcommands • decode: Print the YAML file corresponding to an encoded genesis block. • encode: Create the genesis block of the blockchain from a given yaml file. • hash: Print the block hash of the genesis • init: Create a default Genesis file with appropriate documentation to help creating the YAML file • help ## Examples ### Encode a genesis file jcli genesis encode --input genesis.yaml --output block-0.bin  or equivantely cat genesis.yaml | jcli genesis encode > block-0.bin  ### Get the hash of an encoded genesis file jcli genesis hash --input block-0.bin  # REST Jormungandr comes with a CLI client for manual communication with nodes over HTTP. ## Conventions Many CLI commands have common arguments: • -h <addr> or --host <addr> - Node API address. Must always have http:// or https:// prefix. E.g. -h http://127.0.0.1, --host https://node.com:8443/cardano/api • --debug - Print additional debug information to stderr. The output format is intentionally undocumented and unstable • --output-format <format> - Format of output data. Possible values: json, yaml, default yaml. Any other value is treated as a custom format using values from output data structure. Syntax is Go text template: https://golang.org/pkg/text/template/. ## Node stats Fetches node stats jcli rest v0 node stats get <options>  The options are YAML printed on success --- blockRecvCnt: 7 # Blocks received by node txRecvCnt: 90 # Transactions received by node uptime: 2101 # Node uptitme in seconds  ## Whole UTXO Fetches whole UTXO jcli rest v0 utxo get <options>  The options are YAML printed on success --- - in_idx: 0 # input index in_txid: 50f21ac6bd3f57f231c4bf9c5fff7c45e2529c4dffed68f92410dbf7647541f1 # input transaction hash in hex out_addr: ca1qvqsyqcyq5rqwzqfpg9scrgwpugpzysnzs23v9ccrydpk8qarc0jqxuzx4s # output address in bech32 out_value: 999999999 # output value  ## Post transaction Posts a signed, hex-encoded transaction jcli rest v0 message post <options>  The options are • -h <node_addr> - see conventions • --debug - see conventions • -f --file <file_path> - File containing hex-encoded transaction. If not provided, transaction will be read from stdin. Fragment Id is printed on success (which can help finding transaction status using get message log command) 50f21ac6bd3f57f231c4bf9c5fff7c45e2529c4dffed68f92410dbf7647541f1  ## Get message log Get the node's logs on the message pool. This will provide information on pending transaction, rejected transaction and or when a transaction has been added in a block jcli rest v0 message logs <options>  The options are YAML printed on success --- - fragment_id: 7db6f91f3c92c0aef7b3dd497e9ea275229d2ab4dba6a1b30ce6b32db9c9c3b2 # hex-encoded fragment ID last_updated_at: 2019-06-02T16:20:26.201000000Z # RFC3339 timestamp of last fragment status change received_at: 2019-06-02T16:20:26.201000000Z # RFC3339 timestamp of fragment receivement received_from: Network, # how fragment was received status: Pending, # fragment status  received_from can be one of: received_from: Rest # fragment was received from node's REST API  received_from: Network # fragment was received from the network  status can be one of: status: Pending # fragment is pending  status: Rejected: # fragment was rejected reason: reason of rejection # cause  status: # fragment was included in a block InABlock: "6637.3" # block epoch and slot ID formed as <epoch>.<slot_id>  ## Blockchain tip Retrieves a hex-encoded ID of the blockchain tip jcli rest v0 tip get <options>  The options are ## Get block Retrieves a hex-encoded block with given ID jcli rest v0 block <block_id> get <options>  <block_id> - hex-encoded block ID The options are ## Get next block ID Retrieves a list of hex-encoded IDs of descendants of block with given ID. Every list element is in separate line. The IDs are sorted from closest to farthest. jcli rest v0 block <block_id> next-id get <options>  <block_id> - hex-encoded block ID The options are • -h <node_addr> - see conventions • --debug - see conventions • -c --count - Maximum number of IDs, must be between 1 and 100, default 1 ## Get account state Get account state jcli rest v0 account get <account-id> <options>  - ID of an account, bech32-encoded The options are YAML printed on success --- counter: 1 delegation: c780f14f9782770014d8bcd514b1bc664653d15f73a7158254730c6e1aa9f356 value: 990  • value is the current balance of the account; • counter is the number of transactions performed using this account this is useful to know when signing new transactions; • delegation is the Stake Pool Identifier the account is delegating to. it is possible this value is not set if there is no delegation certificate sent associated to this account. ## Node settings Fetches node settings jcli rest v0 settings get <options>  The options are YAML printed on success --- block0Hash: 8d94ecfcc9a566f492e6335858db645691f628b012bed4ac2b1338b5690355a7 # block 0 hash of block0Time: "2019-07-09T12:32:51+00:00" # block 0 creation time of consensusVersion: bft # currently used consensus currSlotStartTime: "2019-07-09T12:55:11+00:00" # current slot start time fees: # transaction fee configuration certificate: 4 # fee per certificate coefficient: 1 # fee per every input and output constant: 2 # fee per transaction maxTxsPerBlock: 100 # maximum number of transactions in block  ## Node shutdown Node shutdown jcli rest v0 shutdown get <options>  The options are ## Get leaders Fetches list of leader IDs jcli rest v0 leaders get <options>  The options are YAML printed on success --- - 1 # list of leader IDs - 2  ## Register leader Register new leader and get its ID jcli rest v0 leaders post <options>  The options are • -h <node_addr> - see conventions • --debug - see conventions • --output-format - see conventions -f, --file - File containing YAML with leader secret. It must have the same format as secret YAML passed to Jormungandr as --secret. If not provided, YAML will be read from stdin. On success created leader ID is printed 3  ## Delete leader Delete leader with given ID jcli rest v0 leaders delete <id> <options>  - ID of deleted leader The options are ## Get stake pools Fetches list of stake pool IDs jcli rest v0 stake-pools get <options>  The options are YAML printed on success --- - 5cf03f333f37eb7b987dbc9017b8a928287a3d77d086cd93cd9ad05bcba7e60f # list of stake pool IDs - 3815602c096fcbb91072f419c296c3dfe1f730e0f446a9bd2553145688e75615  # Staking with jormungandr Here we will describe how to: • delegate your stake to a stake pool so that you can participate to the consensus and maybe collect rewards for that; If you are a user of the blockchain then you will certainly not need to look at the last section about how to register a stake pool. # Delegating your stake ## how to create the delegation certificate Stake is concentrated in accounts, and you will need your account key to delegate its associated stake. You will need your: • account public key: a bech32 string of a public key • the Stake Pool ID: an hexadecimal string identifying the stake pool you want to delegate your stake to. $ jcli certificate new stake-delegation STAKE_POOL_ID ACCOUNT_PUBLIC_KEY > stake_delegation.cert


## how to sign your delegation certificate

We need to make sure that the owner of the account is authorizing this delegation to happens, and for that we need a cryptographic signature.

We will need the account secret key to create a signature

$cat stake_delegation.cert | jcli certificate sign account_key.prv | tee stake_delegation.cert cert1q8rv4ccl54k99rtnm39...zr0  The output can now be added in the transaction and submitted to a node. ## submitting to a node The jcli transaction add-certificate command should be used to add a certificate before finalizing the transaction. For example:  ... jcli transaction add-certificate$(cat stake_delegation.cert) --staging tx

jcli transaction finalize CHANGE_ADDRESS --fee-constant 5 --fee-coefficient 2 --fee-certificate 2 --staging tx

...



The --fee-certificate flag indicates the cost of adding a certificate, used for computing the fees, it can be omitted if it is zero.

See here for more documentation on transaction creation.

# registering stake pool

There are multiple components to be aware of when running a stake pool:

• your NodeId: it is the identifier within the blockchain protocol (wallet will delegate to your stake pool via this NodeId);
• your VRF key pairs: this is the cryptographic material we will use to participate to the leader election;
• your [KES] key pairs: this is the cryptographic material we will use to sign the block with.

So in order to start your stake pool you will need to generate these objects.

# The primitives

## VRF key pair

To generate your VRF Key pairs, we will utilise [jcli] as described here:

$jcli key generate --type=Curve25519_2HashDH > stake_pool_vrf.prv  stake_pool_vrf.prv file now contains the VRF private key. $ cat stake_pool_vrf.prv | jcli key to-public > stake_pool_vrf.pub


## KES key pair

Similar to above:

$jcli key generate --type=SumEd25519_12 > stake_pool_kes.prv  stake_pool_kes.prv now contains your KES private key $ cat stake_pool_kes.prv | jcli key to-public > stake_pool_kes.pub


# creating your stake pool certificate

The certificate is what will be sent to the blockchain in order to register yourself to the other participants of the blockchain that you are a stake pool too.

$jcli certificate new stake-pool-registration \ --kes-key$(cat stake_pool_kes.pub) \
--vrf-key $(cat stake_pool_vrf.pub) \ --serial 1010101010 > stake_pool.cert  Now you need to sign this certificate with the owner key: $ cat stake_pool.cert | jcli certificate sign stake_key.prv | tee stake_pool.cert
cert1qsqqqqqqqqqqqqqqqqqqq0p5avfqp9tzusr26...cegxaz


And now you can retrieve your stake pool id (NodeId):

$cat stake_pool.cert | jcli certificate get-stake-pool-id | tee stake_pool.id ea830e5d9647af89a5e9a4d4089e6e855891a533316adf4a42b7bf1372389b74  # Advanced This section is meant for advanced users and developers of the node, or if you to learn more about the node. At the moment, it only covers details on how to create your own blockchain genesis configuration, but in normal case, the blockchain configuration should be available with the specific blockchain system. # genesis file The genesis file is the file that allows you to create a new blockchain from block 0. It lays out the different parameter of your blockchain: the initial utxo, the start time, the slot duration time, etc... Example of a BFT genesis file with an initial address UTxO and an account UTxO. More info regarding starting a BFT blockchain here and regarding addresses there. You could also find information regarding the jcli genesis tooling. You can generate a documented pre-generated genesis file: jcli genesis init  For example your genesis file may look like: # The Blockchain Configuration defines the settings of the blockchain. blockchain_configuration: # The block0-date defines the date the blockchain starts # expected value in seconds since UNIX_EPOCH # # By default the value will be the current date and time. Or you can # add a specific time by entering the number of seconds since UNIX # Epoch block0_date: {default_block0_date} # This is the type of discrimination of the blockchain # of this blockchain is meant for production then # use 'production' instead. # # otherwise leave as this discrimination: {discrimination} # The initial consensus version: # # * BFT consensus: bft # * Genesis Praos consensus: genesis block0_consensus: bft # Number of slots in each epoch. # # default value is {default_slots_per_epoch} slots_per_epoch: {default_slots_per_epoch} # The slot duration, in seconds, is the time between the creation # of 2 blocks # # default value is {default_slot_duration} slot_duration: {default_slot_duration} # A list of Ed25519 PublicKey that represents the # BFT leaders encoded as bech32. The order in the list matters. consensus_leader_ids: - {leader_1} - {leader_2} # Genesis praos parameter D # # default value: {default_bft_slots_ratio} bft_slots_ratio: {default_bft_slots_ratio} # Genesis praos active slot coefficient # Determines minimum stake required to try becoming slot leader, must be in range (0,1] # # default value: {default_consensus_genesis_praos_active_slot_coeff} consensus_genesis_praos_active_slot_coeff: {default_consensus_genesis_praos_active_slot_coeff} # The fee calculations settings # # total fees: constant + (num_inputs + num_outputs) * coefficient [+ certificate] linear_fees: # this is the minimum value to pay for every transaction constant: 2 # the additional fee to pay for every inputs and outputs coefficient: 1 # the additional fee to pay if the transaction embeds a certificate certificate: 4 # The speed to update the KES Key in seconds # # default value: {default_kes_update_speed} kes_update_speed: {default_kes_update_speed} # Initial state of the ledger. Each item is applied in order of this list initial: # Initial deposits present in the blockchain - fund: # UTxO addresses or account - address: {initial_funds_address} value: 10000 # Initial certificate - cert: cert1qgqqqqqqqqqqqqqqqqqqq0p5avfqqmgurpe7s9k7933q0wj420jl5xqvx8lywcu5jcr7fwqa9qmdn93q4nm7c4fsay3mzeqgq3c0slnut9kns08yn2qn80famup7nvgtfuyszqzqrd4lxlt5ylplfu76p8f6ks0ggprzatp2c8rn6ev3hn9dgr38tzful4h0udlwa0536vyrrug7af9ujmrr869afs0yw9gj5x7z24l8sps3zzcmv # Initial deposits present in the blockchain #- legacy_fund: # # Legacy Cardano address # - address: 48mDfYyQn21iyEPzCfkATEHTwZBcZJqXhRJezmswfvc6Ne89u1axXsiazmgd7SwT8VbafbVnCvyXhBSMhSkPiCezMkqHC4dmxRahRC86SknFu6JF6hwSg8 # value: 123  There are multiple parts in the genesis file: • blockchain_configuration: this is a list of configuration parameters of the blockchain, some of which can be changed later via the update protocol; • initial: list of steps to create initial state of ledger ## blockchain_configuration options optionformatdescription block0_datenumberthe official start time of the blockchain, in seconds since UNIX EPOCH discriminationstringproduction or test block0_consensusstringbft slot_durationnumberthe number of seconds between the creation of 2 blocks epoch_stability_depthnumberallowed size of a fork (in number of block) consensus_leader_idsarraythe list of the BFT leader at the beginning of the blockchain max_number_of_transactions_per_blocknumberthe maximum number of transactions allowed in a block bft_slots_rationumberplaceholder, do not use linear_feesobjectlinear fee settings, set the fee for transaction and certificate publishing consensus_genesis_praos_active_slot_coeffnumbergenesis praos active slot coefficient. Determines minimum stake required to try becoming slot leader, must be in range (0,1] kes_update_speednumberthe speed to update the KES Key in seconds slots_per_epochnumbernumber of slots in each epoch for more information about the BFT leaders in the genesis file, see Starting a BFT Blockchain ## initial options Each entry can be one of 3 variants: variantformatdescription fundsequenceinitial deposits present in the blockchain (up to 255 outputs per entry) certstringinitial certificate legacy_fundsequencesame as fund, but with legacy Cardano address format Example: initial: - fund: - address: <address> value: 10000 - address: <address2> value: 20000 - address: <address3> value: 30000 - cert: <certificate> - legacy_fund: - address: <legacy address> value: 123 - fund: - address: <another address> value: 1001  ### fund and legacy_fund format variantformatdescription addressstringcan be a single address or an account address valuenumberassigned value legacy_fund differs only in address format, which is legacy Cardano # starting a bft node BFT stands for the Byzantine Fault Tolerant (read the paper). Jormungandr allows you to start a BFT blockchain fairly easily. The main downside is that it is centralized, only a handful of nodes will ever have the right to create blocks. ## How does it work It is fairly simple. A given number of Nodes (N) will generate a key pairs of type Ed25519 (see JCLI's Keys). They all share the public key and add them in the genesis.yaml file. It is the source of truth, the file that will generate the first block of the blockchain: the Block 0. Then, only by one after the other, each Node will be allowed to create a block. Utilising a Round Robin algorithm. ## Example of genesis file blockchain_configuration: block0_date: 1550822014 discrimination: test block0_consensus: bft slots_per_epoch: 5 slot_duration: 15 epoch_stability_depth: 10 consensus_leader_ids: - ed25519e_pk1k3wjgdcdcn23k6dwr0cyh88ad7a4ayenyxaherfazwy363pyy8wqppn7j3 - ed25519e_pk13talprd9grgaqzs42mkm0x2xek5wf9mdf0eefdy8a6dk5grka2gstrp3en bft_slots_ratio: 0.220 consensus_genesis_praos_active_slot_coeff: 0.22 max_number_of_transactions_per_block: 255 linear_fees: constant: 2 coefficient: 1 certificate: 4 kes_update_speed: 43200 initial: - fund: - address: ta1svy0mwwm7mdwcuj308aapjw6ra4c3e6cygd0f333nvtjzxg8ahdvxlswdf0 value: 10000 - cert: cert1qgqqqqqqqqqqqqqqqqqqq0p5avfqqmgurpe7s9k7933q0wj420jl5xqvx8lywcu5jcr7fwqa9qmdn93q4nm7c4fsay3mzeqgq3c0slnut9kns08yn2qn80famup7nvgtfuyszqzqrd4lxlt5ylplfu76p8f6ks0ggprzatp2c8rn6ev3hn9dgr38tzful4h0udlwa0536vyrrug7af9ujmrr869afs0yw9gj5x7z24l8sps3zzcmv - legacy_fund: - address: 48mDfYyQn21iyEPzCfkATEHTwZBcZJqXhRJezmswfvc6Ne89u1axXsiazmgd7SwT8VbafbVnCvyXhBSMhSkPiCezMkqHC4dmxRahRC86SknFu6JF6hwSg8 value: 123  In order to start your blockchain in BFT mode you need to be sure that: • consensus_leader_ids is non empty; more information regarding the genesis file here. ## Creating the block 0 jcli genesis encode --input genesis.yaml --output block-0.bin  This command will create (or replace) the Block 0 of the blockchain from the given genesis configuration file (genesis.yaml). ## Starting the node Now that the blockchain is initialized, you need to start your node. Write you private key in a file on your HD: $ cat node_secret.yaml
bft:
signing_key: ed25519_sk1hpvne...


Configure your Node (config.yml) and run the following command:

$jormungandr --genesis-block block-0.bin \ --config example.config \ --secret node_secret.yaml  It's possible to use the flag --secret multiple times to run a node with multiple leaders. ## Step by step to start the BFT node 1. Generate initial config jcli genesis init > genesis.yaml 2. Generate secret key, e.g.  jcli key generate --type=Ed25519 > key.prv 3. Put secret key in a file, e.g. node_secret.yaml as follows: bft: signing_key: ed25519_sk1kppercsk06k03yk4qgea....  1. Generate public key out of previously generated key  cat key.prv | jcli key to-public 2. Put generated public key as in genesis.yaml under consensus_leader_ids: 3. Generate block = jcli genesis encode --input genesis.yaml --output block-0.bin 4. Create config file and store it on your HD as node.config e.g. -> --- log: level: trace format: json rest: listen: "127.0.0.1:8607" p2p: public_address: /ip4/127.0.0.1/tcp/8606 topics_of_interest: messages: low blocks: normal  1. Start Jörmungandr node : jormungandr --genesis-block block-0.bin --config node.config --secret node_secret.yaml  # Script Additionally, there is a script here that can be used to bootstrap a test node with bft consensus protocol. # starting a genesis blockchain When starting a genesis praos blockchain there is an element to take into consideration while constructing the block 0: the stake distribution. In the context of Genesis/Praos the network is fully decentralized and it is necessary to think ahead about initial stake pools and to make sure there is stake delegated to these stake pools. In your genesis yaml file, make sure to set the following values to the appropriate values/desired values: # The Blockchain Configuration defines the settings of the blockchain. blockchain_configuration: block0_consensus: genesis bft_slots_ratio: 0 consensus_genesis_praos_active_slot_coeff: 0.1 kes_update_speed: 43200 # 12hours  block0_consensus set to genesis means you want to start a blockchain with genesis praos as the consensus layer. bft_slots_ratio needs to be set to 0 (we don't support composite modes between BFT mode and Genesis mode -- yet). consensus_genesis_praos_active_slot_coeff determines minimum stake required to try becoming slot leader, must be in range 0 exclusive and 1 inclusive. ## The initial certificates In the initial_certs field you will set the initial certificate. This is important to declare the stake pool and delegate stake to them. Otherwise no block will be ever created. Remember that in this array the order matters: In order to delegate your stake, you need a stake pool to already exist, so the stake pool registration certificate should go first. ### Stake pool registration Now you can register a stake pool. Follow the instruction in registering stake pool guide. The owner key (the key you sign the stake pool registration certificate) is the secret key associated to a previously registered stake key. ### Delegating stake Now that there is both your stake key and there are stake pools available in the block0 you need to delegate to one of the stake pool. Follow the instruction in delegating stake. And in the initial funds start adding the addresses. To create an address with delegation follow the instruction in JCLI's address guide. Utilise the stake key registered previously as group address: jcli address single$(cat wallet_key.pub) \$(cat stake_key.pub)
ta1sjx4j3jwel94g0cgwzq9au7h6m8f5q3qnyh0gfnryl3xan6qnmjse3k2uv062mzj34eacjnxthxqv8fvdcn6f4xhxwa7ms729ak3gsl4qrq2mm


You will notice that addresses with delegation are longer (about twice longer) than address without delegation.

For example, the most minimal setting you may have is:

initial_certs:
# register a stake pool (P), owner of the stake pool is the stake key (K)
- cert1qsqqqqqqqqqqqqqqqqqqq0p5avfqp9tzusr26chayeddkkmdlap6tl23ceca8unsghc22tap8clhrzslkehdycufa4ywvqvs4u36zctw4ydtg7xagprfgz0vuujh3lgtxgfszqzqj4xk4sxxyg392p5nqz8s7ev5wna7eqz7ycsuas05mrupmdsfk0fqqudanew6c0nckf5tsp0lgnk8e8j0dpnxvjk2usn52vs8umr3qrccegxaz

# delegate stake associated to stake key (K) to stake pool (P)
- cert1q0rv4ccl54k99rtnm39xvhwvqcwjcm385n2dwvamahpu5tmdz3plt65rpewev3a03xj7nfx5pz0xap2cjxjnxvt2ma9y9dalzder3xm5qyqyq0lx05ggrws0ghuffqrg7scqzdsd665v4m7087eam5zvw4f26v2tsea3ujrxly243sgqkn42uttk5juvq78ajvfx9ttcmj05lfuwtq9qhdxzr0

initial_funds:
# address without delegation
- address: ta1swx4j3jwel94g0cgwzq9au7h6m8f5q3qnyh0gfnryl3xan6qnmjsczt057x
value: 10000
# address delegating to stake key (K)
- address: ta1sjx4j3jwel94g0cgwzq9au7h6m8f5q3qnyh0gfnryl3xan6qnmjse3k2uv062mzj34eacjnxthxqv8fvdcn6f4xhxwa7ms729ak3gsl4qrq2mm
value: 1000000


### Starting the node

Now, for starting the node and be able to generate new blocks, you have to put your pool's private keys and id in a file and start the node with the --secret filename parameter.

For example, if you follow the examples of the registering stake pool guide

You could create a file called poolsecret.yaml with the following content.

genesis:
sig_key: Content of stake_pool_kes.prv file
vrf_key: Content of stake_pool_vrf.prv file
node_id: Content of stake_pool.id file


And you could start the node with this command

jormungandr --genesis-block block-0.bin --config config.yaml --secret poolsecret.yaml
`

# Test script

There is a script here that can be used to bootstrap a test node with a pre-set faucet and stake pool and can be used as an example.