# Create Stakepool on Testnet

## 1. Install Cabal, GHC and Set PATH

Update packages and install Ubuntu dependencies:

```
sudo apt-get update -y
sudo apt-get upgrade -y
GETPKG_LIST="aptitude autoconf bc build-essential curl g++ git gnupg htop jq libffi-dev libgmp-dev libncursesw5 libpq-dev libsystemd-dev libssl-dev libtinfo-dev libtinfo-dev libtool make pkg-config rsync secure-delete tcptraceroute tmux wget zlib1g-dev"
sudo apt-get -y install ${GETPKG_LIST}
```

Install Libsodium:

```bash
mkdir $HOME/git
cd $HOME/git
git clone https://github.com/input-output-hk/libsodium
cd libsodium
git checkout 66f017f1
./autogen.sh
./configure
make
sudo make install
```

Install Cabal:

```bash
cd
wget https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz
tar -xf cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz
rm cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz cabal.sig
mkdir -p $HOME/.local/bin
mv cabal $HOME/.local/bin/
```

Install GHC:

```bash
wget https://downloads.haskell.org/~ghc/8.6.5/ghc-8.6.5-x86_64-deb9-linux.tar.xz
tar -xf ghc-8.6.5-x86_64-deb9-linux.tar.xz
rm ghc-8.6.5-x86_64-deb9-linux.tar.xz
cd ghc-8.6.5
./configure
sudo make install
```

Update PATH to include Cabal and GHC and add exports. Your node's location will be in $NODE\_HOME. The cluster configuration is set by $NODE\_CONFIG and $NODE\_BUILD\_NUM.

```bash
echo PATH="$HOME/.local/bin:$PATH" >> $HOME/.bashrc
echo export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" >> $HOME/.bashrc
echo export NODE_HOME=$HOME/cardano-my-node >> $HOME/.bashrc
echo export NODE_CONFIG=testnet>> $HOME/.bashrc
echo export NODE_BUILD_NUM=$(curl https://hydra.iohk.io/job/Cardano/iohk-nix/cardano-deployment/latest-finished/download/1/index.html | grep -e "build" | sed 's/.*build\/\([0-9]*\)\/download.*/\1/g') >> $HOME/.bashrc
source $HOME/.bashrc
```

Update cabal and verify the correct versions were installed successfully.

```bash
cabal update
cabal -V
ghc -V
```

## 9. Generate block producer keys

{% hint style="danger" %}
**Testnet** ADA do not have value and to ease the build all commands are assumed to be run on BP (Block Producer) node.   **Do not do this on your production stake pool.**&#x20;
{% endhint %}

The block-producer node requires you to create 3 keys as defined in the [Shelley ledger specs](https://hydra.iohk.io/build/2473732/download/1/ledger-spec.pdf):

1. stake pool cold key (`node.cert`)
2. stake pool hot key (`kes.skey`)
3. stake pool VRF key (`vrf.skey`)

First, make a KES key pair.

```bash
cd $NODE_HOME
cardano-cli shelley node key-gen-KES \
    --verification-key-file kes.vkey \
    --signing-key-file kes.skey
```

{% hint style="info" %}
KES (key evolving signature) keys are created to secure your stake pool against hackers who might compromise your keys.&#x20;

**On mainnet, you will need to regenerate the KES key every 90 days.**
{% endhint %}

{% hint style="danger" %}
**Cold keys** **must be generated and stored on your air-gapped offline machine.** The cold keys are the files stored in `$HOME/cold-keys.`
{% endhint %}

```bash
mkdir $HOME/cold-keys
pushd $HOME/cold-keys
```

Make a set of cold keys and create the cold counter file.

on Airgap

```bash
cardano-cli shelley node key-gen \
    --cold-verification-key-file node.vkey \
    --cold-signing-key-file node.skey \
    --operational-certificate-issue-counter node.counter
```

{% hint style="warning" %}
Be sure to **back up your all your keys** to another secure storage device. Make multiple copies.
{% endhint %}

{% tabs %}
{% tab title="BP" %}

```
pushd +1
slotsPerKESPeriod=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r '.slotsPerKESPeriod')
echo slotsPerKESPeriod: ${slotsPerKESPeriod}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Before continuing, your node must be fully synchronized to the blockchain. Otherwise, you won't calculate the latest KES period.&#x20;

Your node is synchronized when the *epoch* and *slot#* is equal to that found on a block explorer <https://explorer.cardano-testnet.iohkdev.io/en/browse-blocks>

{% endhint %}

```
slotNo=$(cardano-cli shelley query tip --testnet-magic 1097911063| jq -r '.slotNo')
echo slotNo: ${slotNo}
```

Find the kesPeriod by dividing the slot tip number by the slotsPerKESPeriod.

```
kesPeriod=$((${slotNo} / ${slotsPerKESPeriod}))
echo kesPeriod: ${kesPeriod}
startKesPeriod=$(( ${kesPeriod} - 1 ))
echo startKesPeriod: ${startKesPeriod}
```

With this calculation, you can generate a operational certificate for your pool.&#x20;

Copy **kes.vkey** to your **cold environment**.&#x20;

Change the **startKesPeriod** value accordingly.

{% hint style="info" %}
Stake pool operators must provide an operational certificate to verify that the pool has the authority to run. The certificate includes the operator’s signature, and includes key information about the pool (addresses, keys, etc.). Operational certificates represent the link between the operator’s offline key and their operational key.
{% endhint %}

```
cardano-cli shelley node issue-op-cert \
    --kes-verification-key-file kes.vkey \
    --cold-signing-key-file $HOME/cold-keys/node.skey \
    --operational-certificate-issue-counter $HOME/cold-keys/node.counter \
    --kes-period $startKesPeriod \
    --out-file node.cert
```

Copy **node.cert** to your **hot environment**.

Make a VRF key pair

Open a new terminal window and stop your **BP node** by running the following:

```
killall cardano-node
```

Update your BP startup script with the new KES, VRF and Operation Certificate.

```
cat > $NODE_HOME/startBlockProducingNode.sh << EOF 
DIRECTORY=\$NODE_HOME
PORT=9000
HOSTADDR=0.0.0.0
TOPOLOGY=\${DIRECTORY}/${NODE_CONFIG}-topology.json
DB_PATH=\${DIRECTORY}/db
SOCKET_PATH=\${DIRECTORY}/db/socket
CONFIG=\${DIRECTORY}/${NODE_CONFIG}-config.json
KES=\${DIRECTORY}/kes.skey
VRF=\${DIRECTORY}/vrf.skey
CERT=\${DIRECTORY}/node.cert
cardano-node run --topology \${TOPOLOGY} --database-path \${DB_PATH} --socket-path \${SOCKET_PATH} --host-addr \${HOSTADDR} --port \${PORT} --config \${CONFIG} --shelley-kes-key \${KES} --shelley-vrf-key \${VRF} --shelley-operational-certificate \${CERT}
EOF
```

{% hint style="info" %}
To operate a stake pool, you need the KES, VRF key and Operational Certificate. Cold keys generate new operational certificates periodically.
{% endhint %}

Now start your block producer node.

```
cd $NODE_HOME
./startBlockProducingNode.sh
```

## 10. Setup payment and stake keys

To create our transaction we will need the protocol parameters, so let’s query the parameters and save them in params.json

```
cardano-cli shelley query protocol-parameters \
    --testnet-magic 1097911063 \
    --out-file params.json
```

{% hint style="info" %}
Payment keys are used to send and receive payments and stake keys are used to manage stake delegations.
{% endhint %}

Create a new payment key pair: payment.skey & payment.vkey

```
###
### On BP node machine,
###
cd $NODE_HOME
cardano-cli shelley address key-gen \
    --verification-key-file payment.vkey \
    --signing-key-file payment.skey
```

Create a new stake address key pair: stake.skey & stake.vkey.

```
###
### On air-gapped offline machine,
###
cardano-cli shelley stake-address key-gen \
    --verification-key-file stake.vkey \
    --signing-key-file stake.skey
```

Create your stake address from the stake address verification key and store it in stake.addr

```
###
### On air-gapped offline machine,
###
cardano-cli shelley stake-address build \
    --stake-verification-key-file stake.vkey \
    --out-file stake.addr \
    --testnet-magic 1097911063
```

Build a payment address for the payment key payment.vkey which will delegate to the stake address, stake.vkey

```
###
### On air-gapped offline machine,
###
cardano-cli shelley address build \
    --payment-verification-key-file payment.vkey \
    --stake-verification-key-file stake.vkey \
    --out-file payment.addr \
    --testnet-magic 1097911063
```

Next step is to fund your payment address.  Fill in the form below with your payment.addr

<https://docs.google.com/forms/d/1BmPI3PsBChSIrpKBgroOjscRXe1vI7iQDFLNGVR6y2o/>

Before continuing, your nodes must be fully synchronized to the blockchain. Otherwise, you won't see your funds.

After funding your account, check your payment address balance.

```
cardano-cli shelley query utxo \
    --address $(cat payment.addr) \
    --testnet-magic 1097911063
```

You should see output similar to this. This is your unspent transaction output (UXTO).

```
                           TxHash                                 TxIx        Lovelace
----------------------------------------------------------------------------------------
c69b3e652fa237875a2c13593c3585dcd87f29233d746dd6697159c4fba17e83     0         997820683
```

## 11. Register your stake address

Create a certificate, `stake.cert`, using the `stake.vkey`

```bash
cardano-cli shelley stake-address registration-certificate \
    --stake-verification-key-file stake.vkey \
    --out-file stake.cert
```

You need to find the **tip** of the blockchain to set the **ttl** parameter properly.

```bash
currentSlot=$(cardano-cli shelley query tip --testnet-magic 1097911063 | jq -r '.slotNo')
echo Current Slot: $currentSlot
```

Find your balance and **UTXOs**.

```bash
cardano-cli shelley query utxo \
    --address $(cat payment.addr) \
    --testnet-magic 1097911063 > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out

cat balance.out

tx_in=""
total_balance=0
while read -r utxo; do
    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
    idx=$(awk '{ print $2 }' <<< "${utxo}")
    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
    total_balance=$((${total_balance}+${utxo_balance}))
    echo TxHash: ${in_addr}#${idx}
    echo ADA: ${utxo_balance}
    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}
```

Find the keyDeposit value.

```bash
keyDeposit=$(cat $NODE_HOME/params.json | jq -r '.keyDeposit')
echo keyDeposit: $keyDeposit
```

{% hint style="info" %}
Registration of a stake address certificate (keyDeposit) costs 2000000 lovelace.
{% endhint %}

Run the build-raw transaction command

{% hint style="info" %}
The **ttl** value must be greater than the current tip. In this example, we use current slot + 10000.
{% endhint %}

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+0 \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee 0 \
    --out-file tx.tmp \
    --certificate stake.cert
```

Calculate the current minimum fee:

```bash
fee=$(cardano-cli shelley transaction calculate-min-fee \
    --tx-body-file tx.tmp \
    --tx-in-count ${txcnt} \
    --tx-out-count 1 \
    --testnet-magic 1097911063 \
    --witness-count 2 \
    --byron-witness-count 0 \
    --protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee
```

{% hint style="info" %}
Ensure your balance is greater than cost of fee + keyDeposit or this will not work.
{% endhint %}

Calculate your change output.

```bash
txOut=$((${total_balance}-${keyDeposit}-${fee}))
echo Change Output: ${txOut}
```

Build your transaction which will register your stake address.&#x20;

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${txOut} \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee ${fee} \
    --certificate-file stake.cert \
    --out-file tx.raw
```

Sign the transaction with both the payment and stake secret keys.&#x20;

```bash
cardano-cli shelley transaction sign \
    --tx-body-file tx.raw \
    --signing-key-file payment.skey \
    --signing-key-file stake.skey \
    --testnet-magic 1097911063 \
    --out-file tx.signed
```

Sign transaction.

```bash
cardano-cli shelley transaction submit \
    --tx-file tx.signed \
    --testnet-magic 1097911063
```

## 12. Register your stakepool

Create your pool's metadata with a JSON file. Update with your pool information.

{% hint style="info" %}
**ticker** must be between 3-5 characters in length. Characters must be A-Z and 0-9 only. d**escription** cannot exceed 255 characters in length.
{% endhint %}

```bash
cat > poolMetaData.json << EOF
{
"name": "MyPoolName",
"description": "My pool description",
"ticker": "MPN",
"homepage": "https://myadapoolnamerocks.com"
}
EOF
```

Calculate the hash of your metadata file.

```bash
cardano-cli shelley stake-pool metadata-hash --pool-metadata-file poolMetaData.json > poolMetaDataHash.txt
```

Now upload your poolMetaData.json to your website or a public website such as <https://pages.github.com/>

Find the minimum pool cost.

```bash
minPoolCost=$(cat $NODE_HOME/params.json | jq -r .minPoolCost)
echo minPoolCost: ${minPoolCost}
```

{% hint style="info" %}
minPoolCost is 340000000 lovelace or 340 ADA. Therefore, your `--pool-cost` must be at a minimum this amount.
{% endhint %}

```bash
cardano-cli shelley stake-pool registration-certificate \
    --cold-verification-key-file $HOME/cold-keys/node.vkey \
    --vrf-verification-key-file vrf.vkey \
    --pool-pledge 100000000000 \
    --pool-cost 340000000 \
    --pool-margin 0.01 \
    --pool-reward-account-verification-key-file stake.vkey \
    --pool-owner-stake-verification-key-file stake.vkey \
    --testnet-magic 1097911063 \
    --pool-relay-ipv4 81.108.149.100 \
    --pool-relay-port 9001 \
    --metadata-url <url where you uplaoded poolMetaData.json> \
    --metadata-hash $(cat poolMetaDataHash.txt) \
    --out-file pool.cert
```

Pledge stake to your stake pool.

```bash
cardano-cli shelley stake-address delegation-certificate \
    --stake-verification-key-file stake.vkey \
    --cold-verification-key-file $HOME/cold-keys/node.vkey \
    --out-file deleg.cert
```

You need to find the **tip** of the blockchain to set the **ttl** parameter properly.

```bash
currentSlot=$(cardano-cli shelley query tip --testnet-magic 1097911063 | jq -r '.slotNo')
echo Current Slot: $currentSlot
```

Find your balance and **UTXOs**.

```bash
cardano-cli shelley query utxo \
    --address $(cat payment.addr) \
    --testnet-magic 1097911063 > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out

cat balance.out

tx_in=""
total_balance=0
while read -r utxo; do
    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
    idx=$(awk '{ print $2 }' <<< "${utxo}")
    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
    total_balance=$((${total_balance}+${utxo_balance}))
    echo TxHash: ${in_addr}#${idx}
    echo ADA: ${utxo_balance}
    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}
```

Find the keyDeposit value.

```bash
poolDeposit=$(cat $NODE_HOME/params.json | jq -r '.poolDeposit')
echo poolDeposit: $poolDeposit
```

{% hint style="info" %}
Registration of a stake address certificate (keyDeposit) costs 500000000 lovelace.
{% endhint %}

Run the build-raw transaction command

{% hint style="info" %}
The **ttl** value must be greater than the current tip. In this example, we use current slot + 10000.&#x20;
{% endhint %}

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+$(( ${total_balance} - ${poolDeposit}))  \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee 0 \
    --certificate-file pool.cert \
    --certificate-file deleg.cert \
    --out-file tx.tmp
```

Calculate the current minimum fee:

```bash
fee=$(cardano-cli shelley transaction calculate-min-fee \
    --tx-body-file tx.tmp \
    --tx-in-count ${txcnt} \
    --tx-out-count 1 \
    --testnet-magic 1097911063 \
    --witness-count 3 \
    --byron-witness-count 0 \
    --protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee
```

{% hint style="info" %}
Ensure your balance is greater than cost of fee + minPoolCost or this will not work.
{% endhint %}

Calculate your change output.

```bash
txOut=$((${total_balance}-${poolDeposit}-${fee}))
echo txOut: ${txOut}
```

Build your transaction:&#x20;

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${txOut} \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee ${fee} \
    --certificate-file pool.cert \
    --certificate-file deleg.cert \
    --out-file tx.raw
```

Sign the transaction with both the payment and stake secret keys.&#x20;

```bash
cardano-cli shelley transaction sign \
    --tx-body-file tx.raw \
    --signing-key-file payment.skey \
    --signing-key-file $HOME/cold-keys/node.skey \
    --signing-key-file stake.skey \
    --testnet-magic 1097911063 \
    --out-file tx.signed
```

Sign transaction.

```bash
cardano-cli shelley transaction submit \
    --tx-file tx.signed \
    --testnet-magic 1097911063
```

## 14. Configure your topology files

{% hint style="info" %}
Shelley has been launched without peer-to-peer (p2p) node discovery so that means we will need to manually add trusted nodes in order to configure our topology. This is a **critical step** as skipping this step will result in your minted blocks being orphaned by the rest of the network.
{% endhint %}

Publishing your Relay Node with topologyUpdater.sh

{% hint style="info" %}
This code has been taken from github and all credit to the developer. <https://gist.github.com/gufmar/7e1bc16f8df62af953567a373d6a8f72>
{% endhint %}

Create the topologyUpdater.sh script which publishes your node information to a topology fetch list.

```
###
### On relaynode1
###
cat > $NODE_HOME/topologyUpdater.sh << EOF
#!/bin/bash
# shellcheck disable=SC2086,SC2034
 
USERNAME=$(whoami)
CNODE_PORT=9001 # must match your relay node port as set in the startup command
CNODE_HOSTNAME="CHANGE ME"  # optional. must resolve to the IP you are requesting from
CNODE_BIN="/usr/local/bin"
CNODE_HOME=$NODE_HOME
CNODE_LOG_DIR="\${CNODE_HOME}/logs"
GENESIS_JSON="\${CNODE_HOME}/${NODE_CONFIG}-shelley-genesis.json"

###########################################

NETWORKID=\$(jq -r .networkId \$GENESIS_JSON)
CNODE_VALENCY=1   # optional for multi-IP hostnames
NWMAGIC=\$(jq -r .networkMagic < \$GENESIS_JSON)
[[ "\${NETWORKID}" = "Mainnet" ]] && HASH_IDENTIFIER="--mainnet" || HASH_IDENTIFIER="--testnet-magic \${NWMAGIC}"
[[ "\${NWMAGIC}" = "764824073" ]] && NETWORK_IDENTIFIER="--mainnet" || NETWORK_IDENTIFIER="--testnet-magic \${NWMAGIC}"
 
export PATH="\${CNODE_BIN}:\${PATH}"
export CARDANO_NODE_SOCKET_PATH="\${CNODE_HOME}/db/socket"
 
blockNo=\$(cardano-cli shelley query tip \${NETWORK_IDENTIFIER} | jq -r .blockNo )
 
# Note:
# if you run your node in IPv4/IPv6 dual stack network configuration and want announced the
# IPv4 address only please add the -4 parameter to the curl command below  (curl -4 -s ...)
if [ "\${CNODE_HOSTNAME}" != "CHANGE ME" ]; then
  T_HOSTNAME="&hostname=\${CNODE_HOSTNAME}"
else
  T_HOSTNAME=''
fi

if [ ! -d \${CNODE_LOG_DIR} ]; then
  mkdir -p \${CNODE_LOG_DIR};
fi
 
curl -s "https://api.clio.one/htopology/v1/?port=\${CNODE_PORT}&blockNo=\${blockNo}&valency=\${CNODE_VALENCY}&magic=\${NWMAGIC}\${T_HOSTNAME}" | tee -a \$CNODE_LOG_DIR/topologyUpdater_lastresult.json
EOF
```

Add permissions and run the updater script.

```
###
### On relaynode1
###
cd $NODE_HOME
chmod +x topologyUpdater.sh
./topologyUpdater.sh
```

Update your relay node topology files

Create relay-topology\_pull.sh script which fetches your relay node buddies and updates your topology file. Update with your block producer's public IP address.

```
###
### On relaynode1
###
cat > $NODE_HOME/relay-topology_pull.sh << EOF
#!/bin/bash
BLOCKPRODUCING_IP=<BLOCK PRODUCERS PUBLIC IP ADDRESS>
BLOCKPRODUCING_PORT=6000
curl -s -o /home/test/cardano-my-node/testnet-topology.json "https://api.clio.one/htopology/v1/fetch/?max=15&magic=1097911063&customPeers=${BLOCKPRODUCING_IP}:${BLOCKPRODUCING_PORT}:1|relays-new.cardano-testnet.iohkdev.io:3001:2"
EOF
```

Add permissions and pull new topology files.

```
###
### On relaynode1
###
chmod +x relay-topology_pull.sh
./relay-topology_pull.sh
```

## 18.4 Changing the pledge, fee, margin, etc.

Find the minimum pool cost.

{% tabs %}
{% tab title="block producer node" %}

```bash
minPoolCost=$(cat $NODE_HOME/params.json | jq -r .minPoolCost)
echo minPoolCost: ${minPoolCost}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
minPoolCost is 340000000 lovelace or 340 ADA. Therefore, your `--pool-cost` must be at a minimum this amount.
{% endhint %}

If you're changing your poolMetaData.json, remember to calculate the hash of your metadata file and re-upload the updated poolMetaData.json file.&#x20;

{% tabs %}
{% tab title="block producer node" %}

```
cardano-cli shelley stake-pool metadata-hash --pool-metadata-file poolMetaData.json > poolMetaDataHash.txt
```

{% endtab %}
{% endtabs %}

Update the below registration-certificate transaction with your desired settings.

If you have **multiple relay nodes,** [**refer to section 12**](https://doc.love2stake.com/how-to-create-stake-pool/testnet/broken-reference) and change your parameters appropriately.

{% hint style="warning" %}
**metadata-url** must be no longer than 64 characters.
{% endhint %}

{% tabs %}
{% tab title="air-gapped offline machine" %}

```bash
cardano-cli shelley stake-pool registration-certificate \
    --cold-verification-key-file $HOME/cold-keys/node.vkey \
    --vrf-verification-key-file vrf.vkey \
    --pool-pledge 100000000000 \
    --pool-cost 340000000 \
    --pool-margin 0.01 \
    --pool-reward-account-verification-key-file stake.vkey \
    --pool-owner-stake-verification-key-file stake.vkey \
    --testnet-magic 1097911063 \
    --pool-relay-ipv4 81.108.149.100 \
    --pool-relay-port 9001 \
    --metadata-url <url where you uplaoded poolMetaData.json> \
    --metadata-hash $(cat poolMetaDataHash.txt) \
    --out-file pool.cert
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Here we are pledging 1000 ADA with a fixed pool cost of 345 ADA and a pool margin of 20%.&#x20;
{% endhint %}

Pledge stake to your stake pool.

{% tabs %}
{% tab title="air-gapped offline machine" %}

```
cardano-cli shelley stake-address delegation-certificate \
    --stake-verification-key-file stake.vkey \
    --cold-verification-key-file $HOME/cold-keys/node.vkey \
    --out-file deleg.cert
```

{% endtab %}
{% endtabs %}

Copy **deleg.cert** to your **hot environment.**

You need to find the **tip** of the blockchain to set the **ttl** parameter properly.

{% tabs %}
{% tab title="block producer node" %}

```bash
currentSlot=$(cardano-cli shelley query tip  --testnet-magic 1097911063 | jq -r '.slotNo')
echo Current Slot: $currentSlot
```

{% endtab %}
{% endtabs %}

Find your balance and **UTXOs**.

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley query utxo \
    --address $(cat payment.addr) \
     --testnet-magic 1097911063 > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out

cat balance.out

tx_in=""
total_balance=0
while read -r utxo; do
    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
    idx=$(awk '{ print $2 }' <<< "${utxo}")
    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
    total_balance=$((${total_balance}+${utxo_balance}))
    echo TxHash: ${in_addr}#${idx}
    echo ADA: ${utxo_balance}
    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}
```

{% endtab %}
{% endtabs %}

Run the build-raw transaction command.

{% hint style="info" %}
The **ttl** value must be greater than the current tip. In this example, we use current slot + 10000.&#x20;
{% endhint %}

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${total_balance} \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee 0 \
    --certificate-file pool.cert \
    --certificate-file deleg.cert \
    --out-file tx.tmp
```

{% endtab %}
{% endtabs %}

Calculate the minimum fee:

{% tabs %}
{% tab title="block producer node" %}

```bash
fee=$(cardano-cli shelley transaction calculate-min-fee \
    --tx-body-file tx.tmp \
    --tx-in-count ${txcnt} \
    --tx-out-count 1 \
     --testnet-magic 1097911063 \
    --witness-count 3 \
    --byron-witness-count 0 \
    --protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee
```

{% endtab %}
{% endtabs %}

Calculate your change output.

{% tabs %}
{% tab title="block producer node" %}

```bash
txOut=$((${total_balance}-${fee}))
echo txOut: ${txOut}
```

{% endtab %}
{% endtabs %}

Build the transaction.&#x20;

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${txOut} \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee ${fee} \
    --certificate-file pool.cert \
    --certificate-file deleg.cert \
    --out-file tx.raw
```

{% endtab %}
{% endtabs %}

Copy **tx.raw** to your **cold environment.**

Sign the transaction.&#x20;

{% tabs %}
{% tab title="air-gapped offline machine" %}

```bash
cardano-cli shelley transaction sign \
    --tx-body-file tx.raw \
    --signing-key-file payment.skey \
    --signing-key-file $HOME/cold-keys/node.skey \
    --signing-key-file stake.skey \
     --testnet-magic 1097911063 \
    --out-file tx.signed
```

{% endtab %}
{% endtabs %}

Copy **tx.signed** to your **hot environment.**

Send the transaction.

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley transaction submit \
    --tx-file tx.signed \
     --testnet-magic 1097911063
```

{% endtab %}
{% endtabs %}

Changes take effect next epoch. After the next epoch transition, verify that your pool settings are correct.

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley query ledger-state  --testnet-magic 1097911063 --out-file ledger-state.json
jq -r '.esLState._delegationState._pstate._pParams."'"$(cat stakepoolid.txt)"'"  // 
```

{% endtab %}
{% endtabs %}

## 18.9 Send a simple transaction example

If you have not downloaded and install bech32 from <https://github.com/input-output-hk/bech32/releases>

```
mkdir $HOME/bech32
cd $HOME/bech32
wget https://github.com/input-output-hk/bech32/releases/download/v1.1.0/bech32-v1.1.0-linux64.tar.gz
tar -xzvf bech32-v1.1.0-linux64.tar.gz
chmod +x $HOME/bech32/bin/bech32
cd $NODE_HOME
```

Example sends **1000 ADA** to Love2Stake **address** &#x20;

First, find the **tip** of the blockchain to set the **ttl** parameter properly.

{% tabs %}
{% tab title="block producer node" %}

```bash
currentSlot=$(cardano-cli shelley query tip --testnet-magic 1097911063 | jq -r '.slotNo')
echo Current Slot: $currentSlot
```

{% endtab %}
{% endtabs %}

Set the amount to send in lovelaces. :sparkles: Remember **1 ADA** = **1,000,000 lovelaces.**

{% tabs %}
{% tab title="block producer node" %}

```bash
amountToSend=99000000000000
echo amountToSend: $amountToSend
```

{% endtab %}
{% endtabs %}

cho "daedalus-address" | bech32 addr\_test

Set the destination address which is where you're sending funds to.

{% tabs %}
{% tab title="block producer node" %}

```bash
testnetDaedalusAddress=addr1qzgc2yx9p55x50ggc3jvr8tfmahx23fvj2zqmqrvyg3he0z89uja3cpcdnpstavx5f37md2xuc03v84zkphz23djd62qdyu0u5
echo ${testnetDaedalusAddress} | destinationAddress=$HOME/bech32/bin/bech32
echo destinationAddress: $destinationAddress
```

{% endtab %}
{% endtabs %}

Find your balance and **UTXOs**.

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley query utxo \
    --address $(cat payment.addr) \
    --testnet-magic 1097911063 > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out

cat balance.out

tx_in=""
total_balance=0
while read -r utxo; do
    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
    idx=$(awk '{ print $2 }' <<< "${utxo}")
    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
    total_balance=$((${total_balance}+${utxo_balance}))
    echo TxHash: ${in_addr}#${idx}
    echo ADA: ${utxo_balance}
    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}
```

{% endtab %}
{% endtabs %}

Run the build-raw transaction command.

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+0 \
    --tx-out ${destinationAddress}+0 \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee 0 \
    --out-file tx.tmp    
```

{% endtab %}
{% endtabs %}

Calculate the current minimum fee:

{% tabs %}
{% tab title="block producer node" %}

```bash
fee=$(cardano-cli shelley transaction calculate-min-fee \
    --tx-body-file tx.tmp \
    --tx-in-count ${txcnt} \
    --tx-out-count 2 \
    --testnet-magic 1097911063 \
    --witness-count 1 \
    --byron-witness-count 0 \
    --protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee
```

{% endtab %}
{% endtabs %}

Calculate your change output.

{% tabs %}
{% tab title="block producer node" %}

```bash
txOut=$((${total_balance}-${fee}-${amountToSend}))
echo Change Output: ${txOut}
```

{% endtab %}
{% endtabs %}

Build your transaction.&#x20;

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${txOut} \
    --tx-out ${destinationAddress}+${amountToSend} \
    --ttl $(( ${currentSlot} + 10000)) \
    --fee ${fee} \
    --out-file tx.raw
```

{% endtab %}
{% endtabs %}

Copy **tx.raw** to your **cold environment.**

Sign the transaction with both the payment and stake secret keys.&#x20;

{% tabs %}
{% tab title="air-gapped offline machine" %}

```bash
cardano-cli shelley transaction sign \
    --tx-body-file tx.raw \
    --signing-key-file payment.skey \
    --testnet-magic 1097911063 \
    --out-file tx.signed
```

{% endtab %}
{% endtabs %}

Copy **tx.signed** to your **hot environment.**

Send the signed transaction.

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley transaction submit \
    --tx-file tx.signed \
    --testnet-magic 1097911063
```

{% endtab %}
{% endtabs %}

Check if the funds arrived.

{% tabs %}
{% tab title="block producer node" %}

```bash
cardano-cli shelley query utxo \
    --address ${destinationAddress} \
    --testnet-magic 1097911063
```

{% endtab %}
{% endtabs %}

You should see output similar to this showing the funds you sent.

```
                           TxHash                                 TxIx        Lovelace
----------------------------------------------------------------------------------------
100322a39d02c2ead....                                              0        1000000
```
