Skip to content
Branch: master
Find file Copy path
Find file Copy path
2 contributors

Users who have contributed to this file

@elviejo79 @nahern
715 lines (468 sloc) 26.2 KB

Stake pool operator How-To

A Stake pool operator plays a fundamental role in the health and decentralization of the Cardano Blockchain. In the following sections we are going to see How to become a stake pool operator.

Keep in mind the following diagram as we go along the process to create a stale pool


1. Understand stake pool minimal system requirements

There are hardware, operating system and software requirements to set up a stake pool.

1.1 Hardware

  • 4 GB of RAM
  • A Good network connection and about 1 GB of * bandwidth / hour
  • A public ip4 address
  • Processor speed is not a significant factor

1.2 Operating System

Supported stake pool operating systems

We support Linux, BSD, Mac, and Windows platforms. The following versions are required:

  • Linux (2.6.18 or later)
  • BSD (Net BSD 8.x and Free BSD 12.x)
  • mac OS (10.7 Lion or later)
  • Windows 10

1.3 Software (Jormungandr)

Latest version of Jormungandr and JCLI. Just follow along in the next section. Or check the repository.

2. Start Jormungandr node

First let's download, configure and start the Jormungandr node. Note: If you have any issues while installing Jormungandr and JCLI, please refer to our support portal macOS/Linux instructions.

2.1 Find the latest version of the testnet

You can find the configuration parameters here Select the one for Incentivized testnet and download the appropriate version of Jormungandr from GitHub.

2.2 Download Jormungandr from GitHub

On go to Releases and from there download the appropriate file for your operating system.

  • For Linux download the file ending in ...-x86_64-unknown-linux-gnu.tar.gz
  • For MacOS download the file ending in ...-x86_64-apple-darwin.tar.gz

2.3 Extract the files (in your Terminal or Finder)

  • Using the command line: in terminal, navigate to the directory where you downloaded the file and execute the following command to uncompress it:
tar -xzvf jormungandr-v0.8.2-x86_64-unknown-linux-gnu.tar.gz


  • In Finder: navigate to the folder where you saved the files (the default is the Downloads folder), Double-click the file to extract it. This will create a folder with the same name as the file, the folder will contain two files in it.

2.4 Verify the files were installed correctly

In Terminal just type

./jcli -V

It returns the version of JCLI

$ jcli 0.8.2

Victory! JCLI is available to us.

2.5 Configure your node

2.5.1 Download the config.yaml file

From the Jormungandr Configurations page, save the config.yaml. We will use this file to start Jormungandr, among other things it has the list of trusted peers from which we are going to download our own copy of the blockchain.

2.5.2 Add stake pool configuration parameters

Since we are setting up a stake pool we need to add our public IP, listen address and the storage location to the configuration file.

for example:

cat ./templates/stakepool_config_addenda.json | sed 's/'
    "log": [
            "format": "plain",
            "level": "info",
            "output": "stderr"
    "storage": "./storage/",
    "p2p": {
        "listen_address": "/ip4/",
        "public_address": "/ip4/",
        "topics_of_interest": {
            "blocks": "high",
            "messages": "high"

2.5.3 Create the genesis-hash.txt file

From Jormungandr Configurations page, copy the genesis hash and save it to a file called genesis-hash.txt

Once you have created the genesis-hash.txt file, check its contents to make sure it matches the one dispalyed in Jormungandr Configurations page.

cat genesis-hash.txt

2.6 Start the node

Run the following command in the same location where all 3 files were saved.

./jormungandr --genesis-block-hash $(cat genesis-hash.txt) --config ./stakepool-config.yaml

2.7 Check that the node is syncing

Execute the following command in your command-line interface to check if your node is syncing.

./jcli rest v0 node stats get --host ""

In the output, `blockRecvCnt` tells how many blocks have been downloaded:

blockRecvCnt: 2
lastBlockDate: "0.6056"
lastBlockFees: 4
lastBlockHash: 29f83b496e53073221d26cd5f09050d819069a699c30600f9afbf41170236b7a
lastBlockHeight: "482"
lastBlockSum: 10000000004
lastBlockTime: "2019-12-04T15:57:20+00:00"
lastBlockTx: 1
state: Running
txRecvCnt: 1
uptime: 46
version: jormungandr 0.8.0-ab32b2c

Your node is synced with the blockchain when it receives all the blocks that are created in the network in real-time. You can check that by following the below 2 rules:

  1. Execute the node stats command from above multiple times and check that the value of the lastBlockHash field is updated (with the actual blockchain values, there should be a new block created every 2-5 minutes);
  2. Compare the value of the lastBlockTime field (that is in UTC) with the local time of the node. If the difference if more than 10 minutes, the node might not be synced even the node received blocks in the past (blockRecvCnt > 0);

3. Fund stake pool owner account in JCLI

To register a stake pool in the blockchain, we need to create a stake pool certificate and send it to the blockchain. This requires us to have enough funds to pay for the transaction fee. Note: Step 3.2 will change once the Incentivized testent is launched.

3.1 Create an account address using the script

Run the following command to download the script in the same location:

curl -sLOJ

Make the script executable:

chmod +x
  • Create a new account address.
./ account | tee stakepool_owner_account.txt

The script returns your cryptographic keys and an address of type account. We are saving them in the file stakepool_owner_account.txt IT IS EXTREMELY IMPORTANT THAT YOU SAVE YOUR KEYS FOR FUTURE USE

PRIVATE_KEY_SK: ed25519e_sk1lq2zcyms6exxan0xx2gufjt2hdgsxmytgv5fl7nd4agzc89e6eympdwrhc2e59zkhqrpp3gnc4cfp5kf9xqufr9kn7ddl5uvtdsr84q5rg3ge
PUBLIC_KEY_PK:  ed25519_pk1nm8frtnm8r8yf7tn920akuhtw5s2xaug4mepk84kn3l9znansh0qn206ej
ADDRESS:        addr1sk0vaydw0vuvu38ewv4flkmjad6jpgmh3zh0yxc7k6w8u520kwzaus7z93h

3.2 Send funds to your stake pool account

Depending on when you are reading this How-to, you will have three options to finance your account.

  1. Using the Faucet in the itn_rewards_v1 testnet with test tokens.
  2. Using the Cardano-Wallet with command line.
  3. Using Daedalus.

3.2.1 For The Nightly Testnet

Funding your account for the Nightly testnet is simple, it has a Faucet that disperses test tokens so that you can practice and experiment with them.


3.2.2 For the Incentivized Testnet using Cardano-Wallet CLI

The autorative source for funding in the Incentivized testnet is this article: How to Register Your Stake Pool follow the tutorial along and come back, once you have sent yourself some funds.

3.2.3 For the Incentivized Testnet using Daedalus

With the Daedalus version for the Incentivized testnet you will be able to finance your account directly from your wallet sending funds to your $ACCOUNT_ADDRESS.

3.3 Check balance in your stake pool account

./jcli rest v0 account get $ACCOUNT_ADDRESS -h

4. Create a stake pool certificate in JCLI

4.1 Download the createStakePool and send-certificate scripts

  • Download the script from the repository and save it to the directory where you stored the rest of the files (jcli, Jormungandr, config.yaml, etc). You can download the script using your browser or the following commands:

  • Open the terminal in the location where you have the rest of the files (jcli, Jormungandr, config.yaml, etc) and run the below commands to download the and scripts into that location:

curl -sLOJ
curl -sLOJ

Check that the scripts were downloaded into the current location by executing ls command into the terminal

  • Change the scripts permissions to be able to execute them
chmod +x
chmod +x

4.2 Check the parameters required by the script

./ --help


The REST Listen Port set in node-config.yaml file (EX: 3101)
The fixed cut the stake pool will take from the total reward
The percentage of the remaining value that will be taken from the total
A value that can be set to limit the pool's Tax.
The Secret key of the Source address

For a detailed explanation of the TAX_VALUE, TAX_RATIO and TAX_LIMIT parameters. check this article. Remember the quantities are in Lovelaces i.e. 1 ADA = 1,000,000 Lovelace.

4.3 Execute the script

In this example the Secret Key is:

$ ed25519e_sk1lq2zcyms6exxan0xx2gufjt2hdgsxmytgv5fl7nd4agzc89e6eympdwrhc2e59zkhqrpp3gnc4cfp5kf9xqufr9kn7ddl5uvtdsr84q5rg3ge

Call the script with our secret key and save the output to the createStakePool_output.txt file

./ 3100 10000 1/10 1000000 $PRIVATE_KEY_SK | tee createStakePool_output.txt

That command returns the following output. Pay attention to your node-id and the node_secret.yaml file.

+ + ./ 3100 10000 1/10 1000000 ed25519e_sk1lq2zcyms6exxan0xx2gufjt2hdgsxmytgv5fl7nd4agzc89e6eympdwrhc2e59zkhqrpp3gnc4cfp5kf9xqufr9kn7ddl5uvtdsr84q5rg3ge
tee createStakePool_output.txt
================ Blockchain details =================
REST_PORT:        3100
ACCOUNT_SK:       ed25519e_sk1lq2zcyms6exxan0xx2gufjt2hdgsxmytgv5fl7nd4agzc89e6eympdwrhc2e59zkhqrpp3gnc4cfp5kf9xqufr9kn7ddl5uvtdsr84q5rg3ge
BLOCK0_HASH:      c8a1b4b8cd3b6a6c39adba11f62c34230b37b388f5a8edfe8cd73e7b8f811f48
#1. Create VRF keys
POOL_VRF_SK: vrf_sk15kyr7422z69urytz0j5yx8e0shdsg9hqsqe3cjw289xhkdhdfc9ssr2hdq
POOL_VRF_PK: vrf_pk1g3ac9l7fg27au7zxwc4tyj2pua35tfvrguwf0hg203rez3jffgvsqmtp57
#2. Create KES keys
POOL_KES_SK: kes25519-12-sk1qqqqqq9hcm2aqrhx024uxd748jkrs687qesd945guja5lzqlx36k74yn0g3mgtdevyqzla895ylcdlp8rcq7vqepp6nnpegyunvtupjs6qlyax2lxr8rdzkk846546jkahc5fj63yzhh9fx7ev3cg7x267fms0zdhxeeavzphdhf3cj8cnw9395xf7rufdkge2c033k32rf3q52sd3allhpmqzxrxgy9226236yhesals88l4wl3yupddxa5575cauz0pe2fwe56uhua4t77a8dajgnnmdf997dugx4wk523z3nqskxchp9dyguccwush6pqfax57dr7gj7zcjcrtmfugny3tzc6cyzkyy4wfe3fht6sf2tzy2v5f3kya6jehnz2lv6uqzd8jv7vr35l95g79rjcfrlc9xqrz8q7h2n6hl8lwhv0gdqjuctw40rrakjuhwgd0r2w7t5vwvvvkuuzxf9jq68a0u8kjxp4seeczlp7fmar4e9jc9pvn5hhc30knhfh0jnzckexlh9an053508x9m6qvt37ra4ls8h43req6lu2d8xgv9sptkf9syafvyhqkumqwpx28xng4s9uymv3tk82hhhrxh3kftxqghjt9874ry855axxsacnqxmzh9xxmkxgc5q2l9dgpdhrvdtdk9nhv32ct3yuaw432l5z4e9uct87l294qjnjgz40xk0vczffwqeu8x2l37k6kzjv8daee3hy2kv5f6fkxpd3npj3hmdhvr4d90sstm7v0rr6e5egtdmgd5w6s4n6ntzf7z0qmskrvs2drvejl0hdg7vt76a2a6frf7z3jnfze0d4402x437xa4whu8s4nmxpf5a67a96qvjawphntw6rpp48pzm08a0kr0ka5480w8jfjnlm55xuk06e5fudyq4dgj73kdphz9ssay4whtxssfc7wrwx33dudpddjlsvz6qphsttudlphsyteu5p6djuwt6mpdk27pfnpgftn2lnvnnpx952rz6rywhlqzwvecgud0sf3g059xqhfwn34acjhr5kzrqda3sj9wqp8kl9rts2a66ljecjfhay83l3qzgwscpy67wzcjn4pgq26ljhczkzg9y5lhgj75fa06wv09xmvrk6t4j2l8mrxwga7ksnsc55tl7qc3rhxwnxj4a070qu8g87xchcyuxp570zwjcw08auhy2tumsmmzh0rhrru8sngsd67mmz8dpdh9ssqtl5uksnlphuyu0qresryy82wv89qnjd30sx2rgrunjf7q4krr8c4ze5enlsq42rx9safl66wsknr8d8f7v09qr03lakkc6awayy9qmruu0l6u97hvgnz7slff9hrj9xu4atghjmc5d4wmznyeyq2th2ddwrmgercgjpl50f7qstg3kjlj3t402tp5pnesvjlg4zduvux3ev6sm5ja5j4uyum825pxz6jyeaqphpzggzef30tkxcvejnv5vk49qz7q429lwe45uhrn2d69hj64lq59hcd7dtds8nleshfqtxyw4mpvddjdsfu2c9448l688uq2xy7twsu8cnylv43jvh92fv2re9rrn9rz7jz04chms0x7zxcj8l7kdulxvvvjn4e70cmfnwn27jvw3a73t5y25uwpul9ygr9w76vhc8ptwz554sguc6mdmupp37r3fe8dyhmt99jqcv3kr0z99c6w230q377fxqfzj6alsv0dsmn039usva84z2vs4ajmjvpreue3qxs6vqxc5tqchu74l4fndcp27adeah2tku6excg6skhuwam4vy0y62mpa09ukk7rr3mdaxt9uw9zv7p2an7j0074hw5wvf2fx9cm2rn8yzvzfjmwqwc2u3t37smpwthqz8dyeukl5gmnyt5avy25elwzuwf838ce70rju477ycv2dxc4psv5uncjdz9ttyzp
POOL_KES_PK: kes25519-12-pk1lp3ta4aphvpct84cykhq37cd9vh9005y02gxhrnd0djdcns6up2sjgn884
#3. Create the Stake Pool certificate using above VRF and KEY public keys
 Sign the Stake Pool certificate
SIGNED_STAKE_POOL_CERTIFICATE: signedcert1qvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqz3rmstlujs4ameuyva32kfy5remrgkjcx3cujlws5lz8j9ryjjselp3ta4aphvpct84cykhq37cd9vh9005y02gxhrnd0djdcns6up2sr8kwjxh8kwxwgnuhx25lmdewkafq5dmc3thjrv0td8r7298m8pw7qqqqqqqqqqqzwyqqqqqqqqqqqqqsqqqqqqqqqqq2qqqqqqqqpapyqqqpqq23upxuk26389w6579x6988j6d6chsz2xvzptcelcsgnepyte4nf0rpln9j4vp70gs0z2kqysht2ztm06zrx2s473kjjc8a8m2024grxeq4sp
#4. Send the signed Stake Pool certificate to the blockchain
===============Send Certificate=================
CERTIFICATE_PATH: stake_pool.cert
ACCOUNT_SK: ed25519e_sk1lq2zcyms6exxan0xx2gufjt2hdgsxmytgv5fl7nd4agzc89e6eympdwrhc2e59zkhqrpp3gnc4cfp5kf9xqufr9kn7ddl5uvtdsr84q5rg3ge
BLOCK0_HASH: c8a1b4b8cd3b6a6c39adba11f62c34230b37b388f5a8edfe8cd73e7b8f811f48
#1. Create the offline transaction file
#2. Add the Account to the transaction
#3. Add the certificate to the transaction
#4. Finalize the transaction
#5. Make the witness
#6. Add the witness to the transaction
#7. Show the transaction info
balance: 0
fee: 7
input: 7
  - account: 9ece91ae7b38ce44f9732a9fdb72eb7520a37788aef21b1eb69c7e514fb385de
    kind: account
    value: 7
num_inputs: 1
num_outputs: 0
num_witnesses: 1
output: 0
outputs: []
sign_data_hash: e9ebf7833745cc254bbc1652b4247231946e46a3c343535de8e1de31e163af84
status: finalizing
#8. Seal the transaction
#9. Auth the transactions
#10. Encode and send the transaction
#11. Remove the temporary files
#Waiting for new block to be created (timeout = 200 blocks = 400s)
New block was created - 80d812d1fc73a4c8dbd24bf42276ca1f008a93496259ea36a54017de6c76aeca
#5. Retrieve your stake pool id (NodeId)
============== Stake Pool details ================
Stake Pool ID:    f76184d75c075e08de3750fecd10e5956751f028b5056d121ce0ea87575f5970
Stake Pool owner: ca1sk0vaydw0vuvu38ewv4flkmjad6jpgmh3zh0yxc7k6w8u520kwzauynxpks
TAX_VALUE:        10000
TAX_RATIO:        1/10
TAX_LIMIT:        1000000
#6. Create the node_secret.yaml file
  • Check the results

If everything is fine and you did not receive any error, the last line of the script output is your Stake Pool Node ID. Now you can check if your stake pool id appears in the list of available stake pools by executing the below command.

4.4 Check that the stake pool is in the blockchain.

Get the list of stake pools.

./jcli rest v0 stake-pools get --host ""

You can see that our Node-id is in the list.

4.2 Restart Jormungandr as a stake pool

Go to the terminal where Jormungandr is running and stop the server.

Now you can start the node as a leader candidate, using the --secret node_secret.yaml parameter. The node_secret.yaml file was automatically created in the same location as

Restart Jormungandr with the secret parameter.

./jormungandr --genesis-block-hash $(cat genesis-hash.txt) --config ./stakepool-config.yaml --secret ./node_secret.yaml

5. Register stake pool to the Cardano Foundation

Check the official registration process here: Github Incentivized Testnet Stake Pool Registry to make your stake pool appear as part of the Daedalus interface, so that ADA Holders can delegate their stake to your stake pool.

Let's follow the process for our running example.

5.1 Fork and clone the Cardano Foundation Registry repository.

On GitHub go to the Cardano Foundation Incentivized Testnet Stake Pool Registry and create a fork in your own account.

Clone your fork in your local machine.

With your username you can clone the repository:

git clone$GITHUB_USERNAME/incentivized-testnet-stakepool-registry.git

5.2 Create stake pool JSON file

To register with the Cardano Foundation we need to create a json file with the following fields:

  • owner: public key of the stake pool operator. Created on step 3.1 of this guide.
  • name: name your stake pool
  • ticker: three to five characters that identify your stake pool
  • homepage: your website, where you can inform the public about the advantages of your stake pool.
  • pledge_address: account address of your stake pool. Created on step 3.1 of this guide.

The json file for this example is:

cat ./incentivized-testnet-stakepool-registry/registry/$PUBLIC_KEY_PK.json
'owner': 'ed25519_pk1nm8frtnm8r8yf7tn920akuhtw5s2xaug4mepk84kn3l9znansh0qn206ej',
'name': 'Example stake pool name',
'ticker': 'EXAMP',
'homepage': '',
'pledge_address': 'addr1sk0vaydw0vuvu38ewv4flkmjad6jpgmh3zh0yxc7k6w8u520kwzaus7z93h'

Name your file as your public key with .json extension

5.3 Sign with your owner Private Key

We need to make sure that the person making the submission is the owner of the Public key in the json file. To do that we need to sign the submission with the secret key created on step 3.1 of this guide.

The next command requires the Secret Key to be stored in a file so let's just save it in a file named owner.prv

echo $PRIVATE_KEY_SK > owner.prv

To sign the .json file we use:

./jcli key sign --secret-key owner.prv --output ./incentivized-testnet-stakepool-registry/registry/$PUBLIC_KEY_PK.sig ./incentivized-testnet-stakepool-registry/registry/$PUBLIC_KEY_PK.json

5.4 Verify that we have the correct files.

Let's do a sanity check and make sure we have both files that will be required:

ls  ./incentivized-testnet-stakepool-registry/registry/* | sort

You should see two files, one with .json and one with .sig extension.


5.5 Commit files

Now all we need to do is do a common git commit

cd ./incentivized-testnet-stakepool-registry/registry/
git add $PUBLIC_KEY_PK.json
git add $PUBLIC_KEY_PK.sig
git commit -m "EXAMP"
git push
cd ../../

5.6 Create Pull Request

Now just go to the normal GitHub user interface and create a pull request as you would do on any other github project.

5.7 Check that the stake pool appears in the Daedalus wallet.

Once the Cardano Foundation approves your pull request, you should see your stake pool listed in the delegation interface of Daedalus.

6. Delegate your stake to your stake pool

6.1 Download the delegate-account script

curl -sLOJ
chmod +x

6.2 Check the parameters required by the script

./ --help
The ID of the Stake Pool you want to delegate to
The REST Listen Port set in node-config.yaml file (EX: 3101)
The Secret key of the Account address

6.3 Execute the script


6.4 Check that your stake was delegated

./jcli rest v0 account get $ACCOUNT_ADDRESS -h
counter: 0
pools: []
epoch: 0
reward: 0
value: 10000000000

7. Monitor Delegated Stake

It is easy to see how much delegated stake the pool has. Simply get the balance of the stake pool account and it displays the delegated stake

7.1 Check delegated stake through JCLI

./jcli rest v0 stake-pool get $STAKEPOOL_ID --host ""
You can’t perform that action at this time.