How Cardano UTxO Transactions work — From Theory to Practice

1. Introduction

The goal of this guide is to explain how blockchain transactions work with the UTxO model. The tutorial begins with a short theoretical introduction and ends with a practical example.

Image 1 — UTxO Example
  1. TX1 — from the cardano-cli wallet: once the 1000 tADAs from Faucet are available from the cardano-cli wallet, it’s time to do our custom transaction. In the example:
  • 200 tADAs will be sent to another Daedalus wallet
  • 700 tADAs minus the fees will be sent back to the cardano-cli wallet, like the rest.

1.1 Prerequisite for the practical example

  • Install Daedalus Testnet
  • The tutorial is based on macOS but can be easily adapted to Linux or Windows.
  • To better understand some commands would be better to know the basics of cryptography, like Asymmetric encryption.
  • Understand the basics of bash as variables, stdin, and stdout.

1.2 Macro-steps to submit transactions

The following are the macro-steps we’re going to do in the practical example:

  1. Build a transaction to an address without fees.
  2. Calculating fees.
  3. Build the same transaction again with fees.
  4. Signing the transaction.
  5. Submit the transaction into the blockchain.

2. Practical Example

2.1 Setting up the Cardano CLI (Command Line Interface)

Daedalus allows the computer to run a Cardano Node to interact with the blockchain through a User Interface and a command-line interface, the cardano-cli. The communication is permitted thanks to a socket file.

ps -ef | grep cardano-node
501 78957 78943   0 11:12AM ??        16:53.43 cardano-node run --socket-path cardano-node.socket --shutdown-ipc 3 --topology /Applications/Daedalus --database-path chain --port 56510 --config /Applications/Daedalus
501 78958 78943 0 11:12AM ?? 32:49.67 cardano-wallet serve --shutdown-handler --port 56511 --database
/Users/valeriomellini/Library/Application Support/Daedalus Testnet/wallets --tls-ca-cert
/Users/valeriomellini/Library/Application Support/Daedalus Testnet/tls/server/ca.crt --tls-sv-cert
/Users/valeriomellini/Library/Application Support/Daedalus Testnet/tls/server/server.crt --tls-sv-key
/Users/valeriomellini/Library/Application Support/Daedalus Testnet/tls/server/server.key --token-metadata-server[]( --sync-tolerance 300s --testnet /Applications/Daedalus --node-socket
Users/valeriomellini/Library/Application Support/Daedalus Testnet/cardano-node.socket
export CARDANO_NODE_SOCKET_PATH="/Users/$(YOUR_USER)/Library/Application Support/Daedalus Testnet/cardano-node.socket"export PATH=$PATH:"/Applications/Daedalus"
cardano-cli query tip --testnet-magic 1097911063
"hash": "6781b5c5d6f857e96cf854f4452859914fc299c7e7d0041f96c776329be89471",
"block": 2910987,
"slot": 37243969,
"syncProgress": "100.00",
"era": "Alonzo",
"epoch": 156
export magicnumber=1097911063
export fee=0

2.2 Creation of verification/signing key

To create a verification and signing key, run this command:

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

2.3 Generation of the address

The verification key generates the address with the following command:

cardano-cli address build --payment-verification-key-file payment.vkey --out-file payment.addr --testnet-magic=$magicnumber
export address=$(< payment.addr)
cardano-cli query utxo --address $(< payment.addr) --testnet-magic=$magicnumber
Image 2 — From the terminal on the right, we can’t see any transaction yet on that address

2.4 Sending funds to the address

Now we can send tADAs to the address just created. The service used to send test ADAs is Faucet.

cardano-cli query utxo --address $(< payment.addr) --testnet-magic=$magicnumber
Image 3 — As we can see, there are 1000000000 Lovelace (1000 tADAs ) on the address just created.
export txhash=4c2ccae6d631084a7e74be44356c2fdd0adc3614e7452d47cebfae58fc17cae3
export txix=0
export amount=1000000000

2.5 Submitting a transaction from cardano-cli

As I wrote before, to submit a transaction with cardano-cli, we have to consider the following steps:

  1. Calculating fees
  2. Complete the same transaction again with fees
  3. Signing the transaction
  4. Submitting the transaction into the blockchain.

2.5.1 Performing a transaction to an address without fees

First of all, we need two addresses to generate the two transactions we want to execute. I want to take them from the Daedalus interface.

Image 4 — Daedalus addresses
export addr_tx2=addr_test1qqv27gskhx32en6ua7f7m6enay4e9s5ekmq9l9gqgee6gkn7ymxyum62ndw5jcu4kl9myq2z00hp8vv4adxysauyv8qs9wwy8k
export addr_tx3=addr_test1qq4z657494prfsu80sghq2y0jqdx8qz2c938txcag4pnr8r7ymxyum62ndw5jcu4kl9myq2z00hp8vv4adxysauyv8qspx5a4z
export rest=$(expr $amount - 200000000 - 100000000 - $fee)cardano-cli transaction build-raw \
--fee $fee \
--tx-in $txhash#$txix \
--tx-out $addr_tx2+100000000 \
--tx-out $addr_tx3+200000000 \
--tx-out $address+$rest \
--out-file matx.raw
  • — tx-in: this parameter must include the transaction data necessary to get the tADAs
  • — tx-out: represent the transaction output. In this example, The first two represent the output to the Daedalus address. The last — tx-out means the rest that is sent to the sender wallet. IT’S VERY IMPORTANT THAT SUM OF tADAs REMAINS UNCHANGED, SO REST = INPUTS — OUTPUTS — FEES
  • — out-file: the transaction result that should be signed and sent to the blockchain.

2.5.2 Calculating fees

First of all, it’s necessary to download the protocol parameters.

cardano-cli query protocol-parameters --testnet-magic=$magicnumber --out-file protocol.json
export fee=$(cardano-cli transaction calculate-min-fee --tx-body-file matx.raw --tx-in-count 1 --tx-out-count 3 --witness-count 1 --testnet-magic=$magicnumber --protocol-params-file protocol.json | cut -d " " -f1)
  • — tx-out-count must represent the number of outputs in the transaction. In this case, 3.
  • — tx-body-file: this parameter it’s necessary to retrieve the transaction file.
  • — protocol-params-file: this parameter it’s necessary to retrieve the transaction file.
  • — witness-count: witnesses are the number of signing keys used to sign the transaction.
export rest=$(expr $amount - 200000000 - 100000000 - $fee)
Image 5 — fees and rest calculation

2.5.3 Create the same transaction again with fees

Now that we get all data, it’s possible to repeat the transaction instruction.

cardano-cli transaction build-raw \
--fee $fee \
--tx-in $txhash#$txix \
--tx-out $addr_tx2+100000000 \
--tx-out $addr_tx3+200000000 \
--tx-out $address+$rest \
--out-file matx.raw

2.5.4 Signing the transaction

We are ready to sign the transaction with the payment signing key.

cardano-cli transaction sign  \
--signing-key-file payment.skey \
--testnet-magic $magicnumber --tx-body-file matx.raw \
--out-file matx.signed

2.5.5 Submit the transaction on the blockchain

Finally, we’re able to send the submitted transaction to the blockchain with this command.

cardano-cli transaction submit --tx-file matx.signed --testnet-magic $magicnumber
Image 6— Transaction submission
Image 7— Balance updated



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Valerio Mellini

Karma blockchain solutions was born from the desire to favor the evolution of the Internet through a more trustless and democratic future.