This guide's chapter targets the pool operators for getting their head around of Shelley staking. To fully understand the staking mechanism we need to define and interpret the following key concepts:
- What are the keys
- What are the addresses
- What are the certificates and
- Who are the stake holders that are participanting in staking.
The following picture helps to understand the relations between keys, addresses and certificates.
Keys are just simply asymmetric cryptography key pairs (private/public, signing/verifying) that are used for signing and validating payments and staking related certificates and identifying, defining addresses on the Cardano blockchain.
As it can be seen in the picture there are two main type of keys in Shelley:
- Node keys and
- Address keys.
The node keys are relevant to the security of the blockchain while the address keys are relevant to the functions of the addresses derived from the keys for identifying funds on the blockchain. See details below and above in the picture.
- Node Keys
- Operator/operatioanl key: operator's offline key pair with cert counter for new certificates.
- Hot KES key: operator's hot KES key pair.
- Block signing key: operational VRF key pair, it participates in the "lottery" i.e. right to create and sign the block for the specific slot.
- Address (Payment, Staking etc.) keys
- Payment key: single address key pair (usually for generating UtxO addresses)
- Staking key: stake/reward address key pair (usually generating account/reward addresses)
The addresses, as of now, are just a simple blake2b-256
hash of the relevant veryifying/public keys contatenated with some metadata that are or can be stored on the Cardano
blockchain.
Addresses in this context are only relevant to the ledger specification and not to any wallet addresses. So, the wallets
m/44'/1852'/0'/{0,1,2}
bech32
addresses (e.g.ca1hg9...
) are irrelevant here.
Currently there are three main type of addresses and a reserved address space for future use:
- Payment addresses:
- base addresses (can participate in staking, a.k.a goup addresses in ITN jorm terminology)
- pointer addresses (need to check whether it can or cannot participate in staking)
- enterprise addresses (cannot participate in staking a.k.a UtxO address)
- Reward addresses: Reward/account addresses (can participate in staking)
- Byron addresses: The legacy addresses, for backward compatibility (cannot participate in staking)
- Future addresses: possible 5 main /w 16 subtypes or 80 additional address types)
Therefore addresses, in Cardano Shelley (only in Haskell code), are some serialised data specified in the ledger specification that are stored in the blockhain's blocks (e.g. an UtxO address).
The serialised data (address) contains two parts the metadata and payload (i.e. address = metadata + payload
):
- metadata: is for interpreting the
- payload: the raw or encoded bytes. For example the verifying/public keys or their hashes or even scripts (e.g. plutus smart contract) hashes.
Therefore, in layman definition (by removing some complexity for easy understanding): Addresses are serialised public/verifying keys
See,the detailed address specification here.
Pls, keep in mind, that it does not mean that the specification is currently is used, implemented and/or finalised.
Shelley's PoS protocol requires different certificates posted to the blockhain; which will be pulbicyl available for all participants. Those are valids until explicitly overwritten or revoked.
There are four main type of certificates are in Shelley:
- Operational key certificates (off chain),
- Stake Key registration certificates (on chain),
- Delegation certificates (on chain) and
- Stake pool certificates (on chain).
The operational key certificate
's is created from a operator key
used by stake pool operators for protecting their pool(s) and keys, signing bocke, participating in the lottery and not for delegating staking rights.
This certificate needs for operating a node as a stake pool.
All participants, who want to participate in staking, need to register a stake key on the blockchain by posting a stake key registration certificate. The registration requires a key deposit specified in the genesis (400K lovelace for FnF), but do not require any signature
signed by the corresponding stake signing key
.
The registration is revoked when a de-registration certificate signed by the account's stake signing key
is posted to the blockchain, causing the account to be deleted (Ask what is the impact of this).
Delegation certificates uses a staking key
to grant the right to sign blocks to another key.
A node for operating as a stake pool must post a stake pool registration certificate
signed by all the owners' staking signing key
and the pool operator's operational signing key
.
To revoke the certificate a stake pool retirement certificate
must be posted to the chain signed by only the pool's operational signing key
.
No owner(s) is/are required to sign the retirement certificate.
Tha stake holders in simple words are those who are participating in stakings, namely:
- Operators, who operate staking pools,
- Owners, who own a pool, in some extent, by pledging their stakes to pools and the
- Delegates, who delegate their staking rights to stake pools.
For participating in staking, every stake holder must have some form of different type of address keys
:
- payment keys, which can or cannot participate in staking and
- staking keys for receiving staking (stake or pool) rewards.
The owners are the stake holders who have some funds deposited and want to own, in some extent, a staking pool. The owner's objectives are the following:
- Create
payment key(s)
for generatingbase
payment addresses. - Create
stake key(s)
for generating poolreward address
. - Create and submit the owner's
delegation certificate
for pledging.
Note: In this example the operator's stake and payment keys will be used for pledging. That means the the operator is the owner. See details below
The operator(s) is/are the stake holder(s) who operating a pools. The operators can define their operational costs in the pool certificate, that can be deducted from the rewards.
The objectives are the following:
- Understand off-chain
operational key certificates
, - the required keys and addresses,
payment key(s)
for generatingbase
payment addresses,stake key(s)
for generating poolreward address(es)
,
- the stake address registration process with
key deposit
and - the stake pool registration procedure /w pledge and other params.
Detailed steps are:
- Run a node with an
operational key certificate
- Create stake key registration certificate for registering the operator's stake key (
staking.key
) on the chain, then - Create a pool registration certificate for the node to became a stake pool (
pool.cert
), - Create a delegation certificate for the owner (operator in our exercise) to delegate its stake as pledge to the newly creating pool (
deleg.cert
). - Sends the on-chain certificates to the blockchain in one or more transactions.
The operational key certificates use an operational key (cold) key to grant the right to sign blocks to another key (KES) that will expire after some epochs, that is based on the genesis parameters.
It uses a similar mechanism to the forward secure signature scheme
where the signing key (KES) changes over time period and the end of each time period a new signing key is computed for the next peried and the old one is erased.
The mechanism used for running a node with operational key certificates
are the following:
- KES (Key Evolving Signatures) that creates new (hot) KES keys periodically from the cold key
- Create the cold (offline) key pair,
- Create the hot KES key pairs (periodically), for signing blocks.
- Create the
operational key certificate
- Generate VRF key pair for leader selection (lottery).
- Run stake pool that is using the
- non expired Operational certificate
- non expired KES (hot) signing key
- VRF signing key
Before the old hot (KES) key pair is expiring, a new operational key certificate
needs to be created by using a newly generated hot (KES) key pair and the off-line cold signing key.
In production environment, it is expected that the cold key is generated by some seed generation mechanism (BIP39 or similar) and stored on computer that does not have access to the Internet and when the time arrives, the operational certificates with the hot (KES) key pairs are transferred, by some mechanism (USB stick, air gapped QR etc.) to the stake pool.
# 1.1 Create cold key pair
##########################################
pushd /opt/cardano/fnf && mkdir -p ~/cold-keys && pushd ~/cold-keys || exit 127
# Generate the cold offline key pair
cardano-cli shelley node key-gen \
--verification-key-file cold.vkey \
--signing-key-file cold.skey \
--operational-certificate-issue-counter cold.counter
popd
# 1.2 Generate a new hot KES keypair
cardano-cli shelley node key-gen-KES --verification-key-file priv/kes.vkey --signing-key-file priv/kes.skey
# 1.3 Generate the ops cert based on
# - the `cold signing key`
# - the hot KES key and
# - the cold key's counter
# New periodic cert is based on the new hot KES key.
# kes-period tells how long the ops cert therefrore the hot KES keys are valid
#
cardano-cli shelley node issue-op-cert \
--cold-signing-key-file ~/cold-keys/cold.skey \
--operational-certificate-issue-counter ~/cold-keys/cold.counter \
--hot-kes-verification-key-file priv/kes.vkey \
--kes-period 0 \
--out-file priv/op.cert
# 2. Generate VRF key pair for leader selection
#########################################################
cardano-cli shelley node key-gen-VRF --verification-key-file priv/vrf.vkey --signing-key-file priv/vrf.skey
# 3. Run node /w these new keys generated
#########################################################
cardano-node run \
--config files/config.json \
--topology files/topology.json \
--database-path db \
--socket-path sockets/nodes.socket \
--shelley-kes-key priv/kes.skey \
--shelley-vrf-key priv/vrf.skey \
--shelley-operational-certificate priv/op.cert \
--port 6000
I will use the initial genesis address as input for registering the:
- delegate registration certificate and
- pool registration certificate
Keep in mind the operator also need to have its stake key registered onn the chain.
First we need to create the operator's key in order to register the key on the chain.
The delegate's staking key
needs to be registered on the blockchain in order to participating in staking, which just need a simple transaction using any payment address
.
This is the pool operators's stake key, and not the delegate's one. Therefore I prefixed them it differently i.e.
staking
, to distuinguish between the delegate's (stake
) prefix.
mkdir operator && pushd operator
# Generate the operator's stake keys
cardano-cli shelley stake-address key-gen --verification-key-file staking.vkey --signing-key-file staking.skey
# crate teh reward (staking) address from the operator's stake keys
cardano-cli shelley stake-address build --staking-verification-key-file staking.vkey > staking.addr
# Generate the operator's payment keys
cardano-cli shelley address key-gen --verification-key-file op_pay.vkey --signing-key-file op_pay.skey
# Generate an `enterprise` address for the operator.
cardano-cli shelley address build --payment-verification-key-file op_pay.vkey > op_pay.addr
# Generate the base address i.e. compount `enterprise || reward` address
cardano-cli shelley address build \
--payment-verification-key-file op_pay.vkey \
--staking-verification-key-file staking.vkey \
> base.addr
The next step is creating a stake address registration certificate.
For registering an stake key
on the chain a key deposit1
fee must be paid. The amount can be optained from the genesis for the params file e.g.:
grep keyDep ../params.json
"keyDeposit": 400000,
Generate the operator's stake key registration certificate
Keep, in mind that the a key registration certificates
needs a deposit (keyDeposit in genesis) for the costs of tracking the key and the corresponding reward account. Also, it does not require any witness to register the certificate, but only the witness for the fees from the input of the transaction.
# Keep in mind that this certificates needs a `keyDeposit` specified in the genesis.
cardano-cli shelley stake-address registration-certificate \
--staking-verification-key-file staking.vkey \
--out-file staking.cert
# The certificate contains the `blake2b-256` hash of the stake verifying key
# Calculate the min fee for the following outputs:
# 1. the base address that will contain the funds for pledge
# 2. And the change address.
# Keep in mind just one signing key is required, the paying signing key,
# as stake key reg cert does not need t obe witnessed
cardano-cli shelley transaction calculate-min-fee \
--tx-in-count 1 \
--tx-out-count 2 \
--ttl 500000 \
--testnet-magic 42 \
--signing-key-file /opt/cardano/fnf/addresses/genesis.skey \
--certificate staking.cert \
--protocol-params-file params.json
#
# runTxCalculateMinFee: 174169
# INPUT will be based on the genesis addres (FROM)
# but any pay address is fine.
FROM="617190446876aed298ee207c6b5a335e832e2169a060b8167ef3ba9caff6fa3393"
cardano-cli shelley query utxo --testnet-magic 42 --address "$FROM"
# TxHash TxIx Lovelace
#----------------------------------------------------------------------------------------
#c85b72ee021915f5a8349209db54a51334ad9dfcec2f0fa2619a707556017bb3 0 499999825831
INPUT="c85b72ee021915f5a8349209db54a51334ad9dfcec2f0fa2619a707556017bb3#0"
BALANCE=499999825831
# The amount will be 400K and I will pladge all of it to the pool
AMOUNT=400000000000
KEYDEP=400000
FEE=174169
CHANGE="$FROM+$(( 499999825831 - $FEE - $KEYDEP - $AMOUNT ))"
# So, I used the genesis UtxO to move to some staking (group) address and 500K back to it.
cardano-cli shelley transaction build-raw \
--tx-in "$INPUT" \
--tx-out $(cat base.addr)+$AMOUNT \
--tx-out "$CHANGE" \
--ttl 500000 \
--fee "$FEE" \
--tx-body-file staking-cert.tx \
--certificate staking.cert
# Sign it
cardano-cli shelley transaction sign \
--tx-body-file staking-cert.tx \
--signing-key-file /opt/cardano/fnf/addresses/genesis.skey \
--testnet-magic 42 \
--tx-file signed-staking-cert.tx
# Submit it
cardano-cli shelley transaction submit \
--tx-file signed-staking-cert.tx \
--testnet-magic 42
A node needs a pool certificate
registered on the blockchain for the operator to became a stake pool (pool.cert
),
Now we have a 400K on the operator's base address
and the stake key (staking.key
) is registered.
cardano-cli shelley query utxo --testnet-magic 42 --address $(cat base.addr)
TxHash TxIx Lovelace
----------------------------------------------------------------------------------------
863506d0e7d1afcdb558ac4b021f2e7746f3c3178faecd11e1f0349ded141a74 0 400000000000
In the operator's PoV, for registering a pool, the pool certificate must contain:
- a
node operational verifying key
a.k.a.cold key
, for generating the pool id. - the
VRF verifyig key
a.k.ahot key
, for lottery, to prove that the node has the right to create and sign a block, - an operator
stake verifying keys
for generating the reward address, where the pool rewards would be sent and - owner's
stake verifying keys
generating the pledgestaking
address, that has enough fund for pledging.
Note: the
reward account verification key
and theowner staking verification key
can be the same is, see below example, if the operator is the owner too.
Also, for registering a pool certificate a pool deposit
must be paid too.
# Createing a pools cert with
# - 400K of the owner's (operator in this example) 400K pledge,
# - 1k as cost /w
# - 5% margin
cardano-cli shelley stake-pool registration-certificate \
--stake-pool-verification-key-file ~/cold-keys/pool.vkey \
--vrf-verification-key-file /opt/cardano/fnf/priv/vrf.vkey \
--pool-pledge 400000000000 \
--pool-cost 1000000000 \
--pool-margin 0.05 \
--reward-account-verification-key-file staking.vkey \
--pool-owner-staking-verification-key staking.vkey \
--out-file pool.cert
For pledging, the owner (in our example the operator) must create a stake delegation certificate
for delegating at least a pledge
amount of stake from the owner's staking key
specified in the pool certificate.
In simple words, the owner is delegating its funds (pledge
) to the pool he/she owns.
cardano-cli shelley stake-address delegation-certificate \
--staking-verification-key-file staking.vkey \
--stake-pool-verification-key-file ~/cold-keys/pool.vkey \
--out-file owner-delegation.cert
The certificates can be sent in one transaction.
Please, keep in mind that the registering a pool the operator's must pay a (decaying)
pool deposit
fee.
# grep -i poolDeposit params.json
# "poolDeposit": 500000000,
# or
# cardano-cli shelley query protocol-parameters --testnet-magic 42 | jq '.poolDeposit'
# 500000000
# Calculate the fee for sending the both certificates the
# - pool registration certificate and the
# - owner's (in our case the operator's) delegating certificate.
#
# Also, it will be paid by my genesis key, but any valid `payment` signing key would do that
# has the fee and the deposit
cardano-cli shelley transaction calculate-min-fee \
--tx-in-count 1 \
--tx-out-count 1 \
--ttl 500000 \
--testnet-magic 42 \
--signing-key-file /opt/cardano/fnf/addresses/genesis.skey \
--signing-key-file staking.skey \
--signing-key-file ~/cold-keys/pool.skey \
--certificate pool.cert \
--certificate owner-delegation.cert \
--protocol-params-file ../params.json
# runTxCalculateMinFee: 184377
FEE=184377
POOLDEP=500000000
cardano-cli shelley query utxo --testnet-magic 42 --address "$FROM"
# TxHash TxIx Lovelace
#----------------------------------------------------------------------------------------
#863506d0e7d1afcdb558ac4b021f2e7746f3c3178faecd11e1f0349ded141a74 1 99999251662
BALANCE=99999251662
INPUT="863506d0e7d1afcdb558ac4b021f2e7746f3c3178faecd11e1f0349ded141a74#1"
CHANGE="$FROM+$(( $BALANCE - $FEE - $POOLDEP ))"
# Build
cardano-cli shelley transaction build-raw \
--tx-in "$INPUT" \
--tx-out "$CHANGE" \
--ttl 500000 \
--fee "$FEE" \
--tx-body-file pool-cert.tx \
--certificate pool.cert \
--certificate owner-delegation.cert
# Sign
# - the `genesis.skey` needs for signing the payment from the $FROM address.
# - the `staking.skey` needs for signing the owner's delegation certificate.
# - the `pool.skey` needs for signing the pool's registration certificate.
cardano-cli shelley transaction sign \
--tx-body-file pool-cert.tx \
--signing-key-file /opt/cardano/fnf/addresses/genesis.skey \
--signing-key-file staking.skey \
--signing-key-file ~/cold-keys/pool.skey \
--testnet-magic 42 \
--tx-file signed-pool-cert.tx
# Submit:
cardano-cli shelley transaction submit \
--tx-file signed-pool-cert.tx \
--testnet-magic 42
Done your pool is registered.
To check it you can you the following command:
# Get the Pool Id whihc is in the owner-delegation.cert
POOL_ID=$( tail -1 owner-delegation.cert | cut -c 6- )
echo $POOL_ID
# 5820d07e860c52860d92373893b27d6926e6610c925f905eba40d8e930004bf2dc44
shelley query ledger-state --testnet-magic 42 | grep "poolPubKey" | grep "$POOL_ID"
# "_poolPubKey": "d07e860c52860d92373893b27d6926e6610c925f905eba40d8e930004bf2dc44",
The delegates are the stake holders who have some funds deposited and want to participate in staking. Therefore the steps for delegating stakes are the following:
- Create
stake key(s)
for generating the delegate'sreward address(es)
for collecting theirstake rewards
. - Create
payment key(s)
for generating the delegate'spayment address(es)
for payments that will participate in stake delegation and also deposititing some funds. - Register
stake address
on the blockhain, with key deposit, which is required for participatin in staking and - Create and submit the stake delegation certificate for the selected pool.
Stake address, derived from a stake verification key
, is a simple reward (account) address
which is not a payment address
therefore it cannot be used as an output of a transaction.
In the cardano-cli
they use a CBOR format for preventing it to be added as the input into a transaction.
Keep in mind, that only the reward addresses and the base_, pointer and some script (not available yet) addresses can participate in the staking.
First, we need to create the relevant payment
and stake
keys and the related addresses for the delegate. The payment address for paying the transactions for sending the registration certificate
(which is just simply the reward account address in some CBOR encoded format) to the chain.
# Delegate's staking/acount key, then Staking/Account address
############################################################
mkdir delegate && pushd delegate
cardano-cli shelley stake-address key-gen --verification-key-file stake.vkey --signing-key-file stake.skey
cardano-cli shelley stake-address build --staking-verification-key-file stake.vkey > stake.addr
cat stake.addr
#-------v 32 bytes key starts from here
8200582032a8c3f17ae5dafc3e947f82b0b418483f0a8680def9418c87397f2bd3d35efb
# It's a CBOR representation of the vkey
#82 # array(2)
# 00 # unsigned(0)
# 58 20 # bytes(32)
# 32A8C3F17AE5DAFC3E947F82B0B418483F0A8680DEF9418C87397F2BD3D35EFB #
# "2\xA8\xC3\xF1z\xE5\xDA\xFC>\x94\x7F\x82\xB0\xB4\x18H?\n\x86\x80\xDE\xF9A\x8C\x879\x7F+\xD3\xD3^\xFB"
# Delegates payment key -> payment address (a.k.a legacy UtxO a.k.a enterprise address).
# Ur use some address that already has some fund on it.
############################################################
cardano-cli shelley address build --payment-verification-key-file pay.vkey > pay.addr
cat pay.addr
# As a single Shelley UtXO address and (no CBOR repr)
# header(1) | address(32), so no hash224
# 0x61 = 0110 0001 || 0x47eb...2907 therefore an UtXO enterprise address
6147ebc8bf8714dcf6700ac482a5d42624ffca6afb51ae23930ea6591119a12907
####################################################################
# Generate the delegate's base address (0x01...) from
# 1. the `pay.vkey` (used for enterprise address `0x61...`)
# 2. and from the `stake.key`
# It's a combination of the payment and reward address, with
# the 0b0000 0b0001, as a base address prefix
####################################################################
cardano-cli shelley address build \
--payment-verification-key-file pay.vkey \
--staking-verification-key-file stake.vkey \
> stake.base
# First we need to generate the stake address registration
# certificate using the stake verification key
############################################################
cardano-cli shelley stake-address registration-certificate \
--staking-verification-key-file stake.vkey \
--out-file stake.cert
cat stake.cert
cbor-hex:
18b482008200582032a8c3f17ae5dafc3e947f82b0b418483f0a8680def9418c87397f2bd3d35efb
# 18 B4 # unsigned(180)
#
#82 # array(2)
# 00 # unsigned(0)
# 82 # array(2)
# 00 # unsigned(0)
# 58 20 # bytes(32)
# 32A8C3F17AE5DAFC3E947F82B0B418483F0A8680DEF9418C87397F2BD3D35EFB
# "2\xA8\xC3\xF1z\xE5\xDA\xFC>\x94\x7F\x82\xB0\xB4\x18H?\n\x86\x80\xDE\xF9A\x8C\x879\x7F+\xD3\xD3^\xFB"
The delegate's staking key needs to be registered in the blockchain, which just need a simple transaction using any payment address.
Keep, in mind that the any stake key registration certificates needs a deposit for the costs of tracking the key and the corresponding reward account. Also, it does not require any witness to register the certificate, but only the witness for the fees from the input of the transaction.
# Get param files
export CARDANO_NODE_SOCKET_PATH=/opt/cardano/fnf/sockets/node0.socket
cardano-cli shelley query protocol-parameters \
--testnet-magic 42 \
--out-file params.json
# 3. Calc tx fee
# You need only one singing keys included in fee calculation:
# 1. the `payment` address signing key of the input
# as the stake key reg cert does not need witness
# One UtxO is enough for the change, but I will move some fund from genesis to the delegates address
FEE=$(cardano-cli shelley transaction calculate-min-fee \
--protocol-params-file params.json \
--certificate stake.cert \
--tx-in-count 1 \
--tx-out-count 2 \
--ttl 500000 \
--testnet-magic 42 \
--signing-key-file /opt/cardano/fnf/addresses/genesis.skey \
| awk '{ print $2}')
# I will use the the genesis address as input for paying the fee.
#################################################################
FROM=$( cat /opt/cardano/fnf/addresses/genesis.addr )
# i.e. FROM=617190446876aed298ee207c6b5a335e832e2169a060b8167ef3ba9caff6fa3393
TX=$(cardano-cli shelley query utxo --testnet-magic 42 --address "$FROM" | grep "^[^- ]" | sort -k 2n | tail -1)
UTXO=$( echo "$TX" | awk '{ print $1 }')
ID=$( echo "$TX" | awk '{ print $2 }')
BALANCE=$( echo "$TX" | awk '{ print $3 }')
INPUT="${UTXO}#${ID}"
# This 500K ADA amount is going to the delegates UtxO style address for its delegated stakes
TO=$(cat pay.addr)
AMOUNT=500000000000
OUTPUT1="${FROM}+${CHANGE}"
OUTPUT2="${TO}+${AMOUNT}"
# It also needs a key deposit specified in the genesis e.g.
# grep keyD
# "keyDeposit": 400000,
# "keyDecayRate": 0, Means the key won't decay, i.e. all money will
# get back when the key is de0registered from the chain
KEYDEP=400000
# This means that change will less by 400K Lovelace that will be
# probably (need to check) taken by the treasury
CHANGE=$(( $BALANCE - $FEE - $AMOUNT - $KEYDEP ))
echo "Balance: $BALANCE, Amount: "$AMOUNT", Change: $CHANGE, runTxCalculateMinFee: $FEE"
echo "Input : $INPUT"
echo "Output1: $OUTPUT1"
echo "Output2: $OUTPUT2"
# Build
cardano-cli shelley transaction build-raw \
--tx-in "$INPUT" \
--tx-out "${FROM}+${CHANGE}" \
--tx-out "${TO}+${AMOUNT}" \
--ttl 500000 \
--fee "$FEE" \
--tx-body-file stake-cert-tx
# Sign
cardano-cli shelley transaction sign \
--tx-body-file stake-cert-tx \
--signing-key-file /opt/cardano/fnf/addresses/genesis.skey \
--signing-key-file stake.skey \
--tx-file stake-cert-tx \
--testnet-magic 42
# Submit
# Wait some minutes
# Get the stake address
# cut -c 9- stake.addr
# 32a8c3f17ae5dafc3e947f82b0b418483f0a8680def9418c87397f2bd3d35efb
STAKE_ADDR=$( cut -c 9- stake.addr )
# Before
export CARDANO_NODE_SOCKET_PATH=/opt/cardano/fnf/sockets/node0.socket
cardano-cli shelley query ledger-state --testnet-magic 42 | grep "$STAKE_ADDR"
cardano-cli shelley transaction submit \
--tx-file signed-stake-key-registration.tx \
--testnet-magic 42
# After
cardano-cli shelley query ledger-state --testnet-magic 42 | grep "$STAKE_ADDR"
# "contents": "32a8c3f17ae5dafc3e947f82b0b418483f0a8680def9418c87397f2bd3d35efb"
# "contents": "32a8c3f17ae5dafc3e947f82b0b418483f0a8680def9418c87397f2bd3d35efb"
# "contents": "32a8c3f17ae5dafc3e947f82b0b418483f0a8680def9418c87397f2bd3d35efb"
# Ready to delegate now.
# You can use aither some pool from the google's spreadsheet
echo "type: Node operator verification key
title: Stake pool operator key
cbor-hex:
5820<the 32 bytes length of the pool's operational verification key from the google sheet without the 5820 CBOR tag.>
" > pool.vkey
# or delegate to your own pool by getting its `operational verifycation key` (the cold key)
# !! BE AWARE!! that the `stake.key` must have been already registered on the chain.
cardano-cli shelley stake-address delegation-certificate \
--staking-verification-key-file stake.vkey \
--stake-pool-verification-key-file ~/cold-keys/pool.vkey \
--out-file pool-delegation.cert
####################################################################
####################################################################
# Calculate the minimum fee.
cardano-cli shelley transaction calculate-min-fee \
--tx-in-count 1 \
--tx-out-count 1 \
--ttl 500000 \
--testnet-magic 42 \
--signing-key-file pay.skey \
--signing-key-file stake.skey \
--certificate pool-delegation.cert \
--protocol-params-file params.json
# runTxCalculateMinFee: 172805
FEE=172805
# Get the intput and balance
cardano-cli shelley query utxo --testnet-magic 42 --address $(cat stake.base)
# TxHash TxIx Lovelace
#----------------------------------------------------------------------------------------
#1c089abfd6d56c73ac57aa94c403991041a383956f1f8fd4141a8e03a678a24c 0 499999260330
INPUT="1c089abfd6d56c73ac57aa94c403991041a383956f1f8fd4141a8e03a678a24c#0"
BAL=499999260330
CHANGE=$(( $BAL - $FEE))
# The new `base address`
OUTPUT="$( cat stake.base)+$CHANGE"
# Build
# Input: Your `base` payment address e.g. `stake.base` with "0x01...."
# Output: change back to the base address.
cardano-cli shelley transaction build-raw \
--tx-in "$INPUT" \
--tx-out "$OUTPUT" \
--ttl 500000 \
--fee "$FEE" \
--tx-body-file pool-delegation.tx \
--certificate pool-delegation.cert
# Sign
# You need 2 signing keys
# 1. the `pay.skey` for wittness the input and
# 2. the `staking signing key` for signing the delegation certificate.
cardano-cli shelley transaction sign \
--tx-body-file pool-delegation.tx \
--signing-key-file stake.skey \
--signing-key-file pay.skey \
--testnet-magic 42 \
--tx-file signed-pool-delegation.tx
# Before
# Submit:
cardano-cli shelley transaction submit \
--tx-file signed-pool-delegation.tx \
--testnet-magic 42
# Done As less money is there.
# you need to wait two epochs to be receiving rewards
cardano-cli shelley query utxo --testnet-magic 42 --address $(cat stake.base)
# TxHash TxIx Lovelace
#----------------------------------------------------------------------------------------
#ba544d056f94e559076c0c7a0406f37ed7182a6d0fdc0cf2569498353f9dd797 0 499999087525