Stake address registration
To integrate the latest (Conway) era, which differs significantly from previous eras, cardano-cli
has introduced <era>
as a top-level command, replacing the former <era>
flags. For example, instead of using era-specific flags like --babbage-era
with commands such as cardano-cli transaction build --babbage-era
, users must now utilize the syntax cardano-cli <era> transaction build <options>
.
Registering a stake address
To participate in the protocol, such as delegating stake to a stake pool to earn rewards or, in the Conway era, delegating stake to a delegate representative, you must first register your stake credentials on the chain. This registration is accomplished by submitting a stake address registration certificate within a transaction. The process includes paying a deposit, the amount of which is determined by the stakeAddressDeposit
protocol parameter. You can get the deposit back when you submit a stake address deregistration certificate.
Delegating to a stake pool also involves submitting a certificate to the chain, in this case, a stake address delegation certificate.
You can easily generate such certificates with cardano-cli
. The corresponding commands can be found under cardano-cli latest stake-address
:
cardano-cli latest stake-address
Usage: cardano-cli latest stake-address
( key-gen
| key-hash
| build
| registration-certificate
| deregistration-certificate
| stake-delegation-certificate
| stake-and-vote-delegation-certificate
| vote-delegation-certificate
| registration-and-delegation-certificate
| registration-and-vote-delegation-certificate
| registration-stake-and-vote-delegation-certificate
)
Stake address commands.
Generating the stake address registration certificate
Query the protocol parameters to find out the amount of lovelace required as a deposit for registering a stake address, in this case, it is 2000000 lovelace (two ada):
cardano-cli latest query protocol-parameters | jq .stakeAddressDeposit
2000000
To generate the registration certificate, run:
cardano-cli latest stake-address registration-certificate \
--stake-verification-key-file stake.vkey \
--key-reg-deposit-amt 2000000 \
--out-file registration.cert
The 'cborHex' field encodes the details of the certificate:
cat registration.cert
{
"type": "CertificateShelley",
"description": "Stake Address Registration Certificate",
"cborHex": "82008200581c521da955ad8f24bdff8d3cb8f5a155c49870037019fcdf20949e7e5e"
}
Submitting the stake address registration certificate in a transaction
To submit the registration certificate, you need to build, sign, and submit a transaction. You can use either the build
or build-raw
commands. In any case, you need to use the --certificate-file
flag to include the registration.cert
in the transaction body.
It's important to note that when using build
, the deposit is automatically included, and the transaction is balanced accordingly. However, when using build-raw
, you must manually include the deposit. Below, you'll find examples of both methods.
Using the build
command
cardano-cli latest transaction build \
--tx-in $(cardano-cli latest query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \
--change-address $(< payment.addr) \
--certificate-file registration.cert \
--out-file tx.raw
With the build
command, you don't need to worry about the transaction fees and deposit, it handles it automatically:
Inspecting the tx.raw
file reveals that this transaction includes the certificate, and is ready to be signed and submitted.
cardano-cli debug transaction view --tx-file tx.raw
{
"auxiliary scripts": null,
"certificates": [
{
"stake address registration": {
"keyHash": "521da955ad8f24bdff8d3cb8f5a155c49870037019fcdf20949e7e5e"
}
}
],
"collateral inputs": [],
"era": "Babbage",
"fee": "166733 Lovelace",
"inputs": [
"055c758abcc64653f106a55c42d4ff23d6b96e46b73c42a4f830a0aee2ffab11#0"
],
"metadata": null,
"mint": null,
"outputs": [
{
"address": "addr_test1qp9khgeajxw8snjjvaaule727hpytrvpsnq8z7h9t3zeue2jrk54ttv0yj7llrfuhr66z4wynpcqxuqeln0jp9y70e0qvjewan",
"address era": "Shelley",
"amount": {
"lovelace": 9997668118
},
"network": "Testnet",
"payment credential key hash": "4b6ba33d919c784e52677bcfe7caf5c2458d8184c0717ae55c459e65",
"reference script": null,
"stake reference": {
"stake credential key hash": "521da955ad8f24bdff8d3cb8f5a155c49870037019fcdf20949e7e5e"
}
}
],
"reference inputs": [],
"required signers (payment key hashes needed for scripts)": null,
"return collateral": null,
"total collateral": null,
"update proposal": null,
"validity range": {
"lower bound": null,
"upper bound": null
},
"withdrawals": null,
"witnesses": []
}
Using the build-raw
command
Using the build-raw
command involves a slightly more intricate process. Similarly to the steps outlined in simple transactions, you should calculate the fee yourself, and handle the deposit accordingly.
Query the balance of the payment.addr
:
cardano-cli latest query utxo --address $(< paymentstake.addr)
TxHash TxIx Amount
--------------------------------------------------------------------------------------
0690c70f117281627fc128ede51b1fe762c2bbc15c2e3d4eff2101c9d2613cd8 0 9999834851 lovelace + TxOutDatumNone
You can leverage jq
by having cardano-cli
return the output in JSON:
cardano-cli latest query utxo --address $(< paymentstake.addr) --output-json
{
"0690c70f117281627fc128ede51b1fe762c2bbc15c2e3d4eff2101c9d2613cd8#0": {
"address": "addr_test1qp9khgeajxw8snjjvaaule727hpytrvpsnq8z7h9t3zeue2jrk54ttv0yj7llrfuhr66z4wynpcqxuqeln0jp9y70e0qvjewan",
"datum": null,
"datumhash": null,
"inlineDatum": null,
"referenceScript": null,
"value": {
"lovelace": 9999834851
}
}
}
Using jq
to parse that JSON
cardano-cli latest query utxo --address $(< payment.addr) --output-json | jq -r .[].value.lovelace
9999834851
Query the protocol parameters:
cardano-cli latest query protocol parameters --out-file pparams.json
Draft the transaction to calculate its transaction fee:
cardano-cli latest transaction build-raw \
--tx-in $(cardano-cli latest query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \
--tx-out $(< payment.addr)+"$(cardano-cli latest query utxo --address $(< payment.addr) --out-file /dev/stdout | jq -r .[].value.lovelace)" \
--fee 0 \
--certificate-file registration.cert \
--out-file tx.draft
Calculate the transaction fee, it is useful to assign the output to a variable (fee
):
cardano-cli latest transaction calculate-min-fee \
--tx-body-file tx.draft \
--protocol-params-file pparams.json \
--tx-in-count 1 \
--tx-out-count 1 \
--witness-count 1
>171089 Lovelace
Calculate the change of the transaction. Note that the deposit is not explicitly included, instead, you should deduct the deposit amount (2000000 lovelace) from the change Change = currentBalance - fee - deposit:
Query the protocol parameters to get the deposit amount:
cardano-cli latest query protocol-parameters | jq .stakeAddressDeposit
2000000
Query the current balance of payment.addr
:
cardano-cli latest query utxo --address $(< payment.addr) --output-json | jq -r .[].value.lovelace
9999834851
change=$((9999834851 - 171089 - 2000000))
Build the transaction:
cardano-cli latest transaction build-raw \
--tx-in $(cardano-cli latest query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \
--tx-out $(< payment.addr)+$change \
--fee 171089 \
--certificate-file registration.cert \
--out-file tx.raw
Sign and submit the transaction
cardano-cli latest transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--signing-key-file stake.skey \
--out-file tx.signed
cardano-cli latest transaction submit \
--tx-file tx.signed