cardano course
  • Welcome!
  • Video lessons
  • Handbook
    • Module 1. Building and running the node
      • Building the node
      • Running the node and connecting to a network
    • Module 2. Basic operations
      • Creating keys and addresses
      • Creating a simple transaction
      • Registering the stake address and delegating
    • Module 3. Protocol parameters and configuration files
      • Protocol parameters
      • Byron genesis file
      • Shelley genesis file
      • Alonzo genesis file
      • Conway genesis file
      • Node configuration file
      • Topology file
    • Module 4. Peer-to-peer (P2P) networking
    • Module 5. Creating a stake pool
      • The setup
      • Generating keys
      • Registering a stake pool
      • Runtime system options
      • Running the nodes
      • Stake snapshots
      • Upgrading cardano-node and cardano-cli
      • Pool operations and maintenance
      • Retiring a stake pool
    • Module 6. Monitoring the nodes
    • Module 7. Cardano governance
      • Update proposals
      • Polls
    • Module 8. Setting up a local cluster
      • Creating a local cluster
      • Spending the genesis UTXO
      • From Byron to Shelley
      • Moving funds to a Shelley address
      • Creating a first stake pool
      • Bringing decentralization parameter down to .80
      • From Shelley to Alonzo
      • Creating a second stake pool before moving to the Babbage era
      • Redelegating genesis keys
      • Vasil hard fork
      • Creating a local cluster with the mkfiles script
    • Module 9. Simple scripts and Plutus scripts
    • Module 10. New tracing system
    • Module 11. Running the SMASH server
    • Module 12. Running the token metadata server
  • Curated playlist
Powered by GitBook
On this page
  • Registering the stake key
  • Registering a stake pool
  • Bringing decentralization down to 0

Was this helpful?

Edit on GitHub
  1. Handbook
  2. Module 8. Setting up a local cluster

Creating a second stake pool before moving to the Babbage era

The decentralization parameter is removed in the Babbage era (Vasil hard fork). This means that current BFT nodes will not be able to continue producing blocks in Babbage. You will need at least one more stake pool:

mkdir pool2

Create keys and an address to send some funds to the second pool.

The payment keys:

cardano-cli address key-gen \
--verification-key-file pool2/payment.vkey \
--signing-key-file pool2/payment.skey

The stake keys:

cardano-cli stake-address key-gen \
--verification-key-file pool2/stake.vkey \
--signing-key-file pool2/stake.skey

Build the address:

cardano-cli address build \
--payment-verification-key-file pool2/payment.vkey \
--stake-verification-key-file pool2/stake.vkey \
--out-file pool2/payment.addr \
--testnet-magic 42

Build transactions to send some funds to the second pool owner:

cardano-cli transaction build \
--alonzo-era \
--testnet-magic 42 \
--invalid-hereafter $(expr $(cardano-cli query tip --testnet-magic 42 | jq .slot) + 1000) \
--tx-in $(cardano-cli query utxo --address $(cat utxo-keys/user1.payment.addr) --testnet-magic 42 --out-file  /dev/stdout | jq -r 'keys[]') \
--tx-out $(cat pool2/payment.addr)+50000000000000 \
--change-address $(cat utxo-keys/user1.payment.addr) \
--out-file transactions/tx6.raw

Sign the transaction:

cardano-cli transaction sign \
--tx-body-file transactions/tx6.raw \
--signing-key-file utxo-keys/user1.payment.skey \
--testnet-magic 42 \
--out-file transactions/tx6.signed

Submit it to the blockchain:

cardano-cli transaction submit \
--testnet-magic 42 \
--tx-file transactions/tx6.signed
cardano-cli query utxo --address $(cat pool2/payment.addr) --testnet-magic 42

Generate cold keys:

cardano-cli node key-gen \
--cold-verification-key-file pool2/cold.vkey \
--cold-signing-key-file pool2/cold.skey \
--operational-certificate-issue-counter-file pool2/opcert.counter

Generate VRF keys:

cardano-cli node key-gen-VRF \
--verification-key-file pool2/vrf.vkey \
--signing-key-file pool2/vrf.skey

Generate KES keys:

cardano-cli node key-gen-KES \
--verification-key-file pool2/kes.vkey \
--signing-key-file pool2/kes.skey

Issue the operational certificate:

cardano-cli node issue-op-cert \
--kes-verification-key-file pool2/kes.vkey \
--cold-signing-key-file pool2/cold.skey \
--operational-certificate-issue-counter pool2/opcert.counter \
--kes-period 0 \
--out-file pool2/opcert.cert

Create a topology file for pool2 and update pool1 topology. You will shut down bft0 and bft1 after the Vasil hard fork so there is no need to update them:

cat > pool1/topology.json <<EOF
{
   "Producers": [
     {
       "addr": "127.0.0.1",
       "port": 3000,
       "valency": 1
     },
     {
       "addr": "127.0.0.1",
       "port": 3001,
       "valency": 1
     },
     {
       "addr": "127.0.0.1",
       "port": 3003,
       "valency": 1
     }
   ]
 }
EOF
cat > pool2/topology.json <<EOF
{
   "Producers": [
     {
       "addr": "127.0.0.1",
       "port": 3000,
       "valency": 1
     },
     {
       "addr": "127.0.0.1",
       "port": 3001,
       "valency": 1
     },
     {
       "addr": "127.0.0.1",
       "port": 3002,
       "valency": 1
     }
   ]
 }
EOF

You can now write a script to start the pool2 node:

cat > pool2/startnode.sh <<EOF
#!/usr/bin/env bash

cardano-node run \
--config ../configuration/config.json \
--topology topology.json \
--database-path db \
--socket-path node.socket \
--port 3003 \
--shelley-kes-key kes.skey \
--shelley-vrf-key vrf.skey \
--shelley-operational-certificate opcert.cert
EOF

Give it executable permissions:

chmod +x pool2/startnode.sh

Start the node from the pool2 directory.

Registering the stake key

Create a registration certificate:

cardano-cli stake-address registration-certificate \
--stake-verification-key-file pool2/stake.vkey \
--out-file pool2/stake.cert
CHANGE=$(($(cardano-cli query utxo --address $(cat pool2/payment.addr) --testnet-magic 42 --out-file  /dev/stdout | jq -cs '.[0] | to_entries | .[] | .value.value.lovelace') - 3000000))
cardano-cli transaction build-raw \
--alonzo-era \
--fee 1000000 \
--invalid-hereafter $(expr $(cardano-cli query tip --testnet-magic 42 | jq .slot) + 1000) \
--tx-in $(cardano-cli query utxo --address $(cat pool2/payment.addr) --testnet-magic 42 --out-file  /dev/stdout | jq -r 'keys[]') \
--tx-out $(cat pool2/payment.addr)+$CHANGE \
--certificate-file pool2/stake.cert \
--out-file transactions/tx7.raw
cardano-cli transaction sign \
--tx-body-file transactions/tx7.raw \
--signing-key-file pool2/payment.skey \
--signing-key-file pool2/stake.skey \
--testnet-magic 42 \
--out-file transactions/tx7.signed
cardano-cli transaction submit \
--testnet-magic 42 \
--tx-file transactions/tx7.signed

Registering a stake pool

wget https://git.io/JJWdJ -O pool2/poolmetadata.json

Get the metadata and save it:

cardano-cli stake-pool metadata-hash --pool-metadata-file pool2/poolmetadata.json --out-file pool2/poolmetadata.hash

Generate the registration certificate:

cardano-cli stake-pool registration-certificate \
--cold-verification-key-file pool2/cold.vkey \
--vrf-verification-key-file pool2/vrf.vkey \
--pool-pledge 1000000000000 \
--pool-cost 340000000 \
--pool-margin 10/100 \
--pool-reward-account-verification-key-file pool2/stake.vkey \
--pool-owner-stake-verification-key-file pool2/stake.vkey \
--testnet-magic 42 \
--pool-relay-ipv4 127.0.0.1 \
--pool-relay-port 3003 \
--metadata-url https://git.io/JJWdJ \
--metadata-hash $(cat pool2/poolmetadata.hash) \
--out-file pool2/pool-registration.cert

Create a delegation certificate:

cardano-cli stake-address delegation-certificate \
--stake-verification-key-file pool2/stake.vkey \
--cold-verification-key-file pool2/cold.vkey \
--out-file pool2/delegation.cert

Build the transaction to register the pool and the delegation certificate:

CHANGE=$(($(cardano-cli query utxo --address $(cat pool2/payment.addr) --testnet-magic 42 --out-file  /dev/stdout | jq -cs '.[0] | to_entries | .[] | .value.value.lovelace') - 501000000))
cardano-cli transaction build-raw \
--alonzo-era \
--fee 1000000 \
--invalid-hereafter $(expr $(cardano-cli query tip --testnet-magic 42 | jq .slot) + 10000) \
--tx-in $(cardano-cli query utxo --address $(cat pool2/payment.addr) --testnet-magic 42 --out-file  /dev/stdout | jq -r 'keys[]') \
--tx-out $(cat pool2/payment.addr)+$CHANGE \
--certificate-file pool2/pool-registration.cert \
--certificate-file pool2/delegation.cert \
--out-file transactions/tx8.raw
cardano-cli transaction sign \
--tx-body-file transactions/tx8.raw \
--signing-key-file pool2/payment.skey \
--signing-key-file pool2/stake.skey \
--signing-key-file pool2/cold.skey \
--testnet-magic 42 \
--out-file transactions/tx8.signed
cardano-cli transaction submit \
--testnet-magic 42 \
--tx-file transactions/tx8.signed
cardano-cli stake-pool id --cold-verification-key-file pool2/cold.vkey --output-format "hex"

Wait for two epochs for pool2 to start producing blocks.

Bringing decentralization down to 0

cardano-cli governance create-update-proposal \
--out-file transactions/update.D0.proposal \
--epoch $(cardano-cli query tip --testnet-magic 42 | jq .epoch) \
--genesis-verification-key-file genesis-keys/non.e.shelley.000.vkey \
--genesis-verification-key-file genesis-keys/non.e.shelley.001.vkey \
--decentralization-parameter 0/100
CHANGE=$(($(cardano-cli query utxo --address $(cat pool1/payment.addr) --testnet-magic 42 --out-file  /dev/stdout | jq -cs '.[0] | to_entries | .[] | .value.value.lovelace') - 1000000))
cardano-cli transaction build-raw \
--shelley-era \
--fee 1000000 \
--invalid-hereafter $(expr $(cardano-cli query tip --testnet-magic 42 | jq .slot) + 1000) \
--tx-in $(cardano-cli query utxo --address $(cat pool1/payment.addr) --testnet-magic 42 --out-file  /dev/stdout | jq -r 'keys[]') \
--tx-out $(cat pool1/payment.addr)+$CHANGE \
--update-proposal-file transactions/update.D0.proposal \
--out-file transactions/update.D0.proposal.txbody
cardano-cli transaction sign \
--tx-body-file transactions/update.D0.proposal.txbody \
--signing-key-file pool1/payment.skey \
--signing-key-file bft0/shelley.000.skey \
--signing-key-file bft1/shelley.001.skey \
--out-file transactions/update.D0.proposal.txsigned
cardano-cli transaction submit --testnet-magic 42 --tx-file transactions/update.D0.proposal.txsigned
Event: LedgerUpdate (HardForkUpdateInEra S (S (S (S (Z (WrapLedgerUpdate {unwrapLedgerUpdate = ShelleyUpdatedProtocolUpdates [ProtocolUpdate {protocolUpdateProposal = UpdateProposal {proposalParams = PParams {_minfeeA = SNothing, _minfeeB = SNothing, _maxBBSize = SNothing, _maxTxSize = SNothing, _maxBHSize = SNothing, _keyDeposit = SNothing, _poolDeposit = SNothing, _eMax = SNothing, _nOpt = SNothing, _a0 = SNothing, _rho = SNothing, _tau = SNothing, _d = SJust (0 % 1), _extraEntropy = SNothing, _protocolVersion = SNothing, _minPoolCost = SNothing, _coinsPerUTxOWord = SNothing, _costmdls = SNothing, _prices = SNothing, _maxTxExUnits = SNothing, _maxBlockExUnits = SNothing, _maxValSize = SNothing, _collateralPercentage = SNothing, _maxCollateralInputs = SNothing}, proposalVersion = Nothing, proposalEpoch = EpochNo 10}, protocolUpdateState = UpdateState {proposalVotes = [KeyHash "0bc4c92289432762de7910d9db34ac709228581aea448d0bc3cc8fa6",KeyHash "a9bd5e3a633a9b46a889f974bfea91af8e4d0af9595a9bcd1537472c"], proposalReachedQuorum = True}}]}))))))
PreviousFrom Shelley to AlonzoNextRedelegating genesis keys

Last updated 1 year ago

Was this helpful?

Reuse the metadata file :

https://git.io/JJWdJ
Page cover image