# Table of Contents
- [Get Started | Cardano Developer Portal](#get-started-cardano-developer-portal)
- [Test Custom Clusters Locally With cardano-testnet | Cardano Developer Portal](#test-custom-clusters-locally-with-cardano-testnet-cardano-developer-portal)
- [Get started with the technical concepts | Cardano Developer Portal](#get-started-with-the-technical-concepts-cardano-developer-portal)
- [Get Started in the Cardano Developer Community | Cardano Developer Portal](#get-started-in-the-cardano-developer-community-cardano-developer-portal)
- [Installing cardano-wallet | Cardano Developer Portal](#installing-cardano-wallet-cardano-developer-portal)
- [Air Gap Environment | Cardano Developer Portal](#air-gap-environment-cardano-developer-portal)
- [Get started with testnets | Cardano Developer Portal](#get-started-with-testnets-cardano-developer-portal)
- [Cardano Components | Cardano Developer Portal](#cardano-components-cardano-developer-portal)
- [Integrate Cardano | Cardano Developer Portal](#integrate-cardano-cardano-developer-portal)
- [Get started with Cardano CLI | Cardano Developer Portal](#get-started-with-cardano-cli-cardano-developer-portal)
- [How to contribute to the developer portal | Cardano Developer Portal](#how-to-contribute-to-the-developer-portal-cardano-developer-portal)
- [Operate a Stake Pool | Cardano Developer Portal](#operate-a-stake-pool-cardano-developer-portal)
- [Style Guide | Cardano Developer Portal](#style-guide-cardano-developer-portal)
- [Careers on Cardano | Cardano Developer Portal](#careers-on-cardano-cardano-developer-portal)
- [Get Started with Aiken | Cardano Developer Portal](#get-started-with-aiken-cardano-developer-portal)
- [Fund your Project with Catalyst | Cardano Developer Portal](#fund-your-project-with-catalyst-cardano-developer-portal)
- [How to run cardano-node | Cardano Developer Portal](#how-to-run-cardano-node-cardano-developer-portal)
- [Simple transactions | Cardano Developer Portal](#simple-transactions-cardano-developer-portal)
- [Getting cardano-node and cardano-cli | Cardano Developer Portal](#getting-cardano-node-and-cardano-cli-cardano-developer-portal)
- [Dynamic block forging | Cardano Developer Portal](#dynamic-block-forging-cardano-developer-portal)
- [Stake address registration | Cardano Developer Portal](#stake-address-registration-cardano-developer-portal)
- [Minting NFTs | Cardano Developer Portal](#minting-nfts-cardano-developer-portal)
- [Overview of the Blockfrost ecosystem | Cardano Developer Portal](#overview-of-the-blockfrost-ecosystem-cardano-developer-portal)
- [Cardano Developer Portal](#cardano-developer-portal)
- [Discover Native Tokens | Cardano Developer Portal](#discover-native-tokens-cardano-developer-portal)
- [Build with transaction metadata | Cardano Developer Portal](#build-with-transaction-metadata-cardano-developer-portal)
- [Participate in Governance | Cardano Developer Portal](#participate-in-governance-cardano-developer-portal)
- [Delegating stake to a stake pool | Cardano Developer Portal](#delegating-stake-to-a-stake-pool-cardano-developer-portal)
- [Governance related queries. | Cardano Developer Portal](#governance-related-queries-cardano-developer-portal)
- [Runtime system options for Cardano Node | Cardano Developer Portal](#runtime-system-options-for-cardano-node-cardano-developer-portal)
- [Exploring Cardano wallets | Cardano Developer Portal](#exploring-cardano-wallets-cardano-developer-portal)
- [Testnet Faucet | Cardano Developer Portal](#testnet-faucet-cardano-developer-portal)
- [Multi-witness transactions | Cardano Developer Portal](#multi-witness-transactions-cardano-developer-portal)
- [(Re)introduction to Cardano | Cardano Developer Portal](#-re-introduction-to-cardano-cardano-developer-portal)
- [Authenticated Products on Cardano Store | Cardano Developer Portal](#authenticated-products-on-cardano-store-cardano-developer-portal)
- [Get Started with the Frankenwallet | Cardano Developer Portal](#get-started-with-the-frankenwallet-cardano-developer-portal)
- [Aiken | Cardano Developer Portal](#aiken-cardano-developer-portal)
- [Topology | Cardano Developer Portal](#topology-cardano-developer-portal)
- [Get Started with Guild Operators Tools | Cardano Developer Portal](#get-started-with-guild-operators-tools-cardano-developer-portal)
- [Listening for ada payments using cardano-cli | Cardano Developer Portal](#listening-for-ada-payments-using-cardano-cli-cardano-developer-portal)
- [Secure Transaction Workflow | Cardano Developer Portal](#secure-transaction-workflow-cardano-developer-portal)
- [Cardano Key Pairs | Cardano Developer Portal](#cardano-key-pairs-cardano-developer-portal)
- [Withdraw rewards | Cardano Developer Portal](#withdraw-rewards-cardano-developer-portal)
- [Understanding the Relay and Block Producer topology | Cardano Developer Portal](#understanding-the-relay-and-block-producer-topology-cardano-developer-portal)
- [Get Started with cardanocli-js | Cardano Developer Portal](#get-started-with-cardanocli-js-cardano-developer-portal)
- [Plutus scripts | Cardano Developer Portal](#plutus-scripts-cardano-developer-portal)
- [Native assets | Cardano Developer Portal](#native-assets-cardano-developer-portal)
- [Minimum hardware requirements to run a stake pool | Cardano Developer Portal](#minimum-hardware-requirements-to-run-a-stake-pool-cardano-developer-portal)
- [On-Chain Polls | Cardano Developer Portal](#on-chain-polls-cardano-developer-portal)
- [Authenticating users with their Cardano wallet | Cardano Developer Portal](#authenticating-users-with-their-cardano-wallet-cardano-developer-portal)
- [Receiving payments (Blockfrost API) | Cardano Developer Portal](#receiving-payments-blockfrost-api-cardano-developer-portal)
- [Simple scripts | Cardano Developer Portal](#simple-scripts-cardano-developer-portal)
- [Quick start | Cardano Developer Portal](#quick-start-cardano-developer-portal)
- [Introduction to Cardano Protocol Governance | Cardano Developer Portal](#introduction-to-cardano-protocol-governance-cardano-developer-portal)
- [Deregister stake address | Cardano Developer Portal](#deregister-stake-address-cardano-developer-portal)
- [Get Started with Koios | Cardano Developer Portal](#get-started-with-koios-cardano-developer-portal)
- [Exchange Integrations | Cardano Developer Portal](#exchange-integrations-cardano-developer-portal)
- [Treasury donation | Cardano Developer Portal](#treasury-donation-cardano-developer-portal)
- [Constitutional Committee: A Guide for New Members | Cardano Developer Portal](#constitutional-committee-a-guide-for-new-members-cardano-developer-portal)
- [Minting Native Assets | Cardano Developer Portal](#minting-native-assets-cardano-developer-portal)
- [Listening for ada payments using cardano-wallet | Cardano Developer Portal](#listening-for-ada-payments-using-cardano-wallet-cardano-developer-portal)
- [Hardening the server | Cardano Developer Portal](#hardening-the-server-cardano-developer-portal)
- [Cardano governance | Cardano Developer Portal](#cardano-governance-cardano-developer-portal)
- [Get Started with `plu-ts` | Cardano Developer Portal](#get-started-with-plu-ts-cardano-developer-portal)
- [Cardano Tracer | Cardano Developer Portal](#cardano-tracer-cardano-developer-portal)
- [Cardano Relay Node Configuration | Cardano Developer Portal](#cardano-relay-node-configuration-cardano-developer-portal)
- [Generating wallet keys (Faucet for tADA) | Cardano Developer Portal](#generating-wallet-keys-faucet-for-tada-cardano-developer-portal)
- [Get Started with CardanoSharp Wallet | Cardano Developer Portal](#get-started-with-cardanosharp-wallet-cardano-developer-portal)
- [Get Started with Ogmios | Cardano Developer Portal](#get-started-with-ogmios-cardano-developer-portal)
- [Secure Webhooks | Cardano Developer Portal](#secure-webhooks-cardano-developer-portal)
- [Blockfrost Open Source | Cardano Developer Portal](#blockfrost-open-source-cardano-developer-portal)
- [Cardano API | Cardano Developer Portal](#cardano-api-cardano-developer-portal)
- [Get started with Blockfrost | Cardano Developer Portal](#get-started-with-blockfrost-cardano-developer-portal)
- [IPFS and Milkomeda API | Cardano Developer Portal](#ipfs-and-milkomeda-api-cardano-developer-portal)
- [Get Started with Lucid Evolution | Cardano Developer Portal](#get-started-with-lucid-evolution-cardano-developer-portal)
- [Get Started with cardano-wallet-js | Cardano Developer Portal](#get-started-with-cardano-wallet-js-cardano-developer-portal)
- [Get Started with Cardano Serialization Lib | Cardano Developer Portal](#get-started-with-cardano-serialization-lib-cardano-developer-portal)
- [metadata | Cardano Developer Portal](#metadata-cardano-developer-portal)
- [Overview | Cardano Developer Portal](#overview-cardano-developer-portal)
- [Cardano Token Registry | Cardano Developer Portal](#cardano-token-registry-cardano-developer-portal)
- [Marlowe | Cardano Developer Portal](#marlowe-cardano-developer-portal)
- [Plutus | Cardano Developer Portal](#plutus-cardano-developer-portal)
- [opshin | Cardano Developer Portal](#opshin-cardano-developer-portal)
- [plu-ts | Cardano Developer Portal](#plu-ts-cardano-developer-portal)
- [Why hasn't my pull request (PR) been merged yet? | Cardano Developer Portal](#why-hasn-t-my-pull-request-pr-been-merged-yet-cardano-developer-portal)
- [Retrieving your metadata | Cardano Developer Portal](#retrieving-your-metadata-cardano-developer-portal)
- [How to create a metadata transaction using cardano-wallet | Cardano Developer Portal](#how-to-create-a-metadata-transaction-using-cardano-wallet-cardano-developer-portal)
- [How to create a metadata transaction using cardano-cli | Cardano Developer Portal](#how-to-create-a-metadata-transaction-using-cardano-cli-cardano-developer-portal)
- [Registering as Delegated Representative (DReps) | Cardano Developer Portal](#registering-as-delegated-representative-dreps-cardano-developer-portal)
- [Delegate votes to a Delegated Representative (DRep) | Cardano Developer Portal](#delegate-votes-to-a-delegated-representative-drep-cardano-developer-portal)
- [Submitting votes as DRep, Stake pool or Constitutional Committee member | Cardano Developer Portal](#submitting-votes-as-drep-stake-pool-or-constitutional-committee-member-cardano-developer-portal)
- [Constitutional committee | Cardano Developer Portal](#constitutional-committee-cardano-developer-portal)
- [Submitting governance actions | Cardano Developer Portal](#submitting-governance-actions-cardano-developer-portal)
- [Monitoring with gLiveView | Cardano Developer Portal](#monitoring-with-gliveview-cardano-developer-portal)
- [Governance Actions | Cardano Developer Portal](#governance-actions-cardano-developer-portal)
- [Generating Cardano Block producer Keys | Cardano Developer Portal](#generating-cardano-block-producer-keys-cardano-developer-portal)
- [Cardano Token Registry | Cardano Developer Portal](#cardano-token-registry-cardano-developer-portal)
- [CIP 26 | Cardano Developer Portal](#cip-26-cardano-developer-portal)
- [Create & Choose Wallets | Cardano Developer Portal](#create-choose-wallets-cardano-developer-portal)
- [Submitting Governance Actions on Cardano | Cardano Developer Portal](#submitting-governance-actions-on-cardano-cardano-developer-portal)
- [How to prepare an entry for the registry (Plutus script) | Cardano Developer Portal](#how-to-prepare-an-entry-for-the-registry-plutus-script-cardano-developer-portal)
- [Improve Grafana Security | Cardano Developer Portal](#improve-grafana-security-cardano-developer-portal)
- [Registering a Stake Address | Cardano Developer Portal](#registering-a-stake-address-cardano-developer-portal)
- [Audit your node | Cardano Developer Portal](#audit-your-node-cardano-developer-portal)
- [Grafana Dashboard Tutorial | Cardano Developer Portal](#grafana-dashboard-tutorial-cardano-developer-portal)
- [How do I delete my entry from the registry? | Cardano Developer Portal](#how-do-i-delete-my-entry-from-the-registry-cardano-developer-portal)
- [Is my token name and ticker unique in the registry ? | Cardano Developer Portal](#is-my-token-name-and-ticker-unique-in-the-registry-cardano-developer-portal)
- [Registering a Pool (JSON Metadata) | Cardano Developer Portal](#registering-a-pool-json-metadata-cardano-developer-portal)
- [Where do I register my metadata for assets that exist on one of the publicly available testnets (e.g. preview, preprod environments) only? | Cardano Developer Portal](#where-do-i-register-my-metadata-for-assets-that-exist-on-one-of-the-publicly-available-testnets-e-g-preview-preprod-environments-only-cardano-developer-portal)
- [Why has my pull request (PR) been closed? | Cardano Developer Portal](#why-has-my-pull-request-pr-been-closed-cardano-developer-portal)
- [How do I update my entry in the registry? | Cardano Developer Portal](#how-do-i-update-my-entry-in-the-registry-cardano-developer-portal)
- [How to submit an entry to the registry | Cardano Developer Portal](#how-to-submit-an-entry-to-the-registry-cardano-developer-portal)
- [Create React App for Serialization-Lib | Cardano Developer Portal](#create-react-app-for-serialization-lib-cardano-developer-portal)
- [How to prepare an entry for the registry (NA policy script) | Cardano Developer Portal](#how-to-prepare-an-entry-for-the-registry-na-policy-script-cardano-developer-portal)
- [CIP 68 | Cardano Developer Portal](#cip-68-cardano-developer-portal)
- [Minting Transactions | Cardano Developer Portal](#minting-transactions-cardano-developer-portal)
- [Transactions | Cardano Developer Portal](#transactions-cardano-developer-portal)
- [React Web App | Cardano Developer Portal](#react-web-app-cardano-developer-portal)
- [prerequisite-knowledge | Cardano Developer Portal](#prerequisite-knowledge-cardano-developer-portal)
- [Transaction Builder | Cardano Developer Portal](#transaction-builder-cardano-developer-portal)
- [Staking Transactions | Cardano Developer Portal](#staking-transactions-cardano-developer-portal)
- [Governance Transactions | Cardano Developer Portal](#governance-transactions-cardano-developer-portal)
- [Get Started | Cardano Developer Portal](#get-started-cardano-developer-portal)
- [Smart Contract Lib | Cardano Developer Portal](#smart-contract-lib-cardano-developer-portal)
- [Smart Contracts Transactions | Cardano Developer Portal](#smart-contracts-transactions-cardano-developer-portal)
- [generating-transactions | Cardano Developer Portal](#generating-transactions-cardano-developer-portal)
- [Cardano Token Registry Server | Cardano Developer Portal](#cardano-token-registry-server-cardano-developer-portal)
- [generating-keys | Cardano Developer Portal](#generating-keys-cardano-developer-portal)
- [Wallets Integration | Cardano Developer Portal](#wallets-integration-cardano-developer-portal)
- [Basic Transactions | Cardano Developer Portal](#basic-transactions-cardano-developer-portal)
---
# Get Started | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page

Welcome to the Cardano Developer Portal. This content is for technical people; if you are looking for a Cardano wallet please head to the [showcase section](https://developers.cardano.org/showcase)
.
It is noteworthy to mention that the Developer Portal covers everything you can do **today** on the Cardano **mainnet**.
What is Cardano?[](https://developers.cardano.org/docs/get-started/#what-is-cardano "Direct link to What is Cardano?")
------------------------------------------------------------------------------------------------------------------------
Cardano is a collection of [open-source](https://en.wikipedia.org/wiki/Open_source)
, patent-free protocols. It's a platform that enables you to store, transform, and manage value, identity, and governance. Cardano follows research not opinions or bias.
How did it start?[](https://developers.cardano.org/docs/get-started/#how-did-it-start "Direct link to How did it start?")
---------------------------------------------------------------------------------------------------------------------------
Cardano started as a significant research and development project in 2015, and it took almost two years of research to get to a position to start writing code.
The purpose of Cardano was to ask: How can we build a sustainable financial and social operating system for billions of people? What collections of technologies do we need to bring together to get everything at an affordable cost?
Besides cryptographic research, there was game-theoretic research, identity-management research, and programming-language research. This academic rigor process produced more than 100 academic papers. Most were accepted in cryptography conferences like Eurocrypt and Asiacrypt and went through the standard peer-review process. For example, the paper [“Ouroboros: A Provably Secure Proof-of-Stake Blockchain Protocol”](https://eprint.iacr.org/2016/889.pdf)
was one of [the most cited security papers from 2015-2019](https://sweis.medium.com/most-cited-security-papers-from-2015-2019-d21515db3681)
.
What you need to bring[](https://developers.cardano.org/docs/get-started/#what-you-need-to-bring "Direct link to What you need to bring")
-------------------------------------------------------------------------------------------------------------------------------------------
To get the most out of the Cardano Developer Portal, you should have programming experience and a basic understanding of blockchain concepts of Cardano such as [UTxO](https://developers.cardano.org/docs/get-started/technical-concepts#unspent-transaction-output-utxo)
, [transactions](https://developers.cardano.org/docs/get-started/technical-concepts#transactions)
, [addresses](https://developers.cardano.org/docs/get-started/technical-concepts#addresses)
, [key derivation](https://developers.cardano.org/docs/get-started/technical-concepts#key-derivation)
, and [networking](https://developers.cardano.org/docs/get-started/technical-concepts#networking)
.
If you are unfamiliar with these terms, start with [technical concepts](https://developers.cardano.org/docs/get-started/technical-concepts)
, and you can complete the [stake pool course](https://developers.cardano.org/docs/operate-a-stake-pool/)
afterward. It will also help you understand basic concepts, even if you don't want to run a stake pool.
Cardano is different[](https://developers.cardano.org/docs/get-started/#cardano-is-different "Direct link to Cardano is different")
-------------------------------------------------------------------------------------------------------------------------------------
If you have experience with other smart contract platforms and want to start building on Cardano, it is vital to know its differences:
* It makes sense to get your head around the [concept of UTxO](https://developers.cardano.org/docs/get-started/technical-concepts#unspent-transaction-output-utxo)
and later [the extended UTxO model](https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/)
.
* [Tokens on Cardano](https://developers.cardano.org/docs/native-tokens/)
are not built with smart contracts. Instead, tokens are native and live on the ledger. The protocol treats them as first-class citizens, like ada. It is quite different from our peers that don’t have native tokens and need to use a smart contract to send tokens.
* [Native tokens](https://developers.cardano.org/docs/native-tokens/)
use the core infrastructure, and the network has to do everything else instead of running a smart contract and calling a method called 'transfer'. On Cardano, you are sending a standard transaction. This removes a layer of extra complexity and the risk of human mistakes, as the ledger handles all token-related functions.
* [Smart contracts](https://developers.cardano.org/docs/smart-contracts/)
work different on Cardano because of the [eUTxO model](https://iohk.io/en/blog/posts/2021/03/11/cardanos-extended-utxo-accounting-model/)
. Misconceptions were floating around suggesting [that Cardano only supports one transaction per block](https://sundaeswap-finance.medium.com/concurrency-state-cardano-c160f8c07575)
.
What you can do on Cardano today[](https://developers.cardano.org/docs/get-started/#what-you-can-do-on-cardano-today "Direct link to What you can do on Cardano today")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* You can send and receive [native tokens](https://developers.cardano.org/docs/native-tokens/)
, including ada.
* You can delegate your ada to one of the [existing pools](https://developers.cardano.org/showcase?tags=pooltool)
and earn rewards.
* You can [vote with your ada](https://developers.cardano.org/docs/governance/project-catalyst#participate-as-a-voter)
to distribute over a billion dollars worth of ada from the treasury to fund community-driven proposals on [Project Catalyst](https://developers.cardano.org/docs/governance/project-catalyst)
.
* You can earn ada rewards by [voting on proposals](https://developers.cardano.org/docs/governance/project-catalyst#participate-as-a-voter)
.
* You can participate in the [Cardano Improvement Proposals](https://developers.cardano.org/docs/get-started/technical-concepts#cardano-improvement-proposals-cip)
(CIP) process.
* You can interact with [smart contracts](https://developers.cardano.org/docs/smart-contracts/)
.
Why build on Cardano?[](https://developers.cardano.org/docs/get-started/#why-build-on-cardano "Direct link to Why build on Cardano?")
---------------------------------------------------------------------------------------------------------------------------------------
* Cardano offers a better infrastructure to build products because it is faster, more secure, and cost-effective.
* Cardano offers accurate cost predictability when it comes to transactions. There are no auctions for transaction fees.
* Cardano has an energetic community and more than two million wallets. If you stick to specific standards, we are keen to try out and engage with new products. Participating now makes you a first mover.
* Cardano brings its venture fund. If you build on Cardano you can get [your project funded](https://developers.cardano.org/docs/governance/project-catalyst)
. Every 6 to 8 weeks, projects can be proposed, discussed, and voted on by the Cardano community.
* Cardano is a proof-of-stake blockchain. By design, it consumes much less energy and computational power.
* Cardano is built with the rigor of high-assurance formal development methods. The consensus mechanism [Ouroboros](https://cardano.org/ouroboros/)
was delivered with several peer-reviewed papers presented in top-tier conferences and publications in cybersecurity and cryptography. If you build on Cardano, you build on this foundation.
What you can build on Cardano today[](https://developers.cardano.org/docs/get-started/#what-you-can-build-on-cardano-today "Direct link to What you can build on Cardano today")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* You can [integrate Cardano](https://developers.cardano.org/docs/integrate-cardano/)
into existing websites and services.
* You can issue [native tokens](https://developers.cardano.org/docs/native-tokens/)
and [NFTs](https://developers.cardano.org/docs/native-tokens/minting-nfts)
.
* You can add [metadata to transactions](https://developers.cardano.org/docs/transaction-metadata/)
to give transactions a story, a background or even an identity.
* You can prove the existence of a file, text or any other data at a specific point in time with [transaction metadata](https://developers.cardano.org/docs/transaction-metadata/)
. You can even use [transaction metadata](https://developers.cardano.org/docs/transaction-metadata/)
to validate and verify external physical products and genuine articles.
* You can [setup, manage and maintain a stake pool](https://developers.cardano.org/docs/operate-a-stake-pool/)
on Cardano.
* You can [create smart contracts](https://developers.cardano.org/docs/smart-contracts/)
.
* [What is Cardano?](https://developers.cardano.org/docs/get-started/#what-is-cardano)
* [How did it start?](https://developers.cardano.org/docs/get-started/#how-did-it-start)
* [What you need to bring](https://developers.cardano.org/docs/get-started/#what-you-need-to-bring)
* [Cardano is different](https://developers.cardano.org/docs/get-started/#cardano-is-different)
* [What you can do on Cardano today](https://developers.cardano.org/docs/get-started/#what-you-can-do-on-cardano-today)
* [Why build on Cardano?](https://developers.cardano.org/docs/get-started/#why-build-on-cardano)
* [What you can build on Cardano today](https://developers.cardano.org/docs/get-started/#what-you-can-build-on-cardano-today)
---
# Test Custom Clusters Locally With cardano-testnet | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-testnet/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
In the future, cardano-testnet will be available from [cardano-node GitHub Releases](https://github.com/IntersectMBO/cardano-node/releases)
page. Until then, it is obtained by building [cardano-node](https://github.com/IntersectMBO/cardano-node)
from source.
Building cardano-testnet[](https://developers.cardano.org/docs/get-started/cardano-testnet/#building-cardano-testnet "Direct link to Building cardano-testnet")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
We refer to [the instructions](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
for building cardano-node from source. Once you are done with these instructions, run the following to build cardano-testnet.
cabal build cardano-testnet
This should succeed 🙂 Now, define two environment variables pointing to your `cardano-node` and `cardano-cli` executables (which you can obtain from [cardano-node's GitHub releases](https://github.com/IntersectMBO/cardano-node/releases)
):
export CARDANO_CLI=path to your executableexport CARDANO_NODE=path to your executable
Options for launching a local cluster[](https://developers.cardano.org/docs/get-started/cardano-testnet/#options-for-launching-a-local-cluster "Direct link to Options for launching a local cluster")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To launch a local cluster, you should use the `cardano-testnet cardano` command, whose API is as follows:
Usage: cardano-testnet cardano [--num-pool-nodes COUNT | --node-config FILEPATH] [ --shelley-era | --allegra-era | --mary-era | --alonzo-era | --babbage-era | --conway-era ] [--max-lovelace-supply WORD64] [--enable-p2p BOOL] [--nodeLoggingFormat LOGGING_FORMAT] [--num-dreps NUMBER] [--enable-new-epoch-state-logging] [--output-dir DIRECTORY] --testnet-magic INT [--epoch-length SLOTS] [--slot-length SECONDS] [--active-slots-coeff DOUBLE] Start a testnet in any eraAvailable options: --num-pool-nodes COUNT Number of pool nodes. Note this uses a default node configuration for all nodes. (default: 1) --node-config FILEPATH Path to the node's configuration file (which is generated otherwise). If you use this option, you should also pass all the genesis files (files pointed to by the fields "AlonzoGenesisFile", "ShelleyGenesisFile", etc.). --shelley-era Specify the Shelley era - DEPRECATED - will be removed in the future --allegra-era Specify the Allegra era - DEPRECATED - will be removed in the future --mary-era Specify the Mary era - DEPRECATED - will be removed in the future --alonzo-era Specify the Alonzo era - DEPRECATED - will be removed in the future --babbage-era Specify the Babbage era (default) - DEPRECATED - will be removed in the future --conway-era Specify the Conway era --max-lovelace-supply WORD64 Max lovelace supply that your testnet starts with. Ignored if a custom Shelley genesis file is passed. (default: 100000020000000) --enable-p2p BOOL Enable P2P (default: False) --nodeLoggingFormat LOGGING_FORMAT Node logging format (json|text) (default: NodeLoggingFormatAsJson) --num-dreps NUMBER Number of delegate representatives (DReps) to generate. Ignored if a custom Conway genesis file is passed. (default: 3) --enable-new-epoch-state-logging Enable new epoch state logging to logs/ledger-epoch-state.log --output-dir DIRECTORY Directory where to store files, sockets, and so on. It is created if it doesn't exist. If unset, a temporary directory is used. --testnet-magic INT Specify a testnet magic id. --epoch-length SLOTS Epoch length, in number of slots. Ignored if a custom Shelley genesis file is passed. (default: 500) --slot-length SECONDS Slot length. Ignored if a custom Shelley genesis file is passed. (default: 0.1) --active-slots-coeff DOUBLE Active slots coefficient. Ignored if a custom Shelley genesis file is passed. (default: 5.0e-2) -h,--help Show this help text
We now go over these different options as there are many interactions between them.
### Using a custom node configuration file and custom genesis files[](https://developers.cardano.org/docs/get-started/cardano-testnet/#using-a-custom-node-configuration-file-and-custom-genesis-files "Direct link to Using a custom node configuration file and custom genesis files")
cardano-testnet has two behaviors, depending on whether you want to use defaults or not. You can either:
1. default the node configuration file and the Alonzo, Shelley, and Conway genesis files. In this case, don't specify `--node-config`: cardano-testnet will take care of generating all these files.
2. pass the node configuration file using `--node-config`. In this case, you should also specify the Alonzo, Shelley, and Conway genesis files, using the fields `AlonzoGenesisFile`, `ShelleyGenesisFile`, and `ConwayGenesisFile` from the node configuration file.
Right now, for scenario 2., there is no way to generate the node configuration file and the genesis files automatically, but this will be [made available soon](https://github.com/IntersectMBO/cardano-node/issues/6153)
.
### Using a custom output directory[](https://developers.cardano.org/docs/get-started/cardano-testnet/#using-a-custom-output-directory "Direct link to Using a custom output directory")
If you don't specify `--output-dir`, cardano-testnet will create a fresh temporary directory to run. This directory will contain both (SPO, dreps, etc.) keys as well the nodes' data. If you specify `--output-dir`, cardano-testnet will use the specified directory to store the keys and the nodes' data. In this case we recommend using a fresh directory every time, otherwise there is a risk that one run poisons the other. In addition, using your own directory makes it easier to inspect the logs after the testnet has finished, or while it is running. The structure of the directory is as follows (using bash pseudo-syntax to avoid enumerations):
├── byron-gen-command│ └── genesis-keys.00{0,1,2}.key├── delegate-keys│ ├── delegate{1,2,3}│ │ ├── kes.{skey,vkey}│ │ ├── key.{skey,vkey}│ │ ├── opcert.{cert,counter}│ │ └── vrf.{skey,vkey}│ └── README.md├── drep-keys│ ├── drep{1,2,3}│ │ └── drep.{skey,vkey}│ └── README.md├── genesis-keys│ ├── genesis{1,2,3}│ │ └── key.{skey,vkey}│ └── README.md├── logs│ ├── node{1,2,3}│ │ └── {stderr,stdout}.log│ ├── ledger-epoch-state-diffs.log│ ├── ledger-epoch-state.log│ ├── node-20241010121635.log│ └── node.log -> node-20241010121635.log├── node-data│ ├── node{1,2,3}│ │ ├── db│ │ │ └── │ │ ├── port│ │ └── topology.json├── pools-keys│ ├── pool1│ │ ├── byron-delegate.key│ │ ├── byron-delegation.cert│ │ ├── cold.{skey,vkey}│ │ ├── kes.{skey,vkey}│ │ ├── opcert.{cert,counter}│ │ ├── staking-reward.{skey,vkey}│ │ └── vrf.{skey,vkey}│ └── README.md├── socket│ ├── node{1,2,3}│ │ └── sock├── stake-delegators│ ├── delegator{1,2,3}│ │ ├── payment.{skey,vkey}│ │ └── staking.{skey,vkey}├── utxo-keys│ ├── utxo{1,2,3}│ │ └── utxo.{addr,skey,vkey}│ └── README.md├── {alonzo,byron,conway,shelley}-genesis.json├── configuration.json└── current-stake-pools.json
We draw the reader's attention to two things:
1. The nodes' logs are located in `logs/node1/`, `logs/node2/`, etc. Those are useful for debugging.
2. The genesis files are at the root of the output directory. If you are not providing your own genesis files initially, look at the generated ones. They can be used as a starting point to craft your own genesis files.
### Era-specific flags: Shelley[](https://developers.cardano.org/docs/get-started/cardano-testnet/#era-specific-flags-shelley "Direct link to Era-specific flags: Shelley")
There are four flags that control values specified in the Shelley genesis file:
--max-lovelace-supply WORD64 Max lovelace supply that your testnet starts with. Ignored if a custom Shelley genesis file is passed. (default: 100000020000000) --epoch-length SLOTS Epoch length, in number of slots. Ignored if a custom Shelley genesis file is passed. (default: 500) --slot-length SECONDS Slot length. Ignored if a custom Shelley genesis file is passed. (default: 0.1) --active-slots-coeff DOUBLE Active slots coefficient. Ignored if a custom Shelley genesis file is passed. (default: 5.0e-2)
Note that all of these flags are ignored when a node configuration file and Shelley genesis file are specified.
### Era-specific flags: Conway[](https://developers.cardano.org/docs/get-started/cardano-testnet/#era-specific-flags-conway "Direct link to Era-specific flags: Conway")
There is one flag that control values that appear in the Conway genesis file and that's the number of dreps:
--num-dreps NUMBER Number of delegate representatives (DReps) to generate. Ignored if a custom Conway genesis file is passed. (default: 3)
Like the Shelley flags, this flag is ignored if a node configuration file and a Conway genesis file are specified.
Launching a local cluster: an example script[](https://developers.cardano.org/docs/get-started/cardano-testnet/#launching-a-local-cluster-an-example-script "Direct link to Launching a local cluster: an example script")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A typical way to launch a testnet cluster will look like this, using a Bash script:
#!/usr/bin/env bashset -euxTMP_DIR=$(mktemp -d)# Install your custom configuration files (node configuration + genesis files)cp /configuration.json $TMP_DIR/.# This assumes the AlonzoGenesisFile JSON field in the node configuration file is "alonzo-genesis.json"# Same for Shelley and Conwayfor era in shelley alonzo conwaydo cp /$era-genesis.json $TMP_DIR/.donecabal run cardano-testnet -- cardano --node-config $TMP_DIR/configuration.json --output-dir $TMP_DIR --testnet-magic 42
When you execute this script, you will see output similar to this:
✗ failed at src/Testnet/Property/Run.hs:89:7 after 1 test. shrink path: 1: forAll0 = ━━━━ File: /tmp/nix-shell.iZ2TPc/tmp.ly3nO21w1e/current-stake-pools.json ━━━━ [ "pool1r8fuwkk3kkfekh6el0kzydrn009yqd89mrv4zpjq77wg6639ese" ] forAll1 = Reading file: /tmp/nix-shell.iZ2TPc/tmp.ly3nO21w1e/current-stake-pools.json forAll2 = ━━━━ command ━━━━ /home/churlin/.local/state/cabal/store/ghc-8.10.7/cardano-cli-10.4.0.0-e-cardano-cli-3b9fee1097cc434bbca7740006a83745fcc229aa57d45fcca2712990862bc6b9/bin/cardano-cli latest query stake-pools --out-file /tmp/nix-shell.iZ2TPc/tmp.ly3nO21w1e/current-stake-pools.json forAll3 = /tmp/nix-shell.iZ2TPc/tmp.ly3nO21w1e/current-stake-pools.json...... lots of output...forAll75 = Reusing /tmp/nix-shell.iZ2TPc/tmp.ly3nO21w1e This failure can be reproduced by running: > recheckAt (Seed 1622863211725641548 12217359344083085813) "1:" Testnet is running. Type CTRL-C to exit.
You can ignore the initial `✗ failed` log. This is an artifact from the fact that cardano-testnet relies on a test library to run. The same applies to all `forAllX = ...` logs. That being said, those logs give the location of the output directory being used: it is `/tmp/nix-shell.iZ2TPc/tmp.ly3nO21w1e/` in the log above. This can be useful if you didn't specify `--output-dir` yourself and rely on cardano-testnet's default behavior.
Once the line `Testnet is running. Type CTRL-C to exit.` appears, the testnet is running and building blocks, and regular queries commands (for example using [cardano-cli](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/)
) can be executed against it.
Stopping a local cluster[](https://developers.cardano.org/docs/get-started/cardano-testnet/#stopping-a-local-cluster "Direct link to Stopping a local cluster")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Right now, there is no built-in way to stop a running cluster (this will be improved in the future). We recommend using one of these methods to kill a running testnet:
1. Call `pidof cardano-node` and then `kill` the corresponding process.
2. Call `killall cardano-node`
* [Building cardano-testnet](https://developers.cardano.org/docs/get-started/cardano-testnet/#building-cardano-testnet)
* [Options for launching a local cluster](https://developers.cardano.org/docs/get-started/cardano-testnet/#options-for-launching-a-local-cluster)
* [Using a custom node configuration file and custom genesis files](https://developers.cardano.org/docs/get-started/cardano-testnet/#using-a-custom-node-configuration-file-and-custom-genesis-files)
* [Using a custom output directory](https://developers.cardano.org/docs/get-started/cardano-testnet/#using-a-custom-output-directory)
* [Era-specific flags: Shelley](https://developers.cardano.org/docs/get-started/cardano-testnet/#era-specific-flags-shelley)
* [Era-specific flags: Conway](https://developers.cardano.org/docs/get-started/cardano-testnet/#era-specific-flags-conway)
* [Launching a local cluster: an example script](https://developers.cardano.org/docs/get-started/cardano-testnet/#launching-a-local-cluster-an-example-script)
* [Stopping a local cluster](https://developers.cardano.org/docs/get-started/cardano-testnet/#stopping-a-local-cluster)
---
# Get started with the technical concepts | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/technical-concepts/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
To get the most out of the Cardano Developer Portal, you should have programming experience and a basic understanding of blockchain concepts such as [UTxO](https://developers.cardano.org/docs/get-started/technical-concepts/#unspent-transaction-output-utxo)
, [transactions](https://developers.cardano.org/docs/get-started/technical-concepts/#transactions)
, [addresses](https://developers.cardano.org/docs/get-started/technical-concepts/#addresses)
, [key derivation](https://developers.cardano.org/docs/get-started/technical-concepts/#key-derivation)
, and [networking](https://developers.cardano.org/docs/get-started/technical-concepts/#networking)
.
Introduction to Cardano: the big picture[](https://developers.cardano.org/docs/get-started/technical-concepts/#introduction-to-cardano-the-big-picture "Direct link to Introduction to Cardano: the big picture")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Learn fundamental terms like blockchain, consensus, decentralization delegation and incentives. Understand the big picture of Cardano and why stake pools are so important.
Unspent Transaction Output (UTxO)[](https://developers.cardano.org/docs/get-started/technical-concepts/#unspent-transaction-output-utxo "Direct link to Unspent Transaction Output (UTxO)")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
UTxO or Unspent Transaction Outputs are how ada moves around the Cardano network. Learn how they work in the Cardano ledger.
Transactions[](https://developers.cardano.org/docs/get-started/technical-concepts/#transactions "Direct link to Transactions")
--------------------------------------------------------------------------------------------------------------------------------
Learn what is inside the guts of a Cardano transaction. We show how unsigned and signed transactions look like, and we cover how signing works.
Addresses[](https://developers.cardano.org/docs/get-started/technical-concepts/#addresses "Direct link to Addresses")
-----------------------------------------------------------------------------------------------------------------------
Cardano Addresses are used as destinations to send ada on the blockchain. We break them down into their parts and show how they're created.
Transaction Fees[](https://developers.cardano.org/docs/get-started/technical-concepts/#transaction-fees "Direct link to Transaction Fees")
--------------------------------------------------------------------------------------------------------------------------------------------
Understand how transaction fees are calculated on Cardano. Brief coverage of the topics reserve and treasury.
Mnemonic seed phrase (BIP39)[](https://developers.cardano.org/docs/get-started/technical-concepts/#mnemonic-seed-phrase-bip39 "Direct link to Mnemonic seed phrase (BIP39)")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BIP39 is the standard for creating a mnemonic seed phrase for wallets. In this video, we break down how it's created from randomness on Cardano.
Key Derivation[](https://developers.cardano.org/docs/get-started/technical-concepts/#key-derivation "Direct link to Key Derivation")
--------------------------------------------------------------------------------------------------------------------------------------
Key Derivation is the process a wallet uses to go from a mnemonic phrase to a whole set of keys and addresses that the wallet controls.
Block and transaction propagation[](https://developers.cardano.org/docs/get-started/technical-concepts/#block-and-transaction-propagation "Direct link to Block and transaction propagation")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Learn how transactions make it from the mempool into blocks and how blocks move around the network.
Networking[](https://developers.cardano.org/docs/get-started/technical-concepts/#networking "Direct link to Networking")
--------------------------------------------------------------------------------------------------------------------------
We answer your questions about how nodes on Cardano talk to each other. Learn about TCP Sockets, mini-protocols and the future of P2P.
Cardano Improvement Proposals (CIP)[](https://developers.cardano.org/docs/get-started/technical-concepts/#cardano-improvement-proposals-cip "Direct link to Cardano Improvement Proposals (CIP)")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The [Cardano Improvement Proposal](https://cips.cardano.org/)
(CIP) process allows the community to interact with the Cardano Foundation to improve the Cardano ecosystem in a formal way.
Slot Lottery[](https://developers.cardano.org/docs/get-started/technical-concepts/#slot-lottery "Direct link to Slot Lottery")
--------------------------------------------------------------------------------------------------------------------------------
In this video, we describe exactly how a stake pool on Cardano gets elected to make a block.
Slot Battles[](https://developers.cardano.org/docs/get-started/technical-concepts/#slot-battles "Direct link to Slot Battles")
--------------------------------------------------------------------------------------------------------------------------------
On Cardano, slot battles happen when two pools try to make a block in the same slot (at the same time). We break down how the blockchain determines which block should win and what is the "correct" source of truth on the blockchain.
Catalyst Voting[](https://developers.cardano.org/docs/get-started/technical-concepts/#catalyst-voting "Direct link to Catalyst Voting")
-----------------------------------------------------------------------------------------------------------------------------------------
What is Catalyst voting, how to register, how to vote and why you should participate.
Franken Addresses[](https://developers.cardano.org/docs/get-started/technical-concepts/#franken-addresses "Direct link to Franken Addresses")
-----------------------------------------------------------------------------------------------------------------------------------------------
Franken Addresses are a way to register additional pledge to a pool without registering a second owner on the blockchain.
NFT[](https://developers.cardano.org/docs/get-started/technical-concepts/#nft "Direct link to NFT")
-----------------------------------------------------------------------------------------------------
Non-Fungible Tokens on cardano are native assets that represent immutable art or physical things.
Catalyst Voting Registration[](https://developers.cardano.org/docs/get-started/technical-concepts/#catalyst-voting-registration "Direct link to Catalyst Voting Registration")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
How does the Catalyst voting registration on the side-chain work?
Epoch Nonce[](https://developers.cardano.org/docs/get-started/technical-concepts/#epoch-nonce "Direct link to Epoch Nonce")
-----------------------------------------------------------------------------------------------------------------------------
The epoch nonce allows you to calculate leaderlogs for your stake pool on Cardano.
Guaranteed Transaction Delivery[](https://developers.cardano.org/docs/get-started/technical-concepts/#guaranteed-transaction-delivery "Direct link to Guaranteed Transaction Delivery")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
How dropped transactions happen on cardano and how to ensure we always deliver them into blocks.
SundaeSwap & Merkel Trees[](https://developers.cardano.org/docs/get-started/technical-concepts/#sundaeswap--merkel-trees "Direct link to SundaeSwap & Merkel Trees")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Learn about the SundaeSwap ISO and how Merkel Trees work.
DripDropz & Phyrhose[](https://developers.cardano.org/docs/get-started/technical-concepts/#dripdropz--phyrhose "Direct link to DripDropz & Phyrhose")
-------------------------------------------------------------------------------------------------------------------------------------------------------
DripDropz, the token AirDrop vending machine, powered by Phyrhose.
P2P Networking[](https://developers.cardano.org/docs/get-started/technical-concepts/#p2p-networking "Direct link to P2P Networking")
--------------------------------------------------------------------------------------------------------------------------------------
Learn about Byron era network, Shelley era network, unidirectional (Half-Duplex) connections, the Topology Updater, manual P2P vs. automatic P2P.
TPS vs. eUTxO[](https://developers.cardano.org/docs/get-started/technical-concepts/#tps-vs-eutxo "Direct link to TPS vs. eUTxO")
----------------------------------------------------------------------------------------------------------------------------------
Which is better, high transactions per second or eUTxO?
LocalTxMonitor[](https://developers.cardano.org/docs/get-started/technical-concepts/#localtxmonitor "Direct link to LocalTxMonitor")
--------------------------------------------------------------------------------------------------------------------------------------
Learn about the new LocalTxMonitor miniprotocol in cardano-node.
Network Congestion[](https://developers.cardano.org/docs/get-started/technical-concepts/#network-congestion "Direct link to Network Congestion")
--------------------------------------------------------------------------------------------------------------------------------------------------
How does network congestion happen? What are mempool errors?
Multisig[](https://developers.cardano.org/docs/get-started/technical-concepts/#multisig "Direct link to Multisig")
--------------------------------------------------------------------------------------------------------------------
What is multisig? And how does it work on Cardano?
JorManager 6[](https://developers.cardano.org/docs/get-started/technical-concepts/#jormanager-6 "Direct link to JorManager 6")
--------------------------------------------------------------------------------------------------------------------------------
Learn about what's new in the Cardano stake pool management software JorManager 6.
How to create a FT on Cardano that doesn't completely suck
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Learn how to create fungible tokens on Cardano using StakePool Operator Scripts.
Governance Snapshots[](https://developers.cardano.org/docs/get-started/technical-concepts/#governance-snapshots "Direct link to Governance Snapshots")
--------------------------------------------------------------------------------------------------------------------------------------------------------
Learn how to take blockchain snapshots for Governance voting purposes.
Djed Stablecoin[](https://developers.cardano.org/docs/get-started/technical-concepts/#djed-stablecoin "Direct link to Djed Stablecoin")
-----------------------------------------------------------------------------------------------------------------------------------------
Learn a little bit about the Algorithmic stablecoin Djed coming to Cardano.
Genesis Key Delegation[](https://developers.cardano.org/docs/get-started/technical-concepts/#genesis-key-delegation "Direct link to Genesis Key Delegation")
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Learn about how Genesis Keys work on cardano and how they are delegated.
Music NFTs[](https://developers.cardano.org/docs/get-started/technical-concepts/#music-nfts "Direct link to Music NFTs")
--------------------------------------------------------------------------------------------------------------------------
Learn and dive into CIP-60 which is the Music NFT metadata standard on Cardano.
Pointer Addresses[](https://developers.cardano.org/docs/get-started/technical-concepts/#pointer-addresses "Direct link to Pointer Addresses")
-----------------------------------------------------------------------------------------------------------------------------------------------
Learn and dive into CPS-0002 which focuses on Pointer Addresses.
Kogmios[](https://developers.cardano.org/docs/get-started/technical-concepts/#kogmios "Direct link to Kogmios")
-----------------------------------------------------------------------------------------------------------------
Learn about Kogmios, a Kotlin library for communicating with Ogmios.
Aiken[](https://developers.cardano.org/docs/get-started/technical-concepts/#aiken "Direct link to Aiken")
-----------------------------------------------------------------------------------------------------------
Learn about Aiken, a bespoke smart contract language for Cardano.
Voltaire Governance[](https://developers.cardano.org/docs/get-started/technical-concepts/#voltaire-governance "Direct link to Voltaire Governance")
-----------------------------------------------------------------------------------------------------------------------------------------------------
Learn about the upcoming CIP-1694 and how voting and governance might work in the Voltaire era.
NEWM Catalyst F9 Update[](https://developers.cardano.org/docs/get-started/technical-concepts/#newm-catalyst-f9-update "Direct link to NEWM Catalyst F9 Update")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Learn about projects from Catalyst Fund 9 and where they're at today.
* [Introduction to Cardano: the big picture](https://developers.cardano.org/docs/get-started/technical-concepts/#introduction-to-cardano-the-big-picture)
* [Unspent Transaction Output (UTxO)](https://developers.cardano.org/docs/get-started/technical-concepts/#unspent-transaction-output-utxo)
* [Transactions](https://developers.cardano.org/docs/get-started/technical-concepts/#transactions)
* [Addresses](https://developers.cardano.org/docs/get-started/technical-concepts/#addresses)
* [Transaction Fees](https://developers.cardano.org/docs/get-started/technical-concepts/#transaction-fees)
* [Mnemonic seed phrase (BIP39)](https://developers.cardano.org/docs/get-started/technical-concepts/#mnemonic-seed-phrase-bip39)
* [Key Derivation](https://developers.cardano.org/docs/get-started/technical-concepts/#key-derivation)
* [Block and transaction propagation](https://developers.cardano.org/docs/get-started/technical-concepts/#block-and-transaction-propagation)
* [Networking](https://developers.cardano.org/docs/get-started/technical-concepts/#networking)
* [Cardano Improvement Proposals (CIP)](https://developers.cardano.org/docs/get-started/technical-concepts/#cardano-improvement-proposals-cip)
* [Slot Lottery](https://developers.cardano.org/docs/get-started/technical-concepts/#slot-lottery)
* [Slot Battles](https://developers.cardano.org/docs/get-started/technical-concepts/#slot-battles)
* [Catalyst Voting](https://developers.cardano.org/docs/get-started/technical-concepts/#catalyst-voting)
* [Franken Addresses](https://developers.cardano.org/docs/get-started/technical-concepts/#franken-addresses)
* [NFT](https://developers.cardano.org/docs/get-started/technical-concepts/#nft)
* [Catalyst Voting Registration](https://developers.cardano.org/docs/get-started/technical-concepts/#catalyst-voting-registration)
* [Epoch Nonce](https://developers.cardano.org/docs/get-started/technical-concepts/#epoch-nonce)
* [Guaranteed Transaction Delivery](https://developers.cardano.org/docs/get-started/technical-concepts/#guaranteed-transaction-delivery)
* [SundaeSwap & Merkel Trees](https://developers.cardano.org/docs/get-started/technical-concepts/#sundaeswap--merkel-trees)
* [DripDropz & Phyrhose](https://developers.cardano.org/docs/get-started/technical-concepts/#dripdropz--phyrhose)
* [P2P Networking](https://developers.cardano.org/docs/get-started/technical-concepts/#p2p-networking)
* [TPS vs. eUTxO](https://developers.cardano.org/docs/get-started/technical-concepts/#tps-vs-eutxo)
* [LocalTxMonitor](https://developers.cardano.org/docs/get-started/technical-concepts/#localtxmonitor)
* [Network Congestion](https://developers.cardano.org/docs/get-started/technical-concepts/#network-congestion)
* [Multisig](https://developers.cardano.org/docs/get-started/technical-concepts/#multisig)
* [JorManager 6](https://developers.cardano.org/docs/get-started/technical-concepts/#jormanager-6)
* [How to create a FT on Cardano that doesn't completely suck!](https://developers.cardano.org/docs/get-started/technical-concepts/#how-to-create-a-ft-on-cardano-that-doesnt-completely-suck)
* [Governance Snapshots](https://developers.cardano.org/docs/get-started/technical-concepts/#governance-snapshots)
* [Djed Stablecoin](https://developers.cardano.org/docs/get-started/technical-concepts/#djed-stablecoin)
* [Genesis Key Delegation](https://developers.cardano.org/docs/get-started/technical-concepts/#genesis-key-delegation)
* [Music NFTs](https://developers.cardano.org/docs/get-started/technical-concepts/#music-nfts)
* [Pointer Addresses](https://developers.cardano.org/docs/get-started/technical-concepts/#pointer-addresses)
* [Kogmios](https://developers.cardano.org/docs/get-started/technical-concepts/#kogmios)
* [Aiken](https://developers.cardano.org/docs/get-started/technical-concepts/#aiken)
* [Voltaire Governance](https://developers.cardano.org/docs/get-started/technical-concepts/#voltaire-governance)
* [NEWM Catalyst F9 Update](https://developers.cardano.org/docs/get-started/technical-concepts/#newm-catalyst-f9-update)
---
# Get Started in the Cardano Developer Community | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-developer-community/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Apart from the two leading platforms [Stack Exchange](https://cardano.stackexchange.com/)
and [Cardano Forum](https://forum.cardano.org/c/developers/29)
, Cardano developers and stake pool operators spread across different platforms. Each with its niche.
Cardano developers channels[](https://developers.cardano.org/docs/get-started/cardano-developer-community/#cardano-developers-channels "Direct link to Cardano developers channels")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[**cardano.stackexchange.com**](https://cardano.stackexchange.com/)
Stack Exchange communities are democratically created and maintained. It is a question-and-answer website, not meant for extensive discussion or opinions.
[**forum.cardano.org**](https://forum.cardano.org/c/developers/29)
The developer categories on the [Cardano Forum](https://forum.cardano.org/c/developers/29)
is an excellent place for extensive discussions and opinions, but also to get support.
[**Cardano Community Discord**](https://discord.gg/kfATXEENPD)
Visit the developer categories on the [Cardano Community Discord](https://discord.gg/kfATXEENPD)
if you prefer chat-style conversations.
[**reddit.com/r/CardanoDevelopers**](https://www.reddit.com/r/CardanoDevelopers/)
A subreddit dedicated to everyone building on the Cardano blockchain.
[**t.me/CardanoDevelopersOfficial**](https://t.me/CardanoDevelopersOfficial)
Chat style conversations on Telegram in one of the oldest Cardano developer groups.
[**IOG Technical Discord**](https://discord.com/invite/w6TwW9bGA6)
Head to the [IOG Discord](https://discord.com/invite/w6TwW9bGA6)
if you want to join the [Plutus Pioneers](https://developers.cardano.org/docs/smart-contracts/plutus#get-started-with-the-plutus-pioneer-program)
.
[**t.me/IOHK\_Marlowe**](https://t.me/IOHK_Marlowe)
Dedicated channel for Marlowe developers and users. Marlowe is a specialised domain-specific language for financial smart contracts on Cardano. You can ask questions, participate in discussions and meet the team behind Marlowe.
[**CIPs - biweekly meetings**](https://discord.com/invite/Jy9YM69Ezf)
CIP meetings discuss Cardano Improvement Proposals every other week. Join Editors and community members in the dedicated discord server to keep up with the ongoing technical discussions regarding standards, processes and ongoing Cardano conversations.
Stake pool operator channels[](https://developers.cardano.org/docs/get-started/cardano-developer-community/#stake-pool-operator-channels "Direct link to Stake pool operator channels")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[**t.me/CardanoStakePoolWorkgroup**](https://t.me/CardanoStakePoolWorkgroup)
Best practice workgroup on Telegram for stake pool operators. This group is hectic. A good resource to search for answers.
[**forum.cardano.org**](https://forum.cardano.org/c/staking-delegation/156)
If you care about well structured, long format discussions, visit the stake pool operator categories on [forum.cardano.org](https://forum.cardano.org/c/staking-delegation/156)
.
Developer Surveys[](https://developers.cardano.org/docs/get-started/cardano-developer-community/#developer-surveys "Direct link to Developer Surveys")
--------------------------------------------------------------------------------------------------------------------------------------------------------
[**Developer Ecosystem Survey 2022**](https://cardano-foundation.github.io/state-of-the-developer-ecosystem/2022)
For the first time ever, an annual survey to assess the state of the Cardano developer ecosystem was conducted. This survey comes as part of our commitment to both empower the Cardano community and foster the open source maturity of the Cardano ecosystem.
[**Developer Ecosystem Survey 2023**](https://cardano-foundation.github.io/state-of-the-developer-ecosystem)
The second edition of the annual survey to assess the state of the Cardano developer ecosystem was conducted.
* [Cardano developers channels](https://developers.cardano.org/docs/get-started/cardano-developer-community/#cardano-developers-channels)
* [Stake pool operator channels](https://developers.cardano.org/docs/get-started/cardano-developer-community/#stake-pool-operator-channels)
* [Developer Surveys](https://developers.cardano.org/docs/get-started/cardano-developer-community/#developer-surveys)
---
# Installing cardano-wallet | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
### Overview[](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#overview "Direct link to Overview")
In this guide, we will show you how to compile and install `cardano-wallet` into your operating system of choice, directly from the source-code. This component provides a [CLI (Command Line Interface)](https://en.wikipedia.org/wiki/Command-line_interface)
and [Web API](https://en.wikipedia.org/wiki/Web_API)
for creating multiple **Cardano** wallets, sending transactions, getting transaction history details, wallet balances and more!
note
If you want to avoid compiling the binaries yourself, you can download the latest pre-built binaries from the GitHub repository: [`cardano-wallet` Releases](https://github.com/cardano-foundation/cardano-wallet/releases)
This guide assumes you have installed `cardano-node` and `cardano-cli` into your system. If not you can refer to [Installing cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
guide for instructions on how to do that.
important
You must connect your `cardano-node` to a [testnet network](https://developers.cardano.org/docs/get-started/testnets-and-devnets)
and make sure it is fully synchronized. If you are not sure how to do that, It is recommended to read [Running cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano)
guide before proceeding.
### Choose your Platform[](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#choose-your-platform "Direct link to Choose your Platform")
* [MacOS / Linux](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#macos--linux)
* [Windows](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#windows)
MacOS / Linux[](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#macos--linux "Direct link to MacOS / Linux")
---------------------------------------------------------------------------------------------------------------------------------------------
In this section, we will walk you through the process of downloading, compiling and installing `cardano-wallet` into your **Linux / MacOS** based operating system.
#### Downloading & Compiling[](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#downloading--compiling "Direct link to Downloading & Compiling")
We need to install cabal, if we don't have it. See the following link for instructions: [https://www.haskell.org/cabal/](https://www.haskell.org/cabal/)
If you have followed the [Installing cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
guide, You should have the `$HOME/cardano-src` directory. If not, let's create a working directory to store the source-code and build for `cardano-wallet`.
mkdir -p $HOME/cardano-srccd $HOME/cardano-src
Next we download the `cardano-wallet` source-code:
git clone https://github.com/cardano-foundation/cardano-wallet.git cd ./cardano-wallet/
Switch the repository to the latest tagged commit:
TAG=$(git describe --tags --abbrev=0) && echo latest tag $TAG git checkout $TAG
important
You can check the latest available version / tag by visiting the `cardano-wallet` [Github Release](https://github.com/cardano-foundation/cardano-wallet/releases)
page. At the time of writing this, the current version is `v2021-11-11`. You can list all tags also with `git tag -l` command.
#### Building and installing the node[](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#building-and-installing-the-node "Direct link to Building and installing the node")
We can now build `cardano-wallet` code to produce executable binaries.
cabal build all
Install the newly built `cardano-wallet` binary to the `$HOME/.local/bin` directory:
cabal install cardano-wallet
Check the version that has been installed:
cardano-wallet version
You should see something like this:
v2021-11-11 (git revision: dac16ba7e3bf64bf5474497656932fd342c3b720)
Congratulations, you have successfully installed `cardano-wallet` into your Linux/MacOS system! 🎉🎉🎉
Windows[](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#windows "Direct link to Windows")
----------------------------------------------------------------------------------------------------------------------------
important
Currently, the **Windows** installation guide is still in-progress. In the meantime we recommend using [WSL (Windows Subsystem for Linux)](https://docs.microsoft.com/en-us/windows/wsl/)
to get a Linux environment on-top of Windows. Once you have that installed you can use the [Linux](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#macos--linux)
guide to install and run `cardano-node` within **WSL**.
Optionally, you can download the latest precompiled Windows binary from the GitHub repository: [`cardano-wallet` Releases](https://github.com/cardano-foundation/cardano-wallet/releases)
* [Overview](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#overview)
* [Choose your Platform](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#choose-your-platform)
* [MacOS / Linux](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#macos--linux)
* [Windows](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet/#windows)
---
# Air Gap Environment | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/air-gap/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
"Air gap" originally meant a computer or subnetwork was surrounded by "air" — as defined by no data cable connections in or out — so it would be isolated from other computers & networks. These days it also means there are no radio-based network connections either (WiFi, Bluetooth, etc.).
Developers & Cardano stake pool operators generally need an air gap environment in which to work with payment keys, stake pool keys and other cryptocurrency resources that offer high-value targets for hackers.
Some specialised hardware (e.g. hardware wallets) may also perform this function. If you believe you have such a device, please be certain that it offers isolation features for your stake pool or development _and_ that you feel secure entrusting your assets to those who have implemented these features.
Otherwise, generally **you need a second computer** to create this air-gapped environment, and the rest of this guide is to help you do that.
Linux veterans only
If you don't have an extra computer, or want to try building a standalone Linux environment on a USB drive, [skip to the final section](https://developers.cardano.org/docs/get-started/air-gap/#option-2-install-your-air-gap-environment-on-a-persistent-usb-drive)
.
Option 1: Install your air gap environment on a standalone computer[](https://developers.cardano.org/docs/get-started/air-gap/#option-1-install-your-air-gap-environment-on-a-standalone-computer "Direct link to Option 1: Install your air gap environment on a standalone computer")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Choose the right computer[](https://developers.cardano.org/docs/get-started/air-gap/#choose-the-right-computer "Direct link to Choose the right computer")
You will get better results from an Intel PC than a Mac:
* Mac booting has peculiarities that are too complicated to generally address here: therefore the rest of this document assumes you'll be using a PC and not a Mac.
You will need this computer's whole disc:
* Any second drive should be removed if you don't know how to completely disable it in the Linux installation process.
* The modern minimum drive size of 80GB will be enough for the Linux installation _and_ all your Cardano support files, even if you are building them from scratch.
You can use an older machine, even a _very_ old one:
* Linux, although well supported on most new machines, is less likely to have missing device drivers on older machines: so you might do better with an older machine than a newer one.
* This suits many developers & SPOs since an old or retired extra machine, or one with damaged software which will be replaced in the installation process, will be a good candidate to devote to the single purpose of an air gap environment.
### Confirm Ubuntu as installation OS, or choose differently[](https://developers.cardano.org/docs/get-started/air-gap/#confirm-ubuntu-as-installation-os-or-choose-differently "Direct link to Confirm Ubuntu as installation OS, or choose differently")
We choose Ubuntu here because:
* It's a common choice on servers, so if you're building a stake pool you'll have the option of copying your `cardano-cli` binary from a stake pool server to the air gap machine instead of compiling it again.
* The Ubuntu desktop environment & commands are arguably better documented on the Internet than any other Linux distribution. Getting help needs to be as easy as possible since you won't be able to search the Internet for help on the air gap machine itself.
The rest of these instructions will assume the choice of **Ubuntu** for your air gap environment OS. If installing a different variant of Linux, please remember:
* When you read the term Ubuntu or show screenshots of its installer, look for equivalents on your own chosen Linux variant.
* There may be better choices than Ubuntu now or in the future: please feel free to share your results with others in the Cardano community, perhaps [contributing](https://developers.cardano.org/docs/portal-contribute)
your findings & procedures here on the Developer Portal.
### Prepare to follow Ubuntu installation instructions[](https://developers.cardano.org/docs/get-started/air-gap/#prepare-to-follow-ubuntu-installation-instructions "Direct link to Prepare to follow Ubuntu installation instructions")
Read through the standard Ubuntu installation steps here (external link): [Ubuntu Tutorials > Install Ubuntu desktop](https://ubuntu.com/tutorials/install-ubuntu-desktop)
#### Decide in advance whether to encrypt your air gap machine's files.[](https://developers.cardano.org/docs/get-started/air-gap/#decide-in-advance-whether-to-encrypt-your-air-gap-machines-files "Direct link to Decide in advance whether to encrypt your air gap machine's files.")
When setting up the Ubuntu filesystems, you'll be given the option of creating a Volume Group so it can encrypt your entire partition contents with a variant of the AES algorithm.
caution
Your boot and UEFI partitions might not be encrypted, depending on the type of computer you have & version of the GRUB software with your OS installer.
Therefore, as a precaution, never attach a USB drive to your air gap machine unless you've either formatted the drive or built it as installation media.
The main advantage to encrypting your air gap system:
* Someone gaining physical access to your machine, or stealing it, will be prevented from violating your address (e.g. stealing your stake pool pledge!) or stake pool (e.g. cloning your stake pool) security. 😎
The main disadvantage to encrypting it:
* If you lose your disk encryption password, or set it incorrectly to something you can't reproduce, you will effectively lose all the data on the air gap machine's disk... including any account information or keys stored there. 😖
#### (optional, if encrypting your partition) Choose encryption password[](https://developers.cardano.org/docs/get-started/air-gap/#optional-if-encrypting-your-partition-choose-encryption-password "Direct link to (optional, if encrypting your partition) Choose encryption password")
Suggested password requirements:
* has never been transmitted over, or stored in, cleartext on the Internet, or stored in cleartext on your computer itself (just in case your air gap is accidentally broken)
* has length & complexity enough to hash to about 2^128 possible values: this means at least 20 apparently random characters.
### Begin standard Ubuntu installation (with some modifications)[](https://developers.cardano.org/docs/get-started/air-gap/#begin-standard-ubuntu-installation-with-some-modifications "Direct link to Begin standard Ubuntu installation (with some modifications)")
As you follow the standard procedure (also linked above), stop at the points in the headings below to ensure you're installing your air gap environment correctly.
Before starting, there is no need to physically disconnect your chosen air gap machine from the Internet, or do anything to your home router to disable WiFi.
note
The Internet will be unconfigured and disconnected after the OS is installed & patched and a small number of initial packages are installed (including the Cardano CLI).
### Follow instructions: [Ubuntu Tutorials > Install Ubuntu desktop](https://ubuntu.com/tutorials/install-ubuntu-desktop)
[](https://developers.cardano.org/docs/get-started/air-gap/#follow-instructions-ubuntu-tutorials--install-ubuntu-desktop "Direct link to follow-instructions-ubuntu-tutorials--install-ubuntu-desktop")
... paying particular attention to these steps:
#### Wireless (if asked)[](https://developers.cardano.org/docs/get-started/air-gap/#wireless-if-asked "Direct link to Wireless (if asked)")
If your computer doesn't have a cabled connection, it is acceptable under our security model to add it to the WiFi network during OS installation.
* Whatever wireless key you enter _will_ be retained on the installed system, _but_ you will be reminded to disconnect the Internet before the end of our own procedure.
#### Updates and other software[](https://developers.cardano.org/docs/get-started/air-gap/#updates-and-other-software "Direct link to Updates and other software")

Select **Minimal installation**, since this is the least likely to leave you with security intrusive applications and services.
* The "Normal" installation has cloud based services and games which tend to initiate Internet connections.
* LibreOffice software is not included in the "minimal" packages but is recommended to add later (since it helps encrypt password & mnemonic backups).
**Do not select** (as you normally would) the option for **third-party software for graphics and WiFi** because of the potential for institutional spyware.
* Your graphics will be stable & high enough resolution without the performance enhancements of proprietary graphics drivers (otherwise you wouldn't see this installation screen).
* WiFi performance enhancements are likewise unnecessary because you generally won't be using WiFi, and if you need a network cable you'll be disconnecting it soon & won't be using it again.
#### Installation type[](https://developers.cardano.org/docs/get-started/air-gap/#installation-type "Direct link to Installation type")

Tick **Erase disk and install Ubuntu**.... you've already confirmed there's nothing else that needs to be kept on this computer, and that it won't have any other operating systems or working disks.
caution
The air gap installation should not be a part of any conventional dual-booting environment because of the inevitable security risks that would create.
Before you hit **Continue**, if you've chosen to encrypt your files:
##### (optional) Set up the hard drive for encryption[](https://developers.cardano.org/docs/get-started/air-gap/#optional-set-up-the-hard-drive-for-encryption "Direct link to (optional) Set up the hard drive for encryption")

Hit the button below the _Erase disk_ option: **Advanced Features** which will at first say _None selected_.
* Tick the feature **Use LVM with the new Ubuntu installation**.
* Tick the option below it: **Encrypt the new Ubuntu installation for security**.
Don’t hit the **Continue** button unless you can verify it now says _**LVM and encryption selected**_ under Advanced options:

Enter the password you have prepared earlier as a **volume decryption key.**
* At this point you might want to check a few times that you can type this password properly: either with consistency from written notes, or from memory.
* To double check in this installation environment: move over to the left (the "dock") where you'll see a text editor icon, in which you can practice typing the password without leaving a record.
* At this point the disk is only emulated in RAM: but just to be safe, don't save this file anywhere!
#### Finish & reboot[](https://developers.cardano.org/docs/get-started/air-gap/#finish--reboot "Direct link to Finish & reboot")
Confirm the installation drive, click **Install now** and **Continue**.
* The rest of the options (user name & information, login method, etc.) can be set according to your inclination.
Ubuntu will finish installing and then you'll be prompted to remove the installation media & reboot. When rebooting, you will see two things you may never have seen before:
* If you followed these recommendations to only install one single OS on one single disk, the boot menu you see (from [GRUB](https://help.ubuntu.com/community/Grub2)
) will have only one choice: **Ubuntu**, with the software you just installed, which will be selected by default after a few seconds whenever the system starts.
* If you selected the encryption option for your Ubuntu system, you will need to enter the encryption password every time you start the system.
### Configure Ubuntu according to security recommendations[](https://developers.cardano.org/docs/get-started/air-gap/#configure-ubuntu-according-to-security-recommendations "Direct link to Configure Ubuntu according to security recommendations")
At the screen "Welcome to Ubuntu" (which new users are currently _forced_ to interact with), _refuse **everything**_ it offers you:
* no online accounts
* no Canonical Livepatch
* no sending any system information, ever!
* no Location Services
#### Basic security tightening at command line[](https://developers.cardano.org/docs/get-started/air-gap/#basic-security-tightening-at-command-line "Direct link to Basic security tightening at command line")
##### Remove packages requiring routine network access:[](https://developers.cardano.org/docs/get-started/air-gap/#remove-packages-requiring-routine-network-access "Direct link to Remove packages requiring routine network access:")
sudo apt remove cupssudo apt remove unattended-upgrades
##### (optional) Remove Snap software subsystem.[](https://developers.cardano.org/docs/get-started/air-gap/#optional-remove-snap-software-subsystem "Direct link to (optional) Remove Snap software subsystem.")
[Snap](https://snapcraft.io/)
is questionable for security reasons because (like [AppImage](https://appimage.org/)
and [Flatpak](https://flatpak.org/)
) it links application components with libraries that don't have to be compiled from source or security-vetted like the libraries that come with your OS itself.
Removing Snap is optional because default snaps on the Ubuntu installation media have the same security provenance as the default packages on that same release... yet snaps will also be upgraded in the next part of this procedure, and these upgraded snaps may not be subjected to the same security vetting.
To proceed with removing Snap, follow these instructions (the exact procedure changes often & these instructions may be the best maintained to date):
* **[How do I turn off snap in Ubuntu?](https://linuxhint.com/turn-off-snap-ubuntu/)
**
#### Update system software & all packages to current time[](https://developers.cardano.org/docs/get-started/air-gap/#update-system-software--all-packages-to-current-time "Direct link to Update system software & all packages to current time")
This will upgrade everything on your system from what you received on installation media:
sudo apt updatesudo apt upgrade
#### Install minimal set of packages for encrypting files/folders & text documents[](https://developers.cardano.org/docs/get-started/air-gap/#install-minimal-set-of-packages-for-encrypting-filesfolders--text-documents "Direct link to Install minimal set of packages for encrypting files/folders & text documents")
##### (optional) Install LibreOffice[](https://developers.cardano.org/docs/get-started/air-gap/#optional-install-libreoffice "Direct link to (optional) Install LibreOffice")
This is recommended because it will give you a means of taking password-encrypted notes that can move between your air gap and computer host environments _in both directions_, so you can:
* record transaction details from your home computer environment & Internet connected machines, for use in the air gap (as per [Secure Workflow](https://developers.cardano.org/docs/get-started/secure-workflow)
):
* your Cardano account balances, UTxO addresses & payment addresses
* notes from personal files & web sites about the work you will be doing within the air gap (since you won't have Internet access there);
* take notes in the air gap environment (problems, error messages) to copy back to your computer, since you can't upload them through the air gap.
LibreOffice documents saved with a password are entirely AES-encrypted with a key deriving from that password, which produces arguably the best commercially available security for files & data.
To install:
sudo apt install libreoffice
#### Install encrypting archiver[](https://developers.cardano.org/docs/get-started/air-gap/#install-encrypting-archiver "Direct link to Install encrypting archiver")
Whether a developer or a stake pool operator, at some point you will also need to encrypt files & folders so they can be extracted on your stake pool or application server, where LibreOffice will generally not run but you can use the installable command `p7zip` instead:
apt install p7zip-full p7zip-rar
Adding the extra package `p7zip-rar` should make saving files with encryption & compression an option in your file manager (`nautilus`).
#### Install secure deletion tools[](https://developers.cardano.org/docs/get-started/air-gap/#install-secure-deletion-tools "Direct link to Install secure deletion tools")
You might need to erase any trace of an unencrypted file that could lead to loss of your funds or Cardano enterprises if it were reconstructed (since ordinary file deletions don't delete data blocks). Therefore you should [install the `secure-delete` tools](https://www.unixmen.com/securely-delete-hard-drive-data-with-secure-delete/)
to allow you to zero-write files & their metadata or drive contents & empty disk space:
apt install secure-delete
### Reboot again[](https://developers.cardano.org/docs/get-started/air-gap/#reboot-again "Direct link to Reboot again")
This confirms that your system will start properly after having updated your system software.
### Install `cardano-cli`[](https://developers.cardano.org/docs/get-started/air-gap/#install-cardano-cli "Direct link to install-cardano-cli")
Use the standard instructions here at the Developer Portal:
* **[Installing the node from source](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
**
Note this will build `cardano-node` as well as `cardano-cli`, but don't worry: you won't be running a node inside the air gap. 😜
### Unplug from Internet FOREVER[](https://developers.cardano.org/docs/get-started/air-gap/#unplug-from-internet-forever "Direct link to Unplug from Internet FOREVER")
We will leave the definition of "forever" up to your understanding of Internet threats and whether these can come from OS package repositories, etc., with this in mind:
* Software updates at 6-month intervals (e.g. after the Ubuntu "point releases") will patch security problems identified during that period: as well as install new software which may introduce _new_ security problems.
* Any spyware or backdoor deliberately placed in the package upgrades on Ubuntu or any other version of Linux could generally just as easily have been placed on the packages used to build your installation media.
### Precautions to avoid accidental connection to the Internet[](https://developers.cardano.org/docs/get-started/air-gap/#precautions-to-avoid-accidental-connection-to-the-internet "Direct link to Precautions to avoid accidental connection to the Internet")
#### BIOS settings: disable WiFi and Ethernet connection[](https://developers.cardano.org/docs/get-started/air-gap/#bios-settings-disable-wifi-and-ethernet-connection "Direct link to BIOS settings: disable WiFi and Ethernet connection")
See your computer instructions to review how to get into the BIOS, if you're interested in disabling the network adapters at a very low level so they can't accidentally (or due to a hack) be turned on in software.
* If there's no BIOS setting, WiFi can usually be disabled almost as easily on laptops by opening them up to remove, or disconnect the leads to, the WiFi card.
#### Put Ubuntu in [Airplane mode](https://help.ubuntu.com/stable/ubuntu-help/net-wireless-airplane.html)
[](https://developers.cardano.org/docs/get-started/air-gap/#put-ubuntu-in-airplane-mode "Direct link to put-ubuntu-in-airplane-mode")
This will disable any Bluetooth services as well as WiFi, and shows as an Airplane on Ubuntu & other GNOME desktops as an airplane icon in the upper right corner of the screen.
With Airplane Mode always engaged, you would need the obvious Internet cable plugged in to have any network access (unlike WiFi which can often be connected by accident).
#### Add your computer's WiFi MAC address to the blacklist on your Internet router[](https://developers.cardano.org/docs/get-started/air-gap/#add-your-computers-wifi-mac-address-to-the-blacklist-on-your-internet-router "Direct link to Add your computer's WiFi MAC address to the blacklist on your Internet router")
Some routers maintain a list of MAC addresses which will not be given an IP address by DHCP, which isolates them from the Internet unless that network interface is configured manually.
Therefore, you can [find your WiFi MAC address](https://help.ubuntu.com/stable/ubuntu-help/net-macaddress.html.en)
and add it to your router's blacklist: usually in its DNS, DHCP, or LAN settings.
### Congratulations, your air gap environment is complete
You now have a safe place you can use for your [Secure Transaction Workflow](https://developers.cardano.org/docs/get-started/secure-workflow)
.
Option 2: Install your air gap environment on a persistent USB drive[](https://developers.cardano.org/docs/get-started/air-gap/#option-2-install-your-air-gap-environment-on-a-persistent-usb-drive "Direct link to Option 2: Install your air gap environment on a persistent USB drive")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
caution
Linux veterans only! (otherwise please [follow option 1](https://developers.cardano.org/docs/get-started/air-gap/#option-1-install-your-air-gap-environment-on-a-standalone-computer)
)
This option may suit more demanding users, especially those:
* who travel a lot and need to maintain their Cardano operations "on the road";
* who need the convenience of booting in an air gap environment which has direct access to all their files on the host computer (as you would when booting off from an installer USB drive);
* who, instead of using a USB drive to transfer unencrypted files in & out of the air gap, would rather use that same USB drive to store these files with encryption while also providing the Cardano CLI for use on any machine supporting the same boot method;
* who want to make encrypted backups or their keys, passwords and other records from their air gap environment directly to the host computer.
If this appeals to you, and you don't mind following a more complicated and error-prone installation procedure, you might want to install the air gap environment on a bootable USB drive instead. You can then boot a computer from this drive to have access to your secure resources and `cardano-cli` while isolating that computer from the Internet as well as any malicious software that might be installed on that computer.
This loosely documented configuration has been called the **Frankenwallet**, with separate instructions at these links which mostly follow the procedure above:
* **[The Frankenwallet](https://frankenwallet.com/)
** - detailed external web site, including semantics for using your bootable USB environment in secure & blockchain workflow
* [Get Started with the Frankenwallet](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet)
- one-page summary here on the Developer Portal
warning
These instructions may be difficult or unsafe to follow unless you have experience with "dual boot" Linux installations and other custom OS & booting configurations.
* [Option 1: Install your air gap environment on a standalone computer](https://developers.cardano.org/docs/get-started/air-gap/#option-1-install-your-air-gap-environment-on-a-standalone-computer)
* [Choose the right computer](https://developers.cardano.org/docs/get-started/air-gap/#choose-the-right-computer)
* [Confirm Ubuntu as installation OS, or choose differently](https://developers.cardano.org/docs/get-started/air-gap/#confirm-ubuntu-as-installation-os-or-choose-differently)
* [Prepare to follow Ubuntu installation instructions](https://developers.cardano.org/docs/get-started/air-gap/#prepare-to-follow-ubuntu-installation-instructions)
* [Begin standard Ubuntu installation (with some modifications)](https://developers.cardano.org/docs/get-started/air-gap/#begin-standard-ubuntu-installation-with-some-modifications)
* [Follow instructions: Ubuntu Tutorials > Install Ubuntu desktop](https://developers.cardano.org/docs/get-started/air-gap/#follow-instructions-ubuntu-tutorials--install-ubuntu-desktop)
* [Configure Ubuntu according to security recommendations](https://developers.cardano.org/docs/get-started/air-gap/#configure-ubuntu-according-to-security-recommendations)
* [Reboot again](https://developers.cardano.org/docs/get-started/air-gap/#reboot-again)
* [Install `cardano-cli`](https://developers.cardano.org/docs/get-started/air-gap/#install-cardano-cli)
* [Unplug from Internet FOREVER](https://developers.cardano.org/docs/get-started/air-gap/#unplug-from-internet-forever)
* [Precautions to avoid accidental connection to the Internet](https://developers.cardano.org/docs/get-started/air-gap/#precautions-to-avoid-accidental-connection-to-the-internet)
* [Congratulations, your air gap environment is complete!](https://developers.cardano.org/docs/get-started/air-gap/#congratulations-your-air-gap-environment-is-complete)
* [Option 2: Install your air gap environment on a persistent USB drive](https://developers.cardano.org/docs/get-started/air-gap/#option-2-install-your-air-gap-environment-on-a-persistent-usb-drive)
---
# Get started with testnets | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Cardano testnets[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#cardano-testnets "Direct link to Cardano testnets")
----------------------------------------------------------------------------------------------------------------------------------------------
The [Cardano testnets](https://docs.cardano.org/cardano-testnets/environments)
are your playgrounds when testing [Cardano integration](https://developers.cardano.org/docs/integrate-cardano/)
, building with [transaction metadata](https://developers.cardano.org/docs/transaction-metadata/)
, exploring [native tokens](https://developers.cardano.org/docs/native-tokens/)
or learning how to [operate a stake pool](https://developers.cardano.org/docs/operate-a-stake-pool/)
.
The testnets are an essential part of the development process for Cardano, as they allow developers to test and refine their code before deploying it on the live network, ultimately improving reliability and security.
### What testnet should I use?[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#what-testnet-should-i-use "Direct link to What testnet should I use?")
#### Preview Testnet[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#preview-testnet "Direct link to Preview Testnet")
* The Preview Testnet is a testing environment used to showcase new features and functionality to the Cardano community before they are deployed on the Mainnet.
* It allows developers and users to test and provide feedback on new features and changes before they are released to the wider community.
* The Preview Testnet helps to ensure that new features are user-friendly and meet the needs of the community, ultimately improving the user experience on the Mainnet.
* Leads Mainnet hard forks by at least 4 weeks.
You can download the current Cardano blockchain network configuration files for Preview Testnet here: [The Cardano Operations Book > Preview Testnet.](https://book.world.dev.cardano.org/environments.html#preview-testnet)
#### Guild Network[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#guild-network "Direct link to Guild Network")
* Guild Network is a community maintained public testnet network that is primarily useful for 'quick' testing for development/integrations, as it runs short 1-hour epochs.
* The primary use case for this network is often short-term scope-specific testing, it has gone through previous forks on the Cardano chain with minimal data to ensure we do have different data objects across older forks. The faucet distribution for this network is manual and available with members across timezones based on request in [support](https://t.me/guild_operators_official)
channel.
* The timeline for forks lead Mainnet but are flexible depending on community needs that could be discussed on [github](https://github.com/cardano-community/guild-operators/)
(unless specific conditions require testing beforehand), and is useful for testing data against longer history (over 10K epochs).
You can download the current Cardano blockchain network configuration files for Guild Network [here](https://github.com/cardano-community/guild-operators/tree/alpha/files)
#### Pre-Production Testnet[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#pre-production-testnet "Direct link to Pre-Production Testnet")
* The Pre-Production Testnet is a testing environment used to validate major upgrades and releases before deployment to the Mainnet.
* It is a staging area where developers can simulate real-world scenarios and ensure that everything is working as expected before going live.
* The preprod testnet helps to minimize the risk of bugs, security issues, and other problems that could negatively impact the Mainnet.
* Hard forks at approximately the same time as Mainnet (within an epoch of each other)
You can download the current Cardano blockchain network configuration files for Pre-Production Testnet here: [The Cardano Operations Book > Pre-Production Testnet.](https://book.world.dev.cardano.org/env-preprod.html)
#### Summary[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#summary "Direct link to Summary")
The Pre-Production Testnet is a more comprehensive testing environment used to validate major upgrades, while the Preview Testnet is a more targeted testing environment used to showcase new features and gather feedback from the community.
### Where to get a testnet wallet?[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#where-to-get-a-testnet-wallet "Direct link to Where to get a testnet wallet?")
* [Lace Wallet](https://www.lace.io/)
is a lightweight wallet developed by IOG and supports both PreProd, Preview and Sancho testnets.
* [Eternl Wallet](https://eternl.io/)
is a another lightweight wallet supporting both with PreProd, Preview and Sancho testnets.
* [Yoroi Nightly Wallet](https://chromewebstore.google.com/detail/yoroi-nightly/poonlenmfdfbjfeeballhiibknlknepo?hl=en&authuser=0)
is a lightweight wallet developed by Emurgo and supports PreProd, PreView and Sancho testnet.
* [Typhon Wallet](https://testnet.typhonwallet.io/#/wallet/access)
is a lightweight wallet developed by StricaHQ and supports PreProd testnet.
* [Ledger Nano S and Ledger Nano X](https://www.ledger.com/)
are hardware wallets that support both PreProd and Preview testnets.
* [Cardano-wallet](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-wallet)
is a convenient way of using the cardano-wallet HTTP Application Programming Interface.
It's important to note that while all of these wallets support Cardano testnets, you will need to choose the testnet network option within the wallet when setting it up or switching to testnet, or choose the right version before you install a specific testnet wallet.
### Where to get test ada?[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#where-to-get-test-ada "Direct link to Where to get test ada?")
Because the [Cardano testnets](https://docs.cardano.org/cardano-testnets/environments/)
are independent networks, separate from the Cardano mainnet, they require their own token: test ada (tAda).
Test ada is worth nothing. With it you can safely perform all tests free of charge - the reason why you want to develop on the testnets.
To get free test ada for Preprod or Preview, you need to visit: [Cardano Testnet Faucet.](https://docs.cardano.org/cardano-testnets/tools/faucet)
In depth explanation about Cardano Testnet Faucet can be found [here.](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet/)
### Which block explorers can I use for the Cardano testnets?[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#which-block-explorers-can-i-use-for-the-cardano-testnets "Direct link to Which block explorers can I use for the Cardano testnets?")
* [testnet.cardanoscan.io](https://testnet.cardanoscan.io/)
is a Pre-Production and Preview block explorer by [Cardanoscan](https://cardanoscan.io/)
.
* [testnet.cexplorer.io](https://testnet.cexplorer.io/)
is a Pre-Production and Preview block explorer by [Cexplorer](https://cexplorer.io/)
.
### Which metadata explorers can I use for the Cardano testnets?[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#which-metadata-explorers-can-i-use-for-the-cardano-testnets "Direct link to Which metadata explorers can I use for the Cardano testnets?")
* [cardanoscan.io/metadata](https://preprod.cardanoscan.io/metadata)
is a preprod metadata explorer by [CardanoScan.io](https://cardanoscan.io/)
* [cexplorer.io/metadata](https://preprod.cexplorer.io/metadata)
is a preprod metadata explorer by [cExplorer.io](https://cexplorer.io/)
### What kind of monitoring tools are available for the testnets?[](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#what-kind-of-monitoring-tools-are-available-for-the-testnets "Direct link to What kind of monitoring tools are available for the testnets?")
* Set up your own node's [Grafana/Promtheus monitoring](https://developers.cardano.org/docs/operate-a-stake-pool/grafana-dashboard-tutorial/#4-setting-up-grafana-dashboard)
system
* [Cardano testnets](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#cardano-testnets)
* [What testnet should I use?](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#what-testnet-should-i-use)
* [Where to get a testnet wallet?](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#where-to-get-a-testnet-wallet)
* [Where to get test ada?](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#where-to-get-test-ada)
* [Which block explorers can I use for the Cardano testnets?](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#which-block-explorers-can-i-use-for-the-cardano-testnets)
* [Which metadata explorers can I use for the Cardano testnets?](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#which-metadata-explorers-can-i-use-for-the-cardano-testnets)
* [What kind of monitoring tools are available for the testnets?](https://developers.cardano.org/docs/get-started/testnets-and-devnets/#what-kind-of-monitoring-tools-are-available-for-the-testnets)
---
# Cardano Components | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-node/cardano-components/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
The Cardano blockchain is powered by a flock of inter-connected nodes. The [`cardano-node`](https://github.com/IntersectMBO/cardano-node)
is the software capable of running as a core block producer, as a relay or as a local entry-point to the network. The node itself is made out of several inter-connected component parts:
* [`The settlement layer`](https://github.com/IntersectMBO/cardano-ledger#cardano-ledger)
: a multi-era ledger implementation derived from a set of formal specifications. This is where the core Cardano entities are defined as well as the rules for using them. This is the bedrock on top of which all other components build upon.
* [`The consensus layer`](https://github.com/IntersectMBO/ouroboros-consensus#ouroboros-consensus)
: an implementation of the consensus layer of the Ouroboros family of protocols. If you've heard about _"The Hard-Fork Combinator"_, this is where you can find it. For a high-level − albeit technical − introduction, have a look at [The Abstract Nature of The Consensus Layer](https://iohk.io/en/blog/posts/2020/05/28/the-abstract-nature-of-the-consensus-layer/)
.
* [`The networking layer`](https://github.com/IntersectMBO/ouroboros-network/#ouroboros-network)
: a peer-to-peer networking stack geared towards Proof-of-Stake systems. This includes a framework for writing typed protocols with supports for pipelining, multiplexing and various protections against adversarial peers.
* [`The scripting layer`](https://github.com/IntersectMBO/plutus#plutus-core)
: also known as _Plutus_, it is a scripting language embedded in the Cardano ledger to provide smart-contract capabilities to the network. At its core, it is a typed Lambda-Calculus which acts as low-level interpreted assembly code.
---
# Integrate Cardano | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/integrate-cardano/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page

Introduction[](https://developers.cardano.org/docs/integrate-cardano/#introduction "Direct link to Introduction")
-------------------------------------------------------------------------------------------------------------------
Here we show you how to integrate Cardano into existing websites and services.
Integration Components[](https://developers.cardano.org/docs/integrate-cardano/#integration-components "Direct link to Integration Components")
-------------------------------------------------------------------------------------------------------------------------------------------------
* [Overview](https://developers.cardano.org/docs/get-started/cardano-node/cardano-components)
of the different Cardano components.
* [cardano-node](https://github.com/IntersectMBO/cardano-node)
is the top level for the node and aggregates the other components from other packages: consensus, ledger and networking, with configuration, CLI, logging and monitoring.
* [cardano-wallet](https://github.com/cardano-foundation/cardano-wallet)
helps you manage ada. You can use it to send and receive payments on the Cardano blockchain via a http and cli interface.
* [cardano-db-sync](https://github.com/IntersectMBO/cardano-db-sync)
follows the Cardano chain and takes information from the chain and an internally maintained copy of ledger state. Data is then extracted from the chain and inserted into a PostgreSQL database.
* [cardano-graphql](https://github.com/cardano-foundation/cardano-graphql)
a cross-platform, typed, and queryable API for Cardano.
* [cardano-rosetta](https://github.com/cardano-foundation/cardano-rosetta-java)
a multi-platform implementation of [Rosetta](https://www.rosetta-api.org/)
for Cardano, targeting the version defined in the [API docs](https://cardano-foundation.github.io/cardano-rosetta-java/api)
.
* [cardano-addresses](https://github.com/IntersectMBO/cardano-addresses)
provides mnemonic (backup phrase) creation, and conversion of a mnemonic to seed for wallet restoration, and address derivation functionalities.
Tutorials[](https://developers.cardano.org/docs/integrate-cardano/#tutorials "Direct link to Tutorials")
----------------------------------------------------------------------------------------------------------
* [Explore Cardano wallets](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet)
- learn how to create a Cardano wallet, receive test ada and create basic transactions.
* [Multi-witness transactions](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli)
- learn how to create transactions with multiple inputs and one output.
* [Listening for ada payments using cardano-cli](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli)
- how to listen to a specific address using cardano-cli.
* [Listening for ada payments using cardano-wallet](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-wallet)
- how to listen to a specific address using cardano-wallet.
* [Testnet Faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet)
- a service that provides test ada (tAda) to users of the Cardano testnets.
* [Sample queries](https://iohk.zendesk.com/hc/en-us/articles/4402395914009-Sample-cardano-rosetta-queries)
for cardano-rosetta.
* [Sample queries](https://iohk.zendesk.com/hc/en-us/articles/900000906566-Sample-cardano-graphql-queries)
for cardano-graphql.
* [Introduction](https://developers.cardano.org/docs/integrate-cardano/#introduction)
* [Integration Components](https://developers.cardano.org/docs/integrate-cardano/#integration-components)
* [Tutorials](https://developers.cardano.org/docs/integrate-cardano/#tutorials)
---
# Get started with Cardano CLI | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Setting up environment variables[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#setting-up-environment-variables "Direct link to Setting up environment variables")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### CARDANO\_NODE\_SOCKET\_PATH[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#cardano_node_socket_path "Direct link to CARDANO_NODE_SOCKET_PATH")
Cardano CLI uses the _node-to-client_ protocol to communicate with the node. This requires setting an environment variable for the node socket path. Ensure you use the path declared when starting the node.
export CARDANO_NODE_SOCKET_PATH=~/node.socket
### CARDANO\_NODE\_NETWORK\_ID[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#cardano_node_network_id "Direct link to CARDANO_NODE_NETWORK_ID")
Each network has a unique identifier (--mainnet or --testnet-magic NATURAL). This is used by the node-to-client protocol to ensure communication with a node on the desired network. It is useful to set up an environment variable for the network ID. Alternatively, you can provide the flag `--testnet-magic ` with each command that interacts with the node.
* **Mainnet**
export CARDANO_NODE_NETWORK_ID=mainnet
* **Pre-production testnet**
export CARDANO_NODE_NETWORK_ID=1
* **Preview testnet**
export CARDANO_NODE_NETWORK_ID=2
* **SanchoNet testnet**
export CARDANO_NODE_NETWORK_ID=4
Generating keys and addresses[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#generating-keys-and-addresses "Direct link to Generating keys and addresses")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
info
For a complete overview of Cardano address types, read [CIP-19](https://cips.cardano.org/cips/cip19/)
.
### Generate a payment key pair and an address[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#generate-a-payment-key-pair-and-an-address "Direct link to Generate a payment key pair and an address")
To generate a key pair, run:
cardano-cli address key-gen \--verification-key-file payment.vkey \--signing-key-file payment.skey
### Build an address[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#build-an-address "Direct link to Build an address")
This address will not have staking rights. It cannot delegate or receive rewards because it does not have a stake part associated with it, only a payment part (see [CIP-19](https://cips.cardano.org/cips/cip19/)
).
cardano-cli address build \--payment-verification-key-file payment.vkey \--out-file paymentNoStake.addr
cat paymentNoStake.addraddr_test1vzdtyyt48yrn2fa3wvh939rat0gyv6ly0ljt449sw8tppzq84xstz
info
Testnet addresses start with 'addr\_test' and mainnet addresses with 'addr'.
### Generate a stake key pair[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#generate-a-stake-key-pair "Direct link to Generate a stake key pair")
cardano-cli latest stake-address key-gen \--verification-key-file stake.vkey \--signing-key-file stake.skey
### Build the address with payment and stake parts[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#build-the-address-with-payment-and-stake-parts "Direct link to Build the address with payment and stake parts")
The resulting address will be associated with the **payment** and **stake** credentials:
cardano-cli address build \--payment-verification-key-file payment.vkey \--stake-verification-key-file stake.vkey \--out-file payment.addr
cat payment.addraddr_test1qzdtyyt48yrn2fa3wvh939rat0gyv6ly0ljt449sw8tppzrcc3g0zu63cp6rnjumfcadft63x3w8ds4u28z6zlvra4fqy2sm8n
### Query the balance of an address[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#query-the-balance-of-an-address "Direct link to Query the balance of an address")
cardano-cli query utxo --address $(< paymentNoStake.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------262c7891f932cde390bcc04c25805f3f422c1a5687d5d47f6681e68bb384fe6d 0 10000000000 lovelace + TxOutDatumNone
tip
* You can get test tokens for **pre-production** and **preview** testnets [using this faucet](https://docs.cardano.org/cardano-testnets/tools/faucet)
* For SanchoNet tokens, go to the [SanchoNet faucet](https://sancho.network/faucet)
.
* [Setting up environment variables](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#setting-up-environment-variables)
* [CARDANO\_NODE\_SOCKET\_PATH](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#cardano_node_socket_path)
* [CARDANO\_NODE\_NETWORK\_ID](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#cardano_node_network_id)
* [Generating keys and addresses](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#generating-keys-and-addresses)
* [Generate a payment key pair and an address](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#generate-a-payment-key-pair-and-an-address)
* [Build an address](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#build-an-address)
* [Generate a stake key pair](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#generate-a-stake-key-pair)
* [Build the address with payment and stake parts](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#build-the-address-with-payment-and-stake-parts)
* [Query the balance of an address](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/#query-the-balance-of-an-address)
---
# How to contribute to the developer portal | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/portal-contribute/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
We wanted to build a developer portal as open and inclusive as Cardano. A portal that is in the hands of the Cardano community and can be constantly evolved by it.
For this to be successful, the portal relies on your contributions, and the fact that you are reading this text probably means that you have something to contribute, **even if you are not a Developer**.
If you want to install the portal on your local machine, you can [jump directly to the installation instructions.](https://developers.cardano.org/docs/portal-contribute/#installation)
Why should I contribute?[](https://developers.cardano.org/docs/portal-contribute/#why-should-i-contribute "Direct link to Why should I contribute?")
------------------------------------------------------------------------------------------------------------------------------------------------------
**Build your reputation:** Contributions to the developer portal will give your GitHub name and profile higher visibility as more and more people come across your work online. As visibility increases, so too will the reputation of your name and brand.
**Build your confidence:** Creating tutorials and showing fellow community members how to create will not only elevate your knowledge of your own skills and processes, but will also bestow you with greater confidence in your abilities as you interact with others.
As an added bonus, since everything is public, people typically pay greater attention to how well something is written or programmed. This will also afford you with an invaluable set of eyes on your contributions that will serve as a crucial peer-reviewed tool to catch errors and refine your work.
**Build your resume:** Each contribution you make acts as a precious notch on your belt towards career development or job searches within the Cardano ecosystem. It is also a way for people to find examples of your work and verify your abilities. By contributing to open source projects, you will not only gain a lot of valuable experience, but if your profile (or brand) reaches a certain level of attention and recognition, you are also more likely to get professional opportunities further down the line.
I got the spirit. What can I do to contribute?[](https://developers.cardano.org/docs/portal-contribute/#i-got-the-spirit-what-can-i-do-to-contribute "Direct link to I got the spirit. What can I do to contribute?")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Spread the word[](https://developers.cardano.org/docs/portal-contribute/#spread-the-word "Direct link to Spread the word")
Often underestimated: spread the word. For example: if someone asks you for Cardano wallets, link to the [wallet showcase](https://developers.cardano.org/showcase?tags=wallet)
if they want to know about Cardano block explorers, link to the [block explorer showcase](https://developers.cardano.org/showcase?tags=explorer)
.
### Create issues[](https://developers.cardano.org/docs/portal-contribute/#create-issues "Direct link to Create issues")
Creating an issue is the first step to improving the portal. You don't even have to do the improvement yourself. You can think of it as creating a topic in a forum.
An "issue" can be anything from a simple suggestion to a fully elaborated plan with many sub-items and tasks to check off. You can also open an issue to discuss things. Like a public task manager, people can assign tasks to themselves. [Create an issue now](https://github.com/cardano-foundation/developer-portal/issues)
If creating an issue in GitHub is too much for you please consider opening a topic [on the Cardano Forum](https://forum.cardano.org/c/developers/general-developer-talk/152)
with a title like "Developer Portal Suggestion: your suggestion".
### Improve texts[](https://developers.cardano.org/docs/portal-contribute/#improve-texts "Direct link to Improve texts")
Fix typos and improve texts, especially if you are a native speaker and have strong writing skills.
### Create graphics[](https://developers.cardano.org/docs/portal-contribute/#create-graphics "Direct link to Create graphics")
If you are a talented graphic designer, you can improve various charts and diagrams. We should always use graphics that work well in both light mode and dark mode for the portal. You can also make one graphic for each.
### Participate in the discussions[](https://developers.cardano.org/docs/portal-contribute/#participate-in-the-discussions "Direct link to Participate in the discussions")
If you think something is wrong or something fundamental should change, discussions are the appropriate start to find consensus. There are always [ongoing discussions](https://github.com/cardano-foundation/developer-portal/discussions/243)
on how to handle or improve something. Please take part in them. Even if you are not a developer, your views are valuable:
* [Issues in the GitHub Repo](https://github.com/cardano-foundation/developer-portal/issues)
* [Discussions in the GitHub Repo](https://github.com/cardano-foundation/developer-portal/discussions)
### Add a project to showcase[](https://developers.cardano.org/docs/portal-contribute/#add-a-project-to-showcase "Direct link to Add a project to showcase")
Help to add good projects to the [showcase section](http://developers.cardano.org/showcase/)
. Please note the guidelines for adding new projects:
* It must be built on Cardano and have a real use case. For example, a forum where people can talk about Cardano is great, but not for this showcase section.
* It has to run on Cardano mainnet.
* It has to have a running product. (no presale, no protected pages, no coming soon messages)
* It has to have enough community reputation.
* It has to provide a unique value distinct from existing showcase items.
* It has to have a stable domain name. (a random Netlify/Vercel domain is not allowed, no URL shortener, no app store links, or similar)
* The GitHub account that adds the project must not be new.
* The GitHub account must have a history/or already be known in the Cardano community.
* Describe what makes your project special, avoid phrases like "the first this and that". Granular details like which project was first is tribal attribute known to cause rift and conflicts.
* Please refrain from adding NFT projects unless they are immensely different from what is already listed in terms of utility. We can't list hundreds of NFT projects. For details please follow or take part in the discussion [here](https://github.com/cardano-foundation/developer-portal/discussions/243)
. (TL;DR: we are adding winners of the [CNFT Awards](https://www.cnft-awards.io/)
)
* If you add a project with a main component of NFTs, please select "nftproject" as tag. (not "nftsupport")
Mainly the project showcase should be a place where someone new to the ecosystem can come to see what can be done. For example we agreed that projects have to have a running product today on Cardano mainnet, no promises, no pre-sales, no coming soon pages. We also don't [aim to map out a future ecosystem.](https://developers.cardano.org/showcase?tags=ecosystem)
Adding projects to the [showcase section](http://developers.cardano.org/showcase/)
will require [creating a pull request](https://developers.cardano.org/docs/portal-contribute/#create-pull-requests)
.
### Add tools to builder tools[](https://developers.cardano.org/docs/portal-contribute/#add-tools-to-builder-tools "Direct link to Add tools to builder tools")
Help to add useful tools to the [builder tools section](http://developers.cardano.org/tools/)
. Please note the guidelines for adding new builder tools:
* It is an actual builder tool that adds value to Cardano developers.
* It has a stable domain name (a random for example, Netlify/Vercel domain is not allowed)
* The GitHub account that adds the builder tool must not be new.
* The GitHub account must have a history/or already be known in the Cardano community.
A builder tool is a software application or platform that enables users to create, modify, and deploy software applications, or other digital products on Cardano.
Adding tools to the [builder tools section](http://developers.cardano.org/tools/)
will require [creating a pull request](https://developers.cardano.org/docs/portal-contribute/#create-pull-requests)
.
### Create/improve documentation[](https://developers.cardano.org/docs/portal-contribute/#createimprove-documentation "Direct link to Create/improve documentation")
Documentation can constantly be improved, and there are gaps in the developer portal. In particular, the stake pool operator section needs a lot of work. [To create and improve documentation, you should install the portal on your local machine.](https://developers.cardano.org/docs/portal-contribute/#installation)
### Create/improve tutorials[](https://developers.cardano.org/docs/portal-contribute/#createimprove-tutorials "Direct link to Create/improve tutorials")
Apart from documentation, tutorials are an excellent way to explain things. If you already have a website with tutorials, consider moving them to the Developer Portal. [To create and improve documentation, you should install the portal on your local machine.](https://developers.cardano.org/docs/portal-contribute/#installation)
### Create pull requests[](https://developers.cardano.org/docs/portal-contribute/#create-pull-requests "Direct link to Create pull requests")
A pull request is a proposal to change something on the developer portal. It can be a small change like fixing a typo or a complete category with hundreds of new files. [Pull requests must be reviewed.](https://developers.cardano.org/docs/portal-contribute/#how-are-pull-requests-reviewed)
### Review pull requests[](https://developers.cardano.org/docs/portal-contribute/#review-pull-requests "Direct link to Review pull requests")
If you have an excellent technical understanding and mistakes catch your eye, you can review pull requests. You should have made contributions before [please read here for more details](https://developers.cardano.org/docs/portal-contribute/#how-to-become-a-reviewer)
.
Frequently Asked Questions[](https://developers.cardano.org/docs/portal-contribute/#frequently-asked-questions "Direct link to Frequently Asked Questions")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
### How are pull requests reviewed?[](https://developers.cardano.org/docs/portal-contribute/#how-are-pull-requests-reviewed "Direct link to How are pull requests reviewed?")
Pull requests must be approved by three reviewers to be merged. They are always merged into the staging branch. [https://staging-dev-portal.netlify.app](https://staging-dev-portal.netlify.app/)
reflects the state of the current staging branch.
Later, the changes are pushed from staging to the main branch. This requires another pull request. (For this reason, there is always a small delay between staging and production).
### How to become a reviewer?[](https://developers.cardano.org/docs/portal-contribute/#how-to-become-a-reviewer "Direct link to How to become a reviewer?")
You should have an excellent technical understanding, great ethics and have already contributed to the developer portal. Your GitHub account should have some reputation. [If you are unsure, just participate in the discussions.](https://developers.cardano.org/docs/portal-contribute/#participate-in-the-discussions)
### How to connect with the developer community?[](https://developers.cardano.org/docs/portal-contribute/#how-to-connect-with-the-developer-community "Direct link to How to connect with the developer community?")
Cardano developers and stake pool operators spread across many different platforms. [We aim to provide a complete overview.](https://developers.cardano.org/docs/get-started/cardano-developer-community)
If you are interested in connecting with people from the Developer Portal, [open a thread in the forum](https://forum.cardano.org/c/developers/29)
.
Installation[](https://developers.cardano.org/docs/portal-contribute/#installation "Direct link to Installation")
-------------------------------------------------------------------------------------------------------------------
To contribute to the Cardano developer portal, you must first install it locally. We have chosen [Docusaurus](https://docusaurus.io/)
, a modern static website generator, as the underlying software.
### Requirements[](https://developers.cardano.org/docs/portal-contribute/#requirements "Direct link to Requirements")
* [Node.js](https://nodejs.org/en/download/)
version >= 18.0 (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm)
for managing multiple Node versions on a single machine installed.
* [Yarn](https://yarnpkg.com/en/)
version >= 1.20 (which can be checked by running `yarn --version`). Yarn is a performant package manager for JavaScript and replaces the `npm` client. It is not strictly necessary but highly encouraged.
* On macOS you also need Xcode and Command Line Tools.
### Local development[](https://developers.cardano.org/docs/portal-contribute/#local-development "Direct link to Local development")
To get a local development environment, clone the repository, navigate into the `developer-portal` folder, install dependencies, and start the development server. Most changes are reflected live without having to restart the server. By default, a browser window will open at `http://localhost:3000`.
git clone --depth 1 https://github.com/cardano-foundation/developer-portal.gitcd developer-portalyarn installyarn start
Limitations of the development build
The development mode will have minor features not working. For example, only blurry images in the responsive images on showcase and tools, search limitations, and some data has fake values because of performance reasons.
**Create at least once a production build** (see below) as this pulls missing files.
### Production build[](https://developers.cardano.org/docs/portal-contribute/#production-build "Direct link to Production build")
yarn build
Use this command instead of `yarn start` to generate static content into the build directory that can be served using any static content hosting service.
Project structure[](https://developers.cardano.org/docs/portal-contribute/#project-structure "Direct link to Project structure")
----------------------------------------------------------------------------------------------------------------------------------
The portal is structured as follows. (See the [Project structure rundown](https://developers.cardano.org/docs/portal-contribute/#project-structure-rundown)
below for details)
developer-portal├── blog│ ├── 2021-01-07-january.md│ ├── 2021-02-03-february.md│ └── *.md├── docs│ ├── fund-your-project│ ├── get-started│ ├── integrate-cardano│ ├── native-tokens│ ├── operate-a-stake-pool│ ├── transaction-metadata│ └── *.md├── examples│ ├── cli│ | ├── dotnet│ │ │ └── *.cs│ | ├── js│ │ │ └── *.js| | └── python│ │ └── *.py| └── wallets│ ├── dotnet│ ├── js| └── python├── scripts│ ├── cip.ts│ ├── rust-library.ts│ ├── token-registry.ts│ └── *.md├── src│ ├── css│ │ └── custom.css│ ├── data│ │ ├── builder-tools│ │ │ └── *.png│ │ ├── showcase│ │ │ └── *.png│ │ ├── builder-tools.js│ │ └── showcases.js│ └── pages│ ├── styles.module.css│ └── index.js├── static│ └── img├── docusaurus.config.js├── package.json├── README.md├── sidebars.js└── yarn.lock
### Project structure rundown[](https://developers.cardano.org/docs/portal-contribute/#project-structure-rundown "Direct link to Project structure rundown")
* `/blog/` - Contains the blog Markdown files for the developer spotlight.
* `/docs/` - Contains the Markdown files for the docs. Customize the order of the docs sidebar in `sidebars.js`.
* `/examples/` - Contains example projects for the Markdown files in the docs. _The structure is not final and will likely change in the future_
* `/scripts/` - Contains scripts to fetch auto generated content like CIPs, Rust Library, Token Registry.
* `/src/` - Non-documentation files like pages or custom React components. You don't have to strictly put your non-documentation files in here, but putting them under a centralized directory makes it easier to specify in case you need to do some sort of linting/processing.
* `/src/data/builder-tools` - Screenshots for the builder tools section.
* `/src/data/builder-tools.js` - Definition file for the builder tools section.
* `/src/data/showcase` - Screenshots for the showcase section.
* `/src/data/showcase.js` - Definition file for the showcase section.
* `/src/pages` - Any files within this directory will be converted into a website page.
* `/static/` - Static directory. Any contents inside here will be copied into the root of the final `build` directory.
* `/docusaurus.config.js` - A config file containing the site configuration.
* `/package.json` - A Docusaurus website is a React app. You can install and use any npm packages you like in them.
* `/sidebar.js` - Used by the documentation to specify the order of documents in the sidebar.
Known problems that may arise[](https://developers.cardano.org/docs/portal-contribute/#known-problems-that-may-arise "Direct link to Known problems that may arise")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
We list here problems you may run into when running the developer portal locally.
### Minimum Node.js version not met[](https://developers.cardano.org/docs/portal-contribute/#minimum-nodejs-version-not-met "Direct link to Minimum Node.js version not met")
**Problem:** `yarn start` throws the error `[ERROR] Minimum Node.js version not met :(`.
**Solution:** use the node version listed below [requirements](https://developers.cardano.org/docs/portal-contribute/#requirements)
. If you have different node versions installed for different projects, `nvm` is a neat tool to deal with it. You can switch versions with for example `nvm use 18`.
### Sidebars file at "developer-portal/sidebars.js" failed to be loaded[](https://developers.cardano.org/docs/portal-contribute/#sidebars-file-at-developer-portalsidebarsjs-failed-to-be-loaded "Direct link to Sidebars file at "developer-portal/sidebars.js" failed to be loaded")
**Problem:** `yarn start` throws the error `[ERROR] Sidebars file at "developer-portal/sidebars.js" failed to be loaded.`.
**Solution:** you need to run at least once `yarn build` as this pulls missing files into your folder, which is then referenced by `sidebars.js`.
### Sidebar category Token Registry has neither any subitem nor a link[](https://developers.cardano.org/docs/portal-contribute/#sidebar-category-token-registry-has-neither-any-subitem-nor-a-link "Direct link to Sidebar category Token Registry has neither any subitem nor a link")
**Problem:** `yarn start` throws the error `[ERROR] Error: Sidebar category Token Registry has neither any subitem nor a link. This makes this item not able to link to anything.`.
**Solution:** you need to run at least once `yarn build` as this pulls missing files into your folder, which is then referenced by `sidebars.js`.
Other questions[](https://developers.cardano.org/docs/portal-contribute/#other-questions "Direct link to Other questions")
----------------------------------------------------------------------------------------------------------------------------
Various other questions and answers.
### Anything I can do to make sure my pull request will not break on the staging/production server?[](https://developers.cardano.org/docs/portal-contribute/#anything-i-can-do-to-make-sure-my-pull-request-will-not-break-on-the-stagingproduction-server "Direct link to Anything I can do to make sure my pull request will not break on the staging/production server?")
Yes, please always do a `yarn build` before submitting a pull request. It will find many more issues than `yarn start`.
### Is there any style guide? Do we have editorial guidelines?[](https://developers.cardano.org/docs/portal-contribute/#is-there-any-style-guide-do-we-have-editorial-guidelines "Direct link to Is there any style guide? Do we have editorial guidelines?")
Yes, both still work in progress but please see [style guide](https://developers.cardano.org/docs/portal-style-guide)
and [editorial guidelines](https://developers.cardano.org/docs/portal-style-guide#editorial-style-guide)
.
### Should I commit the `yarn.lock` file?[](https://developers.cardano.org/docs/portal-contribute/#should-i-commit-the-yarnlock-file "Direct link to should-i-commit-the-yarnlock-file")
No, please do not commit your `yarn.lock` file: this represents a software baseline and should be updated only at regular intervals by site maintainers.
### I committed `yarn.lock` to my PR branch: what do I do?[](https://developers.cardano.org/docs/portal-contribute/#i-committed-yarnlock-to-my-pr-branch-what-do-i-do "Direct link to i-committed-yarnlock-to-my-pr-branch-what-do-i-do")
Assuming:
* `origin` refers to your local fork
* `upstream` refers to the `cardano-foundation` repository
First, do _one_ of these in your the working root directory of your fork (to restore an unmodified `yarn.lock`):
* ... from your working fork's `staging` branch (if you've created your PR branch from there):
* `git checkout staging -- yarn.lock`
* ... from the `staging` branch of your fork itself:
* `git checkout origin/staging -- yarn.lock`
* ... from the official repository:
* `git checkout upstream/staging -- yarn.lock`
Then commit to reverse the changes you've made. For example:
* `git commit -m 'reverting to unmodified yarn.lock'`
The same technique can be used to revert modifications to other portal files. For more help, see the popular thread [Remove a modified file from pull request](https://stackoverflow.com/questions/39459467/remove-a-modified-file-from-pull-request)
.
* [Why should I contribute?](https://developers.cardano.org/docs/portal-contribute/#why-should-i-contribute)
* [I got the spirit. What can I do to contribute?](https://developers.cardano.org/docs/portal-contribute/#i-got-the-spirit-what-can-i-do-to-contribute)
* [Spread the word](https://developers.cardano.org/docs/portal-contribute/#spread-the-word)
* [Create issues](https://developers.cardano.org/docs/portal-contribute/#create-issues)
* [Improve texts](https://developers.cardano.org/docs/portal-contribute/#improve-texts)
* [Create graphics](https://developers.cardano.org/docs/portal-contribute/#create-graphics)
* [Participate in the discussions](https://developers.cardano.org/docs/portal-contribute/#participate-in-the-discussions)
* [Add a project to showcase](https://developers.cardano.org/docs/portal-contribute/#add-a-project-to-showcase)
* [Add tools to builder tools](https://developers.cardano.org/docs/portal-contribute/#add-tools-to-builder-tools)
* [Create/improve documentation](https://developers.cardano.org/docs/portal-contribute/#createimprove-documentation)
* [Create/improve tutorials](https://developers.cardano.org/docs/portal-contribute/#createimprove-tutorials)
* [Create pull requests](https://developers.cardano.org/docs/portal-contribute/#create-pull-requests)
* [Review pull requests](https://developers.cardano.org/docs/portal-contribute/#review-pull-requests)
* [Frequently Asked Questions](https://developers.cardano.org/docs/portal-contribute/#frequently-asked-questions)
* [How are pull requests reviewed?](https://developers.cardano.org/docs/portal-contribute/#how-are-pull-requests-reviewed)
* [How to become a reviewer?](https://developers.cardano.org/docs/portal-contribute/#how-to-become-a-reviewer)
* [How to connect with the developer community?](https://developers.cardano.org/docs/portal-contribute/#how-to-connect-with-the-developer-community)
* [Installation](https://developers.cardano.org/docs/portal-contribute/#installation)
* [Requirements](https://developers.cardano.org/docs/portal-contribute/#requirements)
* [Local development](https://developers.cardano.org/docs/portal-contribute/#local-development)
* [Production build](https://developers.cardano.org/docs/portal-contribute/#production-build)
* [Project structure](https://developers.cardano.org/docs/portal-contribute/#project-structure)
* [Project structure rundown](https://developers.cardano.org/docs/portal-contribute/#project-structure-rundown)
* [Known problems that may arise](https://developers.cardano.org/docs/portal-contribute/#known-problems-that-may-arise)
* [Minimum Node.js version not met](https://developers.cardano.org/docs/portal-contribute/#minimum-nodejs-version-not-met)
* [Sidebars file at "developer-portal/sidebars.js" failed to be loaded](https://developers.cardano.org/docs/portal-contribute/#sidebars-file-at-developer-portalsidebarsjs-failed-to-be-loaded)
* [Sidebar category Token Registry has neither any subitem nor a link](https://developers.cardano.org/docs/portal-contribute/#sidebar-category-token-registry-has-neither-any-subitem-nor-a-link)
* [Other questions](https://developers.cardano.org/docs/portal-contribute/#other-questions)
* [Anything I can do to make sure my pull request will not break on the staging/production server?](https://developers.cardano.org/docs/portal-contribute/#anything-i-can-do-to-make-sure-my-pull-request-will-not-break-on-the-stagingproduction-server)
* [Is there any style guide? Do we have editorial guidelines?](https://developers.cardano.org/docs/portal-contribute/#is-there-any-style-guide-do-we-have-editorial-guidelines)
* [Should I commit the `yarn.lock` file?](https://developers.cardano.org/docs/portal-contribute/#should-i-commit-the-yarnlock-file)
* [I committed `yarn.lock` to my PR branch: what do I do?](https://developers.cardano.org/docs/portal-contribute/#i-committed-yarnlock-to-my-pr-branch-what-do-i-do)
---
# Operate a Stake Pool | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page

There are excellent guidelines available on how to set up cardano-node as a stake pool. You may even set one up without any prior Linux experience or concern for best practices. Simply copy and paste the commands from the instructions into your shell.
Unfortunately, simply getting your node up and running is insufficient. You must be able to manage, update, and safeguard it. To do so, you must first comprehend what you are doing [in one of the testnets](https://developers.cardano.org/docs/get-started/testnets-and-devnets/)
. Consider this category an entry point into the Cardano Pool Operator Community.
What are the prerequisites for persons who wish to learn how to run a stake pool?[](https://developers.cardano.org/docs/operate-a-stake-pool/#what-are-the-prerequisites-for-persons-who-wish-to-learn-how-to-run-a-stake-pool "Direct link to What are the prerequisites for persons who wish to learn how to run a stake pool?")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Knowledge of how to manage a server. You must be familiar with the operating system of your choosing in order to administer, maintain, and secure your server.
* This includes a thorough understanding of how networks operate, as well as how to backup and restore data.
* Experienced in interpreting documentation and implementing best practices.
* Understand Cardano, blockchain, wallets, and key pairs on a fundamental level.
What if I don't meet the requirements?[](https://developers.cardano.org/docs/operate-a-stake-pool/#what-if-i-dont-meet-the-requirements "Direct link to What if I don't meet the requirements?")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you don't meet all of the qualifications, you'll need a strong desire to study and the understanding that you won't be able to learn everything in a few weeks.
We observed people who had no prior knowledge of Linux, shells, or networking, but who were committed and had enough time to properly deal with it, and who now manage a profitable stake pool. It isn't for everyone, and it isn't going to be simple. Here are a few resources to get you started:
* [Start playing around with Linux](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview)
.
* [Have a look at nix and NixOS](https://nixos.org/)
.
* [Stake pool operator forum](https://forum.cardano.org/c/staking-delegation/156)
.
Choose security over comfort[](https://developers.cardano.org/docs/operate-a-stake-pool/#choose-security-over-comfort "Direct link to Choose security over comfort")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Best practices should always be a key consideration when running a stake pool. Security isn't something you can turn on or off or change in a configuration file. It is both an attitude and a way of life, therefore consider following the [security related topics with stake pool operators](https://forum.cardano.org/c/staking-delegation/stake-pool-security/157)
on the Cardano Forum. Make sure to fully understand [Cardano Key Pairs](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs)
in the basic category.
Learn the basics[](https://developers.cardano.org/docs/operate-a-stake-pool/#learn-the-basics "Direct link to Learn the basics")
----------------------------------------------------------------------------------------------------------------------------------
The basic category starts with an [introduction to Cardano](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano)
, you will learn the [relay and block producer topology](https://developers.cardano.org/docs/operate-a-stake-pool/stake-pool-networking)
, what the [hardware requirements](https://developers.cardano.org/docs/operate-a-stake-pool/hardware-requirements)
are, which [keys are available](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs)
, which are hot and sensitive, and which you should never save on a server, no matter how convenient it is.
Stake pool operator resources[](https://developers.cardano.org/docs/operate-a-stake-pool/#stake-pool-operator-resources "Direct link to Stake pool operator resources")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* [Guild Operators](https://cardano-community.github.io/guild-operators)
, famous for their [CNTools](https://cardano-community.github.io/guild-operators/#/Scripts/cntools)
and top-notch content.
* [Topology Updater](https://cardano-community.github.io/guild-operators/#/Scripts/topologyupdater)
is intended to be a temporary solution to allow everyone to activate their relay nodes without having to postpone and wait for manual topology completion requests.
* [CNCLI](https://github.com/cardano-community/cncli)
is a collection of utilities to enhance and extend cardano-cli.
* [Jormanager](https://bitbucket.org/muamw10/jormanager/src/develop/)
a Cardano stake pool management software.
* [Stake Pool Operator Scripts](https://github.com/gitmachtl/scripts)
a collection of scripts to manage your stake pool step-by-step.
* [Coin Cashew Guides](https://www.coincashew.com/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node)
for stake pool operators.
* [RaspberryPi with Docker](https://github.com/speedwing/cardano-staking-pool-edu)
Full guide to build and run both testnet and mainnet Cardano stake pool with Docker on Raspberry Pi. [Youtube Playlist](https://www.youtube.com/playlist?list=PLBhbLwOuj0DfTnneuG3vyoDHY7Dv_aiyq)
* [TOPO Guide](https://es-kb.topopool.com/primeros-pasos)
. A friendly and complete guide to create a stake pool in Spanish
* [Cardano Course](https://cardano-course.gitbook.io/cardano-course/)
, a cardano-node and cardano-cli course by IOG.
* [What are the prerequisites for persons who wish to learn how to run a stake pool?](https://developers.cardano.org/docs/operate-a-stake-pool/#what-are-the-prerequisites-for-persons-who-wish-to-learn-how-to-run-a-stake-pool)
* [What if I don't meet the requirements?](https://developers.cardano.org/docs/operate-a-stake-pool/#what-if-i-dont-meet-the-requirements)
* [Choose security over comfort](https://developers.cardano.org/docs/operate-a-stake-pool/#choose-security-over-comfort)
* [Learn the basics](https://developers.cardano.org/docs/operate-a-stake-pool/#learn-the-basics)
* [Stake pool operator resources](https://developers.cardano.org/docs/operate-a-stake-pool/#stake-pool-operator-resources)
---
# Style Guide | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/portal-style-guide/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
You can write content using [GitHub-flavored Markdown syntax](https://github.github.com/gfm/)
. [Markdown](https://github.github.com/gfm/)
is a way to style text on the web. You control the display of the document; formatting words as bold or italic, adding images, and creating lists are just a few of the things we can do with Markdown. Mostly, Markdown is just regular text with a few non-alphabetic characters thrown in, like `#` or `*`.
Markdown Examples[](https://developers.cardano.org/docs/portal-style-guide/#markdown-examples "Direct link to Markdown Examples")
-----------------------------------------------------------------------------------------------------------------------------------
This page will help you learn about the Markdown used in the Cardano Developer Portal, but the list is not intended to be exhaustive. Read the [docusaurus Markdown features](https://docusaurus.io/docs/next/markdown-features)
for more examples.
Let's start with the basics:
* Text
* Headers
* Links
* Quotes
* Images
* Lists
Emphasis, aka italics, with *asterisks* or _underscores_.Strong emphasis, aka bold, with **asterisks** or __underscores__.Combined emphasis with **asterisks and _underscores_**.Strikethrough uses two tildes. ~~Scratch this.~~You can even [link to the Forum!](https://forum.cardano.org)
Emphasis, aka italics, with _asterisks_ or _underscores_.
Strong emphasis, aka bold, with **asterisks** or **underscores**.
Combined emphasis with **asterisks and _underscores_**.
Strikethrough uses two tildes. ~Scratch this.~
You can even [link to the Forum!](https://forum.cardano.org/)
Avoid top-level headings
`#Level 1` headings are rendered automatically from the `title` property of your `frontmatter`.
Therefore use `## Level 2` headings as the top most heading in the docs.
---id: front-mattertitle: I am the frontmatterdescription: Always include the frontmatter in your documents---## Structured documentsAs a rule, it is useful to have different levelsof headings to structure your documents. Start rows with a `##` to create headings. Several `#` in a row indicate smaller heading sizes.### This is a level 3 heading#### This is a level 4 headingYou can use up to `######` six for different heading sizes.
I am the frontmatter
====================
Structured documents[](https://developers.cardano.org/docs/portal-style-guide/#structured-documents "Direct link to Structured documents")
--------------------------------------------------------------------------------------------------------------------------------------------
As a rule, it is useful to have different levels of headings to structure your documents. Start rows with a `#` to create headings. Several `##` in a row indicate smaller heading sizes.
### This is a level 3 heading[](https://developers.cardano.org/docs/portal-style-guide/#this-is-a-level-3-heading "Direct link to This is a level 3 heading")
#### This is a level 4 heading[](https://developers.cardano.org/docs/portal-style-guide/#this-is-a-level-4-heading "Direct link to This is a level 4 heading")
You can use up to `######` six for different heading sizes.
[I'm an inline-style link](https://forum.cardano.org)[I'm an inline-style link with title](https://forum.cardano.org "Cardano Forum")[I'm a reference-style link][arbitrary case-insensitive reference text][You can use numbers for reference-style link definitions][1]Or leave it empty and use the [link text itself].URLs and URLs in angle brackets will automatically get turned into links. http://www.cardano.org or .Some text to show that the reference links can follow later.[arbitrary case-insensitive reference text]: https://www.cardano.org[1]: https://forum.cardano.org[link text itself]: https://www.cardano.org
[I'm an inline-style link](https://forum.cardano.org/)
[I'm an inline-style link with title](https://forum.cardano.org/ "Cardano Forum")
[I'm a reference-style link](https://www.cardano.org/)
[You can use numbers for reference-style link definitions](https://forum.cardano.org/)
Or leave it empty and use the [link text itself](https://www.cardano.org/)
.
URLs will automatically get turned into links. Example: [https://www.cardano.org](https://www.cardano.org/)
Some text to show that the reference links can follow later.
If you'd like to quote someone, use the > character before the line:> It’s not about who’s first to market or how quickly we can upgrade something. It’s about what’s fit for purpose. - **Charles Hoskinson**
If you'd like to quote someone, use the > character before the line:
> It’s not about who’s first to market or how quickly we can upgrade something. It’s about what’s fit for purpose. - **Charles Hoskinson**
Here's is the Plutus logo (hover to see the title text):Inline-style: Reference-style: ![alt text][logo][logo]: https://raw.githubusercontent.com/adam-p/markdown-here/master/src/common/images/icon48.png 'This is a logo reference-style'Images from any folder can be used by providing path to file. Path should be relative to Markdown file:
Here's is the Plutus logo (hover to see the title text): Inline-style: 
Reference-style: !\[alt text\]\[logo\] \[logo\]: [https://raw.githubusercontent.com/adam-p/markdown-here/master/src/common/images/icon48.png](https://raw.githubusercontent.com/adam-p/markdown-here/master/src/common/images/icon48.png)
'This is a logo reference-style'
Images from any folder can be used by providing path to file. Path should be relative to Markdown file: 
1. First ordered list item2. Another item - Unordered sub-list.3. Actual numbers don't matter, just that it's a number 1. Ordered sub-list4. And another item.* Unordered list can use asterisks- Or minuses+ Or pluses
1. First ordered list item
2. Another item
* Unordered sub-list.
3. Actual numbers don't matter, just that it's a number
1. Ordered sub-list
4. And another item.
* Unordered list can use asterisks
* Or minuses
* Or pluses
* * *
Code[](https://developers.cardano.org/docs/portal-style-guide/#code "Direct link to Code")
--------------------------------------------------------------------------------------------
In the developer portal, you will often have to display code. You can display code with different syntax highlighting:
* JavaScript
* Python
* C#
* JSON
* Shell
* Text
* Extras
var s = 'JavaScript syntax highlighting';alert(s);
var s = 'JavaScript syntax highlighting';alert(s);
s = "Python syntax highlighting"print(s)
s = "Python syntax highlighting"print(s)
using System;var s = "c# syntax highlighting";Console.WriteLine(s);
using System;var s = "c# syntax highlighting";Console.WriteLine(s);
{ "json_number": 225, "json_boolean": true, "json_string": "JSON syntax highlighting"}
{ "json_number": 225, "json_boolean": true, "json_string": "JSON syntax highlighting"}
ls echo "Shell syntax highlighting"sudo dmesgtop
ls echo "Shell syntax highlighting"sudo dmesgtop
No language indicated, so no syntax highlighting.But let's throw in a tag.
No language indicated, so no syntax highlighting.But let's throw in a tag.
function highlightMe() { console.log('This line can be highlighted!'); console.log('You can also highlight multiple lines');}
function highlightMe() { console.log('This line can be highlighted!'); console.log('You can also highlight multiple lines');}
You can add a title to the code block by adding `title` key after the language (leave a space between them).
/src/components/HelloCodeTitle.js
function HelloCodeTitle(props) { return
Hello, {props.name}
;}
/src/components/HelloCodeTitle.js
function HelloCodeTitle(props) { return
Hello, {props.name}
;}
* * *
Tabs[](https://developers.cardano.org/docs/portal-style-guide/#tabs "Direct link to Tabs")
--------------------------------------------------------------------------------------------
You can use tabs to display code examples in different languages. For example:
html import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
* JavaScript
* PHP
* Python
function helloWorld() { console.log('Hello, world!'); }
Hello, world!
'; ?>
def hello_world(): print 'Hello, world!'
* JavaScript
* PHP
* Python
function helloWorld() { console.log('Hello, world!');}
Hello, world!'; ?>
def hello_world(): print 'Hello, world!'
note
Note that the empty lines above and below each language block (in the \*md file) is intentional.
* * *
Synching tab choices[](https://developers.cardano.org/docs/portal-style-guide/#synching-tab-choices "Direct link to Synching tab choices")
--------------------------------------------------------------------------------------------------------------------------------------------
You can also switch multiple tabs at the same time based on user input:
Use Ctrl + C to copy.Use Command + C to copy.Use Ctrl + C to copy.Use Ctrl + V to paste.Use Command + V to paste.Use Ctrl + V to paste.
* Windows
* macOS
* Linux
Use Ctrl + C to copy.
Use Command + C to copy.
Use Ctrl + C to copy.
* Windows
* macOS
* Linux
Use Ctrl + V to paste.
Use Command + V to paste.
Use Ctrl + V to paste.
Video embedding[](https://developers.cardano.org/docs/portal-style-guide/#video-embedding "Direct link to Video embedding")
-----------------------------------------------------------------------------------------------------------------------------
Use this code to embed YouTube videos:
* * *
Tables[](https://developers.cardano.org/docs/portal-style-guide/#tables "Direct link to Tables")
--------------------------------------------------------------------------------------------------
Colons can be used to align columns:
| Tables | Are | Cool || ------------- | :-----------: | -----: || col 3 is | right-aligned | $1600 || col 2 is | centered | $12 || zebra stripes | are neat | $1 |
| Tables | Are | Cool |
| --- | --- | --- |
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
There must be at least 3 dashes separating each header cell. The outer pipes (|) are optional, and you don't need to make the raw Markdown line up prettily. You can also use inline Markdown.
| Markdown | Less | Pretty || -------- | --------- | ---------- || _Still_ | `renders` | **nicely** || 1 | 2 | 3 |
| Markdown | Less | Pretty |
| --- | --- | --- |
| _Still_ | `renders` | **nicely** |
| 1 | 2 | 3 |
* * *
Inline HTML[](https://developers.cardano.org/docs/portal-style-guide/#inline-html "Direct link to Inline HTML")
-----------------------------------------------------------------------------------------------------------------
Inline HTML is basically possible, but should be avoided for various reasons.
Definition list
Is something people use sometimes.
Markdown in HTML
Does *not* work **very** well. Use HTML tags.
Definition list
Is something people use sometimes.
Markdown in HTML
Does _not_ work **very** well. Use HTML _tags_.
* * *
Line Breaks[](https://developers.cardano.org/docs/portal-style-guide/#line-breaks "Direct link to Line Breaks")
-----------------------------------------------------------------------------------------------------------------
Here's a line for us to start with.This line is separated from the one above by two newlines, so it will be a _separate paragraph_. This line is a separate line in the _same paragraph_, created either by two blank spaces or explicit tag at the end of the previous line.
Here's a line for us to start with.
This line is separated from the one above by two newlines, so it will be a _separate paragraph_.
This line is a separate line in the _same paragraph_, created either by two blank spaces or explicit ` ` tag at the end of the previous line.
* * *
Admonitions[](https://developers.cardano.org/docs/portal-style-guide/#admonitions "Direct link to Admonitions")
-----------------------------------------------------------------------------------------------------------------
These different admonitions are available to you. As a general rule: don't overdo it and avoid using admonitions in a row.
* Note
* Tip
* Important
* Caution
* Warning
* Custom
:::noteThis is a note:::
note
This is a note
:::tipThis is a tip:::
tip
This is a tip
:::importantThis is important:::
important
This is important
:::cautionThis is a caution:::
caution
This is a caution
:::warningThis is a warning:::
warning
This is a warning
:::tip[Custom Title]This is a tip admonition with a custom title:::
Custom Title
This is a tip admonition with a custom title
Mermaid[](https://developers.cardano.org/docs/portal-style-guide/#mermaid "Direct link to Mermaid")
-----------------------------------------------------------------------------------------------------
To use Mermaid diagram, add a code block with language `mermaid`. See the [Mermaid syntax documentation](https://mermaid-js.github.io/mermaid/#/./n00b-syntaxReference)
for more information on the Mermaid syntax and the different diagrams. Some examples:
Other style elements[](https://developers.cardano.org/docs/portal-style-guide/#other-style-elements "Direct link to Other style elements")
--------------------------------------------------------------------------------------------------------------------------------------------
Please try to avoid other style elements, and always keep in mind that people with visual handicaps should also be able to cope with your content.
Editor extensions and configurations[](https://developers.cardano.org/docs/portal-style-guide/#editor-extensions-and-configurations "Direct link to Editor extensions and configurations")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Last but not least, let's talk about editors, extensions and configurations.
You can use any text editor you like to write Markdown. [Visual Studio Code](https://code.visualstudio.com/)
, [Sublime](https://www.sublimetext.com/)
, [Atom](https://atom.io/)
, etc. have plugins that help you adhere to style guides by displaying warnings if you break the rules.
Below are some extensions for these editors that help you write clean guides for the developer portal.
### markdownlint[](https://developers.cardano.org/docs/portal-style-guide/#markdownlint "Direct link to markdownlint")
Adds syntax highligting for Markdown files and display configurable warnings for invalid formatting.
* Visual Studio Code
* Sublime
* Install the extension via _Command Palette (Ctrl+P)_ using `ext install DavidAnson.vscode-markdownlint`
* Add a `.markdownlint.json` file to your project with the following configuration.
{ "line-length": false, "MD004" : false, "MD033":{ "allowed_elements": ["TabItem", "br", "iframe", "dl", "dt","dd", "em"] }, "MD034" : false, "MD046" : false}
1. Install SublimeLinter as described [here](http://www.sublimelinter.com/en/stable/)
2. Install [Node.js](https://nodejs.org/)
3. Install `markdownlint` by using `npm install -g markdownlint-cli`
4. Within Sublime Text's _Command Palette (Ctrl+Shift+P)_ type `install` and select `Package Control: Install Package`.
5. When the plug-in list appears, type `markdownlint` and select `SublimeLinter-contrib-markdownlint`.
* Add a `.markdownlintrc` file to your project with the following configuration.
{ "line-length": false, "MD004" : false, "MD033":{ "allowed_elements": ["TabItem", "br", "iframe", "dl", "dt","dd", "em"] }, "MD034" : false, "MD046" : false}
### markdowntables[](https://developers.cardano.org/docs/portal-style-guide/#markdowntables "Direct link to markdowntables")
Helps you work with tables
* Visual Studio Code
* Install the extension via _Command Palette (Ctrl+P)_ using `ext install pharndt.vscode-markdown-table`
| Keybindings | |
| --- | --- |
| `Ctrl+Q Ctrl+F` | format table under cursor. |
| `Ctrl+Q Space` | clear cell under cursor. |
| `Ctrl+Q Ctrl+Q` | toggle table mode |
* In table mode
| Keybindings | |
| --- | --- |
| `Tab` | navigate to the next cell in table |
| `Shift+Tab` | navigate to the previous cell in table |
| `Alt+Numpad +` | Create new column left to the current position |
| `Alt+Numpad -` | delete current column |
### rest-book[](https://developers.cardano.org/docs/portal-style-guide/#rest-book "Direct link to rest-book")
When you write guides for `cardano-wallet` or other components with an API, you might want to include the response for a certain request in your guide. It can be useful not to leave the environment of your editor as to not lose focus or get distracted. `rest-book` allows you to execute HTTP requests within your editor.
* Visual Studio Code
* Install the extension via _Command Palette (Ctrl+P)_ using `ext install tanhakabir.rest-book`
* Open or create a `.restbook` file to use the extension.
Editorial Style Guide[](https://developers.cardano.org/docs/portal-style-guide/#editorial-style-guide "Direct link to Editorial Style Guide")
-----------------------------------------------------------------------------------------------------------------------------------------------
To make everything consistent we should agree on spellings and terms here.
| Spelling/Term | Comment |
| --- | --- |
| `ada` | When talking about the cryptocurrency, do not capitalize, unless at the beginning of a sentence. The idea behind this is to treat it like dollars or euros. If you are in doubt, in English, prefer ada over ADA. Capitalised ADA stands for the ticker symbol only. |
| `ADA` | The ticker symbol for ada, like EUR or USD. |
| `tAda` | Test ada is tAda, not tADA or TADA. See `ada`. |
| `Basho` | The fourth era of the Cardano development focused on performance. Named after Matsuo Basho, a Japanese poet and the master of haiku. |
| `Byron` | First era in Cardano development. Named after the Romantic poet who was the father of Ada Lovelace. |
| `the Cardano Foundation` | Always use **the** Cardano Foundation. |
| `DApp` | Note the capitalization: Decentralized Application. |
| `dcSpark` | Creators of Flint Wallet and Milkomeda. Capitalized S, everything else lower case. |
| `DRep` | Note the capitalization: Delegated Representative. `DRep` as an abbreviation for Delegated Representative follows standard practices for abbreviations in English: taking the first letter of each word. This makes it intuitive and clear in most contexts. It is also in line with the `DApp` abbreviation. In crypto, the lowercase “d“ is often used to signify “decentralized,” as in dApp (decentralized application) or dGov (decentralized governance). Using “dRep” might imply “decentralized representative”. |
| `EMURGO` | All caps in line with EMURGO’s branding. |
| `the Foundation` | Interchangeable with `the Cardano Foundation`, the is not capitalized, but Foundation should be. |
| `GitHub` | Note the capitalized H. |
| `Goguen` | The third era of the Cardano development focused on smart contracts. Named in honour of Joseph Goguen, an US computer scientist. |
| `hard fork` | Two words. |
| `IOHK` | IOHK is now IOG. |
| `IOG` | IOG was IOHK. |
| `Mainnet` | One word. Capitalise when it's a noun (the _Mainnet_) but not when it's an adjective (_mainnet_ functionality), qualified by another proper name (the Cardano _mainnet_), or used as a symbol (e.g. enable Marlowe on `mainnet`). |
| `Ouroboros` | Ouroboros is a family of Cardano's consensus protocols. There are different flavors: Classic, Praos, Genesis, Chronos |
| `sidechains` | One word. |
| `stake pool` | Two words. |
| `staking` | Try to avoid term `staking` without context as it is ambiguous. `staking` refers to the whole process of both delegating and setting up a pool but many people confuse this with the actual process of creating blocks. `delegating` means that people delegate their stake to a stake pool. |
| `Strica` | Creators of Typhon Wallet, Cardanoscan and Flac Finance. Capitalized S, everything else lower case. |
| `proof of stake` | Lower case. Hyphenate when followed by a noun: proof-of-stake systems. |
| `proof of work` | Lower case. Hyphenate when followed by a noun: proof-of-work systems. |
| `Testnet` | One word. Capitalise when it's a particular testnet (e.g. Preview _testnet_) but not when it's an adjective (e.g. _testnet_ functionality) or referring to more than one (e.g. new iterations of the _testnets_). |
| `use case` | Not use-case. |
| `Voltaire` | The fifth era of the Cardano development focused on governance and treasury. Named after the French philosopher who prized criticism and argued for the separation of church and state. |
| `white paper` | Two words. |
* [Markdown Examples](https://developers.cardano.org/docs/portal-style-guide/#markdown-examples)
* [Structured documents](https://developers.cardano.org/docs/portal-style-guide/#structured-documents)
* [This is a level 3 heading](https://developers.cardano.org/docs/portal-style-guide/#this-is-a-level-3-heading)
* [Code](https://developers.cardano.org/docs/portal-style-guide/#code)
* [Tabs](https://developers.cardano.org/docs/portal-style-guide/#tabs)
* [Synching tab choices](https://developers.cardano.org/docs/portal-style-guide/#synching-tab-choices)
* [Video embedding](https://developers.cardano.org/docs/portal-style-guide/#video-embedding)
* [Tables](https://developers.cardano.org/docs/portal-style-guide/#tables)
* [Inline HTML](https://developers.cardano.org/docs/portal-style-guide/#inline-html)
* [Line Breaks](https://developers.cardano.org/docs/portal-style-guide/#line-breaks)
* [Admonitions](https://developers.cardano.org/docs/portal-style-guide/#admonitions)
* [Mermaid](https://developers.cardano.org/docs/portal-style-guide/#mermaid)
* [Other style elements](https://developers.cardano.org/docs/portal-style-guide/#other-style-elements)
* [Editor extensions and configurations](https://developers.cardano.org/docs/portal-style-guide/#editor-extensions-and-configurations)
* [markdownlint](https://developers.cardano.org/docs/portal-style-guide/#markdownlint)
* [markdowntables](https://developers.cardano.org/docs/portal-style-guide/#markdowntables)
* [rest-book](https://developers.cardano.org/docs/portal-style-guide/#rest-book)
* [Editorial Style Guide](https://developers.cardano.org/docs/portal-style-guide/#editorial-style-guide)
---
# Careers on Cardano | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/careers/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Are you passionate about Cardano and looking for a job working in the Cardano ecosystem? There are several organizations which practically always have open vacancies and career opportunities.
Most of these jobs are 100% remote. You can work from anywhere in the world with a flexible schedule.
Work on Cardano projects full-time[](https://developers.cardano.org/docs/careers/#work-on-cardano-projects-full-time "Direct link to Work on Cardano projects full-time")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* [Jobs at Cardano Foundation](https://cardanofoundation.org/careers)
* [Jobs at dcSpark](https://dcspark.io/#careers)
* [Jobs at EMURGO](https://emurgo.io/careers/)
* [Jobs at IOHK](https://apply.workable.com/io-global/)
* [Work on Cardano projects full-time](https://developers.cardano.org/docs/careers/#work-on-cardano-projects-full-time)
---
# Get Started with Aiken | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/aiken/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Aiken is a modern smart contract platform for Cardano.
Installation[](https://developers.cardano.org/docs/get-started/aiken/#installation "Direct link to Installation")
-------------------------------------------------------------------------------------------------------------------
### Install Aiken from Source[](https://developers.cardano.org/docs/get-started/aiken/#install-aiken-from-source "Direct link to Install Aiken from Source")
To install Aiken from source we recommend `cargo`, a package manager for Rust. To install it, please refer to the [Rust Installation Guide](https://doc.rust-lang.org/stable/book/ch01-01-installation.html)
.
cargo install --git https://github.com/aiken-lang/aiken.git
### Install Aiken from Nix Flakes[](https://developers.cardano.org/docs/get-started/aiken/#install-aiken-from-nix-flakes "Direct link to Install Aiken from Nix Flakes")
nix build .#aiken
Quick Start[](https://developers.cardano.org/docs/get-started/aiken/#quick-start "Direct link to Quick Start")
----------------------------------------------------------------------------------------------------------------
aiken --help
Editor Integrations[](https://developers.cardano.org/docs/get-started/aiken/#editor-integrations "Direct link to Editor Integrations")
----------------------------------------------------------------------------------------------------------------------------------------
These editor integrations are currently available for Aiken:
| Editor | Plugin |
| --- | --- |
| VSCode | [editor-integration-vscode](https://github.com/aiken-lang/editor-integration-vscode) |
| Vim/Neovim | [editor-integration-nvim](https://github.com/aiken-lang/editor-integration-nvim) |
Hello World[](https://developers.cardano.org/docs/get-started/aiken/#hello-world "Direct link to Hello World")
----------------------------------------------------------------------------------------------------------------
You are ready now to write and execute your first smart contract on Cardano. Have a look at the [hello world example contract](https://developers.cardano.org/docs/smart-contracts/aiken)
.
Visit the Aiken website and explore [other examples](https://aiken-lang.org/example--hello-world)
.
* [Installation](https://developers.cardano.org/docs/get-started/aiken/#installation)
* [Install Aiken from Source](https://developers.cardano.org/docs/get-started/aiken/#install-aiken-from-source)
* [Install Aiken from Nix Flakes](https://developers.cardano.org/docs/get-started/aiken/#install-aiken-from-nix-flakes)
* [Quick Start](https://developers.cardano.org/docs/get-started/aiken/#quick-start)
* [Editor Integrations](https://developers.cardano.org/docs/get-started/aiken/#editor-integrations)
* [Hello World](https://developers.cardano.org/docs/get-started/aiken/#hello-world)
---
# Fund your Project with Catalyst | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/governance/project-catalyst/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Visit the official [Project Catalyst website](https://projectcatalyst.io/)
for a comprehensive overview of the services and solutions provided by the world's largest decentralized innovation engine for solving real-world challenges.
The portal on [cardano.ideascale.com](https://cardano.ideascale.com/)
is where the Cardano community’s ideas come to life. Here, users can browse active campaigns, participate in discussions, and put forward their ideas for feedback and voting from the community.
Built around ‘Active Campaigns’, the Project Catalyst Ideascale contains several categories of proposals that idea-makers and entrepreneurs can explore when making a proposal. These include classes like ‘DApps and Integrations’, ‘Local Community Centers’, ‘Developer Ecosystem’ proposals, and more. There are separate funds available for each category, and some classes already have well over 100 active proposals.
Within each active campaign, you can find a campaign brief. This is a short explainer of what proposals should include, how to meet the campaign's requirements and some guiding questions for proposals. You will also find a stage flow that guides you through the timeline of each campaign.
Discover a wealth of community-generated proposals by visiting one of the [idea explorers](https://developers.cardano.org/docs/governance/project-catalyst/#browse-funded-ideas)
listed below. Explore existing proposals to gain valuable insights into what makes a successful proposal and how to position your submission for maximum impact. Whether you're considering submitting an idea or simply looking to engage with the community, this is the place to start.
Catalyst Announcements
The best way to keep up to date with Project Catalyst is to follow [the announcement channel on Telegram](https://t.me/cardanocatalyst)
.
Why participate?[](https://developers.cardano.org/docs/governance/project-catalyst/#why-participate "Direct link to Why participate?")
----------------------------------------------------------------------------------------------------------------------------------------
* To build your reputation.
* To build something impactful and meaningful.
* To get your project funded.
* To learn and grow.
### Participate as a proposer[](https://developers.cardano.org/docs/governance/project-catalyst/#participate-as-a-proposer "Direct link to Participate as a proposer")
You will need to create an account first on [Cardano IdeaScale](https://cardano.ideascale.com/)
and then submit your proposal there. You can collaborate with the community to develop and refine your proposal on the [proposals channel](https://t.me/catalystproposers)
on Telegram.
### Participate as a proposal assessor[](https://developers.cardano.org/docs/governance/project-catalyst/#participate-as-a-proposal-assessor "Direct link to Participate as a proposal assessor")
You can provide reviews, assessments, and mentor proposers in their delivery and presentation. Check the [community channel](https://t.me/CatalystCommunityAdvisors)
on Telegram.
### Participate as a voter[](https://developers.cardano.org/docs/governance/project-catalyst/#participate-as-a-voter "Direct link to Participate as a voter")
Download the Catalyst voting app in the [Apple Store](https://apps.apple.com/kg/app/catalyst-voting/id1517473397)
or [Google Play Store](https://play.google.com/store/apps/details?id=io.iohk.vitvoting&gl=US)
and vote for your favourite projects.
Previous Project Catalyst voting results[](https://developers.cardano.org/docs/governance/project-catalyst/#previous-project-catalyst-voting-results "Direct link to Previous Project Catalyst voting results")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* [Project Catalyst Fund 11 Voting Results](https://projectcatalyst.io/funds/11/voting-results)
* [Project Catalyst Fund 10 Voting Results](https://projectcatalyst.io/fund10-voting-results.pdf)
* [Project Catalyst Fund 9 Voting Results](https://drive.google.com/file/d/1HiI0fgiJWbirl2QEGNwiUbKLSQXqdxdv/view)
* [Project Catalyst Fund 8 Voting Results](https://drive.google.com/file/d/1s3jCE7pmoUujy3ASMia-UhFl2KLi_hnf/view)
* [Project Catalyst Fund 7 Voting Results](https://drive.google.com/file/d/193GZulHuk0zhpTrMiLhcNC4OeEMoRyIa/view)
* [Project Catalyst Fund 6 Voting Results](https://drive.google.com/file/d/13h5JFtwqyylMUNMoRGXQZ-FJEM4bznOJ/view)
* [Project Catalyst Fund 5 Voting Results](https://drive.google.com/file/d/1h3-nZYZ0G66UXVd-JdIq_dpXSJAaVOZk/view)
* [Project Catalyst Fund 4 Voting Results](https://drive.google.com/file/d/19VMTYn_sv5Xsp2mC5VUN_-z_aXYHL_Dd/view)
* [Project Catalyst Fund 3 Voting Results](https://drive.google.com/file/d/1X6BnuFBvNO8yF2DeUgBqA3yyYSvqeKvg/view)
* [Project Catalyst Fund 2 Voting Results](https://drive.google.com/file/d/1ZEM12Mbc-gkdNrTg03-ORbGg3DUpug8A/view)
* Fund 1 was the first time the idea was introduced to the Cardano community. This voting cycle did not offer ‘real’ funding.
Communication channels[](https://developers.cardano.org/docs/governance/project-catalyst/#communication-channels "Direct link to Communication channels")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Please join our different channels on Telegram, Discord and Forum to join our Catalyst funding community and discuss your ideas and proposals:
* [Telegram Announcements](https://t.me/cardanocatalyst)
* [Telegram Catalyst Chat](https://t.me/joinchat/JL08XEfhBVIB1NFXx8XwiA)
* [Forum Catalyst category](https://forum.cardano.org/c/english/governance/140)
* [General Voltaire discussions](https://t.me/CardanoGovernanceOfficial)
* [Improving project Catalyst process on Ideascale](https://cardano.ideascale.com/a/campaign-home/25622)
* [Cardano Project Catalyst Discord](https://discord.gg/GUeYabmP4r)
Instruction guides[](https://developers.cardano.org/docs/governance/project-catalyst/#instruction-guides "Direct link to Instruction guides")
-----------------------------------------------------------------------------------------------------------------------------------------------
* [Project Catalyst (Fund12) Challenge and Proposal Guide](https://docs.projectcatalyst.io/fund-documentation/fund12-docs/how-to-submit-a-proposal)
* [Proposal Assessor (formerly Community Advisor) Guide](https://docs.google.com/document/d/1g-iZhDlKhUBZkui1uv8NVNfJC4oVD3JtR-P6Fue7XPU/edit#heading=h.nvn8rjkdb8jh)
FAQ[](https://developers.cardano.org/docs/governance/project-catalyst/#faq "Direct link to FAQ")
--------------------------------------------------------------------------------------------------
Find common FAQ and the FAQ of previous funds on Project Catalyst:
* [General Project Catalyst FAQ](https://cardanocataly.st/en/faq/)
* [Project Catalyst Knowledge base](https://docs.projectcatalyst.io/)
Browse funded ideas[](https://developers.cardano.org/docs/governance/project-catalyst/#browse-funded-ideas "Direct link to Browse funded ideas")
--------------------------------------------------------------------------------------------------------------------------------------------------
* [Project Catalyst Website](https://projectcatalyst.io/search)
* [Catalyst Explorer by LIDO Nation](https://www.lidonation.com/en/project-catalyst/proposals)
Alternative funding options[](https://developers.cardano.org/docs/governance/project-catalyst/#alternative-funding-options "Direct link to Alternative funding options")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[Project Catalyst](https://developers.cardano.org/docs/governance/project-catalyst)
should be your tool of choice when it comes to project funding on Cardano. For the sake of completeness, here is a place to list alternative funding options for your project.
### The cFund[](https://developers.cardano.org/docs/governance/project-catalyst/#the-cfund "Direct link to The cFund")
The [cFund](https://cfund.vc/)
is a venture fund that manages all centralized fund operations secured by [IOHK](https://iohk.io/)
and [Wave Financial](https://wavegp.com/)
where each of them participated with 10$ million to back ambitious founders globally.
The [cFund](https://cfund.vc/)
is a homage to Apple's iFund that was introduced in 2008 to bootstrap iOS development. Compared to Project Catalyst, the funds available here are relatively small.
The **cFund** started in July 2020 with the goals to achieve:
* Growing the Cardano ecosystem.
* Working with governments, especially in developing countries in Africa and South America.
* Providing access to high-speed, adaptable financing for founders to manage payment flows and invest in the Cardano ecosystem.
The first **cFund** investment took place In April 2021. It provided $500,000 to innovative enterprise-grade fintech technology called [COTI, the currency of the internet](https://coti.io/)
. **COTI** secured the investment to support stakeholder-driven payment solutions and enables them to pack digitally any currency.
* [Why participate?](https://developers.cardano.org/docs/governance/project-catalyst/#why-participate)
* [Participate as a proposer](https://developers.cardano.org/docs/governance/project-catalyst/#participate-as-a-proposer)
* [Participate as a proposal assessor](https://developers.cardano.org/docs/governance/project-catalyst/#participate-as-a-proposal-assessor)
* [Participate as a voter](https://developers.cardano.org/docs/governance/project-catalyst/#participate-as-a-voter)
* [Previous Project Catalyst voting results](https://developers.cardano.org/docs/governance/project-catalyst/#previous-project-catalyst-voting-results)
* [Communication channels](https://developers.cardano.org/docs/governance/project-catalyst/#communication-channels)
* [Instruction guides](https://developers.cardano.org/docs/governance/project-catalyst/#instruction-guides)
* [FAQ](https://developers.cardano.org/docs/governance/project-catalyst/#faq)
* [Browse funded ideas](https://developers.cardano.org/docs/governance/project-catalyst/#browse-funded-ideas)
* [Alternative funding options](https://developers.cardano.org/docs/governance/project-catalyst/#alternative-funding-options)
* [The cFund](https://developers.cardano.org/docs/governance/project-catalyst/#the-cfund)
---
# How to run cardano-node | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
### Overview[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#overview "Direct link to Overview")
This guide will show you how to run `cardano-node` and `cardano-cli` on your system and some simple examples of how you can interact with the **Cardano** blockchain.
note
This guide assumes you installed `cardano-node` and `cardano-cli` into your system. If not, you can refer to [Installing cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
guide for instructions on how to do that.
important
This guide does not cover the topic of running a block-producing `cardano-node` or running a **Cardano Stake Pool**. For more information regarding that topic, please visit the [Stake Pool Operation](https://developers.cardano.org/docs/operate-a-stake-pool/)
section.
Cardano blockchain nets:[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#cardano-blockchain--nets "Direct link to Cardano blockchain nets:")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Testnet[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#testnet "Direct link to Testnet")
There are two types of testnet: `preview` and `pre-prod`.
* **Preview Testnet**: Testing release candidates and Mainnet releases. Leads Mainnet hard forks by at least 4 weeks. This net is for those who just want to see how it runs, get familiarised and play with cardano-node.
* **Pre-Production Testnet**: Testing release candidates and Mainnet releases. Forks at approximately same time as Mainnet (within an epoch of each other). This net is ideal for those who are ready to run the Mainnet but want to test it before running it.
### Production (Mainnet)[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#production-mainnet "Direct link to Production (Mainnet)")
This is the live Production. Only gets official Mainnet releases. Please use this net once you are ready to use the cardano-node.
### Configuration Files[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#configuration-files "Direct link to Configuration Files")
The `cardano-node` application requires at least four configuration files to run as of writing this article.
* **Main Config**: It contains general node settings such as **logging** and **versioning**. It also points to the **Byron Genesis** and the **Shelly Genesis** file.
* **Byron Genesis**: It contains the initial protocol parameters and instructs the `cardano-node` on how to bootstrap the **Byron Era** of the **Cardano** blockchain.
* **Shelly Genesis**: It contains the initial protocol parameters and instructs the `cardano-node` on how to bootstrap the **Shelly Era** of the **Cardano** blockchain.
* **Alonzo Genesis**: It contains the initial protocol parameters and instructs the `cardano-node` on how to bootstrap the **Alonzo Era** of the **Cardano** blockchain.
* **Conway Genesis**: It contains the initial protocol parameters and instructs the `cardano-node` on how to bootstrap the **Conway Era** of the **Cardano** blockchain.
* **Topology**: It contains the list of network peers (**`IP Address` and `Port` of other nodes running the blockchain network**) that your node will connect to.
important
Currently, the `cardano-node` topology is manually set by the community of network operators in the **Cardano** blockchain. But an automated p2p (peer-to-peer) system is in the works. For more information visit, [Boosting network decentralization with P2P](https://iohk.io/en/blog/posts/2021/04/06/boosting-network-decentralization-with-p2p/)
.
For more information about **Cardano** blockchain eras and upgrades, please visit the [Cardano Roadmap](https://roadmap.cardano.org/en)
.
You can download the current **Cardano** blockchain network configuration files here: [The Cardano Operations Book > Environments](https://book.play.dev.cardano.org/environments.html)
…or by running:
#### Testnet / Preview[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#testnet--preview "Direct link to Testnet / Preview")
**NetworkMagic**: `2`
curl -O -J "https://book.play.dev.cardano.org/environments/preview/{config,db-sync-config,submit-api-config,topology,byron-genesis,shelley-genesis,alonzo-genesis,conway-genesis}.json"
#### Testnet / Preprod[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#testnet--preprod "Direct link to Testnet / Preprod")
**NetworkMagic**: `1`
curl -O -J "https://book.play.dev.cardano.org/environments/preprod/{config,db-sync-config,submit-api-config,topology,byron-genesis,shelley-genesis,alonzo-genesis,conway-genesis}.json"
#### Mainnet / Production[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#mainnet--production "Direct link to Mainnet / Production")
**NetworkMagic**: `764824073`
curl -O -J "https://book.play.dev.cardano.org/environments/mainnet/{config,db-sync-config,submit-api-config,topology,byron-genesis,shelley-genesis,alonzo-genesis,conway-genesis,checkpoints}.json"
The latest supported networks can be found at [https://book.play.dev.cardano.org/environments.html](https://book.play.dev.cardano.org/environments.html)
note
Each network has a `config` file, `genesis` file(s), `topology` file, and unique identifier called the **Network Magic**.
This section will be updated when new **Cardano** networks come online with their respective configuration files and **Network Magic**.
You might be asking what the difference is between `mainnet` and `testnet` and why there are two official network types? To put it simply, **Cardano** is an open-source blockchain, and anyone is free to spin up a network based on **Cardano's** software components. The `mainnet` network was the first one established during the start of the **Byron** era in 2017. And everyone participating in the network agreed that is where all the real value of **Cardano** lives.
Testing the network's features and capabilities can be expensive and will consume real value. So [Input-Output Global](https://iohk.io/)
has spun up sandboxes or testnet versions of the network. Instead of using real `ada` tokens for transactions, you use the `tAda` or **Test ADA**. Alternatively, you can spin up your own custom **Cardano** network, but that is outside the scope of this guide.
Running the node[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#running-the-node "Direct link to Running the node")
------------------------------------------------------------------------------------------------------------------------------------------------------
To run `cardano-node` you enter something like this into the terminal:
cardano-node run \ --topology path/to/mainnet-topology.json \ --database-path path/to/db \ --socket-path path/to/db/node.socket \ --host-addr x.x.x.x \ --port 3001 \ --config path/to/mainnet-config.json
To get the complete list of available options, use `cardano-node run --help`
Usage: cardano-node run [--topology FILEPATH] [ --database-path FILEPATH | --immutable-database-path FILEPATH --volatile-database-path FILEPATH ] [--validate-db] [--socket-path FILEPATH] [--tracer-socket-path-accept FILEPATH | --tracer-socket-path-connect FILEPATH] [--config NODE-CONFIGURATION] [--byron-delegation-certificate FILEPATH] [--byron-signing-key FILEPATH] [--shelley-kes-key FILEPATH] [--shelley-vrf-key FILEPATH] [--shelley-operational-certificate FILEPATH] [--bulk-credentials-file FILEPATH] [--non-producing-node] [--host-addr IPV4] [--host-ipv6-addr IPV6] [--port PORT]w Run the node.Available options: --topology FILEPATH The path to a file describing the topology. --database-path FILEPATH Directory where the state is stored. --immutable-database-path FILEPATH Directory where the state is stored. --volatile-database-path FILEPATH Directory where the state is stored. --validate-db Validate all on-disk database files --socket-path FILEPATH Path to a cardano-node socket --tracer-socket-path-accept FILEPATH Accept incoming cardano-tracer connection at local socket --tracer-socket-path-connect FILEPATH Connect to cardano-tracer listening on a local socket --config NODE-CONFIGURATION Configuration file for the cardano-node --byron-delegation-certificate FILEPATH Path to the delegation certificate. --byron-signing-key FILEPATH Path to the Byron signing key. --shelley-kes-key FILEPATH Path to the KES signing key. --shelley-vrf-key FILEPATH Path to the VRF signing key. --shelley-operational-certificate FILEPATH Path to the delegation certificate. --bulk-credentials-file FILEPATH Path to the bulk pool credentials file. --non-producing-node Start the node as a non block producing node even if credentials are specified. --host-addr IPV4 An optional IPv4 address --host-ipv6-addr IPV6 An optional IPv6 address --port PORT The port number --shutdown-ipc FD Shut down the process when this inherited FD reaches EOF --shutdown-on-slot-synced SLOT Shut down the process after ChainDB is synced up to the specified slot --shutdown-on-block-synced BLOCK Shut down the process after ChainDB is synced up to the specified block -h,--help Show this help text
### cardano-node parameters[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#cardano-node-parameters "Direct link to cardano-node parameters")
note
In this section, we will use the path `$HOME/cardano/testnet` to store all the testnet `cardano-node` related files as an example, and please replace it with the directory you have chosen to store the files.
We will focus on six key command-line parameters for running a node:
**`--topology`**: This requires the path of the `topology.json` file that you have downloaded as instructed [above](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano#configuration-files)
.
> For example, If you have downloaded the `topology.json` file to the path `$HOME/cardano/testnet/topology.json`, then the argument would be something like this:
--topology $HOME/cardano/testnet/topology.json
**`--database-path`**: This expects the path to a directory where we will store the actual blockchain data like **blocks**, **transactions**, **metadata**, and other data type that people stored in the **Cardano** blockchain. We explore how we can query those kinds of data in the cardano-db-sync section. _**@TODO: link to the cardano-db-sync section.**_
> For example, if we decide that all files required by `cardano-node` will be in the path `$HOME/cardano/testnet`. Then we could create a database directory like this, `mkdir -p $HOME/cardano/testnet/db`. The directory structure would then be something like this:
$HOME/cardano/testnet/├── db├── alonzo-genesis.json├── byron-genesis.json├── config.json├── shelley-genesis.json└── topology.json1 directory, 5 files
> As you may have noticed, we are planning to run a testnet node in this example and have downloaded the configuration files into the `$HOME/cardano/testnet/` directory. We also see that we have created the `db` directory inside `$HOME/cardano/testnet/` successfully. The argument would look something like this:
--database-path $HOME/cardano/testnet/db
> Please download and move the configuration files to your Cardano directory as shown above to continue following this guide.
**`--socket-path`**: This expects the path to the `unix socket` or `named pipe` path that the `cardano-node` will use for [IPC (Inter-Process-Communication)](https://en.wikipedia.org/wiki/Inter-process_communication)
.
> The `cardano-node` uses **IPC (Inter-Process-Communication)** for communicating with other **Cardano** components like `cardano-cli`, `cardano-wallet`, and `cardano-db-sync`. In **Linux** and **MacOS** it uses something called [unix sockets](https://en.wikipedia.org/wiki/Unix_domain_socket)
> and [Named Pipes](https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes)
> in **Windows**.
>
> Here is an example `--socket-path` argument for **Linux**:
--socket-path $HOME/cardano/testnet/db/node.socket
> As you can see, the argument points to a file since **unix sockets** are represented as files (like everything else in **Linux**). In this case, we put the socket file in the `db` directory that we have just created before.
>
> In **Windows**, the `--socket-path` argument would look something like this:
--socket-path "\\\\.\\pipe\\cardano-node-testnet"
> As you may notice, it's like a network `URI` or a network `Path` than a file. It is a crucial difference that you will have to be aware of depending on your operating system. You can replace the string `cardano-node-testnet` in the argument with whatever you like. This example path is used in the [Daedalus Testnet Wallet](https://daedaluswallet.io/)
> for **Windows**.
**`--host-addr`**: This expects the `IP Address` of the machine that `cardano-node` will be running. Other nodes will use this address in their `topology.json` file to connect to your node if you are planning to run it as a `relay` node.
> Here is an example `--host-addr` argument:
--host-addr 192.168.0.1
> In this case, we expect nodes in your [LAN (Local Area Network)](https://en.wikipedia.org/wiki/Local_area_network)
> to connect via `192.168.0.1`, assuming that the `IP Address` of the machine `cardano-node` is running on; replace it with your real `IP Address`. If you don't expect or need external nodes to connect to your node, you can use the loopback address `127.0.0.1`. If you have multiple network interfaces and unsure what to use, you can simply use `0.0.0.0` to accept connections from any network interface.
**`--port`**: In conjunction with the `IP Address`, we will also set the `port` that your `cardano-node` will use for listening to any incoming connection.
> Here is an example `--port` argument:
--port 1337
> You can choose whatever `port` number you like, but it is recommended to use `port` numbers `1024` and above. See [Registered Port](https://www.sciencedirect.com/topics/computer-science/registered-port)
> for more information.
**`--config`**: This expects the path to the main configuration file that we have downloaded previously.
> Here is an example `--config` argument:
--config $HOME/cardano/testnet/config.json
> Please make sure that the `alonzo-genesis.json`, `byron-genesis.json` and `shelley-genesis.json` are in the same directory as the `config.json`.
Here is a realistic example for running `cardano-node`:
cardano-node run \--config $HOME/cardano/testnet/config.json \--database-path $HOME/cardano/testnet/db/ \--socket-path $HOME/cardano/testnet/db/node.socket \--host-addr 127.0.0.1 \--port 1337 \--topology $HOME/cardano/testnet/topology.json
If you have everything set correctly, you should see something like this:
Listening on http://127.0.0.1:12798[cardano.node.networkMagic:Notice:5] [2021-05-20 12:17:10.02 UTC] NetworkMagic 1097911063[cardano.node.basicInfo.protocol:Notice:5] [2021-05-20 12:17:10.02 UTC] Byron; Shelley[cardano.node.basicInfo.version:Notice:5] [2021-05-20 12:17:10.02 UTC] 1.XX.X[cardano.node.basicInfo.commit:Notice:5] [2021-05-20 12:17:10.02 UTC] 9a7331cce5e8bc0ea9c6bfa1c28773f4c5a7000f[cardano.node.basicInfo.nodeStartTime:Notice:5] [2021-05-20 12:17:10.02 UTC] 2021-05-20 12:17:10.024924 UTC[cardano.node.basicInfo.systemStartTime:Notice:5] [2021-05-20 12:17:10.02 UTC] 2019-07-24 20:20:16 UTC[cardano.node.basicInfo.slotLengthByron:Notice:5] [2021-05-20 12:17:10.02 UTC] 20s[cardano.node.basicInfo.epochLengthByron:Notice:5] [2021-05-20 12:17:10.02 UTC] 21600[cardano.node.basicInfo.slotLengthShelley:Notice:5] [2021-05-20 12:17:10.02 UTC] 1s[cardano.node.basicInfo.epochLengthShelley:Notice:5] [2021-05-20 12:17:10.02 UTC] 432000[cardano.node.basicInfo.slotsPerKESPeriodShelley:Notice:5] [2021-05-20 12:17:10.02 UTC] 129600[cardano.node.basicInfo.slotLengthAllegra:Notice:5] [2021-05-20 12:17:10.02 UTC] 1s[cardano.node.basicInfo.epochLengthAllegra:Notice:5] [2021-05-20 12:17:10.02 UTC] 432000[cardano.node.basicInfo.slotsPerKESPeriodAllegra:Notice:5] [2021-05-20 12:17:10.02 UTC] 129600[cardano.node.basicInfo.slotLengthMary:Notice:5] [2021-05-20 12:17:10.02 UTC] 1s[cardano.node.basicInfo.epochLengthMary:Notice:5] [2021-05-20 12:17:10.02 UTC] 432000[cardano.node.basicInfo.slotsPerKESPeriodMary:Notice:5] [2021-05-20 12:17:10.02 UTC] 129600[cardano.node.addresses:Notice:5] [2021-05-20 12:17:10.05 UTC] [SocketInfo 0.0.0.0:9999,SocketInfo [::]:9999][cardano.node.diffusion-mode:Notice:5] [2021-05-20 12:17:10.05 UTC] InitiatorAndResponderDiffusionMode[cardano.node.dns-producers:Notice:5] [2021-05-20 12:17:10.05 UTC] [DnsSubscriptionTarget {dstDomain = "relays-new.cardano-testnet.iohkdev.io", dstPort = 3001, dstValency = 2}][cardano.node.ip-producers:Notice:5] [2021-05-20 12:17:10.05 UTC] IPSubscriptionTarget {ispIps = [], ispValency = 0}[cardano.node.ChainDB:Info:5] [2021-05-20 12:17:10.06 UTC] Opened imm db with immutable tip at genesis (origin) and chunk 0[cardano.node.ChainDB:Info:5] [2021-05-20 12:17:10.06 UTC] Opened vol db[cardano.node.ChainDB:Info:5] [2021-05-20 12:17:10.06 UTC] Replaying ledger from genesis[cardano.node.ChainDB:Info:5] [2021-05-20 12:17:10.07 UTC] Opened lgr db[cardano.node.ChainDB:Info:5] [2021-05-20 12:17:10.07 UTC] Opened db with immutable tip at genesis (origin) and tip genesis (origin)[cardano.node.ChainDB:Notice:33] [2021-05-20 12:17:10.08 UTC] Chain extended, new tip: 1e64e74bd7ac76d6806480a28017deb0aedd356fb61844ec95c429ae2f30c7c3 at slot 0
Syncing the blockchain from zero can take a while. Please be patient. If you want to stop syncing, you can do so by pressing `CTRL` + `C` while in the terminal. Rerunning the `cardano-node run` command with the correct parameters will resume syncing the blockchain.
Querying the Cardano Blockchain[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#querying-the-cardano-blockchain "Direct link to Querying the Cardano Blockchain")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Now that we have `cardano-node` running and syncing, we can test it out by querying the blockchain tip data; which is the current point your local node is synced. To do this, we use the `cardano-cli` command-line application.
But before we can do that, `cardano-cli` and other **Cardano** software components need to know where the node socket file is located. We saved it to the path `$HOME/cardano/db/node.socket` in the previous example. The components read the shell environment variable `CARDANO_NODE_SOCKET_PATH` to find this.
So we will set that in `$HOME/.bashrc` or `$HOME/.zshrc`, depending on which shell application that you use. In Windows, you can follow this guide: [How to Set Environment Variable in Windows](https://phoenixnap.com/kb/windows-set-environment-variable)
.
Add this line to the bottom of your shell profile (**MacOS** and **Linux**):
export CARDANO_NODE_SOCKET_PATH="$HOME/cardano/testnet/db/node.socket"
Once saved, reload your shell/terminal for changes to take effect.
Finally, we can now test querying the blockchain tip of our `cardano-node`:
* First, run `cardano-node` in a separate terminal for it to start syncing (if not already).
* Open another terminal and run the following command `cardano-cli query tip --testnet-magic 1`.
> You should see something like this:
{ "block": 2598870, "epoch": 133, "era": "Shelley", "hash": "7b5633590bf8924d8fce5b6515f34fga0c712f64e9b7d273f915656f88fba872", "slot": 27149964, "syncProgress": "57.09" "block": 2598870, "epoch": 133, "era": "Shelley", "hash": "7b5633590bf8924d8fce5b6515f34fga0c712f64e9b7d273f915656f88fba872", "slot": 27149964, "syncProgress": "57.09"}
note
We include `--testnet-magic ` in the parameter for `cardano-cli query tip` because we are using a testnet node. If you intend to query `mainnet` instead, please use the `--mainnet` parameter and make sure your node is connected to the `mainnet` network.
What you see here is the local tip data of your node. This case, means that you are synced up to `block: 2598870` and `slot: 27149964`.
`syncProgress` is the percentage your node that has been synced. `100` meaning it is fully synced.
To know whether you are fully synced or not, you can check the **Cardano Blockchain Explorer** of the relevant network:
#### Mainnet Explorer[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#mainnet-explorer "Direct link to Mainnet Explorer")
[https://explorer.cardano.org](https://explorer.cardano.org/)
#### Testnet Explorer[](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#testnet-explorer "Direct link to Testnet Explorer")
[https://preprod.cardanoscan.io/](https://preprod.cardanoscan.io/)
[https://preview.cardanoscan.io/](https://preview.cardanoscan.io/)
Scroll down to the **Latest Blocks** section, and you can find the latest network tip.

important
Before making any transactions, make sure you are fully synced to the blockchain network.
Congratulations, you are now ready to explore the world of **Cardano**! 🎉🎉🎉
* [Overview](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#overview)
* [Cardano blockchain nets:](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#cardano-blockchain--nets)
* [Testnet](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#testnet)
* [Production (Mainnet)](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#production-mainnet)
* [Configuration Files](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#configuration-files)
* [Running the node](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#running-the-node)
* [cardano-node parameters](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#cardano-node-parameters)
* [Querying the Cardano Blockchain](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano/#querying-the-cardano-blockchain)
---
# Simple transactions | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Simple transactions[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#simple-transactions "Direct link to Simple transactions")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Cardano transactions involve consuming one or more Unspent Transaction Outputs (UTXOs) and generating one or more new UTXOs. The most basic transaction type involves transferring ada from one address to another. It is essential to ensure that all transactions are 'well-balanced', meaning that the sum of outputs and transaction fees equals the sum of inputs. This balance ensures the integrity and validity of the transaction. Unbalanced transactions are rejected by the local node.
Creating a transaction using the CLI follows a three-step process:
* **Build:** construct the transaction with relevant details
* **Sign:** authenticate the transaction with appropriate signatures
* **Submit:** send the signed transaction to the network for processing.
You'll find commands for these tasks under `cardano-cli conway transaction`
cardano-cli conway transactionUsage: cardano-cli conway transaction ( build-raw | build | build-estimate | sign | witness | assemble | submit | policyid | calculate-min-fee | calculate-min-required-utxo | hash-script-data | txid ) Transaction commands.
`cardano-cli` provides several options for constructing transactions: `transaction build-raw`, `transaction build`, and `build-estimate`. The key difference between these methods lies in their offline and online capabilities, as well as the degree of manual or automatic processing involved.
* The `build-raw` command enables offline transaction building, eliminating the need for a connection to a running node. However, this method requires manual calculation of fees and balancing the transaction.
* The `build` command automatically calculates fees and balances the transaction, but it necessitates a connection to a running node
* The `build-estimate` command is a command that is useful for estimating the size and fee of a transaction when the CLI is not connected to the node. This command automatically balances a transaction related to the script one would like to execute.
When building a transaction, it's essential to specify the following elements:
* **Inputs:** one or multiple Unspent Transaction Outputs (UTXOs) being utilized
* **Outputs:** the addresses where the funds will be sent, including the amount in lovelace for each recipient and any change that needs to be returned to yourself
* **Transaction fee:** the fee paid for the transaction to be processed on the chain.
Building transactions with the `build-raw` command[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#building-transactions-with-the-build-raw-command "Direct link to building-transactions-with-the-build-raw-command")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To create a transaction using `build-raw`, you will need the protocol parameters. These parameters are necessary for calculating the transaction fee at a later stage. Querying the protocol parameters requires a running node:
cardano-cli conway query protocol-parameters --out-file pparams.json
You also need to know the inputs (UTXOs) you will use. A UTXO is identified by its **transaction hash** (`TxHash`) and **transaction index** (`TxIx`) with the syntax `TxHash#TxIx`. You can only use UTXOs controlled by your `payment.skey`.
To query the UTXOs associated to your `payment.addr`, run:
cardano-cli conway query utxo --address $(< payment.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab8125594038891 0 9994790937 lovelace + TxOutDatumNone
In this example, the address has one UTXO associated with it. It holds 9,994,790,937 lovelace (9,994.790937 ada).
Assume you want to send 1,000,000 lovelace (1,000 ada) from `payment.addr` to a `payment2.addr`. This transaction will have one input and two outputs:
* The single input is the UTXO that the transaction will consume, in this case `e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab8125594038891#0`
* The first output corresponds to the 1000 ada we are sending to `payment2.addr`
* The second output corresponds to the change of the transaction. We are sending the difference (8994790937 lovelace) to `payment.addr`.
At this stage, you do not need to worry about the transaction fees. Save the transaction body in the `tx.draft` file:
cardano-cli conway transaction build-raw \ --tx-in e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab8125594038891#0 \ --tx-out addr_test1vzuztsedkqanfm7elu9nshfr4gh2gl0aj4djmayav2t7x8ch3pg30+1000000000 \ --tx-out addr_test1qp39w0fa0ccdc4gmg87puydf2kxt5mgt0vteq4a22ktrcssg7ysmx64l90xa0k4z25wpuejngya833qeu9cdxvveynfscsskf5+8994790937 \ --fee 0 \ --protocol-params-file pparams.json \ --out-file tx.draft
`cardano-cli` can handle the nesting of commands. For example, you can use `cat` within `cardano-cli` to read the addresses directly from the file.
cardano-cli conway transaction build-raw \ --tx-in e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab8125594038891#0 \ --tx-out "$(< payment2.addr)+1000000000" \ --tx-out "$(< payment.addr)+8994790937" \ --fee 0 \ --protocol-params-file pparams.json \ --out-file tx.draft
Let's explore the created `tx.draft` file. It is a text envelope. The 'type' field says that it is an **Unwitnessed Babbage era transaction**. 'Unwitnessed' means that it has not been signed yet. The "cborHex" field encodes all transaction details:
cat tx.draft{ "type": "Unwitnessed Tx BabbageEra", "description": "Ledger Cddl Format", "cborHex": "84a30081825820e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab812559403889100018282581d60b825c32db03b34efd9ff0b385d23aa2ea47dfd955b2df49d6297e31f1a3b9aca008258390062573d3d7e30dc551b41fc1e11a9558cba6d0b7b179057aa55963c4208f121b36abf2bcdd7daa2551c1e6653413a78c419e170d3319924d31b0000000218219e190200a0f5f6"}
Use the `transaction view` command to show the transaction body in a human-readable format:
cardano-cli debug transaction view --tx-body-file tx.draft
{ "auxiliary scripts": null, "certificates": null, "collateral inputs": [], "era": "Babbage", "fee": "0 Lovelace", "inputs": [ "e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab8125594038891#0" ], "metadata": null, "mint": null, "outputs": [ { "address": "addr_test1vzuztsedkqanfm7elu9nshfr4gh2gl0aj4djmayav2t7x8ch3pg30", "address era": "Shelley", "amount": { "lovelace": 1000000000 }, "network": "Testnet", "payment credential key hash": "b825c32db03b34efd9ff0b385d23aa2ea47dfd955b2df49d6297e31f", "reference script": null, "stake reference": null }, { "address": "addr_test1qp39w0fa0ccdc4gmg87puydf2kxt5mgt0vteq4a22ktrcssg7ysmx64l90xa0k4z25wpuejngya833qeu9cdxvveynfscsskf5", "address era": "Shelley", "amount": { "lovelace": 8994790937 }, "network": "Testnet", "payment credential key hash": "62573d3d7e30dc551b41fc1e11a9558cba6d0b7b179057aa55963c42", "reference script": null, "stake reference": { "stake credential key hash": "08f121b36abf2bcdd7daa2551c1e6653413a78c419e170d3319924d3" } } ], "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": []}
### Calculating transaction fees and balancing a transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#calculating-transaction-fees-and-balancing-a-transaction "Direct link to Calculating transaction fees and balancing a transaction")
info
In Cardano, transaction fees are [deterministic](https://iohk.io/en/blog/posts/2021/09/06/no-surprises-transaction-validation-on-cardano/)
, meaning that you can know in advance how much a transaction will cost.
To process a transaction on the network, it must include fees specified within the transaction body. To calculate the exact cost, use the `transaction calculate-min-fee` command, which takes `tx.draft` and `pparams.json` files as inputs. Within this command, specify details like the total number of inputs, outputs, and the required number of signatures. In this case, only one witness, the `payment.skey` signature, is needed:
cardano-cli conway transaction calculate-min-fee \ --tx-body-file tx.draft \ --protocol-params-file pparams.json \ --witness-count 1
Running the command returns the fee that needs to be paid:
173993 Lovelace
With this, recalculate the change that needs to go to `payment.addr` with a simple operation: `Change = originalBalance - amountSent - Fee`:
echo $((9994790937 - 1000000000 - 173993))8994616944
Re-run `transaction build-raw`, include the fee, and adjust the change (the second tx-out). This completes the transaction body, and conventionally, it is saved into the `tx.raw` file.
cardano-cli conway transaction build-raw \ --tx-in e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab8125594038891#0 \ --tx-out $(< payment2.addr)+1000000000 \ --tx-out $(< payment.addr)+8994616944 \ --fee 173993 \ --protocol-params-file pparams.json \ --out-file tx.raw
### Signing the transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#signing-the-transaction "Direct link to Signing the transaction")
Sign the transaction with the `transaction sign` command. You must sign with the `payment.skey` that controls the UTXO you are trying to spend. This time, we produce the `tx.signed` file:
cardano-cli conway transaction sign \--tx-body-file tx.raw \--signing-key-file payment.skey \--testnet-magic 2 \--out-file tx.signed
Inspecting `tx.signed` with `transaction view` reveals that the `"witnesses"` field is no longer empty; it now contains the signature.
cardano-cli debug transaction view --tx-file tx.signed
{ "auxiliary scripts": null, "certificates": null, "collateral inputs": [], "era": "Babbage", "fee": "173993 Lovelace", "inputs": [ "e29e96a012c2443d59f2e53c156503a857c2f27c069ae003dab8125594038891#0" ], "metadata": null, "mint": null, "outputs": [ { "address": "addr_test1vzuztsedkqanfm7elu9nshfr4gh2gl0aj4djmayav2t7x8ch3pg30", "address era": "Shelley", "amount": { "lovelace": 1000000000 }, "network": "Testnet", "payment credential key hash": "b825c32db03b34efd9ff0b385d23aa2ea47dfd955b2df49d6297e31f", "reference script": null, "stake reference": null }, { "address": "addr_test1qp39w0fa0ccdc4gmg87puydf2kxt5mgt0vteq4a22ktrcssg7ysmx64l90xa0k4z25wpuejngya833qeu9cdxvveynfscsskf5", "address era": "Shelley", "amount": { "lovelace": 8994616944 }, "network": "Testnet", "payment credential key hash": "62573d3d7e30dc551b41fc1e11a9558cba6d0b7b179057aa55963c42", "reference script": null, "stake reference": { "stake credential key hash": "08f121b36abf2bcdd7daa2551c1e6653413a78c419e170d3319924d3" } } ], "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": [ { "key": "VKey (VerKeyEd25519DSIGN \"8e090717d4c91437d3b8c467acc850197485913efdbfb48114a4d6cf0ca2dc02\")", "signature": "SignedDSIGN (SigEd25519DSIGN \"897d4774e3da7a9ff92cbfb36ba03443bad0473a449cd65a4855e4e167e6800267d6b38ba836cab05420c3c5a781855ea92e0266be511e96217dd91050abcb06\")" } ]}
### Submitting the transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#submitting-the-transaction "Direct link to Submitting the transaction")
Submitting the transaction means sending it to the blockchain for processing by the stake pools and eventual inclusion in a block. While building and signing a transaction can be done without a running node, submitting the transaction requires an active connection to a running node. Use the `tx.signed` file:
cardano-cli conway transaction submit \ --tx-file tx.signed Transaction successfully submitted.
Building transactions with the `build` command[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#building-transactions-with-the-build-command "Direct link to building-transactions-with-the-build-command")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Using the `build` command for transaction construction simplifies the process significantly. However, it requires an active connection to the node to obtain the protocol parameters in real time. These parameters are then used to automatically calculate the fee to be paid. Additionally, the `build` command offers the `--change-address` flag, which automatically balances the transaction by sending the change to the specified address.
For example, let's send 500 ada (500000000 lovelace) to the `payment2.addr`.
First, query the UTXOs of the input address:
cardano-cli query utxo --address $(< payment.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------c57f25ebf9cf1487b13deeb8449215c499f3d61c2836d84ab92a73b0bbaadd38 1 8994616944 lovelace + TxOutDatumNone
Build the transaction:
cardano-cli conway transaction build \ --tx-in c57f25ebf9cf1487b13deeb8449215c499f3d61c2836d84ab92a73b0bbaadd38#1 \ --tx-out $(< payment2.addr)+500000000 \ --change-address $(< payment.addr) \ --out-file tx.raw
Running this command returns the cost of the transaction fee:
Estimated transaction fee: Lovelace 167041
Inspecting `tx.raw` with `transaction view` reveals that the transaction body already includes the fee, and the transaction is already balanced.
cardano-cli debug transaction view --tx-file tx.raw
{ "auxiliary scripts": null, "certificates": null, "collateral inputs": [], "era": "Babbage", "fee": "167041 Lovelace", "inputs": [ "c57f25ebf9cf1487b13deeb8449215c499f3d61c2836d84ab92a73b0bbaadd38#1" ], "metadata": null, "mint": null, "outputs": [ { "address": "addr_test1vzuztsedkqanfm7elu9nshfr4gh2gl0aj4djmayav2t7x8ch3pg30", "address era": "Shelley", "amount": { "lovelace": 500000000 }, "network": "Testnet", "payment credential key hash": "b825c32db03b34efd9ff0b385d23aa2ea47dfd955b2df49d6297e31f", "reference script": null, "stake reference": null }, { "address": "addr_test1qp39w0fa0ccdc4gmg87puydf2kxt5mgt0vteq4a22ktrcssg7ysmx64l90xa0k4z25wpuejngya833qeu9cdxvveynfscsskf5", "address era": "Shelley", "amount": { "lovelace": 8494449903 }, "network": "Testnet", "payment credential key hash": "62573d3d7e30dc551b41fc1e11a9558cba6d0b7b179057aa55963c42", "reference script": null, "stake reference": { "stake credential key hash": "08f121b36abf2bcdd7daa2551c1e6653413a78c419e170d3319924d3" } } ], "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": []}
### Signing the transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#signing-the-transaction-1 "Direct link to Signing the transaction")
As previously, sign the transaction with the `payment.skey`:
cardano-cli conway transaction sign \ --tx-body-file tx.raw \ --signing-key-file payment.skey \ --out-file tx.signed
### Submitting the transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#submitting-the-transaction-1 "Direct link to Submitting the transaction")
cardano-cli conway transaction submit \ --tx-file tx.signed Transaction successfully submitted.
info
You can parse `cardano-cli` JSON outputs with `jq` to create programmatic workflows. For example, you can parse the output of `query utxo` to obtain the first UTXO associated with the payment address and use it as input (`--tx-in`) in `transaction build`:
cardano-cli conway transaction build \--tx-in $(cardano-cli query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \--tx-out $(< payment.addr)+500000000 \--change-address $(< payment.addr) \--out-file tx.raw
* [Simple transactions](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#simple-transactions)
* [Building transactions with the `build-raw` command](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#building-transactions-with-the-build-raw-command)
* [Calculating transaction fees and balancing a transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#calculating-transaction-fees-and-balancing-a-transaction)
* [Signing the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#signing-the-transaction)
* [Submitting the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#submitting-the-transaction)
* [Building transactions with the `build` command](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#building-transactions-with-the-build-command)
* [Signing the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#signing-the-transaction-1)
* [Submitting the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions/#submitting-the-transaction-1)
---
# Getting cardano-node and cardano-cli | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Binaries for the **latest** version of the node may be downloaded from the [cardano-node GitHub Releases](https://github.com/intersectmbo/cardano-node/releases)
page.
Alternatively, one can build `cardano-node` from source code locally.
Building from source[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#building-from-source "Direct link to Building from source")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The preferred way of building `cardano-node` is via Nix, but the node is buildable also using standard Haskell tools after setting up the building environment.
### Hardware requirements[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#hardware-requirements "Direct link to Hardware requirements")
To set up your platform, you will need:
| Network | CPU Cores | Free RAM | Free storage | OS for Pasive Node | OS for Stake pool |
| --- | --- | --- | --- | --- | --- |
| Mainnet | 2 | 24GB | 300GB of free storage (350GB recommended for future growth) | Linux / Windows / MacOS | Linux |
| Testnet | 2 | 4GB | 20GB | Linux / Windows / MacOS | Linux |
### Building via Nix[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#building-via-nix "Direct link to Building via Nix")
Having [Git](https://git-scm.com/)
and [Nix](https://nixos.org/download/)
installed on your system, run the following command to get a built `cardano-node`:
git clone https://github.com/IntersectMBO/cardano-nodecd cardano-nodegit tag | sort -Vgit switch -d tags/nix build .#cardano-node
Alternatively you can build a node without manually cloning the repository with:
nix build github:IntersectMBO/cardano-node/
Consider setting up the IOG binary cache in order to avoid building the universe locally on your machine. See the [IOGX](https://github.com/input-output-hk/iogx/blob/main/doc/nix-setup-guide.md)
template documentation for more information.
### Building via `cabal`[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#building-via-cabal "Direct link to building-via-cabal")
To download the source code and build it, you need the following packages and tools on your system:
* the version control system `git`,
* a C and C++ compiler, either `gcc` or `clang`,
* developer libraries for:
* the arbitrary precision library `gmp`,
* the compression library `zlib`,
* the service manager `systemd`,
* the TUI library `ncurses`,
* the key-value database `lmdb`,
* the cryptographic suite `openssl`,
* `ncurses` compatibility libraries,
* the Haskell build tool `cabal` (`3.10.2.0` or above),
* the GHC Haskell compiler (version `9.6.7` or above).
#### System libraries[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#system-libraries "Direct link to System libraries")
* Debian/Ubuntu
* Fedora, RedHat or CentOS
* MacOS
* Windows MSYS2
sudo apt-get update -ysudo apt-get install automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libncurses-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libtool autoconf liblmdb-dev -y
sudo yum update -ysudo yum install git gcc gcc-c++ tmux gmp-fdevel make tar xz wget zlib-devel libtool autoconf -ysudo yum install systemd-devel ncurses-devel ncurses-compat-libs which jq openssl-devel lmdb-devel -y
You'll need the following packages and tools on your MacOS system:
* [Xcode](https://developer.apple.com/xcode)
- The Apple Development IDE and SDK/Tools
* [Xcode Command Line Tools](https://developer.apple.com/xcode/features/)
, you can install it by typing `xcode-select --install` in the terminal.
* [Homebrew](https://brew.sh/)
- The Missing Package Manager for MacOS (or Linux)
Then using homebrew install the following:
brew install jq libtool autoconf automake pkg-config openssl
You will need to install llvm in case you are using M1
brew install llvm@13
caution
These instructions might fall out of date unnoticed given the fact that the user base on Windows is small. If you find something is off, please submit a PR.
Git can be installed via [chocolatey](https://community.chocolatey.org/)
(via `choco install git`) or [Scoop](https://scoop.sh/)
(via `scoop install git`).
caution
Using [Winget](https://winget.run/)
will install [Git for Windows](https://gitforwindows.org/)
which might be confusing as it works in an environment separate from MSYS2. It is perfectly possible to use this git but things can become confusing.
The rest of the libraries will be installed inside MSYS2, for whichever [environment](https://www.msys2.org/docs/environments/)
you choose to use. As GHC on Windows switched to `clang` it seems acceptable to recommend using `CLANG64` environment, but others might also work.
GHCup offers installing a MSYS2 environment local to the Haskell installation, just by running the command on [GHCup's front page](https://www.haskell.org/ghcup/)
. It also can work with an existing system-wide [MSYS2](https://www.msys2.org/)
installation if using the following command (just adding a couple of parameters to the invocation of the bootstrap script. If you installed it somewhere else than `C:\msys64` modify the parameter accordingly):
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;try { & ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -Interactive -DisableCurl -ExistingMsys2Dir C:\msys64 -Msys2Env CLANG64 } catch { Write-Error $_ }
Once an MSYS2 environment is installed we should install the following packages via `pacman` (note that you will have to prefix the `pacman` invocation with `ghcup run --mingw-path --` if using the GHCup MSYS2):
pacman -S autoconf autotools ca-certificates mingw-w64-clang-x86_64-toolchain mingw-w64-clang-x86_64-gmp mingw-w64-clang-x86_64-libtool mingw-w64-clang-x86_64-libffi mingw-w64-clang-x86_64-openssl mingw-w64-clang-x86_64-zlib mingw-w64-clang-x86_64-lmdb
#### Installing the Haskell environment[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#installing-the-haskell-environment "Direct link to Installing the Haskell environment")
The recommended way to install the Haskell tools is via [GHCup](https://www.haskell.org/ghcup/)
. Its installation script will guide you through the installation, and warn you about packages that you have to make sure are installed in the system (the ones described on the step above). Check [this page](https://www.haskell.org/ghcup/install/)
for further explanation on the installation process.
caution
On Windows, we discussed how to install GHCup in the step above, depending on how you want to install MSYS2.
Once GHCup is installed, open a new terminal (to get an updated environment) and run:
ghcup install --set ghc 9.6.7ghcup install --set cabal 3.12.1.0
Alternatively, with `ghcup tui` you can pick the specific versions of the tools that you want to install, in particular you should have installed and set:
* `cabal >= 3.12.1.0`
* `GHC >= 9.6.7`
To check that you will use the GHCup tools (and not any other installation on the system), you can execute
which cabal
and it should return a path of this shape: `/home//.ghcup/bin/cabal`.
#### Dependencies required to be at specific versions[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#dependencies-required-to-be-at-specific-versions "Direct link to Dependencies required to be at specific versions")
info
Pre-built libraries can be downloaded from iohk-nix releases, following what is done [in the base CI Github Action](https://github.com/input-output-hk/actions/blob/latest/base/action.yml)
.
In particular for Windows this is probably the easiest method. Note you will need to set these variables in your `.bashrc` or whatever you use to source your shell:
export PKG_CONFIG_PATH=/mingw64/opt/cardano/lib/pkgconfig:$PKG_CONFIG_PATHexport LD_LIBRARY_PATH=/mingw64/opt/cardano/bin:$LD_LIBRARY_PATHexport PATH=/mingw64/opt/cardano/bin:$PATH
Decide which version of Cardano Node you will be installing. A list of available tags is available at: [https://github.com/IntersectMBO/cardano-node/tags](https://github.com/IntersectMBO/cardano-node/tags)
. Set the environment variable to the tag you selected (or use `master` for the latest unstable version):
CARDANO_NODE_VERSION='10.3.1'IOHKNIX_VERSION=$(curl https://raw.githubusercontent.com/IntersectMBO/cardano-node/$CARDANO_NODE_VERSION/flake.lock | jq -r '.nodes.iohkNix.locked.rev')echo "iohk-nix version: $IOHKNIX_VERSION"
The variable `IOHKNIX_VERSION` will be used going forward to retrieve the correct versions of `sodium`, `secp256k1` and `blst`.
caution
Make sure that `secp256k1`, `sodium` and `blst` versions match flake input version in [`iohkNix`](https://github.com/input-output-hk/iohk-nix/blob/master/flake.nix#L14)
for a particular node version used.
##### Installing "sodium"[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#installing-sodium "Direct link to Installing "sodium"")
Cardano uses a custom fork of `sodium` which exposes some internal functions and adds some other new functions. This fork lives in [https://github.com/intersectmbo/libsodium](https://github.com/intersectmbo/libsodium)
. Users need to install that custom version of `sodium` with the following steps.
Create a working directory for your builds:
mkdir -p ~/srccd ~/src
Find out the correct `sodium` version for your build:
SODIUM_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/$IOHKNIX_VERSION/flake.lock | jq -r '.nodes.sodium.original.rev')echo "Using sodium version: $SODIUM_VERSION"
Download and install `sodium`:
: ${SODIUM_VERSION:='dbb48cc'}git clone https://github.com/intersectmbo/libsodiumcd libsodiumgit checkout $SODIUM_VERSION./autogen.sh./configuremakemake checksudo make install
Add the following to your `~/.bashrc` file and source it (or re-open the terminal):
export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
For some distributions you will also need to configure the dynamic linker. If the executable is linked with the right `libsodium.so` file (which you can check by running `ldd`), the running binary might still use the wrong library. You can check this by running `pldd`. If the `pldd` shows that the running executable is using the wrong library, run `ldconfig`.
##### Installing `secp256k1`[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#installing-secp256k1 "Direct link to installing-secp256k1")
Find out the correct `secp256k1` version:
SECP256K1_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/$IOHKNIX_VERSION/flake.lock | jq -r '.nodes.secp256k1.original.ref')echo "Using secp256k1 version: ${SECP256K1_VERSION}"
Download and install `secp256k1`:
: ${SECP256K1_VERSION:='v0.3.2'}git clone --depth 1 --branch ${SECP256K1_VERSION} https://github.com/bitcoin-core/secp256k1cd secp256k1./autogen.sh./configure --enable-module-schnorrsig --enable-experimentalmakemake checksudo make install
##### Installing `blst`[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#installing-blst "Direct link to installing-blst")
Find out the correct `blst` version:
BLST_VERSION=$(curl https://raw.githubusercontent.com/input-output-hk/iohk-nix/$IOHKNIX_VERSION/flake.lock | jq -r '.nodes.blst.original.ref')echo "Using blst version: ${BLST_VERSION}"
Download and install `blst` so that `cardano-base` can pick it up (assuming that `pkg-config` is installed):
: ${BLST_VERSION:='v0.3.11'}git clone --depth 1 --branch ${BLST_VERSION} https://github.com/supranational/blstcd blst./build.shcat > libblst.pc << EOFprefix=/usr/localexec_prefix=\${prefix}libdir=\${exec_prefix}/libincludedir=\${prefix}/includeName: libblstDescription: Multilingual BLS12-381 signature libraryURL: https://github.com/supranational/blstVersion: ${BLST_VERSION#v}Cflags: -I\${includedir}Libs: -L\${libdir} -lblstEOFsudo cp libblst.pc /usr/local/lib/pkgconfig/sudo cp bindings/blst_aux.h bindings/blst.h bindings/blst.hpp /usr/local/include/sudo cp libblst.a /usr/local/libsudo chmod u=rw,go=r /usr/local/{lib/{libblst.a,pkgconfig/libblst.pc},include/{blst.{h,hpp},blst_aux.h}}
#### Installing the node[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#installing-the-node "Direct link to Installing the node")
##### Downloading the source code for cardano-node[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#downloading-the-source-code-for-cardano-node "Direct link to Downloading the source code for cardano-node")
Create a working directory for your builds:
mkdir -p ~/srccd ~/src
Download the Cardano node sources:
git clone https://github.com/intersectmbo/cardano-node.git
Change the working directory to the downloaded source code folder:
cd cardano-node
Check out the latest version of cardano-node (choose the tag with the highest version number: `TAGGED-VERSION`):
git tag | sort -Vgit switch -d tags/
##### Configuring the build options[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#configuring-the-build-options "Direct link to Configuring the build options")
We explicitly use the GHC version that we installed earlier. This avoids defaulting to a system version of GHC that might be different than the one you have installed.
echo "with-compiler: ghc-9.6.7" >> cabal.project.local
You will need to run following commands on M1, those commands will set some cabal related options before building
echo "package trace-dispatcher" >> cabal.project.localecho " ghc-options: -Wwarn" >> cabal.project.localecho "" >> cabal.project.localecho "package HsOpenSSL" >> cabal.project.localecho " flags: -homebrew-openssl" >> cabal.project.localecho "" >> cabal.project.local
caution
More recent versions of MacOS seems to install openssl in a different location than expected by default. If you have installed openssl via homebrew and encounter the following build error:
Failed to build HsOpenSSL-0.11.7.2. The failure occurred during the configurestep.[1 of 1] Compiling Main (...)Linking .../dist-newstyle/tmp/src-75805/HsOpenSSL-0.11.7.2/dist/setup/setup ...Configuring HsOpenSSL-0.11.7.2...setup: Can’t find OpenSSL library
You'll most likely need to add relevant symlinks as follows:
sudo mkdir -p /usr/local/opt/opensslsudo ln -s /opt/homebrew/opt/openssl@3/lib /usr/local/opt/openssl/libsudo ln -s /opt/homebrew/opt/openssl@3/include /usr/local/opt/openssl/include
This is a wart of the `HsOpenSSL` library wrapper, and using classic methods such as setting `LDFLAGS` & `CPPFLAGS`, or using `--extra-include-dirs` and `--extra-lib-dirs` won't work properly.
##### Building and installing the node[](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#building-and-installing-the-node "Direct link to Building and installing the node")
Build the node and CLI with `cabal`:
cabal updatecabal build exe:cardano-nodecabal build exe:cardano-cli
caution
On Windows, should you run into an error like this one when building:
ld.lld: error: undefined symbol: __local_stdio_printf_options>>> referenced by libHSprocess-1.6.25.0-4d1c620770857b639d352d5e988299133f830295.a(runProcess.o):(swprintf_s)clang: error: linker command failed with exit code 1 (use -v to see invocation)
You should comment out `extra-lib-dirs` and `extra-include-dirs` in `~/AppData/Roaming/cabal/config`. See [this ticket](https://github.com/haskell/process/issues/340)
for an example.
Install the newly built node and CLI commands to the `~/.local/bin` directory:
mkdir -p ~/.local/bincp -p "$(cabal list-bin cardano-node)" ~/.local/bin/cp -p "$(cabal list-bin cardano-cli)" ~/.local/bin/
**Note:** If cardano-cli does not build with 'cabal build all', run 'cabal build cardano-cli'. **Note:** `~/.local/bin` should be in the `$PATH`.
Note, we avoid using `cabal install` because that method prevents the installed binaries from reporting the git revision with the `--version` switch.
Check the version that has been installed:
cardano-node --versioncardano-cli --version
Repeat the above process when you need to update to a new version.
**Note:** If serialization of the ledger state changed, snapshots in your `db/ledger` folder will be deleted by the node on startup. Consider backing those up before starting a new version of the node.
* [Building from source](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#building-from-source)
* [Hardware requirements](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#hardware-requirements)
* [Building via Nix](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#building-via-nix)
* [Building via `cabal`](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node/#building-via-cabal)
---
# Dynamic block forging | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-node/dynamic-block-forging/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Peer-to-Peer Block Production and Block Forging Configuration[](https://developers.cardano.org/docs/get-started/cardano-node/dynamic-block-forging/#peer-to-peer-block-production-and-block-forging-configuration "Direct link to Peer-to-Peer Block Production and Block Forging Configuration")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
For redundancy purposes, Stake Pool Operators (SPOs) often operate backup block production nodes. However, with the introduction of peer-to-peer (P2P) nodes, the previous approach of using firewall rules to prevent relays from connecting to the backup node, and thus stop duplicate blocks from being propagated, will no longer be effective.
In the P2P environment, relays can repurpose inbound connections from the block producer, leading to potential complications. To address this issue, we've introduced a way for a block producing node to be started (and stopped) without immediately producing blocks. It will only begin (or stop) block production when it receives a SIGHUP signal.
Enabling and Disabling Block Forging[](https://developers.cardano.org/docs/get-started/cardano-node/dynamic-block-forging/#enabling-and-disabling-block-forging "Direct link to Enabling and Disabling Block Forging")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Block Forging can be toggled on and off using the SIGHUP signal. Sending such a signal triggers the node to read the block forging credential files. Note that this will also trigger the re-reading of the topology configuration file, so connections might be lost.
As these credential files are provided through CLI flags, they cannot be removed without restarting the node. To disable block forging, you need to move, rename, or delete the file at the specified path (for the credential flags), and then send the SIGHUP signal. The code will then recognize that the specified files are missing and disable block forging, recording the appropriate log messages.
Starting as a Non-Producing Node[](https://developers.cardano.org/docs/get-started/cardano-node/dynamic-block-forging/#starting-as-a-non-producing-node "Direct link to Starting as a Non-Producing Node")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you wish to start a block producing node (i.e., passing the credentials in the respective flags) without it acting as a block producer immediately, you can use the `--start-as-non-producing-node` flag. This will run the node with credentials as a standard node. However, upon receiving the SIGHUP signal, it will read the credential files and start block forging.
This configuration allows for safer management of block production in a P2P environment, reducing the risk of duplicate blocks and improving overall network stability.
* [Peer-to-Peer Block Production and Block Forging Configuration](https://developers.cardano.org/docs/get-started/cardano-node/dynamic-block-forging/#peer-to-peer-block-production-and-block-forging-configuration)
* [Enabling and Disabling Block Forging](https://developers.cardano.org/docs/get-started/cardano-node/dynamic-block-forging/#enabling-and-disabling-block-forging)
* [Starting as a Non-Producing Node](https://developers.cardano.org/docs/get-started/cardano-node/dynamic-block-forging/#starting-as-a-non-producing-node)
---
# Stake address registration | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
tip
To integrate the latest (Conway) era, which differs significantly from previous eras, `cardano-cli` has introduced `` as a top-level command, replacing the former `` 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 transaction build `.
Registering a stake address[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#registering-a-stake-address "Direct link to 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-addressUsage: 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[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#generating-the-stake-address-registration-certificate "Direct link to 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 .stakeAddressDeposit2000000
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[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#submitting-the-stake-address-registration-certificate-in-a-transaction "Direct link to 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[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#using-the-build-command "Direct link to 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
note
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[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#using-the-build-raw-command "Direct link to using-the-build-raw-command")
Using the `build-raw` command involves a slightly more intricate process. Similarly to the steps outlined in [simple transactions](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/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
tip
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.lovelace9999834851
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 .stakeAddressDeposit2000000
Query the current balance of `payment.addr`:
cardano-cli latest query utxo --address $(< payment.addr) --output-json | jq -r .[].value.lovelace9999834851
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[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#sign-and-submit-the-transaction "Direct link to 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
* [Registering a stake address](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#registering-a-stake-address)
* [Generating the stake address registration certificate](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#generating-the-stake-address-registration-certificate)
* [Submitting the stake address registration certificate in a transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#submitting-the-stake-address-registration-certificate-in-a-transaction)
* [Using the `build` command](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#using-the-build-command)
* [Using the `build-raw` command](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#using-the-build-raw-command)
* [Sign and submit the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration/#sign-and-submit-the-transaction)
---
# Minting NFTs | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/native-tokens/minting-nfts/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
note
There are many ways to realize NFTs with Cardano. However, in this guide, we will concentrate on the most dominant way, to attach storage references of other services like [IPFS](https://ipfs.io/)
to our tokens.
What's the difference?[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#whats-the-difference "Direct link to What's the difference?")
--------------------------------------------------------------------------------------------------------------------------------------------------------
What is the difference between native assets and NFTs? From a technical point of view, NFTs are the same as native assets. But some additional characteristics make a native asset truly an NFT:
1. As the name states - it must be 'non-fungible. This means you need to have unique identifiers or attributes attached to a token to make it distinguishable from others.
2. Most of the time, NFT's should live on the chain forever. Therefore we need some mechanism to ensure an NFT stays unique and can not be duplicated.
### The policyID[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#the-policyid "Direct link to The policyID")
Native assets in Cardano feature the following characteristics:
1. An amount/value (how much are there?)
2. A name
3. A unique `policyID`
Since asset names are not unique and can be easily duplicated, Cardano NFTs need to be identified by the `policyID`. This ID is unique and attached permanently to the asset. The policy ID stems from a policy script that defines characteristics such as who can mint tokens and when those actions can be made.
Many NFT projects make the `policyID` under which the NFTs were minted publicly available, so anyone can differentiate fraudulent/duplicate NFTs from the original tokens.
Some services even offer to register your `policyID` to detect tokens that feature the same attributes as your token but were minted under a different policy.
### Metadata attributes[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#metadata-attributes "Direct link to Metadata attributes")
In addition to the unique `policyID` we can also attach metadata with various attributes to a transaction.
Here is an example from [Saturn NFT](https://saturnnft.io/)
using the [CardanoSharp Library](https://github.com/CardanoSharp/cardanosharp-wallet)
{ "721": { "{policy_id}": { "{policy_name}": { "name": "", "image": "", "mediaType": "", "files": [ { "name": "", "src": "", "mediaType": "" } ] } } }}
Metadata helps us to display things like image URIs and stuff that truly makes it an NFT. With this workaround of attaching metadata, third-party platforms like [pool.pm](https://pool.pm/)
can easily trace back to the last minting transaction, read the metadata, and query images and attributes accordingly. The query would look something like this:
1. Get asset name and `policyID`.
2. Look up the latest minting transaction of this asset.
3. Check the metadata for label `721`.
4. Match the asset name and (in this case) the `{policy_name}`\-entry.
5. Query the IPFS hash and all other attributes to the corresponding entry.
important
**There are currently 2 standards for Cardano NFT metadata.** The first is [CIP-25](https://cips.cardano.org/cips/cip25/)
which is the old metadata standard that existed before Cardano smart contracts. These are the easiest to create but are very limited in functionality as the metadata cannot be read by smart contracts. As CIP-25 NFTs are easier to create, we will show how to create them in this beginners guide.
The second standard is [CIP-68](https://cips.cardano.org/cips/cip68/)
which is a dynamic standard that allows for complex NFT functionality with metadata that can be read by smart contracts. This is the preferred standard now that smart contracts are fully operational on Cardano.
If you don't mind a minting service having the policyId, [Saturn NFT](https://saturnnft.io/)
supports minting on the standard with custom functionality.
caution
If using a 3rd party service for minting, the service will have control of the minting policy until the policy time locks.
### Time locking[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#time-locking "Direct link to Time locking")
Since NFTs are likely to be traded or sold, they should follow a more strict policy. Most of the time, a value is defined by the (artificial) scarcity of an asset.
You can regulate such factors with [multi-signature scripts](https://github.com/IntersectMBO/cardano-node/blob/c6b574229f76627a058a7e559599d2fc3f40575d/doc/reference/simple-scripts.md)
.
For this guide, we will choose the following constraints:
1. There should be only one defined signature allowed to mint (or burn) the NFT.
2. The signature will expire in **10000 slots** from now to leave the room if we screw something up.
Prerequisites[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#prerequisites "Direct link to Prerequisites")
-------------------------------------------------------------------------------------------------------------------------------
Apart from the same requisites as on the [minting native assets](https://developers.cardano.org/docs/native-tokens/minting)
guide, we will additionally need:
1. Obviously, what / how many NFTs you want to make. --> We are going to make only one NFT
2. An already populated `metadata.json`
3. Know how your minting policy should look like. --> Only one signature allowed (which we will create in this guide) --> No further minting or burning of the asset allowed after 10000 slots have passed since the transaction was made
4. Hash if uploaded image to IPFS --> We will use this [image](https://gateway.pinata.cloud/ipfs/QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw)
note
We recommend upload images to IPFS as it is the most common decentralized storage service. There are alternatives, but IPFS has the biggest adoption in terms of how many NFTs got minted.
Lets get started[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#lets-get-started "Direct link to Lets get started")
----------------------------------------------------------------------------------------------------------------------------------------
Since the creation of native assets is documented extensively in the [minting](https://developers.cardano.org/docs/native-tokens/minting)
chapter, we won't go into much detail here. Here's a little recap and needed setup
### Working directory[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#working-directory "Direct link to Working directory")
note
Minting course is available in three different versions, which are the Preview Testnet, Pre-Production Testnet, and Mainnet.
* Preview
* Pre-Production
* Mainnet
First of all, we are going to set up a new working directory and change into it:
mkdir nftcd nft/
### Set variables[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#set-variables "Direct link to Set variables")
We will set important values in a more readable variable for better readability and debugging of failed transactions.
Since cardano-node version 1.31.0 the token name should be in hex format. We will set the variable $realtokenname (real name in utf-8) and then convert it to $tokenname (name in hex format):
realtokenname="NFT1"tokenname=$(echo -n $realtokenname | xxd -b -ps -c 80 | tr -d '\n')tokenamount="1"fee="0"output="0"ipfs_hash="please insert your ipfs hash here"
note
The IPFS hash is a key requirement and can be found once you upload your image to IPFS. Here's an example of how the IPFS looks like when an image is uploaded in [pinata](https://www.pinata.cloud/)

### Generate keys and address[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#generate-keys-and-address "Direct link to Generate keys and address")
Each NFT is a unique asset and it is important to maintain the security and privacy of the asset and its associated funds. We will be generating new keys and a new payment address:
cardano-cli address key-gen --verification-key-file payment.vkey --signing-key-file payment.skey
Those two keys can now be used to generate an address:
* Preview
* Pre-Production
* Mainnet
cardano-cli address build --payment-verification-key-file payment.vkey --out-file payment.addr --testnet-magic 2
cardano-cli address build --payment-verification-key-file payment.vkey --out-file payment.addr --testnet-magic 1
cardano-cli address build --payment-verification-key-file payment.vkey --out-file payment.addr --mainnet
We will save our address hash in a variable called address:
address=$(cat payment.addr)
### Fund the address[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#fund-the-address "Direct link to Fund the address")
Submitting transactions always require you to pay a fee. Sending native assets requires sending at least 1 ada. So make sure the address you are going to use as the input for the minting transaction has sufficient funds. For our example, the newly generated address was funded with 10 ada.
Use the address you just generated and send ada to it. To find and copy the address use the following command:
cat payment.addr
You will see something similar to this:
addr_test1vzm8e7stya3kzp85zu2jqqj99sqnx268a3ew2k90n7gs36c5fte8v
note
Because the Cardano testnet is an independent network, separate from the Cardano mainnet, it requires its own token: test ada (tAda).
To get free test ada, you need to visit: [Cardano Testnet Faucet](https://docs.cardano.org/cardano-testnet/tools/faucet)
.
To check if the address has successfully received the funds, use the following command:
* Preview
* Pre-Production
* Mainnet
cardano-cli query utxo --address $address --testnet-magic 2
cardano-cli query utxo --address $address --testnet-magic 1
cardano-cli query utxo --address $address --mainnet
You should see something like this:
TxHash TxIx Amount--------------------------------------------------------------------------------------974e98c4529f8fc75fa8baf5618f7b5ade81aa9ed29ce33cd1c2f2e70838180e 0 10000000 lovelace
### Export protocol parameters[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#export-protocol-parameters "Direct link to Export protocol parameters")
For our transaction calculations, we need some of the current protocol parameters. The parameters can be saved in a file called `protocol.json` with this command:
* Preview
* Pre-Production
* Mainnet
cardano-cli query protocol-parameters --testnet-magic 2 --out-file protocol.json
cardano-cli query protocol-parameters --testnet-magic 1 --out-file protocol.json
cardano-cli query protocol-parameters --mainnet --out-file protocol.json
### Creating the policyID[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#creating-the-policyid "Direct link to Creating the policyID")
Just as in generating native assets, we will need to generate some policy-related files like key pairs and a policy script:
mkdir policy
note
We don’t change into this directory, and everything is done from our working directory.
Generate a new set of key pairs:
cardano-cli address key-gen \ --verification-key-file policy/policy.vkey \ --signing-key-file policy/policy.skey
Instead of only defining a single signature (as we did in the native asset minting guide), our script file needs to implement the following characteristics (which we defined above):
1. Only one signature allowed
2. No further minting or burning of the asset allowed after 10000 slots have passed since the transaction was made
For this specific purpose `policy.script` file which will look like this:
{ "type": "all", "scripts": [ { "type": "before", "slot": }, { "type": "sig", "keyHash": "insert keyHash here" } ]}
As you can see, we need to adjust two values here, the `slot` number as well as the `keyHash`.
To set everything at once and copy and paste it, use this command(s): **You need to have the `jq` installed to parse the tip correctly:**
* Preview
* Pre-Production
* Mainnet
echo "{" >> policy/policy.scriptecho " \"type\": \"all\"," >> policy/policy.scriptecho " \"scripts\":" >> policy/policy.scriptecho " [" >> policy/policy.scriptecho " {" >> policy/policy.scriptecho " \"type\": \"before\"," >> policy/policy.scriptecho " \"slot\": $(expr $(cardano-cli query tip --testnet-magic 2 | jq .slot?) + 10000)" >> policy/policy.scriptecho " }," >> policy/policy.scriptecho " {" >> policy/policy.scriptecho " \"type\": \"sig\"," >> policy/policy.scriptecho " \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey)\"" >> policy/policy.scriptecho " }" >> policy/policy.scriptecho " ]" >> policy/policy.scriptecho "}" >> policy/policy.script
echo "{" >> policy/policy.scriptecho " \"type\": \"all\"," >> policy/policy.scriptecho " \"scripts\":" >> policy/policy.scriptecho " [" >> policy/policy.scriptecho " {" >> policy/policy.scriptecho " \"type\": \"before\"," >> policy/policy.scriptecho " \"slot\": $(expr $(cardano-cli query tip --testnet-magic 1 | jq .slot?) + 10000)" >> policy/policy.scriptecho " }," >> policy/policy.scriptecho " {" >> policy/policy.scriptecho " \"type\": \"sig\"," >> policy/policy.scriptecho " \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey)\"" >> policy/policy.scriptecho " }" >> policy/policy.scriptecho " ]" >> policy/policy.scriptecho "}" >> policy/policy.script
echo "{" >> policy/policy.scriptecho " \"type\": \"all\"," >> policy/policy.scriptecho " \"scripts\":" >> policy/policy.scriptecho " [" >> policy/policy.scriptecho " {" >> policy/policy.scriptecho " \"type\": \"before\"," >> policy/policy.scriptecho " \"slot\": $(expr $(cardano-cli query tip --mainnet | jq .slot?) + 10000)" >> policy/policy.scriptecho " }," >> policy/policy.scriptecho " {" >> policy/policy.scriptecho " \"type\": \"sig\"," >> policy/policy.scriptecho " \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey)\"" >> policy/policy.scriptecho " }" >> policy/policy.scriptecho " ]" >> policy/policy.scriptecho "}" >> policy/policy.script
caution
If this command is not working, please set the key hash and correct slot manually. Otherwise skip to `slotnumber` command few rows down below.
To generate the `keyHash`, use the following command:
cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey
To calculate the correct slot, query the current slot and add 10000 to it:
* Preview
* Pre-Production
* Mainnet
cardano-cli query tip --testnet-magic 2
cardano-cli query tip --testnet-magic 1
cardano-cli query tip --mainnet
Make a new file called policy.script in the policy folder:
touch policy/policy.script
Paste the JSON from above, populated with your `keyHash` and your `slot` number into it:
nano policy/policy.script
note
Be aware the slot number is defined as an integer and therefore needs no double quotation marks, whereas the `keyHash` is defined as a string and needs to be wrapped in double quotation marks.
Please take note of your slot number and save it in a variable. Slot number can be found inside of `policy.script` file:
slotnumber="Replace this with your slot number"
And save the location of the script file into a variable as well:
script="policy/policy.script"
The last step is to generate the policyID:
cardano-cli conway transaction policyid --script-file ./policy/policy.script > policy/policyID
### Metadata[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#metadata "Direct link to Metadata")
Since we now have our policy as well as our `policyID` defined, we need to adjust our metadata information.
Here’s an example of the metadata.json which we’ll use for this guide:
{ "721": { "please_insert_policyID_here": { "NFT1": { "description": "This is my first NFT thanks to the Cardano foundation", "name": "Cardano foundation NFT guide token", "id": 1, "image": "" } } }}
note
The third element in the hierarchy needs to have the same name as our NFT native asset.
To save this file as `metadata.json` use the following command:
echo "{" >> metadata.jsonecho " \"721\": {" >> metadata.jsonecho " \"$(cat policy/policyID)\": {" >> metadata.jsonecho " \"$(echo $realtokenname)\": {" >> metadata.jsonecho " \"description\": \"This is my first NFT thanks to the Cardano foundation\"," >> metadata.jsonecho " \"name\": \"Cardano foundation NFT guide token\"," >> metadata.jsonecho " \"id\": \"1\"," >> metadata.jsonecho " \"image\": \"ipfs://$(echo $ipfs_hash)\"" >> metadata.jsonecho " }" >> metadata.jsonecho " }" >> metadata.jsonecho " }" >> metadata.jsonecho "}" >> metadata.json
note
Please make sure the image value / IPFS hash is set with the correct protocol pre-fix _ipfs://_ (for example _"ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw"_)
### Crafting the transaction[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#crafting-the-transaction "Direct link to Crafting the transaction")
Let's begin building our transaction. Before we start, we will again need some setup to make the transaction building easier. Query your payment address and take note of the different values present.
* Preview
* Pre-Production
* Mainnet
cardano-cli query utxo --address $address --testnet-magic 2
cardano-cli query utxo --address $address --testnet-magic 1
cardano-cli query utxo --address $address --mainnet
Your output should look something like this (fictional example):
TxHash TxIx Amount--------------------------------------------------------------------------------------b35a4ba9ef3ce21adcd6879d08553642224304704d206c74d3ffb3e6eed3ca28 0 1000000000 lovelace
Since we need each of those values in our transaction, we will store them individually in a corresponding variable:
txhash="insert your txhash here"txix="insert your TxIx here"funds="insert Amount in lovelace here"policyid=$(cat policy/policyID)output=1400000
Here we are setting the `output` value to `1400000` Lovelace which is equivalent to `1.4` ADA. This amount is used because this is the minimum UTxO requirement.
If you're unsure, check if all of the other needed variables for the transaction are set, each `echo` should return a value, if something is missing please make sure to go over all of the previous steps:
echo $feeecho $addressecho $outputecho $tokenamountecho $policyidecho $tokennameecho $slotnumberecho $script
If everything is set, run the following command:
* Preview
* Pre-Production
* Mainnet
cardano-cli conway transaction build \--testnet-magic 2 \--alonzo-era \--tx-in $txhash#$txix \--tx-out $address+$output+"$tokenamount $policyid.$tokenname" \--change-address $address \--mint="$tokenamount $policyid.$tokenname" \--minting-script-file $script \--metadata-json-file metadata.json \--invalid-hereafter $slotnumber \--witness-override 2 \--out-file matx.raw
cardano-cli conway transaction build \--testnet-magic 1 \--alonzo-era \--tx-in $txhash#$txix \--tx-out $address+$output+"$tokenamount $policyid.$tokenname" \--change-address $address \--mint="$tokenamount $policyid.$tokenname" \--minting-script-file $script \--metadata-json-file metadata.json \--invalid-hereafter $slotnumber \--witness-override 2 \--out-file matx.raw
cardano-cli conway transaction build \--mainnet \--alonzo-era \--tx-in $txhash#$txix \--tx-out $address+$output+"$tokenamount $policyid.$tokenname" \--change-address $address \--mint="$tokenamount $policyid.$tokenname" \--minting-script-file $script \--metadata-json-file metadata.json \--invalid-hereafter $slotnumber \--witness-override 2 \--out-file matx.raw
The above command will generate output as per below:
Minimum required UTxO: Lovelace 1448244
This means that we need to change the value of the `$output` variable to the given value.
output=1448244
Remember to use the value that you got in your own output.
If the minimum value was right then this command will generate `matx.raw` and will give output similar to:
Estimated transaction fee: Lovelace 176677
**NOTE**: Its possible that the Lovelace value for you is different.
Sign the transaction:
cardano-cli conway transaction sign \--signing-key-file payment.skey \--signing-key-file policy/policy.skey \--mainnet --tx-body-file matx.raw \--out-file matx.signed
note
The signed transaction will be saved in a new file called _matx.signed_ instead of _matx.raw_.
### Submit the transaction[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#submit-the-transaction "Direct link to Submit the transaction")
Now we are going to submit the transaction, therefore minting our native assets:
* Preview
* Pre-Production
* Mainnet
cardano-cli conway transaction submit --tx-file matx.signed --testnet-magic 2
cardano-cli conway transaction submit --tx-file matx.signed --testnet-magic 1
cardano-cli conway transaction submit --tx-file matx.signed --mainnet
If everything is correct you should a message like this:
Transaction successfully submitted
Congratulations, we have now successfully minted our own token. After a couple of seconds, we can check the output address.
* Preview
* Pre-Production
* Mainnet
cardano-cli query utxo --address $address --testnet-magic 2
cardano-cli query utxo --address $address --testnet-magic 1
cardano-cli query utxo --address $address --mainnet
and should see something like this:
TxHash TxIx Amount--------------------------------------------------------------------------------------e86535386ecd803d061a923c0da1fad82f46b0f2e3fdd766fb23e7f1b490a0e8 0 1518558 lovelace + 1 ad79da159614ff55130b3a28189fbe5c429c0dfc1c0aeaf94a1de95e.4b6964646f7330373138 + TxOutDatumNone
### Displaying your NFT[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#displaying-your-nft "Direct link to Displaying your NFT")
* Preview
* Pre-Production
* Mainnet
One of the most adopted NFT browsers with testnet supported is [pool.pm](https://pool.pm/test/metadata)
.
Copy metadata from `metadata.json` file into the field and your NFT will be displayed with all its attributes and the corresponding image.

One of the most adopted NFT browsers with testnet supported is [pool.pm](https://pool.pm/test/metadata)
.
Copy metadata from `metadata.json` file into the field and your NFT will be displayed with all its attributes and the corresponding image.

One of the most adopted NFT browsers is [pool.pm](https://pool.pm/tokens)
. Enter your address in the search bar, hit enter, and your NFT will be displayed with all its attributes and the corresponding image.

You can check it out yourself and see the NFT created for this tutorial [here](https://pool.pm/6574f051ee0c4cae35c0407b9e104ed8b3c9cab31dfb61308d69f33c.NFT1)
.
Burn your token[](https://developers.cardano.org/docs/native-tokens/minting-nfts/#burn-your-token "Direct link to Burn your token")
-------------------------------------------------------------------------------------------------------------------------------------
If you messed something up and want to re-start, you can always burn your token if the slot defined in your policy script isn't over yet. Assuming you have still every variable set, you need to re-set:
burnfee="0"burnoutput="0"txhash="Insert your utxo holding the NFT"txix="Insert your txix"burnoutput=1400000
Here we are setting the `output` value to `1400000` Lovelace which is equivalent to `1.4` ADA. This amount is used because this is the minimum UTxO requirement.
The transaction looks like this:
* Preview
* Pre-Production
* Mainnet
cardano-cli conway transaction build --testnet-magic 2 --alonzo-era --tx-in $txhash#$txix --tx-out $address+$burnoutput --mint="-1 $policyid.$tokenname" --minting-script-file $script --change-address $address --invalid-hereafter $slot --witness-override 2 --out-file burning.raw
cardano-cli conway transaction build --testnet-magic 1 --alonzo-era --tx-in $txhash#$txix --tx-out $address+$burnoutput --mint="-1 $policyid.$tokenname" --minting-script-file $script --change-address $address --invalid-hereafter $slot --witness-override 2 --out-file burning.raw
cardano-cli conway transaction build --mainnet --alonzo-era --tx-in $txhash#$txix --tx-out $address+$burnoutput --mint="-1 $policyid.$tokenname" --minting-script-file $script --change-address $address --invalid-hereafter $slot --witness-override 2 --out-file burning.raw
note
The minting parameter is now called with a negative value, therefore destroying one token.
Sign the transaction:
* Preview
* Pre-Production
* Mainnet
cardano-cli conway transaction sign --signing-key-file payment.skey --signing-key-file policy/policy.skey --testnet-magic 2 --tx-body-file burning.raw --out-file burning.signed
cardano-cli conway transaction sign --signing-key-file payment.skey --signing-key-file policy/policy.skey --testnet-magic 1 --tx-body-file burning.raw --out-file burning.signed
cardano-cli conway transaction sign --signing-key-file payment.skey --signing-key-file policy/policy.skey --mainnet --tx-body-file burning.raw --out-file burning.signed
Full send:
* Preview
* Pre-Production
* Mainnet
cardano-cli conway transaction submit --tx-file burning.signed --testnet-magic 2
cardano-cli conway transaction submit --tx-file burning.signed --testnet-magic 1
cardano-cli conway transaction submit --tx-file burning.signed --mainnet
* [What's the difference?](https://developers.cardano.org/docs/native-tokens/minting-nfts/#whats-the-difference)
* [The policyID](https://developers.cardano.org/docs/native-tokens/minting-nfts/#the-policyid)
* [Metadata attributes](https://developers.cardano.org/docs/native-tokens/minting-nfts/#metadata-attributes)
* [Time locking](https://developers.cardano.org/docs/native-tokens/minting-nfts/#time-locking)
* [Prerequisites](https://developers.cardano.org/docs/native-tokens/minting-nfts/#prerequisites)
* [Lets get started](https://developers.cardano.org/docs/native-tokens/minting-nfts/#lets-get-started)
* [Working directory](https://developers.cardano.org/docs/native-tokens/minting-nfts/#working-directory)
* [Set variables](https://developers.cardano.org/docs/native-tokens/minting-nfts/#set-variables)
* [Generate keys and address](https://developers.cardano.org/docs/native-tokens/minting-nfts/#generate-keys-and-address)
* [Fund the address](https://developers.cardano.org/docs/native-tokens/minting-nfts/#fund-the-address)
* [Export protocol parameters](https://developers.cardano.org/docs/native-tokens/minting-nfts/#export-protocol-parameters)
* [Creating the policyID](https://developers.cardano.org/docs/native-tokens/minting-nfts/#creating-the-policyid)
* [Metadata](https://developers.cardano.org/docs/native-tokens/minting-nfts/#metadata)
* [Crafting the transaction](https://developers.cardano.org/docs/native-tokens/minting-nfts/#crafting-the-transaction)
* [Submit the transaction](https://developers.cardano.org/docs/native-tokens/minting-nfts/#submit-the-transaction)
* [Displaying your NFT](https://developers.cardano.org/docs/native-tokens/minting-nfts/#displaying-your-nft)
* [Burn your token](https://developers.cardano.org/docs/native-tokens/minting-nfts/#burn-your-token)
---
# Overview of the Blockfrost ecosystem | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/blockfrost/overview/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
Blockfrost is a comprehensive infrastructure toolkit designed to assist developers in building projects on the Cardano platform.
At the heart of the ecosystem lies a user-friendly, swift, feature-rich and fine-tuned [API as a Service](https://blockfrost.io/)
, providing seamless access to the Cardano blockchain and associated networks. The service is public and freely accessible, making it the perfect alternative to running and maintaining your own infrastructure and tools.
In addition to the Cardano networks, it also provides access to IPFS and Milkomeda.
The core technology of Blockfrost is [open-source](https://github.com/blockfrost/blockfrost-backend-ryo)
, and its development is supported by the collaborative efforts of the Cardano community.
Find out more details on how to build with Blockfrost at [Blockfrost Development Hub](https://blockfrost.dev/)
.
---
# Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/smart-contracts/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page

What are smart contracts?[](https://developers.cardano.org/docs/smart-contracts/#what-are-smart-contracts "Direct link to What are smart contracts?")
-------------------------------------------------------------------------------------------------------------------------------------------------------
Smart contracts are digital agreements defined in code that automate and enforce the terms of a contract without the need for intermediaries, enabling secure and transparent transactions on a blockchain. By leveraging predetermined conditions defined within the smart contract code, the state of a contract can only be updated in a way that follows the rules defined in that contract.
On the Cardano blockchain, the compiled code of smart contracts is stored on, and distributed across, the decentralised network. It is not possible to modify the rules of an existing smart contract, nor is it possible to decompile the stored smart contract code from its compiled state into the original source code.
Introduction[](https://developers.cardano.org/docs/smart-contracts/#introduction "Direct link to Introduction")
-----------------------------------------------------------------------------------------------------------------
As mentioned in the [general overview](https://developers.cardano.org/docs/get-started/)
, smart contracts on Cardano work a bit differently from how they do on other blockchains. The key to understanding smart contracts is to first understand the [eUTXO](https://developers.cardano.org/docs/get-started/technical-concepts/#unspent-transaction-output-utxo)
model.
Smart contracts are more or less just a piece of code that you write to validate the movement of UTXOs locked in your contract's address. You will lock UTXOs at the address of your script and then the UTXOs can only ever be spent/moved if your script allows the transaction spending it to do so.
Conceptual overview[](https://developers.cardano.org/docs/smart-contracts/#conceptual-overview "Direct link to Conceptual overview")
--------------------------------------------------------------------------------------------------------------------------------------
Smart contracts consist of on-chain and off-chain components:
* The on-chain component (validator-script) is a script used to validate that each transaction containing any value locked by the script (UTXOs residing on the script's address) conforms to the rules of the contract. Specialised tools and languages are required for creating these scripts.
* The off-chain component is a script or application that is used to generate transactions that conform to the rules of the contract. These can be created in almost any language.
Important to note here is that smart contracts heavily rely on the datum attached to a UTXO, using it as part of the contract instance "state" to be used in further transactions. If no datum is attached to a UTXO residing on the contract's address, it can end up being locked there forever.
### On-Chain (Validator scripts)[](https://developers.cardano.org/docs/smart-contracts/#on-chain-validator-scripts "Direct link to On-Chain (Validator scripts)")
Validator scripts are executed automatically when a UTXO residing at the address of the script is attempted to be moved by a transaction. These scripts take a transaction as its input and then outputs either true or false depending on whether the transaction is valid or not according to your rules/logic as defined in the script - thus blocking or allowing a transaction to succeed. If you are moving multiple UTXOs residing on the same script address, the validator-script will run once for each UTXO. This script execution happens on the Cardano node validating your transaction.
This means that in order for the validator-script to execute, a transaction must first move a UTXO to the address of the contract; the address is derived from the contract mathematically. You do not need to upload your contract to the chain, although that is also possible using reference scripts.
You might think of this initial transaction where you move a UTXO to the script address to be the initialisation of a contract instance. Each UTXO residing on the address of the contract can thus be seen as an instance of the contract. Note that there is no restriction on the UTXOs being sent to the script address: anyone can send a UTXO containing no datum, or a 'fake' datum.
### Off-Chain[](https://developers.cardano.org/docs/smart-contracts/#off-chain "Direct link to Off-Chain")
The off-chain part is needed in order to locate UTXOs that are locked in your contract and generate transactions that are valid for moving them.
For contracts that require multiple steps to complete, it is common to encode the state of a contract inside of a datum using a specific schema of your own design that is then attached to each transaction. You would then create a 'thread' of UTXOs by designing a validator such that it only allows moving the UTXO to the script address so that the value of the UTXO remains locked in the new UTXO, but with a new datum/state.
Technical overview[](https://developers.cardano.org/docs/smart-contracts/#technical-overview "Direct link to Technical overview")
-----------------------------------------------------------------------------------------------------------------------------------
Smart contracts are really very simple constructs based on validator-scripts which you now know are just some logic/rules created by you to be enforced by the Cardano nodes when they see a transaction attempting to move a UTXO locked inside of your script's address.
Because the validator script has access to read the transaction context (things like who signed it and which assets are being sent to/from where) and datum of the locked UTXO being moved, you can build some very complex contracts this way. For example, [Marlowe](https://developers.cardano.org/docs/smart-contracts/marlowe)
is a good example of this technique used in practice.
More specifically, the validator scripts are passed these three pieces of information as arguments:
* Datum: this is a piece of data attached to the output that the script is locking. This is typically used to carry state.
* Redeemer: this is a piece of data attached to the spending input. This is typically used to provide an input to the script from the spender. For example, your validator can use a function to 'apply' the redeemer contents to the datum and verify that it gets the same result as what the output UTXO datum is set to.
* Context: this is a piece of data that represents information about the spending transaction. This is used to make assertions about the way the output is being sent (such as “Bob signed it”).
The information contained in the context and thus available for your script to read:
| Property | Description |
| --- | --- |
| **inputs** | Outputs to be spent. |
| **reference inputs** | Inputs used for reference only, not spent. |
| **outputs** | New outputs created by the transaction. |
| **fees** | Transaction fees. |
| **minted value** | Minted or burned value. |
| **certificates** | Digest of certificates contained in the transaction. |
| **withdrawals** | Used to withdraw rewards from the stake pool. |
| **valid range** | A range of time in which the transaction is valid. |
| **signatories** | A list of transaction signatures. |
| **redeemers** | Data used to provide an input to the script from the spender. |
| **info data** | A map of datum hashes to their datum value. |
| **id** | Transaction identification. |
### Basic contract workflow[](https://developers.cardano.org/docs/smart-contracts/#basic-contract-workflow "Direct link to Basic contract workflow")
note
This is only an example! The validator does not need to rely on hashsums - you can have any logic you want here.
* You create a validator-script that compares the datum in the UTXO being moved from the contract's address to the hash of the redeemer being used in the transaction moving it. This is your on-chain component.
* You create a script, using your language of choice, that creates a transaction moving some amount of ada or other assets to the address of the validator-script. When generating the transaction you specify the datum to be `Hash("secret")` making sure that only the hashsum of the word "secret" gets stored on-chain. This is your off-chain component.
* You sign and submit the transaction to a Cardano node either directly or via one of many available API's such as Blockfrost. Now the ada you sent to the contract is locked by your validator.
* The only way for anyone to move this locked ada now is to generate a transaction with the word 'secret' as a redeemer, as the UTXO is locked in the script which will enforce this rule you created where the hashsum of the redeemer must match `Hash("secret")`. Normally, your datum would be more complicated than this, and the person running the contract might not know how it is supposed to work at all, so they would rely on your off-chain component to create the transaction - often this is something you would provide an API for.
### Multi-step contract workflow[](https://developers.cardano.org/docs/smart-contracts/#multi-step-contract-workflow "Direct link to Multi-step contract workflow")
Expanding on the basic workflow, imagine that you want to create a contract that required multiple steps. Such a contract might be one that requires 3 different people to agree on who should be able to claim the value locked in a contract instance.
* Your on-chain component, the validator script, would have to encode logic for allowing two different types of actions: moving the contract forward (step), or moving the UTXO and hence its value to any other address (unlock).
* Your off-chain component will need to be able to look at the locked UTXO and decode its datum to see which state the contract is currently in, so that it can correctly generate a transaction for either unlocking the UTXO or driving the contract forward.
note
You can also design contracts that never close, but only ever change state, while still allowing funds to be added and withdrawn from the contract.
### Contract instances[](https://developers.cardano.org/docs/smart-contracts/#contract-instances "Direct link to Contract instances")
When you have contracts designed to run in multiple steps, the UTXO that represents the current state of a specific instance/invocation of that script is something you need to be able to keep track of.
There is no standard for how to do this as of now, but one way to accomplish this is to be to create a minting-policy that only allows minting of thread token NFTs to the script's address, and then use the NFTs as thread-tokens by having the validator script enforce such NFTs be moved with each transaction.
### Real-world use[](https://developers.cardano.org/docs/smart-contracts/#real-world-use "Direct link to Real-world use")
One of the best known examples of real-world use for this type of smart contract on the Cardano blockchain is [Marlowe](https://developers.cardano.org/docs/smart-contracts/marlowe)
.
For the datum used in transactions validated by the Marlowe validator-script, a custom domain specific language (DSL) was designed to make it easy for end users to create their own financial contracts. The off-chain component takes care of creating transactions that include the contract DSL in the transaction together with the current state, while the validator makes sure that all state transitions are valid according to the custom Marlowe logic.
The redeemer sent as part of the state transition transactions contain the 'input' to script, i.e. it specifies what is being applied to the old state in order to create the new state: the datum in the output transaction. The script can apply the input to the old datum locally and see if the result matches that of the output UTXO being created in the transaction currently being evaluated.
Facilitating the actual use of Marlowe also required creating multiple API's, chain indexers and frontends for interacting with such contracts. Of course not all contracts are as complex, requiring the same amount of infrastructure around them, but it is worth noting that the off-chain components are just as important as the on-chain parts.
Programming languages[](https://developers.cardano.org/docs/smart-contracts/#programming-languages "Direct link to Programming languages")
--------------------------------------------------------------------------------------------------------------------------------------------
Cardano introduced smart contracts in 2021 and now supports the development and deployment of smart contracts using multiple different languages.
tip
Writing well-designed smart contracts requires you to have a solid understanding of how Cardano works in general. So, make sure that everything on this page makes sense before you start creating contracts. Many topics are described in more detail on the [Technical Concepts](https://developers.cardano.org/docs/get-started/technical-concepts)
page as well.
* [Aiken](https://developers.cardano.org/docs/smart-contracts/aiken)
- for on-chain validator scripts only: a language & toolchain favouring developer experience.
* [Marlowe](https://developers.cardano.org/docs/smart-contracts/marlowe)
- a domain-specific language, it covers the world of financial contracts.
* [opshin](https://developers.cardano.org/docs/smart-contracts/opshin)
- a programming language for generic Smart Contracts based on Python.
* [Plutus](https://developers.cardano.org/docs/smart-contracts/plutus)
- a platform to write full applications that interact with the Cardano blockchain.
* [plu-ts](https://developers.cardano.org/docs/smart-contracts/plu-ts)
- Typescript-embedded smart contract programming language and a transaction creation library.
* [What are smart contracts?](https://developers.cardano.org/docs/smart-contracts/#what-are-smart-contracts)
* [Introduction](https://developers.cardano.org/docs/smart-contracts/#introduction)
* [Conceptual overview](https://developers.cardano.org/docs/smart-contracts/#conceptual-overview)
* [On-Chain (Validator scripts)](https://developers.cardano.org/docs/smart-contracts/#on-chain-validator-scripts)
* [Off-Chain](https://developers.cardano.org/docs/smart-contracts/#off-chain)
* [Technical overview](https://developers.cardano.org/docs/smart-contracts/#technical-overview)
* [Basic contract workflow](https://developers.cardano.org/docs/smart-contracts/#basic-contract-workflow)
* [Multi-step contract workflow](https://developers.cardano.org/docs/smart-contracts/#multi-step-contract-workflow)
* [Contract instances](https://developers.cardano.org/docs/smart-contracts/#contract-instances)
* [Real-world use](https://developers.cardano.org/docs/smart-contracts/#real-world-use)
* [Programming languages](https://developers.cardano.org/docs/smart-contracts/#programming-languages)
---
# Discover Native Tokens | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/native-tokens/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page

note
There are currently two ways to make your NFTs:
* For the less tech-savvy: through someone else. The showcase section (under [NFT Support](https://developers.cardano.org/showcase/?tags=nftsupport)
) has a few services that offer this.
* Tech-savvy users can issue NFTs on a Cardano node. If you want to have full control over your tokens, you need to mint them **yourself**. And this is what this section is all about.
Minting requires a certain amount of skill in navigating and working with Linux through the terminal and a running Cardano node.
We will not go into how to spin up a Cardano node, but this is covered in the [integrate Cardano category](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
.
What are native tokens/assets?[](https://developers.cardano.org/docs/native-tokens/#what-are-native-tokensassets "Direct link to What are native tokens/assets?")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
The Cardano Blockchain has the unique ability to create, interact with, and delete bespoke tokens (or 'assets') natively. In this example, native means that, in addition to sending and receiving the official currency ada, you may interact with custom assets right out of the box - without the use of smart contracts.
Native assets can practically be treated as ada in every sense because the capability is already built-in. Of course, there are some limitations (which we'll discuss later), but you can think of native assets as a way to produce your own custom for the time being.
What you need to know[](https://developers.cardano.org/docs/native-tokens/#what-you-need-to-know "Direct link to What you need to know")
------------------------------------------------------------------------------------------------------------------------------------------
Before we go any further, here's a quick rundown of what you need to know.
### How we interact with the blockchain[](https://developers.cardano.org/docs/native-tokens/#how-we-interact-with-the-blockchain "Direct link to How we interact with the blockchain")
Almost all interactions with the Cardano network/blockchain are transaction-based. We can divide interactions into two tiers with this in mind.

The top layer emphasizes a visual approach and covers standard interaction. Sending and receiving ada or tokens, delegating your stake, and voting are all examples of this. Wallets such as the full node Daedalus wallet or the lighter Yoroi wallet can be used to carry out these interactions.
However, if we want to drill down and have more options for interacting and creating "custom" interactions, we must go one step deeper. We'll need a whole node in this layer to send transactions with specified parameters. A full node is often a built binary from the official latest cardano-node repository. There are more options, but we'll concentrate on the Linux version.
So, what kinds of sophisticated transactions can we create with a full node, and how can we do it? Working on the command line and issuing transactions from there is the current method. Stake pool operators must utilize this method of transaction to register their stake pool or make changes to their commitment, among other things. However, we may utilize this method to produce, send, receive, and burn tokens.
In the future, this probably will also be the place where smart contracts are written, tested, and maybe executed if there isn't a visual frontend.
### Constraints when working with tokens[](https://developers.cardano.org/docs/native-tokens/#constraints-when-working-with-tokens "Direct link to Constraints when working with tokens")
Since we already learned that interaction with the network is almost always a transaction, we need to be aware of a few things enforced through network parameters.
1. A fee must always be paid whether issuing a transaction or sending something. Currently, the cost is determined by the size of the transaction (read: how much "information" gets sent). The size of a transaction can range from a simple "A transmits 2 ada to B" to a considerably more sophisticated transaction with additional metadata.
2. There is a minimum value that must be sent. Currently, the value is set to 1 ada. This means that if we wish to send a token, we must include at least one ada in the transaction. This is to avoid huge amounts of custom tokens from being created and the network being flooded with custom token transactions.
3. We currently (June 2021) have no standard way to define an NFT. There is an [open pull request](https://github.com/cardano-foundation/CIPs/pull/85)
, however. Most of the current NFTs on Cardano mostly follow the proposed structure, as we will in this section.
Please keep those constraints in mind if you want to work with native assets.
Difference between "regular" token and NFTs[](https://developers.cardano.org/docs/native-tokens/#difference-between-regular-token-and-nfts "Direct link to Difference between "regular" token and NFTs")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In terms of technology, there isn't much of a distinction between "regular" tokens/native assets and NFTs. This is due to the fact that both can be produced using the cardano node cli and are native assets.
Unlike fungible native assets, which might consist of millions of interchangeable tokens, an NFT is a single native asset that cannot be re-minted or destroyed, and it exists on the blockchain in perpetuity.
* [What are native tokens/assets?](https://developers.cardano.org/docs/native-tokens/#what-are-native-tokensassets)
* [What you need to know](https://developers.cardano.org/docs/native-tokens/#what-you-need-to-know)
* [How we interact with the blockchain](https://developers.cardano.org/docs/native-tokens/#how-we-interact-with-the-blockchain)
* [Constraints when working with tokens](https://developers.cardano.org/docs/native-tokens/#constraints-when-working-with-tokens)
* [Difference between "regular" token and NFTs](https://developers.cardano.org/docs/native-tokens/#difference-between-regular-token-and-nfts)
---
# Build with transaction metadata | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/transaction-metadata/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page

Introduction[](https://developers.cardano.org/docs/transaction-metadata/#introduction "Direct link to Introduction")
----------------------------------------------------------------------------------------------------------------------
The **Cardano Transaction Metadata** feature allows anyone to embed metadata into transactions, which is then stored in the blockchain. The following are the four most common uses of metadata:
* **Validation and verification**
Metadata can be utilized to check and verify external physical objects and legitimate content, as the Cardano Foundation has demonstrated with Scantrust and Baia's Wine. This necessitates coupling with a physical identifier, such as a QR-code, but it's especially beneficial for low-cost supply chain tracking of fast-moving consumer goods.
* **Authentication and attribution**
There are frequently physical identifiers to confirm the authenticity of credentials received from an educational institution, membership group, or similar. This is more difficult for digital courses and accreditations. For a low fee, a transaction with metadata might serve as an immutable and always-accessible evidence of certification.
* **Secure record of information**
Metadata attached to a transaction and confirmed on the Cardano blockchain is immutable. This means that no one can alter it, and it will last as long as the Cardano blockchain exists. This is a fantastic way to save and back up vital information, or even just to leave a humorous message for the future.
* **Timestamping**
Any transaction that requires payment data to be attached, as well as the history of ownership of particular assets, can benefit from timestamping. Metadata can be used to create a timestamp within a transaction, allowing anyone to verify the time and date of a purchase, sale, or transfer.
Metadata, in essence, can be utilized to tell a transaction's story. Metadata can act as a confirmation or assurance of authenticity when combined with off-chain infrastructure such as physical identifiers.
Metadata Workshop[](https://developers.cardano.org/docs/transaction-metadata/#metadata-workshop "Direct link to Metadata Workshop")
-------------------------------------------------------------------------------------------------------------------------------------
The Cardano Foundation's integrations team hosted a session on transaction metadata on January 18, 2021. Jeremy Firster and Mel McCann from the Cardano Foundation's integrations team delivered the workshop. Jeremy and Mel introduced transaction metadata and discussed its potential for creating Cardano apps with IOHK's Alan McSherry and Ben O'Hanlon. [The slides of the presentation are also available](https://docs.google.com/presentation/d/1KUy83TxpJwIxMHYoQQK6SYynTKrmokxgv_vRa3bpGw4/edit?usp=sharing)
.
Schema[](https://developers.cardano.org/docs/transaction-metadata/#schema "Direct link to Schema")
----------------------------------------------------------------------------------------------------
Metadata can be expressed as a `JSON` object with some restrictions:
All top-level keys must be **integers** between 0 and 2^64 - 1. Each metadata value is tagged with its type. **Strings** must be at most 64 bytes when UTF-8 is encoded. **Bytestrings** are hex-encoded, with a maximum length of 64 bytes. Metadata aren't stored as `JSON` on the Cardano blockchain but are instead stored using a compact binary encoding (**CBOR**).
The binary encoding of metadata values supports three simple types:
* Integers in the range `-(2^64 - 1) to 2^64 - 1`
* Strings (`UTF-8` encoded)
* Bytestrings
* And two compound types:
* Lists of metadata values
* Mappings from metadata values to metadata values
It is possible to transform any JSON object into this schema.
However, according to your requirements, if your application uses floating-point values, they will need to be converted somehow. Likewise, for **null** or **bool** values. Also, when reading metadata from the chain, be aware that **integers** may exceed the programming language of choice numeric range and may need special **bigint** parsing.
**Example metadata**:
{ "0": { "string": "cardano" }, "1": { "int": 14 }, "2": { "bytes": "0x2512a00e9653fe49a44a5886202e24d77eeb998f" }, "3": { "list": [ { "string": "test" } ] }, "4": { "map": [ { "k": { "string": "key" }, "v": { "string": "value" } } ] }}
**This is equivalent to the normalized JSON version**:
{ "0": "cardano", // string "1": 14, // int "2": [53, 23, 53, 64, 23, 06], // bytes "3": ["test"], // list or array "4": { "key": "value" } // Object}
Explore[](https://developers.cardano.org/docs/transaction-metadata/#explore "Direct link to Explore")
-------------------------------------------------------------------------------------------------------
We invite developers to experiment using **Cardano Transaction Metadata** and come up with new ideas. Next, we'll go over the various methods for creating a transaction that includes metadata.
* [Introduction](https://developers.cardano.org/docs/transaction-metadata/#introduction)
* [Metadata Workshop](https://developers.cardano.org/docs/transaction-metadata/#metadata-workshop)
* [Schema](https://developers.cardano.org/docs/transaction-metadata/#schema)
* [Explore](https://developers.cardano.org/docs/transaction-metadata/#explore)
---
# Participate in Governance | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/governance/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page

Cardano has been meticulously designed to ensure sustainability and longevity. A cornerstone of this vision is its self-sufficient governance and funding model, which eliminates the need for external funding. At the heart of Cardano's innovative approach is an on-chain treasury system, consistently funded each epoch by a fixed percentage of the virtual pot, which encompasses all transaction fees collected within that epoch and the ada allocated from the reserve, with the reserve's ada allocation determined by the monetary expansion rate. These mechanisms are pivotal for the platform's ongoing development. They are detailed in discussions with [Bingsheng Zhang](https://www.youtube.com/watch?v=Hyh3h_yX-S0)
, providing valuable insights into the treasury's operations.
Cardano Protocol Governance[](https://developers.cardano.org/docs/governance/#cardano-protocol-governance "Direct link to Cardano Protocol Governance")
---------------------------------------------------------------------------------------------------------------------------------------------------------
Cardano is embarking on a transformative journey towards decentralized governance with the introduction of [CIP-1694](https://cips.cardano.org/cip/CIP-1694)
, marking the onset of the [Voltaire era](https://roadmap.cardano.org/en/voltaire/)
. This proposal establishes a governance framework comprising three roles: the already established group of Stake Pool Operators (SPOs) and two novel roles consisting of a Constitutional Committee (CC) and Delegated Representatives (DReps). Community participation is at the core of this governance model, allowing every ada holder to engage in the decision-making process directly. Through CIP-1694, the governance model evolves to encourage a more inclusive and community-driven approach, reflecting Cardano's commitment to sustainable growth and innovation.
Cardano Improvement Proposals and Cardano Problem Statements[](https://developers.cardano.org/docs/governance/#cardano-improvement-proposals-and-cardano-problem-statements "Direct link to Cardano Improvement Proposals and Cardano Problem Statements")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[Cardano Improvement Proposals (CIPs)](https://cips.cardano.org/)
and [Cardano Problem Statements (CPSs)](https://cips.cardano.org/?type=cps)
are essential to the ecosystem's evolution, facilitating structured innovation and addressing challenges within the network. CIPs serve as a formal process for proposing enhancements or standards for the Cardano protocol, offering a clear pathway for community engagement and technical refinement. Anybody willing to do the work can introduce ideas, which are then collaboratively refined through community input and with the help of the [CIP editors](https://cips.cardano.org/cip/CIP-0001#editors)
, ensuring proposals are robust and beneficial before implementation.
The CPS process, outlined in [CIP-9999](https://cips.cardano.org/cip/CIP-9999)
, complements this by focusing on identifying and articulating specific issues or areas for improvement within Cardano, allowing for a targeted approach to problem-solving. CIPs and CPSs reflect Cardano's dedication to continuous development and community-driven standards, ensuring adaptability and responsiveness to user needs.
tip
For fuller details about the CIP & CPS processes for authorship, review and editing — including history, ethos, and the roles played by different participants — see the **[Cardano Improvement Proposals (CIPs) Wiki](https://github.com/cardano-foundation/CIPs/wiki)
**.
Empowering Innovation with Project Catalyst[](https://developers.cardano.org/docs/governance/#empowering-innovation-with-project-catalyst "Direct link to Empowering Innovation with Project Catalyst")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[Project Catalyst](https://projectcatalyst.io/)
is described as "the world's largest decentralized innovation engine," aimed at solving real-world challenges through community-driven proposals within the Cardano ecosystem. Members of the Cardano community propose, evaluate, and vote on projects across technical, business, creative, and community domains. It emphasizes the power of collective action, inviting participation from anyone, regardless of their background or location. The initiative has supported many proposals and engaged a vast community, highlighting its impact and the extensive opportunities for involvement.
* [Cardano Protocol Governance](https://developers.cardano.org/docs/governance/#cardano-protocol-governance)
* [Cardano Improvement Proposals and Cardano Problem Statements](https://developers.cardano.org/docs/governance/#cardano-improvement-proposals-and-cardano-problem-statements)
* [Empowering Innovation with Project Catalyst](https://developers.cardano.org/docs/governance/#empowering-innovation-with-project-catalyst)
---
# Delegating stake to a stake pool | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/delegate-to-stake-pool/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Delegating stake to a stake pool[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/delegate-to-stake-pool/#delegating-stake-to-a-stake-pool "Direct link to Delegating stake to a stake pool")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Delegating your stake to a stake pool is the simplest method to engage with the protocol. By delegating your stake, you empower the stake pool to generate blocks on your behalf, which, in turn, accrues rewards for you. Rewards are automatically paid by the protocol at the start of every epoch to all pool members who contributed to block production.
note
In Cardano, delegating to a stake pool doesn't necessitate locking your funds or transferring control over them. Delegation remains non-custodial, ensuring you retain full control of your ada throughout the process.
### Create a delegation certificate[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/delegate-to-stake-pool/#create-a-delegation-certificate "Direct link to Create a delegation certificate")
To delegate your stake to a stake pool, you need to create a **stake delegation certificate**. `cardano-cli` offers a simple way to create one, you'll find the corresponding command under `cardano-cli conway stake-address`:
cardano-cli conway stake-addressUsage: cardano-cli conway 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.
To produce a delegation certificate, your stake address must already be registered on the chain, as outlined in the documentation on [registering the stake address](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/stake-address-registration)
. Additionally, you need to know the pool ID to which you will delegate.
cardano-cli conway stake-address stake-delegation-certificate \--stake-verification-key-file stake.vkey \--stake-pool-id pool17navl486tuwjg4t95vwtlqslx9225x5lguwuy6ahc58x5dnm9ma \--out-file delegation.cert
This is how it looks like, the 'cborHex' field encodes your stake address and the target stake pool:
cat delegation.cert{ "type": "CertificateShelley", "description": "Stake Delegation Certificate", "cborHex": "83028200581c521da955ad8f24bdff8d3cb8f5a155c49870037019fcdf20949e7e5e581cf4facfd4fa5f1d245565a31cbf821f3154aa1a9f471dc26bb7c50e6a"}
### Build, sign, and submit the transaction with the certificate[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/delegate-to-stake-pool/#build-sign-and-submit-the-transaction-with-the-certificate "Direct link to Build, sign, and submit the transaction with the certificate")
After generating the delegation certificate, you need to submit it to the chain in a transaction. To familiarize yourself with transactions, refer to the [simple transactions](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions)
documentation. You can use either `build` or `build-raw`; the example below uses `build`.
This type of transaction requires signatures from both `payment.skey` and `stake.skey`, making the transaction slightly larger due to the two signatures. Consequently, it incurs a slightly higher fee. To help the build command accurately calculate transaction fees, you must use the `--witness-override 2` flag:
cardano-cli conway transaction build \--tx-in $(cardano-cli query utxo --address $(< payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \--change-address $(< payment.addr) \--certificate-file delegation.cert \--witness-override 2 \--out-file tx.raw
cardano-cli conway transaction sign \--tx-body-file tx.raw \--signing-key-file payment.skey \--signing-key-file stake.skey \--out-file tx.signed
cardano-cli conway transaction submit \--tx-file tx.signed
For a quick overview of how stake delegation and rewards distribution work at the protocol level, see :
.
* [Delegating stake to a stake pool](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/delegate-to-stake-pool/#delegating-stake-to-a-stake-pool)
* [Create a delegation certificate](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/delegate-to-stake-pool/#create-a-delegation-certificate)
* [Build, sign, and submit the transaction with the certificate](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/delegate-to-stake-pool/#build-sign-and-submit-the-transaction-with-the-certificate)
---
# Governance related queries. | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
There are various queries you can do to your local node to find relevant information about different aspects of thenpm governance state.
### Query proposals[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-proposals "Direct link to Query proposals")
#### Query all proposals[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-all-proposals "Direct link to Query all proposals")
This query returns all the proposals that can be ratified in the current epoch. This means that it excludes proposals that were submitted on the current epoch, as these cannot be ratified on the current epoch.
cardano-cli conway query proposals --all-proposals
#### Query proposal by ID[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-proposal-by-id "Direct link to Query proposal by ID")
To query an individual proposal by its governance action id:
cardano-cli conway query proposals \--governance-action-tx-id d098afe0db98605c243c13c8a537a3eb51e6ded5e3a48acca83e7082a0086428 \ --governance-action-index 0 [ { "actionId": { "govActionIx": 0, "txId": "d098afe0db98605c243c13c8a537a3eb51e6ded5e3a48acca83e7082a0086428" }, "committeeVotes": {}, "dRepVotes": { "keyHash-68a5f1348300ada6dcec67f9421bdac62ba621006408ece8c8e551d6": "VoteNo" }, "expiresAfter": 842, "proposalProcedure": { "anchor": { "dataHash": "42af10d2f864ace50d41ff7c9c93aa51c6ab0ca57d956653fb67353d97b57400", "url": "https://bafybeigzrnrb3njfuomjsma7zdrcjoz3a4ku2kqafeqerbuquytdl6nxjy.ipfs.dweb.link/?filename=data%20(5).jsonld" }, "deposit": 100000000000, "govAction": { "tag": "InfoAction" }, "returnAddr": { "credential": { "keyHash": "79bb181ab55772b961a883a2a24e73a5416e163375817c898993f120" }, "network": "Testnet" } }, "proposedIn": 812, "stakePoolVotes": {} }]
### Query the gov-state[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-gov-state "Direct link to Query the gov-state")
We are showing only the top level keys of the governance state, the dump is to large to show on this tutorial.
cardano-cli conway query gov-state{ "committee": {}, "constitution": {}, "currentPParams": {}, "futurePParams": {}, "nextRatifyState": { "enactedGovActions": [], "expiredGovActions": [], "nextEnactState": {}, "ratificationDelayed": false }, "previousPParams": {}, "proposals": []}
### Query the constitution:[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-constitution "Direct link to Query the constitution:")
cardano-cli conway query constitution{ "anchor": { "dataHash": "ca41a91f399259bcefe57f9858e91f6d00e1a38d6d9c63d4052914ea7bd70cb2", "url": "ipfs://bafkreifnwj6zpu3ixa4siz2lndqybyc5wnnt3jkwyutci4e2tmbnj3xrdm" }, "script": "fa24fb305126805cf2164c161d852a0e7330cf988f1fe558cf7d4a64"}
### Query the DRep state for all DReps:[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-drep-state-for-all-dreps "Direct link to Query the DRep state for all DReps:")
cardano-cli conway query drep-state --all-dreps[ [ { "scriptHash": "186e32faa80a26810392fda6d559c7ed4721a65ce1c9d4ef3e1c87b4" }, { "anchor": null, "deposit": 500000000, "expiry": 666 } ], [ { "keyHash": "68a5f1348300ada6dcec67f9421bdac62ba621006408ece8c8e551d6" }, { "anchor": null, "deposit": 500000000, "expiry": 667 } ], [ { "keyHash": "739701e411d342e6a385dcbec1f78edc31434ad1ad166d20954912d7" }, { "anchor": null, "deposit": 500000000, "expiry": 666 } ], [ { "keyHash": "8f4fefcf28017a57b41517a67d56ef4c0dc04181a11d35178dd53f4c" }, { "anchor": null, "deposit": 500000000, "expiry": 667 } ]]
### Query the DRep state for an individual DRep:[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-drep-state-for-an-individual-drep "Direct link to Query the DRep state for an individual DRep:")
cardano-cli conway query drep-state --drep-key-hash 8f4fefcf28017a57b41517a67d56ef4c0dc04181a11d35178dd53f4c[ [ { "keyHash": "8f4fefcf28017a57b41517a67d56ef4c0dc04181a11d35178dd53f4c" }, { "anchor": null, "deposit": 500000000, "expiry": 667 } ]]
### Query the DRep stake distribution (voting power):[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-drep-stake-distribution-voting-power "Direct link to Query the DRep stake distribution (voting power):")
cardano-cli conway query drep-stake-distribution --all-dreps[ [ "drep-keyHash-13797df5308dfebf2348fa58b312a177cf97939f5f7d21168e1a54db", 500000000000 ], [ "drep-keyHash-9853551d8b99884f51608822e012bbf0d444eb7bea2807ee664f1241", 495790521257 ], [ "drep-keyHash-cf09b59e134fa14e48da39b552c02299a054d7c8b895b3d827453672", 500000000000 ]]
### Query the committee state:[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-committee-state "Direct link to Query the committee state:")
cardano-cli conway query committee-state{ "committee": { "scriptHash-27999ed757d6dac217471ae61d69b1b067b8b240d9e3ff36eb66b5d0": { "expiration": 500, "hotCredsAuthStatus": { "contents": { "scriptHash": "49fa008218cd619afe6aa8a1a93303f242440722b314f36bda2c2e23" }, "tag": "MemberAuthorized" }, "nextEpochChange": { "tag": "NoChangeExpected" }, "status": "Active" }, "scriptHash-6095e643ea6f1cccb6e463ec34349026b3a48621aac5d512655ab1bf": { "expiration": 500, "hotCredsAuthStatus": { "contents": { "scriptHash": "65d497b875c56ab213586a4006d4f6658970573ea8e2398893857472" }, "tag": "MemberAuthorized" }, "nextEpochChange": { "tag": "NoChangeExpected" }, "status": "Active" }, "scriptHash-7ceede7d6a89e006408e6b7c6acb3dd094b3f6817e43b4a36d01535b": { "expiration": 500, "hotCredsAuthStatus": { "contents": { "scriptHash": "f8f56120e1ec00feb088ece39ef14f07339afeb37b4e949ff12b89ff" }, "tag": "MemberAuthorized" }, "nextEpochChange": { "tag": "NoChangeExpected" }, "status": "Active" }, "scriptHash-87f867a31c0f81360d4d7dcddb6b025ba8383db9bf77a2af7797799d": { "expiration": 500, "hotCredsAuthStatus": { "tag": "MemberNotAuthorized" }, "nextEpochChange": { "tag": "NoChangeExpected" }, "status": "Active" }, "scriptHash-a19a7ba1caede8f3ab3e5e2a928b3798d7d011af18fbd577f7aeb0ec": { "expiration": 500, "hotCredsAuthStatus": { "tag": "MemberNotAuthorized" }, "nextEpochChange": { "tag": "NoChangeExpected" }, "status": "Active" } }, "epoch": 413, "threshold": 0.67}
### Query the state of an individual committee key hash:[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-state-of-an-individual-committee-key-hash "Direct link to Query the state of an individual committee key hash:")
cardano-cli conway query committee-state --cold-script-hash 7ceede7d6a89e006408e6b7c6acb3dd094b3f6817e43b4a36d01535b{ "committee": { "scriptHash-7ceede7d6a89e006408e6b7c6acb3dd094b3f6817e43b4a36d01535b": { "expiration": 500, "hotCredsAuthStatus": { "contents": { "scriptHash": "f8f56120e1ec00feb088ece39ef14f07339afeb37b4e949ff12b89ff" }, "tag": "MemberAuthorized" }, "nextEpochChange": { "tag": "NoChangeExpected" }, "status": "Active" } }, "epoch": 413, "threshold": 0.67}
### Query expired committee members[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-expired-committee-members "Direct link to Query expired committee members")
cardano-cli conway query committee-state --expired{ "committee": { "keyHash-059349cd1e77dc3e500d3ffc498adb7307001ecc022c8b083faaa48b": { "expiration": 161, "hotCredsAuthStatus": { "contents": { "keyHash": "23e05ad2b71317a6348ce4b68dae37aa1c0e545cdea740b23c21742e" }, "tag": "MemberAuthorized" }, "nextEpochChange": "NoChangeExpected", "status": "Expired" } }, "epoch": 169, "quorum": 0.6}
### Query active committee members[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-active-committee-members "Direct link to Query active committee members")
cardano-cli conway query committee-state --active { "committee": { "keyHash-059349cd1e77dc3e500d3ffc498adb7307001ecc022c8b083faaa48b": { "expiration": 161, "hotCredsAuthStatus": { "contents": { "keyHash": "23e05ad2b71317a6348ce4b68dae37aa1c0e545cdea740b23c21742e" }, "tag": "MemberAuthorized" }, "nextEpochChange": "NoChangeExpected", "status": "Active" }, "keyHash-337e0a7fd01c7a7c27e8bac17e40db182bc2a774467795af1e3fe8a9": { "expiration": 201, "hotCredsAuthStatus": { "contents": { "keyHash": "540bedcd4bdcbf523e899c3ef43f2b96ecec4f6303af58d15a413ed1" }, "tag": "MemberAuthorized" }, "nextEpochChange": "NoChangeExpected", "status": "Active" }, "keyHash-9c2aabae5d9187a76ed6b04b40e91ecb4ce3171611c3fd4ec6c6a607": { "expiration": 181, "hotCredsAuthStatus": { "contents": { "keyHash": "6c1d098a366f2274651943a7f778b3b5459c129f0407a0db2902253a" }, "tag": "MemberAuthorized" }, "nextEpochChange": "NoChangeExpected", "status": "Active" } }, "epoch": 105, "quorum": 0.6}
### Query unrecognized committee keys[](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-unrecognized-committee-keys "Direct link to Query unrecognized committee keys")
cardano-cli conway query committee-state --unrecognized{ "committee": {}, "epoch": 106, "quorum": 0.6}
* [Query proposals](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-proposals)
* [Query the gov-state](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-gov-state)
* [Query the constitution:](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-constitution)
* [Query the DRep state for all DReps:](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-drep-state-for-all-dreps)
* [Query the DRep state for an individual DRep:](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-drep-state-for-an-individual-drep)
* [Query the DRep stake distribution (voting power):](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-drep-stake-distribution-voting-power)
* [Query the committee state:](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-committee-state)
* [Query the state of an individual committee key hash:](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-the-state-of-an-individual-committee-key-hash)
* [Query expired committee members](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-expired-committee-members)
* [Query active committee members](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-active-committee-members)
* [Query unrecognized committee keys](https://developers.cardano.org/docs/get-started/cardano-cli/governance/gov-queries/#query-unrecognized-committee-keys)
---
# Runtime system options for Cardano Node | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-node/rts-options-node/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
The Haskell runtime system (RTS) is a software layer that provides a set of services that enable Haskell programs to execute. At a high level, the Haskell runtime system provides the following services:
1. Memory management: the Haskell runtime system manages the allocation and deallocation of memory used by the program. This includes allocating memory for data structures, managing the stack and heap, and freeing memory that is no longer in use.
2. Garbage collection: the Haskell runtime system automatically collects and frees memory that is no longer being used by the program. This ensures that memory is used efficiently and helps to prevent memory leaks.
3. Concurrency and parallelism: the Haskell runtime system provides support for concurrency and parallelism through features like lightweight threads, software transactional memory, and parallel arrays. This enables Haskell programs to take advantage of modern multicore processors and to execute computations in parallel.
4. Exception handling: the Haskell runtime system provides a mechanism for handling exceptions that occur during program execution. This includes both synchronous exceptions, which occur as a result of a program error, and asynchronous exceptions, which occur as a result of external events such as signals.
tip
[RTS Official documentation](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#runtime-system-rts-options)
IOG-released binaries are built with the following RTS options `-T -I0 -A16m -N2 --disable-delayed-os-memory-return` . This means that the node uses these options at runtime by default. You can check it with:
cardano-node +RTS --info
[("GHC RTS", "YES") ,("GHC version", "8.10.7") ,("RTS way", "rts_thr") ,("Build platform", "x86_64-unknown-linux") ,("Build architecture", "x86_64") ,("Build OS", "linux") ,("Build vendor", "unknown") ,("Host platform", "x86_64-unknown-linux") ,("Host architecture", "x86_64") ,("Host OS", "linux") ,("Host vendor", "unknown") ,("Target platform", "x86_64-unknown-linux") ,("Target architecture", "x86_64") ,("Target OS", "linux") ,("Target vendor", "unknown") ,("Word size", "64") ,("Compiler unregisterised", "NO") ,("Tables next to code", "YES") ,("Flag -with-rtsopts", "-T -I0 -A16m -N2 --disable-delayed-os-memory-return") ]
Customized RTS options[](https://developers.cardano.org/docs/get-started/cardano-node/rts-options-node/#customized-rts-options "Direct link to Customized RTS options")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Users have the option to select different configurations by adjusting the `-with-rtsopts` in the node's [Cabal file](https://github.com/IntersectMBO/cardano-node/blob/master/cardano-node/cardano-node.cabal)
and then building the node with the updated settings:
ghc-options: "-with-rtsopts=-T -I0 -A16m -N2 --disable-delayed-os-memory-return"
Users can also extend and override options in `-with-rtsopts` by running `cardano-node` with command-line RTS options. For example, this extends the compilation options with `+RTS -B`, to sounds the bell at the start of each garbage collection.
cardano-node run +RTS -B -RTS --topology topology.json \--database-path db \--socket-path node.socket \--port 3001 \--config config/config.json
Together with the options set in the .cabal file, the above example uses:
* [**\-T**](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#rts-flag--T)
: produces runtime-system statistics, such as the amount of time spent executing the program and in the garbage collector, the amount of memory allocated, the maximum size of the heap, and so on. The three variants provide different levels of detail: `-T` collects the data but produces no output. Access the statistics using [GHC.Stats](https://hoogle.haskell.org/?hoogle=GHC.Stats)
.
* [**\-N2**](https://downloads.haskell.org/ghc/latest/docs/users_guide/using-concurrent.html#rts-options-for-smp-parallelism)
: specifies the number of threads to use for parallel execution. The `-N2` flag indicates that the Haskell runtime system should use two parallel threads.
* [**\-A16m**](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#rts-flag--A%20%E2%9F%A8size%E2%9F%A9)
: sets the maximum heap size for the generational garbage collector to 16 megabytes.
* [**\-I0**](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#rts-flag--I%20%E2%9F%A8seconds%E2%9F%A9)
: specifies the amount of idle time that must pass before an idle GC is performed. Setting `-I0` disables the idle GC.
* [**\--disable-delayed-os-memory-return**](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#rts-flag---disable-delayed-os-memory-return)
: this option is used for accurate resident memory usage of the program, as shown in memory usage reporting tools (eg, the RSS column in top and htop). It makes it easier to verify the real memory usage.
* [**\-B**](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#rts-options-for-hackers-debuggers-and-over-interested-souls)
: sound the bell at the start of each garbage collection. Curious about why you would use this flag? Read [RTS options for hackers, debuggers, and over-interested souls](https://downloads.haskell.org/ghc/latest/docs/users_guide/runtime_control.html#rts-options-for-hackers-debuggers-and-over-interested-souls)
Discover the available options for cardano-node with:
cardano-node +RTS -?
cardano-node:cardano-node: Usage: [+RTS | -RTS ] ... --RTS cardano-node:cardano-node: +RTS Indicates run time system options followcardano-node: -RTS Indicates program arguments to followcardano-node: --RTS Indicates that ALL subsequent arguments will be given to thecardano-node: program (including any of these RTS flags)cardano-node:cardano-node: The following run time system options are available:cardano-node:cardano-node: -? Prints this message and exits; the program is not executedcardano-node: --info Print information about the RTS used by this programcardano-node:cardano-node: --nonmoving-gccardano-node: Selects the non-moving mark-and-sweep garbage collector tocardano-node: manage the oldest generation.cardano-node: --copying-gccardano-node: Selects the copying garbage collector to manage all generations.cardano-node:cardano-node: -K Sets the maximum stack size (default: 80% of the heap)cardano-node: Egs: -K32k -K512k -K8Mcardano-node: -ki Sets the initial thread stack size (default 1k) Egs: -ki4k -ki2mcardano-node: -kc Sets the stack chunk size (default 32k)cardano-node: -kb Sets the stack chunk buffer size (default 1k)cardano-node:cardano-node: -A Sets the minimum allocation area size (default 1m) Egs: -A20m -A10kcardano-node: -AL Sets the amount of large-object memory that can be allocatedcardano-node: before a GC is triggered (default: the value of -A)cardano-node: -F Sets the collecting threshold for old generations as a factor ofcardano-node: the live data in that generation the last time it was collectedcardano-node: (default: 2.0)cardano-node: -n Allocation area chunk size (0 = disabled, default: 0)cardano-node: -O Sets the minimum size of the old generation (default 1M)cardano-node: -M Sets the maximum heap size (default unlimited) Egs: -M256k -M1Gcardano-node: -H Sets the minimum heap size (default 0M) Egs: -H24m -H1Gcardano-node: -xb Sets the address from which a suitable start for the heap memorycardano-node: will be searched from. This is useful if the default addresscardano-node: clashes with some third-party library.cardano-node: -xn Use the non-moving collector for the old generation.cardano-node: -m Minimum % of heap which must be available (default 3%)cardano-node: -G Number of generations (default: 2)cardano-node: -c Use in-place compaction instead of copying in the oldest generationcardano-node: when live data is at least % of the maximum heap size set withcardano-node: -M (default: 30%)cardano-node: -c Use in-place compaction for all oldest generation collectionscardano-node: (the default is to use copying)cardano-node: -w Use mark-region for the oldest generation (experimental)cardano-node: -I Perform full GC after idle time (default: 0.3, 0 == off)cardano-node:cardano-node: -T Collect GC statistics (useful for in-program statistics access)cardano-node: -t[] One-line GC statistics (if omitted, uses stderr)cardano-node: -s[] Summary GC statistics (if omitted, uses stderr)cardano-node: -S[] Detailed GC statistics (if omitted, uses stderr)cardano-node:cardano-node:cardano-node: -Z Don't squeeze out update frames on stack overflowcardano-node: -B Sound the bell at the start of each garbage collectioncardano-node: -h Heap residency profile (output file .hp)cardano-node: -hT Produce a heap profile grouped by closure typecardano-node: -i Time between heap profile samples (seconds, default: 0.1)cardano-node:cardano-node: -C Context-switch interval in seconds.cardano-node: 0 or no argument means switch as often as possible.cardano-node: Default: 0.02 sec.cardano-node: -V Master tick interval in seconds (0 == disable timer).cardano-node: This sets the resolution for -C and the heap profile timer -i,cardano-node: and is the frequency of time profile samples.cardano-node: Default: 0.01 sec.cardano-node:cardano-node: -N[] Use processors (default: 1, -N alone determinescardano-node: the number of processors to use automatically)cardano-node: -maxN[] Use up to processors automaticallycardano-node: -qg[] Use parallel GC only for generations >= cardano-node: (default: 0, -qg alone turns off parallel GC)cardano-node: -qb[] Use load-balancing in the parallel GC only for generations >= cardano-node: (default: 1 for -A < 32M, 0 otherwise;cardano-node: -qb alone turns off load-balancing)cardano-node: -qn Use threads for parallel GC (defaults to value of -N)cardano-node: -qa Use the OS to set thread affinity (experimental)cardano-node: -qm Don't automatically migrate threads between CPUscardano-node: -qi If a processor has been idle for the last GCs, do notcardano-node: wake it up for a non-load-balancing parallel GC.cardano-node: (0 disables, default: 0)cardano-node: --numa[=]cardano-node: Use NUMA, nodes given by (default: off)cardano-node: --install-signal-handlers=cardano-node: Install signal handlers (default: yes)cardano-node: -e Maximum number of outstanding local sparks (default: 4096)cardano-node: -xp Assume that all object files were compiled with -fPICcardano-node: -fexternal-dynamic-refs and load them anywhere in the addresscardano-node: spacecardano-node: -xm Base address to mmap memory in the GHCi linkercardano-node: (hex; must be <80000000)cardano-node: -xq The allocation limit given to a thread after it receivescardano-node: an AllocationLimitExceeded exception. (default: 100k)cardano-node:cardano-node: -Mgrace=cardano-node: The amount of allocation after the program receives acardano-node: HeapOverflow exception before the exception is thrown again, ifcardano-node: the program is still exceeding the heap limit.cardano-node:cardano-node: RTS options may also be specified using the GHCRTS environment variable.cardano-node:cardano-node: Other RTS options may be available for programs compiled a different way.cardano-node: The GHC User's Guide has full details.
* [Customized RTS options](https://developers.cardano.org/docs/get-started/cardano-node/rts-options-node/#customized-rts-options)
---
# Exploring Cardano wallets | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
### Overview[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#overview "Direct link to Overview")
In this guide, we will show you how to create a **Cardano** wallet, receive some `tAda` (**test ada**) on a [testnet network](https://developers.cardano.org/docs/get-started/testnets-and-devnets)
and send basic example transactions. We will explore tools like `cardano-cli` and `cardano-wallet` on how they can help with these functionalities.
note
This guide assumes you have installed `cardano-node` and `cardano-cli` into your system. If not you can refer to [Installing cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
guide for instructions on how to do that.
You must also connect your `cardano-node` to a testnet network and make sure it is fully synchronized.
If you are not sure how to do that, It is recommended to read [Running cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano)
guide before proceeding.
### Cardano Wallets[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#cardano-wallets "Direct link to Cardano Wallets")
So you installed your `cardano-node` and got it running, you probably even tried to query some simple blockchain data (If you read [Running cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano)
guide). But how do you actually create a **Cardano** wallet, receive and send some `ada` or `tAda` tokens?
First we have to look at the applications we can use to create wallets.
* [Daedalus](https://daedaluswallet.io/)
: **Daedalus Wallet** is an example of a **Cardano** full-node wallet, which is a [GUI (Graphical User Interface)](https://en.wikipedia.org/wiki/Graphical_user_interface)
application for the Desktop (**Linux**, **MacOS**, **Windows**). That means that users will get to use a nice UI (User Interface), buttons and layout to interact with the **Cardano** blockchain.
A full-node wallet basically means that it has to synchronize and download the blockchain first before users are able to send transactions and interact with the wallet.
It is open-source mainly being developed by [InputOutputGlobal](https://iohk.io/)
, the development company behind the **Cardano** protocol and also one of the three foundational entities of the **Cardano** project.
* [Yoroi](https://yoroi-wallet.com/#/)
: **Yoroi Wallet** is an example of a **Cardano** light-wallet, It is available as a **mobile application** and as a **browser extension**.
A light-wallet means that users will not be forced to download the entire blockchain, Instead **Yoroi** has a backend server and downloads the blockchain data for the user without the user exposing sensitive data(**Private Keys**) to the server and ultimately maintaining security. This achieves a faster experience for the user due to the fact the user will not have to wait for hours before being able to use the wallet.
It is open-source mainly being developed by [Emurgo](https://emurgo.io/)
, A company based in [Japan](https://en.wikipedia.org/wiki/Japan)
which focuses on Business and Enterprise adoption of the **Cardano** blockchain. It is also one of the three foundational entities of the **Cardano** project.
* [cardano-wallet](https://github.com/cardano-foundation/cardano-wallet)
: `cardano-wallet` is a [CLI (Command Line Interface)](https://en.wikipedia.org/wiki/Command-line_interface)
application that provides **Cardano** wallet functionalities both via command-line parameters or via a [Web API](https://en.wikipedia.org/wiki/Web_API)
.
It is the wallet-backend that **Daedalus** wallet uses under-the-hood so it is also open-source, one of the many Haskell-based **Cardano** software components being written by [InputOutputGlobal](https://iohk.io/)
.
You can find `cardano-wallet` **REST API** documentation here: [https://cardano-foundation.github.io/cardano-wallet/api/edge/](https://cardano-foundation.github.io/cardano-wallet/api/edge/)
* [cardano-cli](https://github.com/IntersectMBO/cardano-node)
: `cardano-cli` is also a [CLI (Command Line Interface)](https://en.wikipedia.org/wiki/Command-line_interface)
application that provides **Cardano** wallet functionalities. But `cardano-cli` purpose is geared more towards general **Cardano** functionalities like generating **keys**, building and submitting **transactions**, managing **stake pools** certificates, simple blockchain queries like wallet address **UTXO** and more.
It is part of the `cardano-node` project repository, so if you [compile and install](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
`cardano-node` you should also have `cardano-cli` as-well. It is one of the many Haskell-based **Cardano** software components being written by [InputOutputGlobal](https://iohk.io/)
.
warning
Always download the wallets from trusted sources. There are many fake wallets, malicious software pretending to be **Cardano** wallets that could potentially steal your tokens / assets.
### Creating a wallet[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#creating-a-wallet "Direct link to Creating a wallet")
As mentioned before, in this guide we will only be focusing on the `cardano-cli` and `cardano-wallet` since they provide some level of programmability which is important when we are talking about **Cardano** integrations for different kinds of use cases.
#### Creating a wallet with `cardano-cli`[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#creating-a-wallet-with-cardano-cli "Direct link to creating-a-wallet-with-cardano-cli")
note
In this section, We will use the path `$HOME/cardano` to store all the `cardano-cli` related files as an example, please replace it with the directory you have chosen to store the files.
important
Please make sure your `cardano-node` is connected and synchronized to a testnet network before proceeding.
warning
In a production environment, it might not be a good idea to store wallets / keys in a public server unless you know what you are doing.
First, lets create a directory to store all our `keys` like so:
mkdir -p $HOME/cardano/keys
Make sure we are inside the `keys` directory like so: `cd $HOME/cardano/keys`
Next, we generate our **payment key-pair** using `cardano-cli`:
cardano-cli address key-gen \--verification-key-file $HOME/cardano/keys/payment1.vkey \--signing-key-file $HOME/cardano/keys/payment1.skey
`cardano-cli address key-gen` : generates a **payment key-pair**.
`--verification-key-file` : points to the path where you want to save the `vkey` file.
`--signing-key-file` : points to the path where you want to save the `skey` file.
You should now have two files in your `keys` directory like so:
$HOME/cardano/keys/├── payment1.skey└── payment1.vkey0 directories, 2 files
Lets try to understand what these keys are used for in a very high-level overview that is relevant to our topic:
* `.vkey` / **Public Verification Key** : Is used to derive a **Cardano** wallet address, a wallet address is basically the hash string value that you share to other users to provide them a way to send `ada` / `tAda` or other assets in the **Cardano** blockchain into your wallet.
**The verification key file should look something like this**:
{ "type": "PaymentVerificationKeyShelley_ed25519", "description": "Payment Verification Key", "cborHex": "582056a29cba161c2a534adae32c4359fda6f90a3f6ae6990491237b28c1caeef0c4"}
* `.skey` / **Private Signing Key** : Is used to sign / approve transactions for your wallet. As you can imagine, it is very important to not expose this file to the public and must be kept secure.
**The signing key file should look something like this**:
{ "type": "PaymentSigningKeyShelley_ed25519", "description": "Payment Signing Key", "cborHex": "58208c61d557e1b8ddd82107fa506fab1b1565ec76fe96e8fb19a922d5460acd5a5b"}
Since we now have our **payment key-pair**, the next step would be to generate a **wallet address** for a testnet network like so:
cardano-cli address build \--payment-verification-key-file $HOME/cardano/keys/payment1.vkey \--out-file $HOME/cardano/keys/payment1.addr \--testnet-magic 1097911063
* `cardano-cli address build` : Generates a **wallet address** from a `vkey` file.
* `--payment-verification-key-file` : The path to the `vkey` file to be used for the derivation.
* `--out-file` : The path to save the wallet address file.
* `--testnet-magic` : The **NetworkMagic** of the network that where you want to use the wallet address.
You should now have `payment1.vkey`, `payment1.skey` and `payment1.addr` in your `keys` directory. It should look something like this:
$HOME/cardano/keys/├── payment1.addr├── payment1.skey└── payment1.vkey0 directories, 3 files
The `payment1.addr` file contains the derived **wallet address** from your `vkey` file. It should look something like this:
addr_test1vz95zjvtwm9u9mc83uzsfj55tzwf99fgeyt3gmwm9gdw2xgwrvsa5
note
You can derive more than one **wallet address** from a **Public Verification Key** for more advanced use cases using `cardano-addresses` component. Which we discuss in more details here: _**@TODO: link to article**_
* Mainnet addresses are **prefixed** with the string value `addr1`.
* testnet addresses are **prefixed** with the string value `addr_test1`.
If you want to create a wallet address to be used on `mainnet`, please use the `--mainnet` flag instead of `--testnet-magic 1097911063`. You can learn more about the different **Cardano** blockchain networks [here](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano#mainnet--production)
.
#### Querying the wallet **UTXO (Unspent Transaction Output)** with `cardano-cli`[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#querying-the-wallet-utxo-unspent-transaction-output-with-cardano-cli "Direct link to querying-the-wallet-utxo-unspent-transaction-output-with-cardano-cli")
Now that we have a **wallet address**, we can then query the **UTXO** of the address like so:
cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat $HOME/cardano/keys/payment1.addr)
* `cardano-cli query utxo` : Queries the wallet address **UTXO**.
* `--testnet-magic 1097911063` : Specifies that we want to query a testnet **Cardano** network.
* `--address $(cat $HOME/cardano/keys/payment1.addr)` : The **wallet address** string value that we want to query, In this case we read the contents of `$HOME/cardano/keys/payment1.addr` using the `cat` command and we pass that value to the `--address` flag. That means you could also directly paste the **wallet address** value like so:
--address addr_test1vz95zjvtwm9u9mc83uzsfj55tzwf99fgeyt3gmwm9gdw2xgwrvsa5
You should see something like this:
TxHash TxIx Amount--------------------------------------------------------------------------------------
Now you might find it odd that there is not much information in the result that was returned the command, but that is totally normal as there are no available **UTXO** in the specific **wallet address** that we have queried just yet as it is a new wallet.
Our next step is to request some `tAda` from the [Cardano Testnet Faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet)
.
Once you requested some `tAda` from the [Cardano Testnet Faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet)
we can then run the query again and you should see something like this:
TxHash TxIx Amount--------------------------------------------------------------------------------------cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 0 1000000000 lovelace
This result tells us that there is one **UTXO** with the amount of 1,000,000,000 `lovelaces` in our specific **wallet address**, that means our wallet has a balance of `1,000 tAda`.
The result also specifies that the **UTXO** **transaction id** (`TxHash` / `TxId`) is `cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85` with the **transaction index** of `0`.
note
In the **Cardano** blockchain, the `lovelace` is the unit used to represent `ada` in **transactions** and **UTXO**.
Where `1 ada` is equal to `1,000,000 lovelace`, so moving forward we will be using `lovelace` instead of `ada` / `tAda`.
You can also use the `TxHash` to view the complete transaction via the **Cardano Blockchain Explorer** for the relevant network. You can check the specific transaction for the example **UTXO** here:
* [testnet.cardanoscan.io](https://testnet.cardanoscan.io/)
is a Pre-Production and Preview block explorer by [Cardanoscan](https://cardanoscan.io/)
.
* [testnet.cexplorer.io](https://testnet.cexplorer.io/)
is a Pre-Production and Preview block explorer by [Cexplorer](https://cexplorer.io/)
.
To learn more about **UTXO (unspent transaction output)** and how transactions work for the **UTXO Model**, we recommend watching this lecture by [Dr. Lars Brünjes](https://iohk.io/en/team/lars-brunjes)
, Education Director at [InputOutputGlobal](https://iohk.io/)
.
#### Creating simple transactions[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#creating-simple-transactions "Direct link to Creating simple transactions")
To have a clearer understanding of how sending transactions work using `cardano-cli`, first lets create another wallet like so:
**Generate payment key-pair**
cardano-cli address key-gen \--verification-key-file $HOME/cardano/keys/payment2.vkey \--signing-key-file $HOME/cardano/keys/payment2.skey
**Generate wallet address**
cardano-cli address build \--payment-verification-key-file $HOME/cardano/keys/payment2.vkey \--out-file $HOME/cardano/keys/payment2.addr \--testnet-magic 1097911063
Once complete you should have the following directory structure:
$HOME/cardano/keys├── payment1.addr├── payment1.skey├── payment1.vkey├── payment2.addr├── payment2.skey└── payment2.vkey0 directories, 6 files
Querying the **UTXO** for the second wallet `payment2.addr` should give you a familiar result:
cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat $HOME/cardano/keys/payment2.addr)
**UTXO Result**
TxHash TxIx Amount--------------------------------------------------------------------------------------
Again, this is to be expected as the `payment2.addr` wallet address and keys has just recently been generated. So we expect that no one has sent any `tAda` to this wallet yet.
In this example, we now have two wallets. We can call them `payment1` and `payment2`. Now remember that we requested some `tAda` from the [Cardano Testnet Faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet)
for `payment1` wallet, and thats how we have the following:
`payment1` **wallet**: `1,000,000,000 lovelace`
UTXO TxHash TxIx Amount--------------------------------------------------------------------------------------cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 0 1000000000 lovelace
`payment2` **wallet**: `0 lovelace`
UTXO TxHash TxIx Amount--------------------------------------------------------------------------------------
Now let's say we want to send `250,000,000 lovelace` to `payment2` **wallet**, how can we achieve that?
We start by storing the current on-chain protocol parameters to a **JSON** file:
**Query Protocol Parameters**
cardano-cli query protocol-parameters \ --testnet-magic 1097911063 \ --out-file $HOME/cardano/protocol.json
This will produce a **JSON** file that looks something like this:
{ "poolDeposit": 500000000, "protocolVersion": { "minor": 0, "major": 4 }, "minUTxOValue": 1000000, "decentralisationParam": 0, "maxTxSize": 16384, "minPoolCost": 340000000, "minFeeA": 44, "maxBlockBodySize": 65536, "minFeeB": 155381, "eMax": 18, "extraEntropy": { "tag": "NeutralNonce" }, "maxBlockHeaderSize": 1100, "keyDeposit": 2000000, "nOpt": 500, "rho": 3.0e-3, "tau": 0.2, "a0": 0.3}
**Create draft transaction**
Next, we create a draft transaction like so:
cardano-cli conway transaction build-raw \--tx-in cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85#0 \--tx-out $(cat $HOME/cardano/keys/payment2.addr)+0 \--tx-out $(cat $HOME/cardano/keys/payment1.addr)+0 \--fee 0 \--out-file $HOME/cardano/tx.draft
`cardano-cli conway transaction build-raw` : This tells `cardano-cli` to build a raw transaction.
`--tx-in` : This specifies the **UTXO** input that the transaction will use, you can add as many **UTXO** input as you want by adding multiple `--tx-in` in the `cardano-cli` arguments as long as they have a unique `TxHash` and `TxIdx` within all your inputs.
`--tx-out` : This specifies the target **wallet address**, **assets** and **quantity** to be sent to. You can add as many **UTXO** outputs as you want as long as the total **UTXO** input can satisfy the **assets** and **quantity** specified by the output.
`--fee` : This specifies the fee amount of the transaction in `lovelace`.
`--out-file` : This is the path to the transaction file that will be generated.
In this case, we are just building a draft transaction to calculate how much fee would the transaction need. We can do that by executing the following command:
cardano-cli conway transaction calculate-min-fee \--tx-body-file $HOME/cardano/tx.draft \--tx-in-count 1 \--tx-out-count 2 \--witness-count 1 \--testnet-magic 1097911063 \--protocol-params-file $HOME/cardano/protocol.json
You should see something like this for the output:
174169 Lovelace
You will notice that we use the `protocol.json` we queried awhile ago to calculate the transaction fee:
--protocol-params-file $HOME/cardano/protocol.json
That is because the transaction fee calculation results changes depending on the on-chain protocol parameters.
The `--witness-count 1` basically tells `cardano-cli` that there will be only `1` **signing key** required for this transaction to be valid. Since the **UTXO** input involved in this transaction will only be coming from `payment1` wallet, so that means we indeed only need `1` key to sign the transaction.
We can then finally build the real transaction like so:
cardano-cli conway transaction build-raw \--tx-in cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85#0 \--tx-out $(cat $HOME/cardano/keys/payment2.addr)+250000000 \--tx-out $(cat $HOME/cardano/keys/payment1.addr)+749825831 \--fee 174169 \--out-file $HOME/cardano/tx.draft
To recap, We want to send `250,000,000 lovelace` from `payment1` wallet to `payment2` wallet. Our `payment1` wallet had the following **UTXO**:
TxHash TxIx Amount--------------------------------------------------------------------------------------cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 0 1000000000 lovelace
So we will use the `TxHash` `cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85` and `TxIx` `0` as our `--tx-input`.
--tx-in cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85#0
We then tell `cardano-cli` that the destination of the `250,000,000 lovelace` is the **wallet address** of `payment2`.
--tx-out $(cat $HOME/cardano/keys/payment2.addr)+250000000
Now, we still have `750000000 lovelace` as the change amount, so we will simply send it back to ourselves like so:
--tx-out $(cat $HOME/cardano/keys/payment1.addr)+749825831
Now an important question you might ask here is that, why is the amount `749825831 lovelace`? Well remember that we calculated the fee to be `174169 lovelace` and someone has to shoulder the transaction fee, so we decide that `payment` should pay for the fee with the change `lovelace` amount. So we calculate that `750000000 - 174169 = 749825831` and so the total change would be `749825831 lovelace`.
We then specify the transaction fee like so:
--fee 174169
And then we specify where we will save the transaction file:
--out-file $HOME/cardano/tx.draft
Now that we have the transaction file, we must sign the transaction in-order to prove that we are the owner of the input **UTXO** that was used.
cardano-cli conway transaction sign \--tx-body-file $HOME/cardano/tx.draft \--signing-key-file $HOME/cardano/keys/payment1.skey \--testnet-magic 1097911063 \--out-file $HOME/cardano/tx.signed
`--signing-key-file $HOME/cardano/keys/payment1.skey` : This argument tells the `cardano-cli` that we will use `payment1.skey` to sign the transaction.
Finally, we submit the transaction to the blockchain!
cardano-cli conway transaction submit \--tx-file $HOME/cardano/tx.signed \--testnet-magic 1097911063
important
If you have waited too long to sign and submit the transaction, the fees might've changed during that time and therefore the transaction might get rejected by the network. To solve this, you simply have to **recalculate the fees, rebuild the transaction, sign it and submit it**!
Checking the balances of both wallets `payment1` and `payment2`:
# payment1 wallet UTXO❯ cardano-cli query utxo --testnet-magic 1097911063 --address $(cat $HOME/cardano/keys/payment1.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------63eeeb7e43171aeea0b3d53c5a36236cf9af92d5ee39e99bfadfe0237c46bd91 1 749825303 lovelace# payment2 wallet UTXO❯ cardano-cli query utxo --testnet-magic 1097911063 --address $(cat $HOME/cardano/keys/payment2.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------63eeeb7e43171aeea0b3d53c5a36236cf9af92d5ee39e99bfadfe0237c46bd91 0 250000000 lovelace
As we can see, `payment2` now has a **UTXO** with the amount of `250,000,000 lovelace` with the change amount returned to `payment1` and has generated a new **UTXO** with the amount of `749,825,303 lovelace` as-well.
Congratulations, You have created and sent your first **Cardano** transaction using `cardano-cli`! 🎉🎉🎉
#### Creating a wallet with `cardano-wallet`[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#creating-a-wallet-with-cardano-wallet "Direct link to creating-a-wallet-with-cardano-wallet")
note
This guide assumes you have installed `cardano-wallet` into your system. If not you can refer to [Installing cardano-wallet](https://developers.cardano.org/docs/get-started/cardano-wallet/cardano-wallet)
guide for instructions on how to do that.
We will use the path `$HOME/cardano/wallets` to store all the `cardano-wallet` related files as an example, please replace it with the directory you have chosen to store the files.
important
Please make sure your `cardano-node` is connected and synchronized to a testnet network before proceeding.
warning
In a production environment, it might not be a good idea to store wallets / keys in a public server unless you know what you are doing.
First, lets create a directory to store all our `wallets` like so:
mkdir -p $HOME/cardano/wallets
**Starting cardano-wallet as a REST API server**
We will be focusing on the [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer)
that `cardano-wallet` provides. In-order to interact with the API, we must first start the server.
cardano-wallet serve \--port 1337 \--testnet $HOME/cardano/testnet-byron-genesis.json \--database $HOME/cardano/wallets/db \--node-socket $CARDANO_NODE_SOCKET_PATH
`cardano-wallet serve` : Runs `cardano-wallet` as a web server that provides a [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer)
.
`--port` : Specifies the port that the web server will listen to for any requests.
> You can choose whatever `port` number you like, but it is recommended to use `port` numbers `1024` and above. See [Registered Port](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml)
> for more information.
`--testnet` : Specifies the **Byron** genesis file path for the testnet network.
> This should match the genesis file that the `cardano-node` you are connected is using as-well. If you meant to connect to `mainnet` then use the `--mainnet` flag and the `mainnet` **Byron** genesis file instead.
`--database` : Specifies the path where the wallet database will be saved.
> It is important to note that the wallet creation function requires a passphrase so all the wallet data will be encrypted by the passphrase.
`--node-socket` : Specifies the `cardano-node` socket path that will be used by the `cardano-wallet` to communicate with the node.
> The `cardano-node` uses **IPC (Inter-Process-Communication)** for communicating with the other **Cardano** components like `cardano-cli`, `cardano-wallet` and `cardano-db-sync`. In **Linux** and **MacOS** it uses something called [unix sockets](https://en.wikipedia.org/wiki/Unix_domain_socket)
> and [Named Pipes](https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes)
> in **Windows**.
>
> Here is an example `--socket-path` argument for **Linux**:
--socket-path $HOME/cardano/db/node.socket
> As you can see the argument points to a file since **unix sockets** are represented as files (like everything else in **Linux**). In this case we put the socket file in the `db` directory that we have just created before.
>
> In **Windows**, the `--socket-path` argument would look something like this:
--socket-path "\\\\.\\pipe\\cardano-node-testnet"
> As you notice its almost like a network `URI` or a network `Path` than a file, this is a key difference that you will have to be aware depending on your operating system. You can replace the string `cardano-node-testnet` in the argument to whatever you like, this example path in particular is used in the [Daedalus Testnet Wallet](https://daedaluswallet.io/)
> for **Windows**.
Once the server is running you should see something like this (among other things):
[cardano-wallet.network:Info:12] [2021-06-03 13:48:24.82 UTC] Protocol parameters for tip are: Decentralization level: 100.00% Transaction parameters: [Fee policy: 155381.0 + 44.0x, Tx max size: 16384] Desired number of pools: 500 Minimum UTxO value: 1.000000 Eras: - byron from -0 - shelley from 74 - allegra from 102 - mary from 112Slotting parameters for tip are: Slot length: 1s Epoch length: 432000 Active slot coeff: 5.0e-2 Security parameter: 2160 block[cardano-wallet.main:Info:4] [2021-06-03 13:48:24.86 UTC] Wallet backend server listening on http://127.0.0.1:1337/
**Checking Wallet Server Information**
The first thing we can do to test if the wallet server is working correctly is to query the network information via the API.
curl --url http://localhost:1337/v2/network/information | jq
The result should be something like this:
{ "node_era": "mary", "network_tip": { "slot_number": 408744, "absolute_slot_number": 28359144, "time": "2021-06-03T13:52:40Z", "epoch_number": 135 }, "next_epoch": { "epoch_start_time": "2021-06-03T20:20:16Z", "epoch_number": 136 }, "sync_progress": { "status": "ready" }, "node_tip": { "height": { "unit": "block", "quantity": 2639489 }, "slot_number": 408722, "absolute_slot_number": 28359122, "time": "2021-06-03T13:52:18Z", "epoch_number": 135 }}
It is important to make sure that the `sync_progress.status` is equal to `ready` before proceeding.
**Creating the wallet**
To create a wallet we must first generate a wallet **recovery phrase** using the `cardano-wallet` in the CLI.
cardano-wallet recovery-phrase generate | jq -c --raw-input 'split(" ")'
You should get a **24-word mnemonic seed** in return similar to this:
["shift", "badge", "heavy", "action", "tube", "divide", "course", "quality", "capable", "velvet", "cart", "marriage", "vague", "aware", "maximum", "exist", "crime", "file", "analyst", "great", "cabbage", "course", "sad", "apology"]
We can now create a **Cardano** wallet using the `/v2/wallets` API endpoint:
curl --request POST \ --url http://localhost:1337/v2/wallets \ --header 'Content-Type: application/json' \ --data '{ "name": "test_cf_1", "mnemonic_sentence": ["shift", "badge", "heavy", "action", "tube", "divide", "course", "quality", "capable", "velvet", "cart", "marriage", "vague", "aware", "maximum", "exist", "crime", "file", "analyst", "great", "cabbage", "course", "sad", "apology"], "passphrase": "test123456"}' | jq
Our requests payload data is composed of:
`name` : The name of the wallet.
`passphrase` : Sets the security phrase to protect the funds inside the wallet. It will be required every time you need write access to the wallet, more specifically sending assets.
`mnemonic_sentence` : This is the wallet **recovery phrase** formatted into a `JSON` array.
If successful, you should see something like this:
{ "address_pool_gap": 20, "passphrase": { "last_updated_at": "2021-06-03T14:25:18.2676524Z" }, "balance": { "available": { "unit": "lovelace", "quantity": 0 }, "total": { "unit": "lovelace", "quantity": 0 }, "reward": { "unit": "lovelace", "quantity": 0 } }, "id": "5076b34c6949dbd150eb9c39039037543946bdce", "state": { "status": "syncing", "progress": { "unit": "percent", "quantity": 0 } }, "name": "test_cf_1", "assets": { "available": [], "total": [] }, "tip": { "height": { "unit": "block", "quantity": 0 }, "slot_number": 0, "absolute_slot_number": 0, "time": "2019-07-24T20:20:16Z", "epoch_number": 0 }, "delegation": { "next": [], "active": { "status": "not_delegating" } }}
Initially, the newly created/restored wallet will need to be synced before it can be used. You can verify if the wallet is already synced by executing the following request:
curl --url http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce | jq '.state'
_**It is important to note that the `5076b34c6949dbd150eb9c39039037543946bdce` string is actually the `wallet.id` of the previously generated wallet.**_
You should see something like this:
{ "status": "ready"}
**Receiving tAda (test ada)**
Now that we have created a wallet, we can now request some tAda from the **Testnet Faucet**. But before we can do that we must first get a cardano address for our wallet.
We can do that by executing the command:
curl --url 'http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce/addresses?state=unused' | jq '.[0]'
The result should be something like this:
{ "derivation_path": [ "1852H", "1815H", "0H", "0", "0" ], "id": "addr_test1qzf9q3qjcaf6kxshwjfw9ge29njtm56r2a08g49l79xgt4je0592agqpwraqajx2dsu2sxj64uese5s4qum293wuc00q7j6vsp", "state": "unused"}
It is important to note that the parameter of this request is the **wallet id** of the target wallet you want to get the address. In this case it is `5076b34c6949dbd150eb9c39039037543946bdce` our previously generated wallet.
We are basically querying the first wallet address that has not been used just yet, Indicated by `state: "unused"`. As we can see the wallet address value is: `addr_test1qzf9q3qjcaf6kxshwjfw9ge29njtm56r2a08g49l79xgt4je0592agqpwraqajx2dsu2sxj64uese5s4qum293wuc00q7j6vsp"`
Now we can finally request some `tAda` for the wallet address from the [Cardano Testnet Faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet)
.
Once you requested some `tAda` from the [Cardano Testnet Faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet)
, we can then check if it has arrived into our wallet like so:
curl --url http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce | jq '.balance'
You should see something like this:
{ "available": { "unit": "lovelace", "quantity": 1000000000 }, "total": { "unit": "lovelace", "quantity": 1000000000 }, "reward": { "unit": "lovelace", "quantity": 0 }}
As we can see here we have a total of `1,000,000,000 lovelace` available to spend that we received from the [Cardano Testnet Faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet)
.
#### Creating simple transactions[](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#creating-simple-transactions-1 "Direct link to Creating simple transactions")
To have a clearer understanding of how sending transactions work using `cardano-wallet`, first lets create another wallet like so:
**Generate recovery-phrase**
cardano-wallet recovery-phrase generate | jq -c --raw-input 'split(" ")'
**Recovery-phrase result**
["then", "tattoo", "copy", "glance", "silk", "kitchen", "kingdom", "pioneer", "off", "path", "connect", "artwork", "alley", "smooth", "also", "foil", "glare", "trouble", "erupt", "move", "position", "merge", "scale", "echo"]
**Create Wallet Request**
curl --request POST \ --url http://localhost:1337/v2/wallets \ --header 'Content-Type: application/json' \ --data '{ "name": "test_cf_2", "mnemonic_sentence": ["then", "tattoo", "copy", "glance", "silk", "kitchen", "kingdom", "pioneer", "off", "path", "connect", "artwork", "alley", "smooth", "also", "foil", "glare", "trouble", "erupt", "move", "position", "merge", "scale", "echo"], "passphrase": "test123456"}' | jq
**Create Wallet Result**
{ "address_pool_gap": 20, "passphrase": { "last_updated_at": "2021-06-04T11:39:06.8887923Z" }, "balance": { "available": { "unit": "lovelace", "quantity": 0 }, "total": { "unit": "lovelace", "quantity": 0 }, "reward": { "unit": "lovelace", "quantity": 0 } }, "id": "4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb", "state": { "status": "syncing", "progress": { "unit": "percent", "quantity": 0 } }, "name": "test_cf_2", "assets": { "available": [], "total": [] }, "tip": { "height": { "unit": "block", "quantity": 0 }, "slot_number": 0, "absolute_slot_number": 0, "time": "2019-07-24T20:20:16Z", "epoch_number": 0 }, "delegation": { "next": [], "active": { "status": "not_delegating" } }}
We now have the following wallets:
| WalletId | Wallet Name | Balance(Lovelace) |
| --- | --- | --- |
| 5076b34c6949dbd150eb9c39039037543946bdce | test\_cf\_1 | 1000000000 |
| 4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb | test\_cf\_2 | 0 |
Now let's say that we want to send `250,000,000 lovelaces` to `test_cf_2` wallet. Well first we have to get `test_cf_2` wallet address like so:
curl --url 'http://localhost:1337/v2/wallets/4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb/addresses?state=unused' | jq '.[0]'
and we should see something like this:
{ "derivation_path": [ "1852H", "1815H", "0H", "0", "0" ], "id": "addr_test1qzyfnjk3zmgzmvnnvnpeguv6se2ptjj3w3uuh30llqe5xdtzdduxxvke8rekwukyn0qt9g5pahasrnrdmv7nr86x537qxdgza0", "state": "unused"}
So now that we have `test_cf_2` wallet address `addr_test1qzyfnjk3zmgzmvnnvnpeguv6se2ptjj3w3uuh30llqe5xdtzdduxxvke8rekwukyn0qt9g5pahasrnrdmv7nr86x537qxdgza0`. We can now use it to send some `tAda` to it from `test_cf_1` wallet like so:
curl --request POST \ --url http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce/transactions \ --header 'Content-Type: application/json' \ --data '{ "passphrase": "test123456", "payments": [ { "address": "addr_test1qzyfnjk3zmgzmvnnvnpeguv6se2ptjj3w3uuh30llqe5xdtzdduxxvke8rekwukyn0qt9g5pahasrnrdmv7nr86x537qxdgza0", "amount": { "quantity": 250000000, "unit": "lovelace" } } ]}'
note
Remember, we use the `test_cf_1` wallet id in the `http://localhost:1337/v2/wallets/` endpoint, because we want the `test_cf_1` to send to `test_cf_2` wallet address.
Now we can check `test_cf_2` wallet balance like so:
curl --url http://localhost:1337/v2/wallets/4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb | jq '.balance'
And we should see that indeed the `250,000,000 tAda` has been received (_**you might need to wait for a few seconds**_).
{ "available": { "unit": "lovelace", "quantity": 250000000 }, "total": { "unit": "lovelace", "quantity": 250000000 }, "reward": { "unit": "lovelace", "quantity": 0 }}
Checking `test_cf_1` wallet balance should show you something like this:
{ "available": { "unit": "lovelace", "quantity": 749831199 }, "total": { "unit": "lovelace", "quantity": 749831199 }, "reward": { "unit": "lovelace", "quantity": 0 }}
Our wallets should now be the following:
| WalletId | Wallet Name | Balance(Lovelace) |
| --- | --- | --- |
| 5076b34c6949dbd150eb9c39039037543946bdce | test\_cf\_1 | 749831199 |
| 4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb | test\_cf\_2 | 250000000 |
note
It is important to note that `cardano-wallet` has automatically determined the fee for the transaction to send `250,000,000 lovelace` from wallet `test_cf_1` to `test_cf_2` and `cardano_wallet` has deducted the fee from `test_cf_1` wallet automatically.
tip
Full documentation of the `cardano-wallet` [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer)
can be found here: [https://cardano-foundation.github.io/cardano-wallet/api/edge](https://cardano-foundation.github.io/cardano-wallet/api/edge)
Congratulations, You have created and sent your first **Cardano** transaction using `cardano-wallet`! 🎉🎉🎉
* [Overview](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#overview)
* [Cardano Wallets](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#cardano-wallets)
* [Creating a wallet](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet/#creating-a-wallet)
---
# Testnet Faucet | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
The Testnet Faucet is a service that provides test ada (tAda) to users of the Cardano testnets. These tokens have no value, but they enable users to experiment with Cardano testnet features without spending real ada on the Mainnet. You can use test ada to [mint native tokens](https://developers.cardano.org/docs/native-tokens/minting)
, to [play around with Cardano wallets](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet)
or to [learn how to operate a stake pool](https://developers.cardano.org/docs/operate-a-stake-pool/)
.
Testnets faucet[](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet/#testnets-faucet "Direct link to Testnets faucet")
-------------------------------------------------------------------------------------------------------------------------------------------
This portal allows you to send test ada to your wallet. You can access it [here](https://docs.cardano.org/cardano-testnet/tools/faucet)
.
Return the test ada
Send your test tokens to this address: `addr_test1qqr585tvlc7ylnqvz8pyqwauzrdu0mxag3m7q56grgmgu7sxu2hyfhlkwuxupa9d5085eunq2qywy7hvmvej456flknswgndm3`
How to get test ada[](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet/#how-to-get-test-ada "Direct link to How to get test ada")
-------------------------------------------------------------------------------------------------------------------------------------------------------
1. Define your environment. You can get tada for either the `preview` or `preprod` testnets.
2. Define your action. Select `Receive test ADA` in this case. You can also ask for `pool delegation` if you are managing a pool (learn [more](https://developers.cardano.org/docs/operate-a-stake-pool/)
).
3. Enter the address of the account where you want to top up funds.
4. If you have been issued with an API key, please enter this to access any additional funds you may have been allocated.
5. Confirm the `I'm not a robot` box and solve the captcha if needed.
6. Click on `Request` and the funds will be in the testnet account you specified within a few minutes. Use the [Cardano PreProd Testnet Explorer](https://preprod.cardanoscan.io/)
and [Cardano PreView Testnet Explorer](https://preview.cardanoscan.io/)
provided by Cardanoscan.io in case you want to check any transactions on a Cardano testnet.
* [Testnets faucet](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet/#testnets-faucet)
* [How to get test ada](https://developers.cardano.org/docs/integrate-cardano/testnet-faucet/#how-to-get-test-ada)
---
# Multi-witness transactions | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Overview[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#overview "Direct link to Overview")
--------------------------------------------------------------------------------------------------------------------------------------
note
This guide assumes that you have completed the [Exploring Cardano Wallets](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet)
guide. You will need one UTxO sitting at each of the wallets (`payment1.addr` and `payment2.addr`) to complete this guide.
This guide also assumes that you have `cardano-node` running in the background and connected to a [testnet network](https://developers.cardano.org/docs/get-started/testnets-and-devnets)
.
### Recap[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#recap "Direct link to Recap")
Let's recap what we did so far. Our goal in the [previous guide](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet)
was to draw `1000 tADA` from the Testnet Faucet and send `250 tAda` from **payment1** to **payment2**.
Make sure we are in the correct folder.
$ pwd$HOME/cardano
* Query UTxO
* Calculate fees
* Build Tx
* Sign & Submit Tx
* Verify Tx
We drew `1000 tAda` from the Testnet Faucet into our **payment1** wallet.
$ cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat keys/payment1.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------264c0aa805652e3607c5ea2b1e8a9f3bf9c3bc8d4d938e1a9035f352083ba703 0 1000000000 lovelace
We used `protocol-parameters` to draft our transaction and calculated the expected fee.
$ cardano-cli query protocol-parameters \--testnet-magic 1097911063 \--out-file protocol.json
$ cardano-cli conway transaction build-raw \--tx-in 264c0aa805652e3607c5ea2b1e8a9f3bf9c3bc8d4d938e1a9035f352083ba703#0 \--tx-out $(cat keys/payment2.addr)+0 \--tx-out $(cat keys/payment1.addr)+0 \--fee 0 \--out-file tx.draft
$ cardano-cli conway transaction calculate-min-fee \--tx-body-file tx.draft \--tx-in-count 1 \--tx-out-count 2 \--witness-count 1 \--testnet-magic 1097911063 \--protocol-params-file protocol.json174169 Lovelace
From the expected fee of `174169 Lovelace`, we were able to calculate the outputs and build our transaction.
cardano-cli conway transaction build-raw \--tx-in 264c0aa805652e3607c5ea2b1e8a9f3bf9c3bc8d4d938e1a9035f352083ba703#0 \--tx-out $(cat keys/payment2.addr)+250000000 \--tx-out $(cat keys/payment1.addr)+749825831 \--fee 174169 \--out-file tx.draft
note
Your fees might have been different hence you would have different amounts.
We used `payment1.skey` to sign our transaction and submitted it to the blockchain.
cardano-cli conway transaction sign \--tx-body-file tx.draft \--signing-key-file keys/payment1.skey \--testnet-magic 1097911063 \--out-file tx.signedcardano-cli conway transaction submit \--tx-file cardano/tx.signed \--testnet-magic 1097911063Transaction successfully submitted.
Finally we verified the transaction by querying the **payment1** and **payment2** wallets.
$ cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat keys/payment1.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251 1 749825831 lovelace
$ cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat payment2.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251 0 250000000 lovelace
We currently have `749.825831 tAda` in our **payment1** wallet and `250 tAda` in our **payment2** wallet.
Let's see how we can spend it all at once!
Use case[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#use-case "Direct link to Use case")
--------------------------------------------------------------------------------------------------------------------------------------
There are many possible reasons why you would want to have multiple wallets sending their ada in a single transaction. One is, you own two wallets (**payment1** and **payment2**) and you want to spend it on something that...
* costs more than you have in any of your two wallets,
* but **both amounts combined** would cover the costs.
Let's say you are at the **bike store** and you see a nice bike with a price tag of `1100 tAda` on it. You only have `999 tAda` (plus change) left.
The bike store owner - _a devious blockchain enthusiast_ - is willing to give you a 10% discount, if you manage to **pay him in a single transaction**
> _There has to be no change, buddy!_ --Bike Store Owner
So we need to make sure to spend all our `tAda` from our two wallets in a single transaction.
note
He can easily verify if we spent all our money by checking if the transaction has more than one output.
There are ways to optimize the amount you spend. We will leave this for you to figure out yourself.
Technical Flow[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#technical-flow "Direct link to Technical Flow")
--------------------------------------------------------------------------------------------------------------------------------------------------------
This scenario is pretty straight forward and looks like this.

As you can see in the diagram above, we will build and submit a **multi-witness transaction**, having _two inputs_ and _one output_.
note
We can't do this with `cardano-wallet`, or any other wallet like Daedalus or Yoroi because we will need both `signing-keys` from **payment1** and **payment2** to sign the transaction.
Time to code[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#time-to-code "Direct link to Time to code")
--------------------------------------------------------------------------------------------------------------------------------------------------
note
As mentioned above, this guide assumes you completed the [Exploring Cardano Wallets](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet)
guide.
We also assume you paid `174169 Lovelace` in transaction fees and that your current balances are:
* **payment1**: `749825831 Lovelace`
* **payment2**: `250000000 Lovelace`
### Create a store-owner wallet[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#create-a-store-owner-wallet "Direct link to Create a store-owner wallet")
If you don't already have a third wallet to use for this guide, let's create one where we can transfer all our funds to.
Make sure you are inside the `keys` directory like so: `cd $HOME/cardano/keys`
Generate a **payment key-pair** using `cardano-cli`:
cardano-cli address key-gen \--verification-key-file $HOME/cardano/keys/store-owner.vkey \--signing-key-file $HOME/cardano/keys/store-owner.skey
Then generate a **wallet address** for the testnet network:
cardano-cli address build \--payment-verification-key-file $HOME/cardano/keys/store-owner.vkey \--out-file $HOME/cardano/keys/store-owner.addr \--testnet-magic 1097911063
Check your `keys` directory. It should look something like this:
$HOME/cardano/keys/├── payment1.addr├── payment1.skey├── payment1.vkey├── payment2.addr├── payment2.skey├── payment2.vkey├── store-owner.addr├── store-owner.skey└── store-owner.vkey0 directories, 9 files
### Calculate the transaction fee[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#calculate-the-transaction-fee "Direct link to Calculate the transaction fee")
Lets create a directory to store our transactions for this guide and enter it:
mkdir -p $HOME/cardano/multi-witness-sample && cd $_;
We want to send **all our tAda** sitting at the two UTxO we verified [before](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#recap)
and send it to the `store-owner.addr`. That means we will have **two inputs**.
What about the outputs? Well, the _devious store-owner_ wants us to spend it all, so there will be **one output to the store-owner** and **zero outputs to us**. Remember? _"...no change, buddy!"_
Lets build that transaction.
cardano-cli conway transaction build-raw \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#0 \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#1 \--tx-out $(cat ../keys/store-owner.addr)+0 \--fee 0 \--out-file tx2.draft
The last thing we need to do is to calculate the fees for `tx2.draft`. Notice the `--tx-in-count` and `--witness-count`.
cardano-cli conway transaction calculate-min-fee \--tx-body-file tx2.draft \--tx-in-count 2 \--tx-out-count 1 \--witness-count 2 \--testnet-magic 1097911063 \--protocol-params-file ../protocol.json 179581 Lovelace
We can calculate the amount the **store-owner** will receive, if both UTxO are spent during the transaction:
749825831 (payment1)+ 250000000 (payment2) --------- 999825831- 179581 (fee) --------- 999646250 (store-owner) =========
### Build, sign and submit transaction[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#build-sign-and-submit-transaction "Direct link to Build, sign and submit transaction")
We know the _output amount_ as well as the _fee_. We can finally build, sign and submit our `tx2.draft` transaction.
We have to use `payment1.skey` and `payment2.skey` to sign our transaction.
cardano-cli conway transaction build-raw \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#0 \--tx-in b73b7503576412219241731230b5b7dd3b64eed62ccfc3ce69eb86822f1db251#1 \--tx-out $(cat ../keys/store-owner.addr)+999646250 \--fee 179581 \--out-file tx2.draft cardano-cli conway transaction sign \--tx-body-file tx2.draft \--signing-key-file ../keys/payment1.skey \--signing-key-file ../keys/payment2.skey \--testnet-magic 1097911063 \--out-file tx2.signedcardano-cli conway transaction submit \--tx-file tx2.signed \--testnet-magic 1097911063Transaction successfully submitted
### Verify multi-witness transactions[](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#verify-multi-witness-transactions "Direct link to Verify multi-witness transactions")
The devious store-owner will now verify that everything went according to his plan.
cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat $HOME/cardano/keys/store-owner.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------258abd628eef7d6ff0f7b4e6866b4f7c21065f4d6b5e49b51e2ac4ff035ad06f 0 999646250 lovelace
Success!
He can see that the transaction has one output to his wallet. No other outputs, hence you must have spent all of your `tAda`.
Congratulations, you are now able to submit **multi-witness transactions on Cardano**. This should help you bring integrations to your existing or new upcoming applications. 🎉🎉🎉
* [Overview](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#overview)
* [Recap](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#recap)
* [Use case](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#use-case)
* [Technical Flow](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#technical-flow)
* [Time to code](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#time-to-code)
* [Create a store-owner wallet](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#create-a-store-owner-wallet)
* [Calculate the transaction fee](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#calculate-the-transaction-fee)
* [Build, sign and submit transaction](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#build-sign-and-submit-transaction)
* [Verify multi-witness transactions](https://developers.cardano.org/docs/integrate-cardano/multi-witness-transactions-cli/#verify-multi-witness-transactions)
---
# (Re)introduction to Cardano | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Developing Cardano is no small feat. There is no other project that has ever been built to these parameters, combining peer reviewed cryptographic research with an implementation in highly secure Haskell code.
This is not the copy and paste code seen in so many other blockchains. Instead, Cardano was designed with input from a large global team including leading experts and professors in the fields of computer programming languages, network design and cryptography.
We are extremely proud of Cardano, which required a months-long meticulous and painstaking development process by our talented engineers.
If you haven't seen it yet, watch the legendary whiteboard video from 2017. Some details are a bit outdated, but it is still worth seeing to understand what Cardano is and where Cardano came from.
Understanding Consensus[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#understanding-consensus "Direct link to Understanding Consensus")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Consensus is the process by which a majority opinion is reached by everyone who is involved in running the blockchain. Agreement must be made on which blocks to produce, which chain to adopt, and to determine the single state of the network. The consensus protocol determines how individual nodes assess the current state of the ledger system and reach a consensus. It has three main responsibilities; to perform a leader check and decide if a block should be produced, to handle chain selection, and to verify blocks that are produced.
Blockchains create consensus by allowing participants to bundle transactions that others have submitted to the system in _blocks_, and add them to their _chain_ (sequence of blocks). Determining who is allowed to produce a block when, and what to do in case of conflicts, (such as two participants adding different blocks at the same point of the chain), is the purpose of the different consensus protocols. Our ground-breaking proof-of-stake consensus protocol [Ouroboros](https://iohk.io/en/blog/posts/2020/06/23/the-ouroboros-path-to-decentralization/)
is proven to have the same security guarantees that proof of work has. Rigorous security guarantees are established by Ouroboros and it was delivered with several peer-reviewed papers that were presented in top-tier conferences and publications in the area of cybersecurity and cryptography. Different [implementations of Ouroboros](https://iohk.io/en/blog/posts/2020/03/23/from-classic-to-hydra-the-implementations-of-ouroboros-explained/)
have been developed. For further details on each flavour of Ouroboros, you can read the technical specifications for [Classic](https://iohk.io/en/research/library/papers/ouroborosa-provably-secure-proof-of-stake-blockchain-protocol/)
, [Byzantine Fault Tolerance (BFT)](https://iohk.io/en/research/library/papers/ouroboros-bfta-simple-byzantine-fault-tolerant-consensus-protocol/)
, [Genesis](https://iohk.io/en/research/library/papers/ouroboros-genesiscomposable-proof-of-stake-blockchains-with-dynamic-availability/)
, [Praos](https://iohk.io/en/research/library/papers/ouroboros-praosan-adaptively-securesemi-synchronous-proof-of-stake-protocol/)
, and more recently the scalability solution [Hydra](https://eprint.iacr.org/2020/299.pdf)
.
Stake Pools[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#stake-pools "Direct link to Stake Pools")
-------------------------------------------------------------------------------------------------------------------------------------------
By running a Cardano node, users participate in and contribute to the network.
A stake pool is a reliable server node that focuses on maintenance and holds the combined stake of various stakeholders in a single entity. Stake pools are responsible for processing transactions and producing new blocks and are at the core of Ouroboros, the Cardano proof-of-stake protocol.
To be secure, Ouroboros requires a good number of ada holders to be online and maintaining sufficiently good network connectivity at any given time. This is why Ouroboros relies on stake pools, entities committed to run the protocol 24/7, on behalf of the contributing ada holders.
While Ouroboros is cheaper to run than a proof of work protocol, running Ouroboros still incurs some costs. Therefore, stake pool operators are rewarded for running the protocol in the form of incentives that come from the transaction fees and from inflation of the circulating supply of ada.
How Are New Blocks Produced?[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#how-are-new-blocks-produced "Direct link to How Are New Blocks Produced?")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The goal of blockchain technology is the production of an independently-verifiable and cryptographically-linked chain of records (blocks). A network of block producers works to collectively advance the blockchain. A consensus protocol provides transparency and decides which candidate blocks should be used to extend the chain.
Submitted valid transactions might be included in any new block. A block is cryptographically signed by its producer (the stake pool) and linked to the previous block in the chain. This makes it impossible to delete transactions from a block, alter the order of the blocks, remove a block from the chain (if it already has a number of other blocks following it), or to insert a new block into the chain without alerting all the network participants. This ensures the integrity and transparency of the blockchain expansion.
### Slots and Epochs[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#slots-and-epochs "Direct link to Slots and Epochs")
The Cardano blockchain uses the Ouroboros Praos protocol to facilitate consensus on the chain.
Ouroboros Praos divides time into epochs. Each Cardano epoch consists of a number of slots, where each slot lasts for one second. A Cardano epoch currently includes 432,000 slots (5 days). In any slot, zero or more block-producing nodes might be nominated to be the slot leader. On average, one node is expected to be nominated every 20 seconds, for a total of 21,600 nominations per epoch. If randomly elected slot leaders produce blocks, one of them will be added to the chain. Other candidate blocks will be discarded.
### Slot Leader Election[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#slot-leader-election "Direct link to Slot Leader Election")
The Cardano network consists of a number of stake pools that control the aggregated stake of their owners and other delegators, also known as stakeholders. Slot leaders are elected randomly from among the stake pools. The more stake the pool controls, the greater the chance it has of being elected as a slot leader to produce a new block that is accepted into the blockchain. This is the concept of proof-of-stake (PoS).
### Transaction Validation[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#transaction-validation "Direct link to Transaction Validation")
When validating a transaction, a slot leader needs to ensure that the sender has included enough funds to pay for that transaction and must also ensure that the transaction’s parameters are met. Assuming that the transaction meets all these requirements, the slot leader will record it as a part of a new block, which will then be connected to other blocks in the chain.
Ouroboros Protocol[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#ouroboros-protocol "Direct link to Ouroboros Protocol")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
### Consensus[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#consensus "Direct link to Consensus")
Blockchains require an agreement mechanism between the participants of the network on how to add new transactions to the ledger and its state at any given moment. This mechanism is known as a consensus protocol.
The goal of the consensus protocol is to ensure that only one chain is adopted and followed, otherwise, the system would collapse immediately.
### The Proof-of-work consensus algorithm[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#the-proof-of-work-consensus-algorithm "Direct link to The Proof-of-work consensus algorithm")
Bitcoin implemented a Proof-of-work consensus algorithm. In this protocol, for a new block to be added to the blockchain, the node that attempts it must provide a proof-of-work, which is expressed by the solution of a mathematical puzzle. This process is known as mining.
The node that solves the puzzle gets the right to create the new block and is rewarded for it.
This scheme puts all nodes into a race against each other, and since only one node is rewarded, wastes a lot of computational power and energy.
Such waste has raised concerns about the Bitcoin’s environmental impact. Currently, the Bitcoin mining process consumes as much energy as countries like the Netherlands or Iceland.
Apart from the environmental concerns, the rewards scheme of the proof-of-work algorithm has also led to the centralization of the Bitcoin network. Up to 75% of the Bitcoin network computing power is located in China. And a single player, Bitmain, controls over 40% of the network hash rate.
The underlying problem is that Bitcoin makes a clear distinction between the actual users of the network and the miners. Owning Bitcoins does not grant you any control over the network, nor any power over the decisions on the evolution of it. The system is controlled by a small pool of developers and miners.
### Ouroboros, a Proof-of-stake consensus algorithm[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#ouroboros-a-proof-of-stake-consensus-algorithm "Direct link to Ouroboros, a Proof-of-stake consensus algorithm")
In Ouroboros, there is no race between stakeholders to produce a block. Instead, a slot leader is randomly selected, proportionally to the amount of tokens he owns (the stake), to get the opportunity to produce a new block.
So it is not hashing power what gives you the opportunity to produce a new block (and get rewarded for it), it is your stake what increases your chances to be elected.
Since there is no race to mine a block, there is no waste of energy or computational resources. In that sense, Ouroboros is a more efficient and cheaper protocol to run than Bitcoin’s proof-of-work, while keeping all the security guarantees.
### What if you are not online? (Stake pools)[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#what-if-you-are-not-online-stake-pools "Direct link to What if you are not online? (Stake pools)")
To produce a block you have to be online, but asking everyone to be online at every moment is impractical and unrealistic. This is why Ouroboros introduces the figure of _Stake Delegation_. As stakeholder, you can delegate your stake to a third party to act on your behalf whenever you are elected slot leader. Such delegates are known as _staking pools_. They are members of the community that commit to run the protocol on your behalf and to be online close to 100% of the time.
An important thing to notice is that you only delegate your rights to participate in the protocol, not your actual funds. Your ada are still secure and under your control in your wallet, and funds are not locked, you can still make transactions.
### What about the incentives?[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#what-about-the-incentives "Direct link to What about the incentives?")
Stakeholders that issue blocks are incentivized to participate in the protocol by collecting transaction fees. But Ouroboros does not incentivize stakeholders to invest computational resources to issue blocks. Rather, availability and transaction verification are preferred.
Rewards come from two sources: transaction fees and funds drawn from the ada Reserve.
In Ouroboros, incentives are not block-dependant, instead, rewards from an epoch are collected in a pool and distributed among the stakeholders and stake pools that participated during these slots proportional to their stake.
In the case of stake pools, those get a fraction of the rewards to cover operational costs and a profit margin. The rest is distributed among the pool members, including the pool owners, proportionally to the stake that they contributed to the pool.
To participate in the protocol, you can choose a staking pool or choose to act on your own at any moment creating your own stake pool.
### What if for some reason there is a fork?[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#what-if-for-some-reason-there-is-a-fork "Direct link to What if for some reason there is a fork?")
Given that stakeholders are not always online, they come and go (a.k.a. dynamic availability), and sometimes they are offline for long periods, it is important for them to be able to resynchronize with the correct chain when they come back online.
The key feature of Ouroboros Genesis is that thanks to a unique chain selection rule, it allows new or re-joining parties to synchronize to the “good chain” with only a trusted copy of the genesis block. This makes the protocol secure against the so-called “long-range attack”.
### Self-produced randomness[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#self-produced-randomness "Direct link to Self-produced randomness")
Making the slot leader selection fair and secure **(staking procedure)** requires a good source of randomness.
Ouroboros protocol (specifically Ouroboros Praos and Ouroboros Genesis) incorporates a Global Random Oracle feature that produces new and fresh randomness at every epoch.
This is achieved by the implementation of a Verifiable Random Function. When evaluated with the key of a stakeholder, It returns a random value which is stored in every new block produced. The hashing of all values from the previous epoch becomes the random seed for the staking procedure. The blockchain itself becomes its source of new randomness.
This is why the protocol is named Ouroboros, the snake that eats its own tail.
### Promoting decentralization[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#promoting-decentralization "Direct link to Promoting decentralization")
Finally, the Ouroboros incentives mechanism promotes the decentralization of the system in a better way than Proof-of-work does. Because Ouroboros considers two key scenarios:
In one hand, a staking pool can only act as a delegate if it represents a certain number of stakeholders whose aggregate stake exceeds a given threshold, for example, 0.1% of all the stake in the blockchain. This prevents a fragmentation attack, where someone tries to affect the performance of the protocol by increasing the delegates population.
At the same time, when the aggregate stake of a stake pool grows beyond a certain threshold, rewards become constant. This makes that particular stake pool less attractive since stakeholders would not be maximizing their rewards. For example, if the threshold is set to 1%, a stake pool with a stake of 2% would gain the same rewards as other that has a stake of only 1%.
All these functionalities make Ouroboros the best proof of stake ledger protocol to date. And its only implementation is currently in the Cardano blockchain.
How it works[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#how-it-works "Direct link to How it works")
----------------------------------------------------------------------------------------------------------------------------------------------
1. **Time** is divided into epochs and slots and begins at Genesis. At most one block is produced in every slot. Only the slot leader can sign a block for a particular slot.
2. **Register:** The first thing a user needs to do to participate in the protocol is registering to:
1. a network to synchronize with the ledger
2. a global clock that indicates the current slot
3. a global random oracle that produces random values (v) and delivers them to the user
3. **Staking procedure**
1. At the beginning of every epoch, the online stakeholders fetch (from the blockchain) the **stake distribution** from the last block of 2 epochs ago. For example, if the current epoch is epoch 100, the stake distribution used is the distribution as it was in the last block of epoch 98.
2. **Random Oracle**: Is a hashing function that takes the random values “v” (included in each block by the slot leader for this purpose) from the first ⅔ slots in previous epoch and hash them together and use it as the random seed to select the slot leaders.
3. Stakeholders evaluate with their **secret key** the **Verifiable Random Function (VRF)** at every slot. If the output value (v) is below a certain threshold, the party becomes slot leader for that block.
1. **Certificate:** The **VRF** produces two outputs: **a random value (v)** and a **proof (π)** that the slot leader will include in the block he produces to certify that he is the legitimate slot leader for that particular slot.
2. Slot leader performs the following duties
3. Collects the transactions to be included in his block.
4. Includes in his block the random value (v) and proof (π) obtained from the VRF output.
5. Before broadcasting the block, the slot leader generates a new secret key **(Key-evolving signature)**. The public key remains the same, but the secret key is updated in every step and the old key is erased.
6. It is impossible to forge old signatures with new keys. And it is also impossible to derive previous keys from new ones.
7. Finally, the slot leader broadcast the new block to the network.
8. The **rewards** obtained by the slot leaders are calculated at the end of the epoch. Rewards come from transaction fees and funds from the ada reserve.
**What happens in the case of a fork in the chain?**
A key aspect of the procedure described above is that from time to time, it will produce slots without a slot leader and slots with multiple slot leaders. Meaning that nodes might receive valid chains from multiple sources. To determine which chain to adopt, each party collects all valid chains and applies the Chain Selection Rule. The same thing is done by users that have been offline for a while and need to synchronize with the blockchain.
The node filters all valid chains (chains whose signatures are consistent with the genesis block and with the keys recorded in the Key Evolving Signature protocol, the variable random function and the global random oracle.
Then applies the Chain Selection Rule: pick the longest chain as long as it grows more quickly (is denser) in the slots following the last common block to both competing chains.
This chain selection rule allows for a party that joins the network at any time to synchronize with the correct blockchain, based only on a trusted copy of the genesis block and by observing how the chain grows for a sufficient time.
Reference material[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#reference-material "Direct link to Reference material")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
[Ouroboros: A Provably Secure Proof-of-Stake Blockchain Protocol](https://eprint.iacr.org/2016/889.pdf)
[Ouroboros Praos: An adaptively-secure, semi-synchronous proof-of-stake blockchain](https://eprint.iacr.org/2017/573.pdf)
[Ouroboros Genesis: Composable Proof-of-Stake Blockchains with Dynamic Availability](https://eprint.iacr.org/2018/378.pdf)
Video: What’s an Ouroboros and how you cook it?[](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#video-whats-an-ouroboros-and-how-you-cook-it "Direct link to Video: What’s an Ouroboros and how you cook it?")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* [Understanding Consensus](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#understanding-consensus)
* [Stake Pools](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#stake-pools)
* [How Are New Blocks Produced?](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#how-are-new-blocks-produced)
* [Slots and Epochs](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#slots-and-epochs)
* [Slot Leader Election](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#slot-leader-election)
* [Transaction Validation](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#transaction-validation)
* [Ouroboros Protocol](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#ouroboros-protocol)
* [Consensus](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#consensus)
* [The Proof-of-work consensus algorithm](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#the-proof-of-work-consensus-algorithm)
* [Ouroboros, a Proof-of-stake consensus algorithm](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#ouroboros-a-proof-of-stake-consensus-algorithm)
* [What if you are not online? (Stake pools)](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#what-if-you-are-not-online-stake-pools)
* [What about the incentives?](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#what-about-the-incentives)
* [What if for some reason there is a fork?](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#what-if-for-some-reason-there-is-a-fork)
* [Self-produced randomness](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#self-produced-randomness)
* [Promoting decentralization](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#promoting-decentralization)
* [How it works](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#how-it-works)
* [Reference material](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#reference-material)
* [Video: What’s an Ouroboros and how you cook it?](https://developers.cardano.org/docs/operate-a-stake-pool/introduction-to-cardano/#video-whats-an-ouroboros-and-how-you-cook-it)
---
# Authenticated Products on Cardano Store | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/native-tokens/authenticated-products/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
The recently opened [Cardano Store](https://store.cardano.org/)
offers sustainably produced promotional items and innovative products. The latter category in particular offers blockchain enthusiasts products and product prototypes that connect the physical world with the virtual world using blockchain technology. The first product of that kind is the [POC Hoodie](https://store.cardano.org/products/hoodie)
, which is equipped with an NFC chip that can be used to verify the authenticity of the hoodie based on the unique possibilities of the Cardano blockchain. A similar approach was already used in summer 2023 with the [Lacrosse World Cup Jersey](https://cardanofoundation.org/en/news/technical-collaboration-with-epoch-sports-merchadise/)
showcase. While the revised approach of the POC Hoodie offers some improvements, particularly in the area of security, it is not the end of the development process.
In the following, we briefly outline the background to the development of the POC Hoodies, provide an overview of the actual implementation and conclude with an outlook on future improvements. First, however, we will show how the hoodies work and how users can validate them.
Proof of Concept Hoodies[](https://developers.cardano.org/docs/native-tokens/authenticated-products/#proof-of-concept-hoodies "Direct link to Proof of Concept Hoodies")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
For the owner of a POC Hoodie the verification process is as straightforward as tapping the NFC tag that’s knitted into the hoodie which redirects them to a website where the verification status is displayed.
Whereas this way of verification is convenient and easily accessible for also non tech savvy people, it relies on a centrally hosted website which essentially one has to trust when being provided with the information of the hoodie’s authenticity. However, if equipped with the right blockchain knowledge and access to tools like a Blockchain Explorer, users can perform further verifications independently from the output of the website by looking up the asset name returned within the URL string of the NFC chip and checking if the policy ID of the found NFT matches `e886a328333c28bf3e8fc527206b02dc9ff65fb04cf569ec71983330`.
What actually happens in the background when the user taps the NFC tag is that by tapping, the smart phone gets provided with a URL that contains encrypted data that identifies and allows the backend to verify the corresponding NFT on the Cardano blockchain. Following that URL the user ends up on the already mentioned website, which forwards the encrypted data to a validation service that is able to decrypt it and use the encoded information (namely the asset id) to look for a corresponding NFT on the Cardano blockchain. If it finds one, the [metadata of this NFT](https://adastat.net/tokens/e886a328333c28bf3e8fc527206b02dc9ff65fb04cf569ec71983330484f4f44494532)
is analysed and compared to the data stored on the NFC chip and thus verified. This verification is based on asymmetric key cryptography meaning a signature made during the minting process is verified with the key data sent within the encrypted data.
The data on the NFC chip is encrypted using symmetric encryption keys, which means there remains a shared secret between the Hoodie (more accurately the secret was available during the preparation of the NFC chip) and the validation service in the backend. Moreover, the NFC chip keeps track of a counter which is incremented with every readout/tapping of the tag and therefore allows the backend to check for so-called replay-attacks (as it can check if a given link has already been used).
The process is depicted in here:

tip
The process of flashing the NFC chips, which model we are using and some tools are available here: [Cardano Store POC Hoodies](https://github.com/cardano-foundation/cardano-store-poc-hoodies)
. An NFC reader/writer is required to write information on the chips.
All NFTs minted corresponding to the physical Hoodies can be found following this link to [pool.pm](https://pool.pm/policy/e886a328333c28bf3e8fc527206b02dc9ff65fb04cf569ec71983330)
or looking for the policy ID `e886a328333c28bf3e8fc527206b02dc9ff65fb04cf569ec71983330` (the hash of the minting policy script) in any other suitable [Explorer](https://developers.cardano.org/showcase?tags=explorer)
.
Future Work[](https://developers.cardano.org/docs/native-tokens/authenticated-products/#future-work "Direct link to Future Work")
-----------------------------------------------------------------------------------------------------------------------------------
The current solution is considered a POC because there are various areas of improvement left open. A major drawback is e.g. that the verification service itself is centrally hosted and the validation of the product’s authenticity cannot be completely done without that service. The NFTs bound to the Hoodies are based on the [CIP-25 NFT standard](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0025)
which lacks certain features of the more dynamic and versatile standard [CIP-68](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068)
. Defining a similar standard to [CIP-68](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068)
that leverages the same mechanisms but applying it to the asset ownership transfer challenge will ensure a secure and trustless transfer of ownership of the digital asset that is tied to the physical good. In that case users can own a token in their wallet, that points to the smart contract responsible for managing the actual ownership and only if a corresponding inline datum storing the list of actual owners points back to the asset, the ownership is considered valid.
The biggest improvement though would be the use of even more sophisticated [NFC chips](https://www.azuki.com/blog/pbt)
which allow for the signing of a presented payload leveraging asymmetric key cryptography which would enable a setup, where there is no shared secret between the customer owned physical goods and the centrally hosted backend. This solution would enable multi signature schemes when it comes to the transfer of ownership of the corresponding NFT.
* [Proof of Concept Hoodies](https://developers.cardano.org/docs/native-tokens/authenticated-products/#proof-of-concept-hoodies)
* [Future Work](https://developers.cardano.org/docs/native-tokens/authenticated-products/#future-work)
---
# Get Started with the Frankenwallet | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
An encrypted, air-gapped Linux bootable USB drive for Cardano (and other) secure operations[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#an-encrypted-air-gapped-linux-bootable-usb-drive-for-cardano-and-other-secure-operations "Direct link to An encrypted, air-gapped Linux bootable USB drive for Cardano (and other) secure operations")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Frankenwallet is not a package, library or product, but rather a set of installation guides, security standards and templates that allow Cardano SPOs, token minters, users with funds in bare addresses, and smart contract creators to configure an ordinary USB drive to boot Linux with a level of security isolation and software prerequisites appropriate to their use case.
When one's primary computer is booted from this removable drive, the secure ("cold") configuration & workflow conventions allow operators to:
* store and work securely and flexibly with private keys
* sign transactions and securely keep records of transaction details
* keep encrypted records & backups without ever revealing keys or passwords in the insecure host environment
warning - Linux veterans only
These instructions may be difficult or unsafe to follow unless you have experience with "dual boot" Linux installations and other custom OS & booting configurations.
Operators needing a safer path can follow instructions at the [Air Gap Environment](https://developers.cardano.org/docs/get-started/air-gap)
page.
### How to use this guide[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#how-to-use-this-guide "Direct link to How to use this guide")
This tool has been developed by the [COSD stake pool](https://cexplorer.io/pool/pool1e98xlcgj80c3rdmm27v5hnvrdtut52e65uk0ema7ctfag596vr2)
, beginning as a publication of their own operating environment when scared to death of losing their pool pledge and not being able to come by a second machine for the conventional [air gap environment](https://developers.cardano.org/docs/get-started/air-gap)
(see origin story: [Why was the Frankenwallet developed?](https://frankenwallet.com/intro/history)
).
At the time of this writing, the full instructions for:
* the reasons you would want to use this tool
* how to provision & build your own Frankenwallet
* how to use the tool for stake pool operations & secure transactions
… are in the online book at this external link: [The Frankenwallet](https://frankenwallet.com/)
. If you see any problems with this material, please submit an issue at:
* [github:rphair/frankenwallet](https://github.com/rphair/frankenwallet)
if you find an error in the material in the externally linked web site
* [github:cardano-foundation/developer-portal](https://github.com/cardano-foundation/developer-portal)
with any updates or corrections to this page itself.
This is a one-page summary of those external instructions to help you (the operator) decide if the Frankenwallet is something you might use in your workflow according to your own level of interest & expertise.
### Use cases for the Frankenwallet[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#use-cases-for-the-frankenwallet "Direct link to Use cases for the Frankenwallet")
➤ Anyone working with private keys & [secure transaction signing](https://developers.cardano.org/docs/get-started/secure-workflow)
, seed phrases, or other high value resources targeted by hackers (e.g., [stake pool keys](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs)
).
➤ Anyone wishing to work in high security with these resources without either a second computer (e.g. perpetual travellers, students, and hardware minimalists) or a hardware wallet ([Frankenwallet vs. Hardware wallets](https://frankenwallet.com/intro/hardware-wallets)
)
➤ Anyone wanting or needing direct access to all their own files on their main computer in the air-gapped environment.
➤ Anyone who has wondered how you might get the same (or better) features as a hardware wallet on an easily obtainable & anonymous USB drive: including a full featured operating system with applications that can edit encrypted and richly formatted files and prepare encrypted document archives.
➤ Anyone using memory sticks to store or back up private keys who has worried about an unencrypted memory stick being lost or stolen.
➤ Anyone wanting to prepare an off-site or even a network backup of their keys, wallet seed phrases, and other cryptocurrency asset records… given that AES based encryption is considered unbreakable when properly used (i.e. never entering the passphrase on a network-connected machine).
### If so universally useful, why the build instructions & not just a downloadable ISO image?[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#if-so-universally-useful-why-the-build-instructions--not-just-a-downloadable-iso-image "Direct link to If so universally useful, why the build instructions & not just a downloadable ISO image?")
**TL;DR** because then all Frankenwallets would be the same, and any security flaw found in one of them might allow all of them to be exploited before a response could be mounted (see [Why is there no ISO image for Frankenwallet?](https://frankenwallet.com/intro/no-iso)
).
### Some other use cases & limitations of this material[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#some-other-use-cases--limitations-of-this-material "Direct link to Some other use cases & limitations of this material")
➤ You _can_ use the Frankenwallet instructions to set up an Air Gap node on a full computer… but since the time of its development, this procedure has been adapted to a more appropriate page on the Dev Portal (the aforementioned [Air Gap Environment](https://developers.cardano.org/docs/get-started/air-gap)
).
From [Frankenwallet > Miscellaneous FAQ's](https://frankenwallet.com/intro/faq)
:
➤ Your VirtualBox or other VM software on your host computer _does not_ isolate you from the network, even if you have the network device disabled… nor can it be ever assumed that the screen or keyboard are isolated either… so VMs are generally unsuitable to create an air gap _or_ to implement these instructions.
➤ Ubuntu + GNOME, though heavyweight and tainted by default with proprietary software, are chosen for their universal documentation especially when it comes to issues of OS installation (_without_ that proprietary software!) and dual booting.
➤ Read more about the [Evil Maid](http://theinvisiblethings.blogspot.com/2009/01/why-do-i-miss-microsoft-bitlocker.html)
to see what she, he, or it can & cannot do with your Frankenwallet by compromising your host computer's BIOS in a way to which all commercial computers are vulnerable.
Preparing to build the Frankenwallet[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#preparing-to-build-the-frankenwallet "Direct link to Preparing to build the Frankenwallet")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
From [Frankenwallet > Preparation](https://frankenwallet.com/prepare)
:
#### Planning your communication with the host computer[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#planning-your-communication-with-the-host-computer "Direct link to Planning your communication with the host computer")
You will avoid moving files around on memory sticks _and_ transferring them over a network (impossible with Air Gap machines) because, when you boot from a USB device based operating system, the main disk on that computer is _also_ accessible as if _it_ were an external device.
Therefore you can plan an area on your host computer (called here the Host Folder) which the Frankenwallet will use to store any encrypted files… as well as read the raw data for the transactions that you will prepare in the air gapped environment.
warning
Remember early & often that nothing should be stored on the host computer that is not saved an encrypted document or archive.
### Procuring your hardware[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#procuring-your-hardware "Direct link to Procuring your hardware")
Though regularly used Frankenwallets have been built on cheap & slow USB drives, to make this tool a dependable part of your workflow you should get either:
* a memory stick with a high benchmark for reading and writing speed, or
* (for best results in author's experience) a SATA SSD drive plus a SATA-to-USB adapter cable.
Users who have built dual-boot configurations before will also know you should **familiarise yourself with the computer's BIOS settings** in anticipation of the same type of setup.
Note there are limitations about using a Mac as host computer which stem from the different means of booting (see [Frankenwallet > Hardware Requirements](https://frankenwallet.com/prepare/hardware)
> What if I have a Mac?).
### Choosing passwords[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#choosing-passwords "Direct link to Choosing passwords")
(from Frankenwallet passwords > [low security](https://frankenwallet.com/prepare/password-low)
& [high security](https://frankenwallet.com/prepare/password-high)
)
The [low security password](https://frankenwallet.com/prepare/password-low)
can be one you've already used to encrypt files on the host computer… strong enough you feel comfortable backing up files over the net.
The [high security password](https://frankenwallet.com/prepare/password-high)
… called the Frankenwallet password itself… should also be strictly long & complex, but should never have been used in a network environment, not even on a network connected machine… otherwise you will be defeating the purpose of using the Air Gap for any purposes of file storage or backup of files to the host computer
See each of these web links to see which of the Cardano asset & stake pool files it would typically be used to encrypt.
optional
If you intend to use the ["cool" Frankenwallet](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#the-cool-frankenwallet-a-sandbox-for-crypto-wallets)
configuration (supporting light browser-based wallets) with a Chrome-based browser like Brave, you should be ready with a second high-security password used only to encrypt your most confidential data… since by default you will have to enter the user account password in the browser UI to unlock the GNOME keyring and therefore expose it in an uncertain security context.
tip
For ease of use, you can separate the "low security" and "high security" stake pool files into two subdirectories, so they can be backed up as two separately password-encrypted archives.
Installing the OS onto the USB device[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#installing-the-os-onto-the-usb-device "Direct link to Installing the OS onto the USB device")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(from [Frankenwallet > Host computer & media](https://frankenwallet.com/prepare/computer)
though end of [Installation](https://frankenwallet.com/install)
section)
The full instructions mainly document the [installation of Ubuntu](https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview)
in the common "dual boot" configuration: something the target audience should feel comfortable with, and can probably improvise for themselves if also following these checklists during the installation & setup or the installed environment:
### Installation notes: software[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#installation-notes-software "Direct link to Installation notes: software")
No need to disconnect from the Internet yet because you will be using it to do your first package updates & software installation.
* Purists might want to do this without Internet access at all: if feeling comfortable with the baseline OS alone (no upgrades) + getting your packages by saving them in your computer's & installing them from there.
Select the Minimal software installation (no network hungry apps & games) and plan to install the LibreOffice package later.
Don't tick **third party hardware for graphics and WiFi** because the proprietary vendor software provided for these devices can contain institutional spyware.
### Installation notes: partitioning[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#installation-notes-partitioning "Direct link to Installation notes: partitioning")
When you select **erase disk and install Ubuntu** you will get the options under Advanced Features for:
* use LVM (the Logical Volume Manager), allowing more flexible disk usage
* select Encrypt the new Ubuntu Installation
* enter the "High Security" password you chose as the drive encryption password
Note the password you chose will be required now to boot the OS as well as decrypt the the partition it creates on any other devices (so your drive is secure when not booting).
warning
At the next screen Erase disk and install Ubuntu, watch out that you don't accidentally select your computer's own drive… this can be very easy to do!
### Setup notes: operating system[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#setup-notes-operating-system "Direct link to Setup notes: operating system")
* Don't let Ubuntu link with any online accounts in its initialisation process: refuse everything like location services, "livepatch", etc.
* Disable lots of little services & settings which might leak your information (see [Frankenwallet > First boot: Secure system settings](https://frankenwallet.com/install/settings)
)
### Setup notes: packages[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#setup-notes-packages "Direct link to Setup notes: packages")
(details: [Frankenwallet > First boot: Package installation](https://frankenwallet.com/install/packages)
)
* Remove all "snaps" and disable Snap.
* Remove CUPS (network printer service).
* Disable unattended upgrades.
* Upgrade the remainder of the system (`apt update; apt upgrade; apt autoremove`)
### Install document & security-oriented packages[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#install-document--security-oriented-packages "Direct link to Install document & security-oriented packages")
* `secure-delete` (in case you accidentally write unencrypted keys or secure data to your host computer drive)
* `LibreOffice` (supporting AES256 encrypted documents)
* `p7zip` (supporting AES256 encrypted archives)
### Tune browser & turn off network access FOREVER[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#tune-browser--turn-off-network-access-forever "Direct link to Tune browser & turn off network access FOREVER")
Lock down the browser settings, just in case, even if you think you'll never use it ([Frankenwallet > Securing Firefox browser](https://frankenwallet.com/install/browser)
)
At this point you disable Wi-Fi and all other networks in the system settings, and go on without any future connection to the Internet in your new environment.
What to use the Frankenwallet for[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#what-to-use-the-frankenwallet-for "Direct link to What to use the Frankenwallet for")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
From a growing body of material beginning at [Frankenwallet > Usage](https://frankenwallet.com/usage)
:
### Prepare and submit secure transactions[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#prepare-and-submit-secure-transactions "Direct link to Prepare and submit secure transactions")
You can now follow the instructions recommended in [Secure Transaction Workflow](https://developers.cardano.org/docs/get-started/secure-workflow)
, with the following modifications:
* Create a file on your networked host computer in the Host Folder, encrypted with the Low Security password (so you feel safe backing it up over the Internet, but won't store any keys or wallet passphrases there).
* When planning your transaction, save the transaction details and any commands to cut-and-paste, in this file.
* Boot into the Frankenwallet and navigate to your Host Folder.
* Copy-paste the transaction commands and/or transaction data into the Frankenwallet command line.
* Save the resulting transaction file to your Host Folder.
* Reboot into the host computer, upload your transaction file if necessary, and submit it.
This means of implementing the [Secure Transaction Workflow](https://developers.cardano.org/docs/get-started/secure-workflow)
process is outlined specifically in [Frankenwallet > Transaction flow](https://frankenwallet.com/cardano/model)
.
### Making & verifying backups of assets & keys[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#making--verifying-backups-of-assets--keys "Direct link to Making & verifying backups of assets & keys")
from [Frankenwallet > Backups to host machine](https://frankenwallet.com/usage/backups)
:
For [highly secure stake pool & asset files](https://frankenwallet.com/prepare/password-high)
, and any documents storing wallet key phrases or raw private key data:
* First create the file archive (with 7z) or text document (with LibreOffice) using your "high security" password.
* Then copy it to your host folder, where it can remain stored or backed up (over the network if desired) along with all your other computer's data.
* This is safe (pending the usual arguments) because **you never have entered, and never will enter, the Frankenwallet (high security) password on your host computer or any other machine**.
* This means you can only verify these backups on this or another Frankenwallet… never on the host computer environment itself!
For [less secure stake pool & asset files](https://frankenwallet.com/prepare/password-low)
, and documents with general transaction records & source data:
* First create the file archive (with 7z) or text document (with LibreOffice) using your "high security" password.
* These files you might feel comfortable verifying on your host computer.
* NOTE for less urgently secure stake pool pool files (e.g. verification keys, operational certificate counters) you might provide a second dedicated password… with "security level" between your general encryption password and the "high security" password… which you only use for the purposes of your assets & stake pool public keys.
### The "cool" Frankenwallet: a sandbox for crypto wallets[](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#the-cool-frankenwallet-a-sandbox-for-crypto-wallets "Direct link to The "cool" Frankenwallet: a sandbox for crypto wallets")
from [Frankenwallet > Cool environments](https://frankenwallet.com/cool)
:
Relaxing the Internet environment (meaning **this device should no longer be used for cold, unencrypted key storage**) allows you to use this device for node- or browser-based wallets.
Even low-bandwidth memory sticks have been tested in use with the resource intensive Daedalus node wallet, and they still work. But keep in mind that a node wallet will be considered very slow to sync… especially when your "daily driver" computer is booted from your Frankenwallet and can be used for no other purpose until booted normally again.
For browser-based wallets, the performance will be better… although the Firefox (or other browser) configuration becomes vital to avoid some institutional or extension spyware possibly compromising your keys.
In either case, you can still use the Frankenwallet to **copy the wallet key phrases to an encrypted file** on your host computer: so you can keep them encrypted with a password that has never been entered on your host machine.
Also keep in mind your security isolation can never be considered complete once you've allowed Internet connection from this "cool" environment… though this "sandbox" is still better than the complete exposure you'd have by running a node or browser based wallet on your network-connected, daily-use machine.
* [An encrypted, air-gapped Linux bootable USB drive for Cardano (and other) secure operations](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#an-encrypted-air-gapped-linux-bootable-usb-drive-for-cardano-and-other-secure-operations)
* [How to use this guide](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#how-to-use-this-guide)
* [Use cases for the Frankenwallet](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#use-cases-for-the-frankenwallet)
* [If so universally useful, why the build instructions & not just a downloadable ISO image?](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#if-so-universally-useful-why-the-build-instructions--not-just-a-downloadable-iso-image)
* [Some other use cases & limitations of this material](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#some-other-use-cases--limitations-of-this-material)
* [Preparing to build the Frankenwallet](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#preparing-to-build-the-frankenwallet)
* [Procuring your hardware](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#procuring-your-hardware)
* [Choosing passwords](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#choosing-passwords)
* [Installing the OS onto the USB device](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#installing-the-os-onto-the-usb-device)
* [Installation notes: software](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#installation-notes-software)
* [Installation notes: partitioning](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#installation-notes-partitioning)
* [Setup notes: operating system](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#setup-notes-operating-system)
* [Setup notes: packages](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#setup-notes-packages)
* [Install document & security-oriented packages](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#install-document--security-oriented-packages)
* [Tune browser & turn off network access FOREVER](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#tune-browser--turn-off-network-access-forever)
* [What to use the Frankenwallet for](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#what-to-use-the-frankenwallet-for)
* [Prepare and submit secure transactions](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#prepare-and-submit-secure-transactions)
* [Making & verifying backups of assets & keys](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#making--verifying-backups-of-assets--keys)
* [The "cool" Frankenwallet: a sandbox for crypto wallets](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet/#the-cool-frankenwallet-a-sandbox-for-crypto-wallets)
---
# Aiken | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/smart-contracts/aiken/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Introduction[](https://developers.cardano.org/docs/smart-contracts/aiken/#introduction "Direct link to Introduction")
-----------------------------------------------------------------------------------------------------------------------
[Aiken](https://github.com/aiken-lang/aiken)
is a new programming language and toolchain for developing smart contracts on the Cardano blockchain. It takes inspiration from many modern languages such as Gleam, Rust, and Elm which are known for friendly error messages and an overall excellent developer experience.
The language is exclusively used for creating the on-chain validator-scripts. You will need to write your off-chain code for generating transactions in another language such as Rust, Haskell, Javascript, Python etc.
caution
Aiken is a still a work in progress and is NOT recommended for use in production.
Getting started[](https://developers.cardano.org/docs/smart-contracts/aiken/#getting-started "Direct link to Getting started")
--------------------------------------------------------------------------------------------------------------------------------
Visit the [Get started with Aiken](https://developers.cardano.org/docs/get-started/aiken)
to install Aiken from Source or Nix Flakes.
A comprehensive guide for getting started with Aiken can be found on the [aiken-lang.org](https://aiken-lang.org/)
website. For more details about the project you might also want to visit the [Aiken git repository](https://github.com/aiken-lang/aiken)
.
### Example contract[](https://developers.cardano.org/docs/smart-contracts/aiken/#example-contract "Direct link to Example contract")
This is a basic validator written in Aiken
use aiken/hash.{Blake2b_224, Hash}use aiken/listuse aiken/stringuse aiken/transaction.{ScriptContext}use aiken/transaction/credential.{VerificationKey} pub type Datum { owner: Hash,} pub type Redeemer { msg: ByteArray,} pub fn spend(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool { let must_say_hello = string.from_bytearray(redeemer.msg) == "Hello, World!" let must_be_signed = list.has(context.transaction.extra_signatories, datum.owner) must_say_hello && must_be_signed}
### Testing[](https://developers.cardano.org/docs/smart-contracts/aiken/#testing "Direct link to Testing")
Tests can be created directly in Aiken and execute them on-the-fly using the "aiken check" command.
Below is an example of how such tests can be defined:
use aiken/interval.{Finite, Interval, IntervalBound, PositiveInfinity} test must_start_after_succeed_when_lower_bound_is_after() { let range: ValidityRange = Interval { lower_bound: IntervalBound { bound_type: Finite(2), is_inclusive: True }, upper_bound: IntervalBound { bound_type: PositiveInfinity, is_inclusive: False }, } must_start_after(range, 1)} test must_start_after_suceed_when_lower_bound_is_equal() { let range: ValidityRange = Interval { lower_bound: IntervalBound { bound_type: Finite(2), is_inclusive: True }, upper_bound: IntervalBound { bound_type: PositiveInfinity, is_inclusive: False }, } must_start_after(range, 2)} test must_start_after_fail_when_lower_bound_is_after() { let range: ValidityRange = Interval { lower_bound: IntervalBound { bound_type: Finite(2), is_inclusive: True }, upper_bound: IntervalBound { bound_type: PositiveInfinity, is_inclusive: False }, } !must_start_after(range, 3)}
Links[](https://developers.cardano.org/docs/smart-contracts/aiken/#links "Direct link to Links")
--------------------------------------------------------------------------------------------------
* [Aiken User-Manual](https://aiken-lang.org/)
* [Aiken Github Repository](https://github.com/aiken-lang/aiken)
.
* [Introduction](https://developers.cardano.org/docs/smart-contracts/aiken/#introduction)
* [Getting started](https://developers.cardano.org/docs/smart-contracts/aiken/#getting-started)
* [Example contract](https://developers.cardano.org/docs/smart-contracts/aiken/#example-contract)
* [Testing](https://developers.cardano.org/docs/smart-contracts/aiken/#testing)
* [Links](https://developers.cardano.org/docs/smart-contracts/aiken/#links)
---
# Topology | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-node/topology/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
The P2P topology file specifies how to obtain the _root peers_.
* The term _local roots_ refers to a group of peer nodes with which a node will aim to maintain a specific number of active or 'hot' connections. These hot connections play an active role in the consensus algorithm. Conversely, 'warm' connections refer to those not yet actively participating in the consensus algorithm. Local roots should comprise local relays, a local block-producing node, and any other peers with which the node needs to maintain a connection. These connections are typically kept private.
* _bootstrap peers_: trusted set of peers, only used for syncing. Optionally starting with `cardano-node-10.2`, the operator has the alternative to use Ouroboros Genesis instead.
* _public roots_: publicly known nodes (e.g. IOG relays or ledger nodes). They are either read from the configuration file directly or from the chain. The configured ones will be used to pass a recent snapshot of peers needed before the node caches up with the recent enough chain to construct root peers by itself.
Unlike local ones, the node does not guarantee a connection with every public root. However, by being present in the set, it gets an opportunity to establish an outbound connection with that peer.
A minimal version of this file looks like this:
{ "localRoots": [ { "accessPoints": [ { "address": "x.x.x.x", "port": 3001 } ], "advertise": false, "valency": 1, "warmValency": 2, "trustable": true, "diffusionMode": "InitiatorAndResponder" } ], "useLedgerAfterSlot": 128908821, "bootstrapPeers": [ { "address": "backbone.cardano.iog.io", "port": 3001 }, { "address": "backbone.mainnet.emurgornd.com", "port": 3001 }, { "address": "backbone.mainnet.cardanofoundation.org", "port": 3001 } ], "publicRoots": [ { "accessPoints": [ { "address": "y.y.y.y", "port": 3002 } ], "advertise": false } ] "peerSnapshotFile": "path/to/big-ledger-peer-snapshot.json"}
### Local Roots[](https://developers.cardano.org/docs/get-started/cardano-node/topology/#local-roots "Direct link to Local Roots")
* `LocalRoots` are designed for peers that the node **should always keep as hot or warm**, such as its own block producer or fulfill arranged agreements with other SPOs.
This means that your node will initiate contact with the node at IP `x.x.x.x` on `port 3001` and resolve the DNS domain `y.y.y.y` (provided it exists). It will then try to connect with at least one of the resolved IPs.
* `hotValency` tells the node the number of connections it should attempt to select from the specified group. When a DNS address is provided, valency determines the count of resolved IP addresses for which the node should maintain an active (hot) connection. Note: one can also use the deprecated now `valency` field for `hotValency`.
* `warmValency` is an optional field, similar to `hotValency`, that informs the node about the number of peers it should maintain as warm. This field is optional and defaults to the value set in the `valency` or `hotValency` field. If a value is specified for `warmValency`, it should be greater than or equal to the one defined in `hotValency`; otherwise, `hotValency` will be adjusted to match this value. We recommend that users set the `warmValency` value to `hotValency + 1` to ensure that at least one backup peer can be promoted to a hot connection in case of unexpected events. Check [this issue](https://github.com/intersectmbo/ouroboros-network/issues/4565)
for more context on this `WarmValency` option.
* The `diffusionMode` is an optional field available since `cardano-node-10.2`. It can either be `"InitiatorAndResponder"` (the default value) or `"InitiatorOnly"` (similar to `DiffusionMode` in the configuration file). If `"InitiatorOnly"` is set, then all local roots in this group will negotiate initiator-only diffusion mode, e.g. the TCP connection will be used as a unidirectional connection.
The topology setting overwrites `DiffusionMode` from the configuration file for given local root peers. It is meant to overwrite the diffusion mode when a node is running in `InitiatorAndResponder` mode (the default). The other way is also possible, but note that when the option in the configuration file is set to `InitiatorOnly`, the node will not run the accept loop.
* The `advertise` parameter instructs a node about the acceptability of sharing addresses through _peer sharing_ (which we'll explain in more detail in a subsequent section). If a node has activated peer sharing, it can receive requests from other nodes seeking peers. However, it will only disclose those peers for which it has both local and remote permissions.
Local permission corresponds to the value of the advertise parameter. On the other hand, 'remote permission' is tied to the `PeerSharing` value associated with the remote address, which is ascertained after the initial handshake between nodes.
* Local root groups shall be non-overlapping.
* Local roots should not be greater than the `TargetNumberOfKnownPeers`. If they are, they will get clamped to the limit.
* Read the next section for `trustablePeers` and `bootstrapPeers`.
Your **block-producing** node must **ONLY** talk to your **relay nodes**, and the relay node should talk to other relay nodes in the network.
You have the option to notify the node of any changes to the topology configuration file by sending a SIGHUP signal to the `cardano-node` process. This can be done, for example, with the command `pkill -HUP cardano-node`. Upon receiving the signal, the `cardano-node` will re-read the configuration file and restart all DNS resolutions.
Please be aware that this procedure is specific to the topology configuration file, not the node configuration file. Additionally, the SIGHUP signal will prompt the system to re-read the block forging credentials file paths and attempt to fetch them to initiate block forging. If this process fails, block forging will be disabled. To re-enable block forging, ensure that the necessary files are present.
### Ledger Peers / Public Roots & Big Ledger Peers[](https://developers.cardano.org/docs/get-started/cardano-node/topology/#ledger-peers--public-roots--big-ledger-peers "Direct link to Ledger Peers / Public Roots & Big Ledger Peers")
The option `useLedgerAfterSlot` configures from which slot the node should start to use peers registered on the ledger. Before the given slot, the node will use `PublicRoots`, unless `bootstrapPeers` are given (see below). If a negative value is specified a node will not use ledger peers. Ledger peers should be disabled for your block producing node.
Ledger peers are drawn from the ledger based on stake distribution. Big ledger peers is a similar notion. It is a subset of ledger peers which contains 90% of them with the largest stake.
`PublicRoots` serve as a source of fallback peers, which are used if we are before the configured `useLedgerAfterSlot` slot (please consider using `bootstrapPeers` instead or Genesis).
### Genesis lite a.k.a Bootstrap Peers[](https://developers.cardano.org/docs/get-started/cardano-node/topology/#genesis-lite-aka-bootstrap-peers "Direct link to Genesis lite a.k.a Bootstrap Peers")
Bootstrap Peers is an interim solution to facilitate syncing client nodes in a P2P environment from a pool of dedicated relays belonging to the original founding organizations of the Cardano blockchain. These relays have a priviledged trusted status within the ecosystem until full decentralization is achieved following a successful rollout of the Ouroboros Genesis protocol.
Bootstrap peers can be disabled by setting `bootstrapPeers: null`. They are enabled by providing a list of addresses. By default, bootstrap peers are disabled.
Trustable peers comprise the bootstrap peers (see `bootstrapPeers` option in the example topology file above) and the trustable local root peers (see `trustable` option in the example topology file above). By default, local root peers are not trustable.
For the node to be able to start and make progress when bootstrap peers are enabled, the user _must_ provide a trustable source of peers via a topology file. This means that the node will only start if either the bootstrap peers list is non-empty or there's a local root group that is trustable. Failing to configure the node with trustable peer sources will cause the node to crash with an exception. __Please note__ that if the only source of trustable peers is a DNS name, the node might be unable to make progress once in the fallback state if DNS is not providing any addresses.
With bootstrap peers enabled, the node will trace the following:
* `TraceLedgerStateJudgmentChanged {TooOld,YoungEnough}`: If it has changed to any of these states.
* `TooOld` state means that the information the node is getting from its peers is outdated and behind at least 20 min. This means there's something wrong, and the node should only connect to trusted peers (trusted peers are bootstrap peers and trustable local root peers) to sync.
* The `YoungEnough` state means the node is caught up and connects to non-trusted peers.
* `TraceOnlyBootstrap`: Once the node transitions to `TooOld,` the node will disconnect from all non-trusted peers and reconnect only to trusted ones in order to sync from trusted sources. This tracing message means that the node has successfully purged all non-trusted connections and is only going to connect to trusted peers.
### [Ouroboros Genesis](https://iohk.io/en/blog/posts/2024/05/08/ouroboros-genesis-design-update/)
[](https://developers.cardano.org/docs/get-started/cardano-node/topology/#ouroboros-genesis "Direct link to ouroboros-genesis")
Ouroboros Genesis is the upcoming consensus mechanism of trustless syncing in a meaningfully decentralized and permissionless P2P environment which is expected to supersede bootstrap peers described in the previous section. In general, it is the successor to Ouroboros Praos with which it is backwards compatible, and externally indistinguishable from in terms of behavior when the node is synced up (**WARNING**: a bug in Genesis as of the 10.2, 10.3, and 10.4 releases makes caught-up nodes susceptible to a kind of eclipse attack; intrepid users experimenting with Genesis should disable it and restart their node once it finishes syncing). Ouroboros Genesis is included as an experimental feature starting with `cardano-node 10.2`, and at the time of this writing it is disabled by default - refer to config.json file section below on instructions how to enable this by toggling a feature flag. Until Ouroboros Genesis is officially adopted by the community following a rollout period, one can configure the node to either use it or fall back on the bootstrap peers mechanism. However, if Genesis mode is enabled, it is incompatible with bootstrap peers and will disable the latter by overriding the configuration, and emit a trace of such occurrence to inform the operator to update the topology file. From the perspective of the topology file, a new entry must be added especially if a node is starting to sync from a blank or some arbitrary but significantly out-of-date state:
`"peerSnapshotFile": "path/to/snapshot.json"`
The file contains a snapshot of so-called big ledger peers which are the relays belonging to the largest pools, by staked ADA, registered on the ledger which cumulatively hold 90% of the total stake at some arbitrary slot number. By virtue of the value of their stake, indicating a level of vested interest in sustaining the network, they are postulated to be a proxy for honest ledger state and therefore moderate exposure to eclipse/sybil attacks. These stake pools need not be priviledged or authoritative in any sense beyond their total delegated stake, nor even necessarily be members of the founding entities. When syncing in this mode, these peers are sampled and connected with to jump-start the process. Such a snapshot file can be created manually apriori with cardano-cli from, ideally, a synced node, and may be signed and distributed with a node release in the future. Once provided, this file remains static while a node is running. The relevant cli command to manually generate a snapshot is `cardano-cli query ledger-peer-snapshot --out-file *arbitrary-file-name*`. Finally, the node will ignore this file if it's own ledger state is more recent and hence it is not strictly necessary for ongoing operation. It is however recommended to periodically update the snapshot, manually or from a latest release, as part of regular maintenance schedule.
### Configuring the node to use P2P[](https://developers.cardano.org/docs/get-started/cardano-node/topology/#configuring-the-node-to-use-p2p "Direct link to Configuring the node to use P2P")
The `cardano-node`'s P2P configuration has a variety of options relating to how many connections are to be initiated, and conversely how many incoming connections can be accepted and it is vital to understand what this actually means in practice to operate a well-configured stake pool, but the provided defaults described below do provide a sensible starting point. The smallest practical network in principle is that between two hosts, and if drawn on paper, the two nodes as points, as a simplification the link between them can be viewed as a single concept when considering the network as a whole. However, to understand the P2P network at a lower level that is useful to us as relay operators, it is crucial to be aware that logically a connection should be split into a pair - its outbound and inbound legs - from _each_ peer to the other most generally. An outbound from a peer/node/host is the inbound as seen from the other side, and vice versa. At any time, a node can maintain an outbound connection to its upstream peer that is not reciprocated. In such situation, the node initiating the outbound connection is the initiator, and it's upstream node is the responder. Even though the underlying TCP bearer supports bidirectional communication, in this scenario the logical communication is inherently one way where the initiator typically queries the responder, whom provides the requested information. At any time, the responder can decide to initiate its own outbound connection back to its previously downstream-only client, and in this case each one runs its initiator and responder mechanisms independently over a single channel/TCP bearer to conserve system resources. The queries from the initiator of one are served by the responder of the other side - but each side can now query the other at its own pace to get the information it wants. Furthermore in this duplex state, the original initiator can at any time decide to close its outbound leg to the other side, at which point it is now the original responder side that is merely in initiator-only mode, and the original initiator is just the responder. It is only when neither side wants to maintain an initiator/outbound leg to the other for querying that the connection is torn down and system resources are released.
You can enable P2P from the configuration file; the field `EnableP2P` can be set to either `false` or `true`. When setting it to `true`, you will also need to configure the target number of _active_, _established_ and _known_ peers, together with the target number of _root_ peers. These values control the number of outbound/initiator connections the node will try to maintain in the appropriate mode to what are collectively named our upstream peers. This is important for the node as blocks are downloaded strictly from these peers and we want to maintain sufficiently many outbound connections to both:
* ensure we remain on the current network blockchain tip in a timely fashion to avoid short forks causing height battles and potentially losing rewards
* to harden ourselves from potential eclipse attacks in the presence of adversarial actors and adopting their dishonest chain These network delays and timeliness issues arise naturally due to traffic congestion and physical limits and so all the node can do is provide mechanisms to manage them.
Importantly, blocks that the node is itself serving on demand, which we ourselves have minted or are ones we relay from _our_ upstream peers, or the transactions it is requesting are determined by its downstream clients on which these peer target values have no bearing on. There isn't any fine-grained way to control theses connection modes for our incoming downstream/client peers, ie. the nodes that have our node as its upstream/responder peer. It is these clients that decide for themselves if our node is either in established or active mode from their initiator perspective, but this does also impact on our resource usage, such as processor utilization, bandwidth consumption, memory footprint, or file descriptor usage. The last item is subtle and easy to overlook - the cardano-node implementation is carefully designed around minimizing file descriptor usage, but it is a limited global resource which other unrelated processes running on the host consume. Running out of file descriptors may make the node unresponsive and essentially appear stuck, requiring a manual intervention. Regardless, these are general points that apply to all software applications, and in particular to this or other blockchain node implementations.
That said, there are global configurable connection limits which govern in the aggregate how many peers we are connected with before we start refusing any more connections to avoid overloading and impairing our performance. Some careful consideration must be given prior to lowering this limit manually when a particular performance metric is a concern, as at some point at the other extreme our block propagation times will suffer, which is a crucial characteristic when engaging in block production. In other words, to reap rewards, we want to have a good variety of these downstream peers dispersed around the globe such that our blocks propagate quickly to and via them such that they are adopted by the whole network as fast as possible. Furthermore, exhausting the connection limit prematurely may prevent our own tooling from connecting with the node. We of course cannot force any arbitrary downstream peers on the network to initiate their outbound leg to us (ie. have them treat our node as its responder/upstream) to improve our block propagation situation, but we can help nudge the odds in our favor by selectively adding a few other relays from around the globe as our local root peers. If our relays are registered on the ledger the effect will be similar. These peer nodes, following accepting our outbound connection to them, may in turn decide, somewhat randomly, to try to establish a connection back to us (ie. the channel is ran in initiator/responder duplex mode for bidirectional queries and responses), and if link performance is satisfactory from their perspective such that _their_ outbound connection is maintained with us over the long term, _our_ block propagation time is expected to improve/decrease. Another good option is to reach out to some other pool operators directly, especially when operating in sparser regions such as South America or Asia Pacific and maintain a reciprocal local root connection to each other's public relays defined in the respective topology files. Such arrangements do not adversely impact blockchain security or our own perceived anonymity/independence if these acquaintances are _**not**_ marked as trustable in the topology file configuration, which is a default, and in general are mutually beneficial if uptime and bandwidth are similar, or help each other's block propagation times, as well as healthy for the network as a whole if partitions were to occur by external commission, omission, or unfortunate accident outside our control.
In summary, as node operators we can specify the maximum overall number of connections we can maintain with our peers, some of which are outbound, others inbound and some of which are both. We only have a fine-grained means of controlling the number of our outbound connections to various types of peer and the mode in which they should operate. There are good reasons why the configuration is as such which is outside of the scope of this guide, but suffice to say that the complexity is not accidental but is necessary for flexibility and meeting design intent of Praos consensus protocol security guarantees which critically rely on timeliness of network communication.
The default configuration values are:
{ ... "EnableP2P": true, "TargetNumberOfRootPeers": 60, "TargetNumberOfActivePeers": 15, "TargetNumberOfEstablishedPeers": 40, "TargetNumberOfKnownPeers": 85, "TargetNumberOfActiveBigLedgerPeers": 5, "TargetNumberOfEstablishedBigLedgerPeers": 10, "TargetNumberOfKnownBigLedgerPeers": 15,}
Collectively, these are known as the deadline targets. Prior to Ouroboros Genesis, this was the only set of static P2P targets available to the node. When Genesis mode is enabled in the configuration file, these deadline targets are in effect strictly when the node deems itself caught up to its upstream peers, and the network is awaiting for the next block to be produced and diffused.
* `TargetNumberOfActivePeers` - the target for active ledger peers (aka hot peers); includes: local roots, ledger peers / public roots, peers from peer-sharing; excludes: big ledger peers. This ordinarily should be least the number of local root peers that are specified as hot in the topology file, otherwise the number of these connections will be clamped below the expected number. However, it is not strictly a misconfiguration and the node will run in such configuration.
* `TargetNumberOfEstablishedPeers` - the target for established connections (the sum of warm & hot peers); includes: local roots roots, ledger peers / public roots, peers from peer-sharing; excludes big ledger peers. Same note as for active peers above applied here as well.
* `TargetNumberOfKnownPeers` - the target for known peers (the sum of cold, warm & hot); includes: local roots, ledger peers / public roots, peers from peer-sharing; excludes big ledger peers.
* `TargetNumberOfActiveBigLedgerPeers` - the target for active big ledger peers (aka hot big ledger peers).
* `TargetNumberOfEstablishedBigLedgerPeers` - the target for established connections with big ledger peers (the sum of warm & hot big ledger peers).
* `TargetNumberOfKnownBigLedgerPeers` - the target for known big ledger peers (the sum of cold, warm & hot big ledger peers).
* `TargetNumberOfRootPeers` - a lower limit for known local roots, ledger peers / public root peers. Anything beyond this target will be filled by peers from peer sharing, ledger / public root peers.
Note, when using bootstrap-peers, feature the targets have to be large enough to accommodate all bootstrap peers.
**Custom targets must satisfy the property that # of known >= # of established >= # of active >= 0 otherwise the node will fail to start as it is a serious misconfiguration.**
#### Ouroboros Genesis protocol's network specific configuration[](https://developers.cardano.org/docs/get-started/cardano-node/topology/#ouroboros-genesis-protocols-network-specific-configuration "Direct link to Ouroboros Genesis protocol's network specific configuration")
Ouroboros Genesis is disabled by default at the time of this writing. To enable it, the node configuration file must contain
* `"ConsensusMode": "GenesisMode"` or the argument `--ConsensusMode GenesisMode` must be given on command line or script when starting up the node process.
Detailed configuration settings for Ouroboros Genesis are beyond the scope of this article; however, sensible defaults are provided and below we document the relevant networking options. These options are available since `cardano-node-10.2` and by default their values are as shown below:
{ "SyncTargetNumberOfActivePeers": 0, "SyncTargetNumberOfActiveBigLedgerPeers": 30, "SyncTargetNumberOfEstablishedBigLedgerPeers": 50, "SyncTargetNumberOfKnownBigLedgerPeers": 100, "MinBigLedgerPeersForTrustedState": 5}
Collectively, these are known as the sync targets and they are in effect automatically when the node's consensus module detects that the local ledger state is out of date vis-à-vis our upstream peers. The node then proceeds to download _and validate_ blocks in bulk from some of its upstream active peers to catch up as soon as possible. As long as there is at least one honest active peer in this set, which need not be the same one(s) for the duration of the process, the Ouroboros Genesis protocol ensures that our node will successfully complete with the honest ledger state. It is important for this reason that the `SyncTargetNumberOfActiveBigLedgerPeers` is not a 'small' number. Optionally, the `SyncTargetNumberOfActivePeers` can be set such that outbound connections are also opened up to local root peers, if defined, as well as other public relays or nodes we learn about via peer sharing, if enabled. Care must be taken to ensure that these sync targets _by themselves_ satisfy the inequality constraints given in the prior section, or the node will fail to start with an appropriate error message. Additionally, this latter option must not exceed `TargetNumberOfEstablishedPeers` from the _deadline_ configuration set as the sole exception. Once sufficiently many blocks have been adopted and the node deems itself caught up again, the number of outbound connections will revert to the deadline set described in the previous section. If at any time during the syncing process the number of hot connections to big ledger peers drops below `MinBigLedgerPeersForTrustedState` value (which must not exceed the `SyncTargetNumberOfActivePeers` for obvious reasons), the node will pause and await until sufficiently many active outbound connections are online. This is only but one of the many safeguards in Ouroboros Genesis protocol to avoid adopting a dishonest chain during the syncing process. The blog post link in a prior section heading provides an approachable but technical deep dive for the curious operator or end user.
* [Local Roots](https://developers.cardano.org/docs/get-started/cardano-node/topology/#local-roots)
* [Ledger Peers / Public Roots & Big Ledger Peers](https://developers.cardano.org/docs/get-started/cardano-node/topology/#ledger-peers--public-roots--big-ledger-peers)
* [Genesis lite a.k.a Bootstrap Peers](https://developers.cardano.org/docs/get-started/cardano-node/topology/#genesis-lite-aka-bootstrap-peers)
* [Ouroboros Genesis](https://developers.cardano.org/docs/get-started/cardano-node/topology/#ouroboros-genesis)
* [Configuring the node to use P2P](https://developers.cardano.org/docs/get-started/cardano-node/topology/#configuring-the-node-to-use-p2p)
---
# Get Started with Guild Operators Tools | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Guild Operators Suite[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#guild-operators-suite "Direct link to Guild Operators Suite")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
The Guild-Operators suite is a set of tools and scripts for setting up, managing, and monitoring Cardano stake pools, as well as managing tokens and keys. It's the outcome of a community collaborative effort by long-time active community members to make common chores for operators easier. We'll try to provide a fast run-through of the tools involved and a high-level overview of procedures to get you started since complete documentation for the suite is hosted [here](https://cardano-community.github.io/guild-operators)
.
### Tools[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#tools "Direct link to Tools")
#### CNTools[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#cntools "Direct link to CNTools")
CNTools is a swiss army knife for pool operators who want to make routine tasks easier. It's a menu-driven bash GUI application for creating and managing wallets, sending ada and tokens, and just about any pool function. In addition, the tool has been enhanced with new features and improvements since its initial release in July 2020, coinciding with the introduction of the Cardano Shelley MainNet. More information regarding CNTools can be found [here](https://cardano-community.github.io/guild-operators/Scripts/cntools/)
.

#### gLiveView[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#gliveview "Direct link to gLiveView")
Guild LiveView, often known as gLiveView, is a local bash CLI monitoring utility with an easy-to-use interface for monitoring node status. It connects to the locally running node via the specified EKG/Prometheus node endpoints to collect and show node metrics, network information, and other information in real time. The program recognizes whether the node is being used as a relay or a block producer and adjusts the output accordingly. More information regarding gLiveView can be found [here](https://cardano-community.github.io/guild-operators/Scripts/gliveview/)
.

#### Topology Updater[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#topology-updater "Direct link to Topology Updater")
Topology Updater was built as a workaround to allow stake pool relays to auto-discover and pair with peers on the network. While P2P implementation was put on hold owing to other priorities, this script has become one of the most important tools for avoiding having to manually contact friends and request that individual nodes be included to topology files. More information about the tool may be found [here](https://cardano-community.github.io/guild-operators/Scripts/topologyupdater/)
.

#### Guild Network and Support for other networks[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#guild-network-and-support-for-other-networks "Direct link to Guild Network and Support for other networks")
Guild Network is a brief (60-minute epoch) network that functions similarly to the Cardano testnets but is entirely governed by the community. It's excellent for experimenting with things in the sandbox, as well as testing out viable features before releasing them to other networks. This network is already supported by all of the tools in the repo, including Mainnet, testnets, and staging.
#### Others..[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#others "Direct link to Others..")
Other utility scripts on a lesser scale include creating core components from source for particular components, setting up environment pre-requisites, and so on. Starting here, you can read about specifics as you go across the homepage [here](https://cardano-community.github.io/guild-operators)
.
note
Please ensure to read the disclaimers on guild website before continuing
### Setting Up Pre-Requisites..[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#setting-up-pre-requisites "Direct link to Setting Up Pre-Requisites..")
For installing OS Packages, dependencies, setting up a [sample directory structure](https://cardano-community.github.io/guild-operators/basics/#folder-structure)
used as an example template input (customisable) for guild tools, fetching of configuration, genesis artifacts, downloading tool scripts, etc , you can use the commands below. The script does have quite a few options (you can use `-h` to check any optional components/arguments you'd want to include).
mkdir "$HOME/tmp";cd "$HOME/tmp"curl -sS -o guild-deploy.sh https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/guild-deploy.shchmod 755 guild-deploy.sh./guild-deploy.sh -b master -n mainnet -s pdl. "$HOME"/.bashrc
note
`-s pdl`
installs (p)rerequisites for the operating system, (d)ownloads the precompiled binaries and also compiles and installs the IOG fork of (l)ibsodium.
consider guild-deploy.sh --help for options when you update the system or want to install additional modules
### Build of Node/DBSync components[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#build-of-nodedbsync-components "Direct link to Build of Node/DBSync components")
We assume you'd have already seen the guide [here](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
. There are similar build scripts/instructions available for building different cardano-node, cardano-db-sync, offline-metadata-tools and setting up postgres+postgREST with dbsync) on guild documentations. You can navigate instructions for each of them [here](https://cardano-community.github.io/guild-operators/build/)
. The instructions will also deploy these as a systemd service, which is recommended to avoid manually managing services.
### Customise configuration[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#customise-configuration "Direct link to Customise configuration")
Now that you've set-up your OS dependencies and built/installed node binaries, it's time for you to customise your configuration, paths, names, etc for your node. You can use [env](https://cardano-community.github.io/guild-operators/Scripts/env/)
file to modify these. Each line contains default value, and a simple explanation about what variable means.
### Contributions/Feedback..[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#contributionsfeedback "Direct link to Contributions/Feedback..")
Issue/PRs are welcome on the [github repository](https://github.com/cardano-community/guild-operators)
.
### Support Requests[](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#support-requests "Direct link to Support Requests")
We do have the [Koios Discussions telegram channel for support requests](https://t.me/CardanoKoios/1)
, but note that we intend to have support channel only for baseline skillset highlighted on [homepage](https://cardano-community.github.io/guild-operators)
.
* [Guild Operators Suite](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#guild-operators-suite)
* [Tools](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#tools)
* [Setting Up Pre-Requisites..](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#setting-up-pre-requisites)
* [Build of Node/DBSync components](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#build-of-nodedbsync-components)
* [Customise configuration](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#customise-configuration)
* [Contributions/Feedback..](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#contributionsfeedback)
* [Support Requests](https://developers.cardano.org/docs/operate-a-stake-pool/guild-ops-suite/#support-requests)
---
# Listening for ada payments using cardano-cli | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Overview[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#overview "Direct link to Overview")
----------------------------------------------------------------------------------------------------------------------------------
note
This guide assumes that you have basic understanding of `cardano-cli`, how to use it and that you have installed it into your system. Otherwise we recommend reading [Installing cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/installing-cardano-node)
, [Running cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano)
and [Exploring Cardano Wallets](https://developers.cardano.org/docs/integrate-cardano/creating-wallet-faucet)
guides first.
This guide also assumes that you have `cardano-node` running in the background and connected to a [testnet network](https://developers.cardano.org/docs/get-started/testnets-and-devnets)
.
Use case[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#use-case "Direct link to Use case")
----------------------------------------------------------------------------------------------------------------------------------
There are many possible reasons why you would want to have the functionality of listening for `ada` payments, but a very obvious use case would be for something like an **online shop** or a **payment gateway** that uses `ada` tokens as the currency.

Technical flow[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#technical-flow "Direct link to Technical flow")
----------------------------------------------------------------------------------------------------------------------------------------------------
To understand how something like this could work in a technical point of view, let's take a look at the following diagram:

So let's imagine a very basic scenario where a **customer** is browsing an online shop. Once the user has chosen and added all the items into the **shopping cart**, the next step would then be to checkout and pay for the items. Of course we will be using **Cardano** for that!
The **front-end** application would then request for a **wallet address** from the backend service and render a QR code to the **customer** to be scanned via a **Cardano wallet**. The backend service would then know that it has to query the **wallet address** using `cardano-cli` with a certain time interval to confirm and alert the **front-end** application that the payment has completed successfully.
In the meantime the transaction is then being processed and settled within the **Cardano** network. We can see in the diagram above that both parties are ultimately connected to the network via the `cardano-node` software component.
Time to code[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#time-to-code "Direct link to Time to code")
----------------------------------------------------------------------------------------------------------------------------------------------
Now let's get our hands dirty and see how we can implement something like this in actual code.
note
In this section, we will use the path `$HOME/receive-ada-sample` to store all the related files as an example, please replace it with the directory you have chosen to store the files. All the code examples in this article assume that you will save all the source-code-files under the root of this directory.
### Generate keys and request tAda[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#generate-keys-and-request-tada "Direct link to Generate keys and request tAda")
First, let's create a directory to store our sample project:
mkdir -p $HOME/receive-ada-sample/keys
Next, we generate our **payment key-pair** using `cardano-cli`:
cardano-cli address key-gen \--verification-key-file $HOME/receive-ada-sample/keys/payment.vkey \--signing-key-file $HOME/receive-ada-sample/keys/payment.skey
Since we now have our **payment key-pair**, the next step would be to generate a **wallet address** for a testnet network like so:
cardano-cli address build \--payment-verification-key-file $HOME/receive-ada-sample/keys/payment.vkey \--out-file $HOME/receive-ada-sample/keys/payment.addr \--testnet-magic 1097911063
Your directory structure should now look like this:
$HOME/receive-ada-sample/receive-ada-sample└── keys ├── payment.addr ├── payment.skey └── payment.vkey
Now using your **programming language** of choice we create our first few lines of code!
### Initial variables[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#initial-variables "Direct link to Initial variables")
First we will set the initial variables that we will be using as explained below:
* JavaScript
* Typescript
* Python
* C#
checkPayment.js
import * as fs from 'fs';// Please add this dependency using npm install node-cmdimport cmd from 'node-cmd';// Path to the cardano-cli binary or use the global oneconst CARDANO_CLI_PATH = "cardano-cli";// The testnet identifier numberconst CARDANO_NETWORK_MAGIC = 1097911063;// The directory where we store our payment keys// assuming our current directory context is $HOME/receive-ada-sampleconst CARDANO_KEYS_DIR = "keys";// The total payment we expect in lovelace unitconst TOTAL_EXPECTED_LOVELACE = 1000000;
checkPayment.ts
import * as fs from 'fs';// Please add this dependency using npm install node-cmd but there is no @type definition for itconst cmd: any = require('node-cmd');// Path to the cardano-cli binary or use the global oneconst CARDANO_CLI_PATH: string = "cardano-cli";// The testnet identifier numberconst CARDANO_NETWORK_MAGIC: number = 1097911063;// The directory where we store our payment keys// assuming our current directory context is $HOME/receive-ada-sample/receive-ada-sampleconst CARDANO_KEYS_DIR: string = "keys";// The total payment we expect in lovelace unitconst TOTAL_EXPECTED_LOVELACE: number = 1000000;
checkPayment.py
import osimport subprocess# Path to the cardano-cli binary or use the global oneCARDANO_CLI_PATH = "cardano-cli"# The testnet identifier numberCARDANO_NETWORK_MAGIC = 1097911063# The directory where we store our payment keys# assuming our current directory context is $HOME/receive-ada-sampleCARDANO_KEYS_DIR = "keys"# The total payment we expect in lovelace unitTOTAL_EXPECTED_LOVELACE = 1000000
Program.cs
using System.Linq;using SimpleExec; // `dotnet add package SimpleExec --version 7.0.0`// Path to the cardano-cli binary or use the global oneconst string CARDANO_CLI_PATH = "cardano-cli";// The testnet identifier numberconst int CARDANO_NETWORK_MAGIC = 1097911063;// The directory where we store our payment keys// assuming our current directory context is $HOME/user/receive-ada-sampleconst string CARDANO_KEYS_DIR = "keys";// The total payment we expect in lovelace unitconst long TOTAL_EXPECTED_LOVELACE = 1000000;
### Read wallet address value[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#read-wallet-address-value "Direct link to Read wallet address value")
Next, we get the string value of the **wallet address** from the `payment.addr` file that we generated awhile ago. Add the following lines to your code:
* JavaScript
* Typescript
* Python
* C#
checkPayment.js
// Read wallet address value from payment.addr fileconst walletAddress = fs.readFileSync(`${CARDANO_KEYS_DIR}/payment.addr`).toString();
checkPayment.ts
// Read wallet address string value from payment.addr fileconst walletAddress: string = fs.readFileSync(`${CARDANO_KEYS_DIR}/payment.addr`).toString();
checkPayment.py
# Read wallet address value from payment.addr filewith open(os.path.join(CARDANO_KEYS_DIR, "payment.addr"), 'r') as file: walletAddress = file.read()
Program.cs
// Read wallet address value from payment.addr filevar walletAddress = await System.IO.File.ReadAllTextAsync($"{CARDANO_KEYS_DIR}/payment1.addr");
### Query UTxO[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#query-utxo "Direct link to Query UTxO")
Then we execute `cardano-cli` programmatically and telling it to query the **UTxO** for the **wallet address** that we have generated with our keys and save the `stdout` result to our `rawUtxoTable` variable.
* JavaScript
* Typescript
* Python
* C#
checkPayment.js
// We use the node-cmd npm library to execute shell commands and read the output dataconst rawUtxoTable = cmd.runSync([ CARDANO_CLI_PATH, "query", "utxo", "--testnet-magic", CARDANO_NETWORK_MAGIC, "--address", walletAddress].join(" "));
checkPayment.ts
// We use the node-cmd npm library to execute shell commands and read the output dataconst rawUtxoTable: any = cmd.runSync([ CARDANO_CLI_PATH, "query", "utxo", "--testnet-magic", CARDANO_NETWORK_MAGIC, "--address", walletAddress].join(" "));
checkPayment.py
# We tell python to execute cardano-cli shell command to query the UTXO and read the output datarawUtxoTable = subprocess.check_output([ CARDANO_CLI_PATH, 'query', 'utxo', '--testnet-magic', str(CARDANO_NETWORK_MAGIC), '--address', walletAddress])
Program.cs
// We use the SimpleExec dotnet library to execute shell commands and read the output datavar rawUtxoTable = await Command.ReadAsync(CARDANO_CLI_PATH, string.Join(" ", "query", "utxo", "--testnet-magic", CARDANO_NETWORK_MAGIC, "--address", walletAddress), noEcho: true);
### Process UTxO table[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#process-utxo-table "Direct link to Process UTxO table")
Once we have access to the **UTXO** table string, we will then parse it and compute the total lovelace that the wallet currently has.
* JavaScript
* Typescript
* Python
* C#
checkPayment.js
// Calculate total lovelace of the UTXO(s) inside the wallet addressconst utxoTableRows = rawUtxoTable.data.trim().split('\n');let totalLovelaceRecv = 0;let isPaymentComplete = false;for (let x = 2; x < utxoTableRows.length; x++) { const cells = utxoTableRows[x].split(" ").filter(i => i); totalLovelaceRecv += parseInt(cells[2]);}
checkPayment.ts
// Calculate total lovelace of the UTXO(s) inside the wallet addressconst utxoTableRows: string[] = rawUtxoTable.data.trim().split('\n');let totalLovelaceRecv: number = 0;let isPaymentComplete: boolean = false;for (let x = 2; x < utxoTableRows.length; x++) { const cells = utxoTableRows[x].split(" ").filter((i: string) => i); totalLovelaceRecv += parseInt(cells[2]);}
checkPayment.py
# Calculate total lovelace of the UTXO(s) inside the wallet addressutxoTableRows = rawUtxoTable.strip().splitlines()totalLovelaceRecv = 0isPaymentComplete = Falsefor x in range(2, len(utxoTableRows)): cells = utxoTableRows[x].split() totalLovelaceRecv += int(cells[2])
Program.cs
// Calculate total lovelace of the UTXO(s) inside the wallet addressvar utxoTableRows = rawUtxoTable.Trim().Split("\n");var totalLovelaceRecv = 0L;var isPaymentComplete = false;foreach(var row in utxoTableRows.Skip(2)){ var cells = row.Split(" ").Where(c => c.Trim() != string.Empty); totalLovelaceRecv += long.Parse(cells.ElementAt(2));}
### Determine if payment is successful[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#determine-if-payment-is-successful "Direct link to Determine if payment is successful")
Once we have the total lovelace amount, we will then determine using our code if a specific payment is a success, ultimately sending or shipping the item if it is indeed successful. In our example, we expect that the payment is equal to `1,000,000 lovelace` that we defined in our `TOTAL_EXPECTED_LOVELACE` constant variable.
* JavaScript
* Typescript
* Python
* C#
checkPayment.js
// Determine if the total lovelace received is more than or equal to// the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACE;console.log(`Total Received: ${totalLovelaceRecv} LOVELACE`);console.log(`Expected Payment: ${TOTAL_EXPECTED_LOVELACE} LOVELACE`);console.log(`Payment Complete: ${(isPaymentComplete ? "✅" : "❌")}`);
checkPayment.ts
// Determine if the total lovelace received is more than or equal to// the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACE;console.log(`Total Received: ${totalLovelaceRecv} LOVELACE`);console.log(`Expected Payment: ${TOTAL_EXPECTED_LOVELACE} LOVELACE`);console.log(`Payment Complete: ${(isPaymentComplete ? "✅" : "❌")}`);
checkPayment.py
# Determine if the total lovelace received is more than or equal to# the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACEprint("Total Received: %s LOVELACE" % totalLovelaceRecv)print("Expected Payment: %s LOVELACE" % TOTAL_EXPECTED_LOVELACE)print("Payment Complete: %s" % {True: "✅", False: "❌"} [isPaymentComplete])
Program.cs
// Determine if the total lovelace received is more than or equal to// the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACE;System.Console.WriteLine($"Total Received: {totalLovelaceRecv} LOVELACE");System.Console.WriteLine($"Expected Payment: {TOTAL_EXPECTED_LOVELACE} LOVELACE");System.Console.WriteLine($"Payment Complete: {(isPaymentComplete ? "✅":"❌")}");
Running and testing[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#running-and-testing "Direct link to Running and testing")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Our final code should look something like this:
* JavaScript
* Typescript
* Python
* C#
checkPayment.js
import * as fs from 'fs';// Please add this dependency using npm install node-cmdimport cmd from 'node-cmd';// Path to the cardano-cli binary or use the global oneconst CARDANO_CLI_PATH = "cardano-cli";// The `testnet` identifier numberconst CARDANO_NETWORK_MAGIC = 1097911063;// The directory where we store our payment keys// assuming our current directory context is $HOME/receive-ada-sample/receive-ada-sampleconst CARDANO_KEYS_DIR = "keys";// The imaginary total payment we expect in lovelace unitconst TOTAL_EXPECTED_LOVELACE = 1000000;// Read wallet address string value from payment.addr fileconst walletAddress = fs.readFileSync(`${CARDANO_KEYS_DIR}/payment.addr`).toString();// We use the node-cmd npm library to execute shell commands and read the output dataconst rawUtxoTable = cmd.runSync([ CARDANO_CLI_PATH, "query", "utxo", "--testnet-magic", CARDANO_NETWORK_MAGIC, "--address", walletAddress].join(" "));// Calculate total lovelace of the UTXO(s) inside the wallet addressconst utxoTableRows = rawUtxoTable.data.trim().split('\n');let totalLovelaceRecv = 0;let isPaymentComplete = false;for(let x = 2; x < utxoTableRows.length; x++) { const cells = utxoTableRows[x].split(" ").filter(i => i); totalLovelaceRecv += parseInt(cells[2]);}// Determine if the total lovelace received is more than or equal to// the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACE;console.log(`Total Received: ${totalLovelaceRecv} LOVELACE`);console.log(`Expected Payment: ${TOTAL_EXPECTED_LOVELACE} LOVELACE`);console.log(`Payment Complete: ${(isPaymentComplete ? "✅" : "❌")}`);
checkPayment.ts
import * as fs from 'fs';// Please add this dependency using npm install node-cmd but there is no @type definition for itconst cmd: any = require('node-cmd');// Path to the cardano-cli binary or use the global oneconst CARDANO_CLI_PATH: string = "cardano-cli";// The testnet identifier numberconst CARDANO_NETWORK_MAGIC: number = 1097911063;// The directory where we store our payment keys// assuming our current directory context is $HOME/receive-ada-sample/receive-ada-sampleconst CARDANO_KEYS_DIR: string = "keys";// The imaginary total payment we expect in lovelace unitconst TOTAL_EXPECTED_LOVELACE: number = 1000000;// Read wallet address string value from payment.addr fileconst walletAddress: string = fs.readFileSync(`${CARDANO_KEYS_DIR}/payment.addr`).toString();// We use the node-cmd npm library to execute shell commands and read the output dataconst rawUtxoTable: any = cmd.runSync([ CARDANO_CLI_PATH, "query", "utxo", "--testnet-magic", CARDANO_NETWORK_MAGIC, "--address", walletAddress].join(" "));// Calculate total lovelace of the UTXO(s) inside the wallet addressconst utxoTableRows: string[] = rawUtxoTable.data.trim().split('\n');let totalLovelaceRecv: number = 0;let isPaymentComplete: boolean = false;for (let x = 2; x < utxoTableRows.length; x++) { const cells = utxoTableRows[x].split(" ").filter((i: string) => i); totalLovelaceRecv += parseInt(cells[2]);}// Determine if the total lovelace received is more than or equal to// the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACE;console.log(`Total Received: ${totalLovelaceRecv} LOVELACE`);console.log(`Expected Payment: ${TOTAL_EXPECTED_LOVELACE} LOVELACE`);console.log(`Payment Complete: ${(isPaymentComplete ? "✅" : "❌")}`);
Program.cs
using System;using System.IO;using System.Linq;// Install using command `dotnet add package SimpleExec --version 7.0.0`using SimpleExec;// Path to the cardano-cli binary or use the global oneconst string CARDANO_CLI_PATH = "cardano-cli";// The `testnet` identifier numberconst int CARDANO_NETWORK_MAGIC = 1097911063;// The directory where we store our payment keys// assuming our current directory context is $HOME/receive-ada-sampleconst string CARDANO_KEYS_DIR = "keys";// The total payment we expect in lovelace unitconst long TOTAL_EXPECTED_LOVELACE = 1000000;// Read wallet address string value from payment.addr filevar walletAddress = await File.ReadAllTextAsync(Path.Combine(CARDANO_KEYS_DIR, "payment.addr"));// We use the SimpleExec library to execute cardano-cli shell command to query the wallet UTXO and read the output datavar rawUtxoTable = await Command.ReadAsync(CARDANO_CLI_PATH, string.Join(" ", "query", "utxo", "--testnet-magic", CARDANO_NETWORK_MAGIC, "--address", walletAddress), noEcho: true);// Calculate total lovelace of the UTXO(s) inside the wallet addressvar utxoTableRows = rawUtxoTable.Trim().Split("\n");var totalLovelaceRecv = 0L;var isPaymentComplete = false;foreach(var row in utxoTableRows.Skip(2)){ var cells = row.Split(" ").Where(c => c.Trim() != string.Empty); totalLovelaceRecv += long.Parse(cells.ElementAt(2));}// Determine if the total lovelace received is more than or equal to// the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACE;Console.WriteLine($"Total Received: {totalLovelaceRecv} LOVELACE");Console.WriteLine($"Expected Payment: {TOTAL_EXPECTED_LOVELACE} LOVELACE");Console.WriteLine($"Payment Complete: {(isPaymentComplete ? "✅":"❌")}");
checkPayment.py
import osimport subprocess# Path to the cardano-cli binary or use the global oneCARDANO_CLI_PATH = "cardano-cli"# The testnet identifier numberCARDANO_NETWORK_MAGIC = 1097911063# The directory where we store our payment keys# assuming our current directory context is $HOME/receive-ada-sampleCARDANO_KEYS_DIR = "keys"# The total payment we expect in lovelace unitTOTAL_EXPECTED_LOVELACE = 1000000# Read wallet address value from payment.addr filewith open(os.path.join(CARDANO_KEYS_DIR, "payment.addr"), 'r') as file: walletAddress = file.read()# We tell python to execute cardano-cli shell command to query the UTXO and read the output datarawUtxoTable = subprocess.check_output([ CARDANO_CLI_PATH, 'query', 'utxo', '--testnet-magic', str(CARDANO_NETWORK_MAGIC), '--address', walletAddress])# Calculate total lovelace of the UTXO(s) inside the wallet addressutxoTableRows = rawUtxoTable.strip().splitlines()totalLovelaceRecv = 0isPaymentComplete = Falsefor x in range(2, len(utxoTableRows)): cells = utxoTableRows[x].split() totalLovelaceRecv += int(cells[2])# Determine if the total lovelace received is more than or equal to# the total expected lovelace and displaying the results.isPaymentComplete = totalLovelaceRecv >= TOTAL_EXPECTED_LOVELACEprint("Total Received: %s LOVELACE" % totalLovelaceRecv)print("Expected Payment: %s LOVELACE" % TOTAL_EXPECTED_LOVELACE)print("Payment Complete: %s" % {True: "✅", False: "❌"} [isPaymentComplete])
Your project directory should look something like this:
* JavaScript
* Typescript
* Python
* C#
# Excluding node_modules directory$HOME/receive-ada-sample/receive-ada-sample├── checkPayment.js├── keys│ ├── payment.addr│ ├── payment.skey│ └── payment.vkey├── package-lock.json└── package.json1 directories, 6 files
# Excluding node_modules directory$HOME/receive-ada-sample/receive-ada-sample├── checkPayment.ts├── keys│ ├── payment.addr│ ├── payment.skey│ └── payment.vkey├── package-lock.json└── package.json1 directories, 6 files
# Excluding bin and obj directories$HOME/receive-ada-sample/receive-ada-sample├── Program.cs├── dotnet.csproj├── keys│ ├── payment.addr│ ├── payment.skey│ └── payment.vkey1 directories, 5 files
$HOME/receive-ada-sample/receive-ada-sample├── checkPayment.py└── keys ├── payment.addr ├── payment.skey └── payment.vkey1 directory, 4 files
Now we are ready to test 🚀, running the code should give us the following result:
* JavaScript
* Typescript
* Python
* C#
❯ node checkPayment.jsTotal Received: 0 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ❌
❯ ts-node checkPayment.tsTotal Received: 0 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ❌
❯ dotnet runTotal Received: 0 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ❌
❯ python checkPayment.py Total Received: 0 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ❌
The code is telling us that our current wallet has received a total of `0 lovelace` and it expected `1,000,000 lovelace`, therefore it concluded that the payment is not complete.
Complete the payment[](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#complete-the-payment "Direct link to Complete the payment")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
What we can do to simulate a successful payment is to send at least `1,000,000 lovelace` into the **wallet address** that we have just generated for this project. We can get the **wallet address** by reading the contents of the `payment.addr` file like so:
cat $HOME/receive-ada-sample/receive-ada-sample/keys/payment.addr
You should see the **wallet address** value:
addr_test1vpfkp665a6wn7nxvjql5vdn5g5a94tc22njf4lf98afk6tgnz5ge4
Now simply send at least `1,000,000 lovelace` to this **wallet address** or request some `test ada` funds from the [Cardano Testnet Faucet](https://docs.cardano.org/cardano-testnet/tools/faucet)
. Once complete, we can now run the code again and we should see a successful result this time.
* JavaScript
* Typescript
* Python
* C#
❯ node checkPayment.jsTotal Received: 1000000000 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ✅
❯ ts-node checkPayment.tsTotal Received: 1000000000 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ✅
❯ dotnet runTotal Received: 1000000000 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ✅
❯ python checkPayment.py Total Received: 1000000000 LOVELACEExpected Payment: 1000000 LOVELACEPayment Complete: ✅
note
It might take 20 seconds or more for the transaction to propagate within the network depending on the network health, so you will have to be patient.
Congratulations, you are now able to detect successful **Cardano** payments programmatically. This should help you bring integrations to your existing or new upcoming applications. 🎉🎉🎉
* [Overview](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#overview)
* [Use case](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#use-case)
* [Technical flow](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#technical-flow)
* [Time to code](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#time-to-code)
* [Generate keys and request tAda](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#generate-keys-and-request-tada)
* [Initial variables](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#initial-variables)
* [Read wallet address value](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#read-wallet-address-value)
* [Query UTxO](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#query-utxo)
* [Process UTxO table](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#process-utxo-table)
* [Determine if payment is successful](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#determine-if-payment-is-successful)
* [Running and testing](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#running-and-testing)
* [Complete the payment](https://developers.cardano.org/docs/integrate-cardano/listening-for-payments-cli/#complete-the-payment)
---
# Secure Transaction Workflow | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/secure-workflow/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
This general guide is written to help Cardano stake pool operators and developers keep to one simple rule:
warning
Payment keys can never be stored, even for a moment, on an Internet connected machine.
Therefore we present a secure, standard workflow for `cardano-cli` commands like the ones presented without consideration of security here:
* **[Create Simple Transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/simple-transactions)
**
Once you feel comfortable doing a simple transaction securely, you'll also be able to use it to securely execute these more complex transactions as well:
* [Minting Native Assets](https://developers.cardano.org/docs/native-tokens/minting)
* [Minting NFTs](https://developers.cardano.org/docs/native-tokens/minting-nfts)
* [Registering a Stake Address](https://developers.cardano.org/docs/operate-a-stake-pool/register-stake-address)
* [Registering a Stake Pool](https://developers.cardano.org/docs/operate-a-stake-pool/register-stake-pool)
### A model for a secure transaction[](https://developers.cardano.org/docs/get-started/secure-workflow/#a-model-for-a-secure-transaction "Direct link to A model for a secure transaction")
All transactions will be done in these 3 steps:
1. on Internet connected computer:
* **Assemble** all transaction details (from Cardano node or other query) in a file & save it to a removable device.
2. in [air gap environment](https://developers.cardano.org/docs/get-started/air-gap)
:
* **Build** information from this file into a signed transaction & save the Tx file back on the same device (note `Tx` = "transaction").
3. on Internet connected computer:
* **Upload** the Tx file to your Cardano node and submit it.
Therefore, the payment signing key (the private component of the [Cardano wallet address key pair](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs#wallet-address-key-pairs)
) **never leaves the air gap environment**. This is vital because:
* A standard assumption in security is that _any_ Internet connection on _any_ computer creates opportunities for malicious people or programs to copy, view, or modify _anything_ unencrypted on that computer.
* Unlike transactions with cryptocurrency wallet software, in which the wallet's private payment keys are carefully encrypted and securely managed, the payment key (in this documentation, `payment.skey`) used for the raw transactions of development & stake pool operations is _not encrypted_.
* This means that this file stored anywhere on your Internet connected computer or server, even for an instant, creates an opportunity for the funds at that address (`payment.addr`) to be _**lost**_.
Prerequisites[](https://developers.cardano.org/docs/get-started/secure-workflow/#prerequisites "Direct link to Prerequisites")
--------------------------------------------------------------------------------------------------------------------------------
### Your [air gap environment](https://developers.cardano.org/docs/get-started/air-gap)
[](https://developers.cardano.org/docs/get-started/secure-workflow/#your-air-gap-environment "Direct link to your-air-gap-environment")
Follow [these instructions](https://developers.cardano.org/docs/get-started/air-gap)
to procure the environment (usually a dedicated "air gap machine") if you haven't already.
### Move any existing keys inside the air gap[](https://developers.cardano.org/docs/get-started/secure-workflow/#move-any-existing-keys-inside-the-air-gap "Direct link to Move any existing keys inside the air gap")
Second, if you've been running your applications, token/NFT generation, or stake pool with keys stored on any Internet connected machine (whether desktop or server):
* Move all those keys onto the air gap host and [securely delete](https://developers.cardano.org/docs/get-started/air-gap#install-secure-deletion-tools)
the originals.
* Also, seriously consider whether those resources should be rebuilt due to the exposure of those private keys.
To simplify the commands below, this guide assumes you will store all your keys and addresses _in the same single directory_ where you will be building your transactions.
### Dedicate a memory stick to moving your Tx files[](https://developers.cardano.org/docs/get-started/secure-workflow/#dedicate-a-memory-stick-to-moving-your-tx-files "Direct link to Dedicate a memory stick to moving your Tx files")
Format a memory stick on a machine you believe to be secure, and then (to be on the safe side) format it again on the air gap machine. Some ideas:
* The objective here is to avoid bringing malicious software from your host computer into the air gap environment, especially via viruses that are designed to propagate by memory sticks.
* Use a filesystem that will be compatible with your regular Internet connected machine _and_ your air gapped Linux environment: the one most likely to be writable by all types of desktop is FAT32.
Steps of a secure transaction[](https://developers.cardano.org/docs/get-started/secure-workflow/#steps-of-a-secure-transaction "Direct link to Steps of a secure transaction")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Note that in general your "Internet connected machine" and your "Cardano node" will be two separate systems, and you will have to transfer files from one to the other with programs like [`rsync`](https://linux.die.net/man/1/rsync)
.
* So if you're running your Cardano node on a home machine (or using the Daedalus node port, for instance), where it says "upload" you only have to copy such files to where you can access them on that node.
### 1\. _Assemble_ all transaction details.[](https://developers.cardano.org/docs/get-started/secure-workflow/#1-assemble-all-transaction-details "Direct link to 1-assemble-all-transaction-details")
On your Internet-connected computer (usually your Cardano node, though you might use query services instead):
#### Get protocol parameters[](https://developers.cardano.org/docs/get-started/secure-workflow/#get-protocol-parameters "Direct link to Get protocol parameters")
Get the protocol parameters and save them to `protocol.json` with:
cardano-cli query protocol-parameters \ --mainnet \ --out-file protocol.json
#### Get the transaction hash and index of the **UTXO** to spend:[](https://developers.cardano.org/docs/get-started/secure-workflow/#get-the-transaction-hash-and-index-of-the-utxo-to-spend "Direct link to get-the-transaction-hash-and-index-of-the-utxo-to-spend")
Here `payment.addr` is the Cardano address you will be paying from, which may be stored on your insecure machine:
cardano-cli query utxo \ --address $(cat payment.addr) \ --mainnet
Copy or redirect the output of this last command to a _scratch file_ of your choice.
Then copy both this file and `protocol.json` to the transfer memory stick.
### 2\. _Build_ Tx details into a signed transaction.[](https://developers.cardano.org/docs/get-started/secure-workflow/#2-build-tx-details-into-a-signed-transaction "Direct link to 2-build-tx-details-into-a-signed-transaction")
Attach your transfer memory stick to the air gap host and copy the files to your working directory:
* `protocol.json`
* your scratch file
#### Draft the transaction[](https://developers.cardano.org/docs/get-started/secure-workflow/#draft-the-transaction "Direct link to Draft the transaction")
Create a draft for the transaction and save it in `tx.draft`. Notes:
* As in the insecure example, `payment2.addr` is the address you're sending a payment _to_, while `payment.addr` (holding the UTxO where the funds are coming _from_), will store the "change" from this transaction.
* For `--tx-in` we use the following syntax: `TxHash#TxIx` where `TxHash` is the transaction hash and `TxIx` is the index.
* For `--tx-out` we use: `TxOut+Lovelace` where `TxOut` is the hex encoded address followed by the amount in `Lovelace`.
* For the transaction draft, the `--tx-out` amounts and `--fee` can be set to zero.
* The values after `--tx-in` are taken from the output of `cardano-cli query utxo` that you saved in your scratch file.
cardano-cli conway transaction build-raw \ --tx-in 4e3a6e7fdcb0d0efa17bf79c13aed2b4cb9baf37fb1aa2e39553d5bd720c5c99#4 \ --tx-out $(cat payment2.addr)+0 \ --tx-out $(cat payment.addr)+0 \ --invalid-hereafter 0 \ --fee 0 \ --out-file tx.draft
#### Calculate the fee[](https://developers.cardano.org/docs/get-started/secure-workflow/#calculate-the-fee "Direct link to Calculate the fee")
The generally simplest transaction needs one input (a valid UTXO from `payment.addr`) and two outputs:
1. The address that receives the transaction.
2. The address that receives the change of the transaction.
Note that to calculate the fee you need to include the draft transaction:
cardano-cli conway transaction calculate-min-fee \ --tx-body-file tx.draft \ --tx-in-count 1 \ --tx-out-count 2 \ --witness-count 1 \ --byron-witness-count 0 \ --mainnet \ --protocol-params-file protocol.json
#### Calculate the change to send back to `payment.addr`[](https://developers.cardano.org/docs/get-started/secure-workflow/#calculate-the-change-to-send-back-to-paymentaddr "Direct link to calculate-the-change-to-send-back-to-paymentaddr")
All amounts must be in Lovelace:
expr `UTXO BALANCE` - `AMOUNT TO SEND` - `TRANSACTION FEE`
For example, if we send 10 ada from a UTxO containing 20 ada, the change to send back to `payment.addr` after paying the fee is: 9.832035 ada:
expr 20000000 - 10000000 - 1679659832035
#### Build the transaction[](https://developers.cardano.org/docs/get-started/secure-workflow/#build-the-transaction "Direct link to Build the transaction")
We write the transaction in a file; we will name it `tx.raw`:
cardano-cli conway transaction build-raw \ --tx-in 4e3a6e7fdcb0d0efa17bf79c13aed2b4cb9baf37fb1aa2e39553d5bd720c5c99#4 \ --tx-out $(cat payment2.addr)+10000000 \ --tx-out $(cat payment.addr)+9832035 \ --fee 167965 \ --out-file tx.raw
#### Sign the transaction[](https://developers.cardano.org/docs/get-started/secure-workflow/#sign-the-transaction "Direct link to Sign the transaction")
Sign the transaction with the signing key `payment.skey` and save the signed transaction in `tx.signed`:
cardano-cli conway transaction sign \ --tx-body-file tx.raw \ --signing-key-file payment.skey \ --mainnet \ --out-file tx.signed
Save the `tx.signed` file back on the transfer memory stick, then [safely remove](https://help.ubuntu.com/stable/ubuntu-help/files-removedrive.html.en)
the memory stick from the air gap machine.
### 3\. **Upload** and submit the Tx file.[](https://developers.cardano.org/docs/get-started/secure-workflow/#3-upload-and-submit-the-tx-file "Direct link to 3-upload-and-submit-the-tx-file")
Reattach your transfer memory stick back to the Internet connected computer, then upload the `tx.signed` file to your Cardano node.
#### Submit the transaction[](https://developers.cardano.org/docs/get-started/secure-workflow/#submit-the-transaction "Direct link to Submit the transaction")
Log into your Cardano node (or prepare Daedalus if using its node) and execute:
cardano-cli conway transaction submit \ --tx-file tx.signed \ --mainnet
Then check for a successful transaction by whatever means you prefer, e.g. a [Cardano Explorer](https://explorer.cardano.org/)
.
FAQ[](https://developers.cardano.org/docs/get-started/secure-workflow/#faq "Direct link to FAQ")
--------------------------------------------------------------------------------------------------
### Why can't I use `cardano-cli conway transaction build`?[](https://developers.cardano.org/docs/get-started/secure-workflow/#why-cant-i-use-cardano-cli-conway-transaction-build "Direct link to why-cant-i-use-cardano-cli-conway-transaction-build")
This is a convenient command to avoid the ["change" (return UTxO) calculation](https://developers.cardano.org/docs/get-started/secure-workflow/#calculate-the-change-to-send-back-to-paymentaddr)
which requires you to prepare a test transaction, estimate fees, and calculate a final value of the funds to be moved. Instead, `transaction build` sends back "change" to a designated address.
Some consider this so much easier to use that _**all**_ transactions should be performed with this command, as discussed here:
* [Please use `cardano-cli conway transaction build` instead of `cardano-cli conway transaction build-raw`](https://forum.cardano.org/t/please-use-cardano-cli-transaction-build-instead-of-cardano-cli-transaction-build-raw/94919)
However, this discussion revealed the undocumented condition that `transaction build` can only be done on a **live** Cardano node. The community in general doesn't know the reasons for this (with some speculation in the thread above), so in the meantime:
* Using `transaction build` would require, in addition to accumulating the UTxO and balance information from your live Cardano node or network environment to build your transaction, that you also run the `build` command in the networked environment as well and save the unsigned transaction file on your transfer media.
* This transaction file would then need to be copied from the live environment to the air gap environment, where it would be signed... but in a security paranoid environment the user could never be sure the transaction was not built or modified maliciously outside the air gap.
Therefore this guide suggests _only_ assembling transaction _details_ outside the air gap, to be applied to `cardano-cli conway transaction build-raw` inside the air gap, because there is not much more convenience overall in using `transaction build` while perhaps introducing some security risk.
Other pending topics in secure workflow[](https://developers.cardano.org/docs/get-started/secure-workflow/#other-pending-topics-in-secure-workflow "Direct link to Other pending topics in secure workflow")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
These are not directly related to transactions, and will all eventually be addressed in their own pages on the Developer Portal:
* pool key installation & updates: transferring keys (e.g. VRF and KES) securely from within the air gap to your stake pool block producer
* making encrypted backups of your private keys (so they can be kept offsite / stored outside your air gap environment)
* keeping secure (encrypted) records of your stake pool & development resources
For ideas on secure backup & record-keeping, see [Get Started with the Frankenwallet > Making & verifying backups of assets & keys](https://developers.cardano.org/docs/operate-a-stake-pool/frankenwallet#making--verifying-backups-of-assets--keys)
.
* [A model for a secure transaction](https://developers.cardano.org/docs/get-started/secure-workflow/#a-model-for-a-secure-transaction)
* [Prerequisites](https://developers.cardano.org/docs/get-started/secure-workflow/#prerequisites)
* [Your air gap environment](https://developers.cardano.org/docs/get-started/secure-workflow/#your-air-gap-environment)
* [Move any existing keys inside the air gap](https://developers.cardano.org/docs/get-started/secure-workflow/#move-any-existing-keys-inside-the-air-gap)
* [Dedicate a memory stick to moving your Tx files](https://developers.cardano.org/docs/get-started/secure-workflow/#dedicate-a-memory-stick-to-moving-your-tx-files)
* [Steps of a secure transaction](https://developers.cardano.org/docs/get-started/secure-workflow/#steps-of-a-secure-transaction)
* [1\. _Assemble_ all transaction details.](https://developers.cardano.org/docs/get-started/secure-workflow/#1-assemble-all-transaction-details)
* [2\. _Build_ Tx details into a signed transaction.](https://developers.cardano.org/docs/get-started/secure-workflow/#2-build-tx-details-into-a-signed-transaction)
* [3\. **Upload** and submit the Tx file.](https://developers.cardano.org/docs/get-started/secure-workflow/#3-upload-and-submit-the-tx-file)
* [FAQ](https://developers.cardano.org/docs/get-started/secure-workflow/#faq)
* [Why can't I use `cardano-cli conway transaction build`?](https://developers.cardano.org/docs/get-started/secure-workflow/#why-cant-i-use-cardano-cli-conway-transaction-build)
* [Other pending topics in secure workflow](https://developers.cardano.org/docs/get-started/secure-workflow/#other-pending-topics-in-secure-workflow)
---
# Cardano Key Pairs | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
It's critical to understand the numerous cryptographic key pairs connected with Cardano, as well as the purpose of each key pair and best practices for securing those keys, before you start working with it. Every ambitious Cardano developer and stake pool operator should get a complete grasp of these key pairs, as well as the ramifications of a single secret (private) key being hacked. Any Cardano developer or stake pool operator must learn how to manage, safeguard, and store private keys in order to succeed.
Cardano cryptographic keys are made up of `ed25519` key pairs, which include a `public verification key file` and a `secret (private) key file`. The public key file is commonly referred to as `keyname.vkey`, whereas the private key file is referred to as `keyname.skey`. The private key file, which is used to sign transactions, is extremely sensitive and should be adequately safeguarded. Under all circumstances, this entails limiting third-party access to your private keys. The most effective technique to prevent private key exposure is to guarantee that the necessary private key is never held for any length of time on any internet-connected machine (hot node). Please note that key pair filenames are completely random and can be named whatever you want.
danger
Use extreme caution to avoid losing or overwriting secret (private) keys.
Wallet address key pairs[](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#wallet-address-key-pairs "Direct link to Wallet address key pairs")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Currently, Cardano wallet addresses only have two parts: a payment address and a counterpart staking address. A payment address (together with its associated key pairs) is used to store, receive, and send money. A stake address (and related keys) is used to store and withdraw rewards, as well as to define the stake pool owner and rewards accounts, as well as the wallet's target stake pool delegation.
`payment.vkey` is the public verification key file for the payment address (not sensitive; may be shared publicly).
`payment.skey` is a highly sensitive payment address secret (private) signing key file. The private signing key file gives you access to monies in your payment address and should be kept safe at all times.
danger
Never place payment signing keys on a hot node.
`stake.vkey` - stake address public verification key file (not sensitive; may be shared publicly).
`stake.skey` - It is a sensitive stake address secret (private) signing key file. This private signing key file gives you access to any awards cash held in the stake address, as well as the ability to delegate the wallet to a pool. It's also a good idea to keep an eye on the stake.skey.
`payment.addr` - This is a Cardano wallet payment address that is usually generated with the help of both a payment.vkey and a stake. As inputs, use the vkey file. If a payment address is merely going to be used to send and receive money, no crucial components need to be staked. In addition, there is a single payment. Multiple unique stake.vkey files can be coupled with vkey to establish different payment addresses that can be staked independently.
`stake.addr` - stake address for a Cardano wallet and is generated using the stake.vkey file
Cardano stake pool key pairs[](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#cardano-stake-pool-key-pairs "Direct link to Cardano stake pool key pairs")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Stake pool cold keys[](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#stake-pool-cold-keys "Direct link to Stake pool cold keys")
`cold.skey` - secret (private) signing key file for a Cardano stake pool (extremely sensitive). The `cold.skey` is required to register a stake pool, to update a stake pool registration certificate parameters, to rotate a stake pool KES keys and to retire a stake pool.
`cold.vkey` - public verification key file for a stake pool's cold.skey private signing key file (cold.vkey is not sensitive; can be shared publicly).
`cold.counter` - incrementing counter file that tracks the number of times an operational certificate (opcert) has been generated for the relevant stake pool.
danger
Always rotate KES keys using the latest `cold.counter`.
### VRF hot keys[](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#vrf-hot-keys "Direct link to VRF hot keys")
`vrf.skey` - secret (private) signing key file for a Cardano stake pool's VRF key (required to start a stake pool's block producing node; sensitive but must be placed on a hot node in order to start a stake pool).
`vrf.vkey` - public verification key file for a Cardano stake pool's vrf.skey (not sensitive and is not required to start a stake pool's block producing node).
### KES hot keys[](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#kes-hot-keys "Direct link to KES hot keys")
`kes.skey`\- secret (private) signature key file for the stake pool's KES key (needed to start the stake pool's block producing node; sensitive, but must be placed on a hot node to start a stake pool and rotated on a regular basis). KES keys are needed to establish a stake pool's operating certificate, which expires 90 days after the opcert's defined KES period has passed. As a result, fresh KES keys must be generated along with a new opcert every 90 days or sooner for a Cardano Stake pool to continue minting blocks.
`kes.vkey` - public verification key file for a Cardano stake pool's corresponding `kes.skey` (not sensitive and is not required to a block producer).
References[](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#references "Direct link to References")
----------------------------------------------------------------------------------------------------------------------------------
* [CIP 19 Cardano Addresses](https://cips.cardano.org/cip/CIP-0019)
* [Wallet address key pairs](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#wallet-address-key-pairs)
* [Cardano stake pool key pairs](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#cardano-stake-pool-key-pairs)
* [Stake pool cold keys](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#stake-pool-cold-keys)
* [VRF hot keys](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#vrf-hot-keys)
* [KES hot keys](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#kes-hot-keys)
* [References](https://developers.cardano.org/docs/operate-a-stake-pool/cardano-key-pairs/#references)
---
# Withdraw rewards | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Querying the stake address balance[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#querying-the-stake-address-balance "Direct link to Querying the stake address balance")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
First, check if you have some rewards to withdraw:
cardano-cli conway query stake-address-info --address $(< stake.addr)[ { "address": "stake_test1ur453z5nxrgvvu9wfyuxut8ss0mrvca4n8ly44tcu8camlqaz98mh", "delegationDeposit": 2000000, "rewardAccountBalance": 10534638802, "stakeDelegation": "pool17xgtj7ayvsaju4clums0mfusla4pmtfm6t4fj6guqqlsvne2mwm", "voteDelegation": "scriptHash-59aa3f091b3bcef254abfb89aea64973a61b78fdb2ac44839c7ccba8" }]
Nice! There are some rewards, let's store the `rewardAccountBalance` in a variable for future use:
rewards="$(cardano-cli conway query stake-address-info --address $(< stake1.addr) | jq .[].rewardAccountBalance)"
Building the transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#building-the-transaction "Direct link to Building the transaction")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To withdraw rewards from the rewards account, you must withdraw its entire balance; partial withdrawals are not allowed. Use the `--withdrawal` flag followed by the stake address and its balance using the syntax: `stakeAddress+lovelace`.
By default, the `build` command considers the transaction to only require one witness. However, this type of transaction needs to be signed by `payment.skey` to pay for the transaction fees, and also by `stake.skey` to prove that we control that stake address. Therefore, we inform the `build` command that the transaction will carry two signatures using the `--witness-override 2` flag. This has a slight impact on the fee:
cardano-cli conway transaction build \ --tx-in $(cardano-cli query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \ --withdrawal stake_test1ur453z5nxrgvvu9wfyuxut8ss0mrvca4n8ly44tcu8camlqaz98mh+10534638802 \ --change-address $(< payment1.addr) \ --witness-override 2 \ --out-file tx.raw> Estimated transaction fee: Coin 180593
or using `<` and the `$rewards` variable from above:
cardano-cli conway transaction build \ --tx-in $(cardano-cli query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \ --withdrawal "$(< stake.addr)+$rewards" \ --change-address $(< payment.addr) \ --witness-override 2 \ --out-file tx.raw> Estimated transaction fee: Coin 180593
Signing the transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#signing-the-transaction "Direct link to Signing the transaction")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
As before, sign the transaction with the `payment.skey`:
cardano-cli conway transaction sign \--tx-body-file tx.raw \--signing-key-file payment.skey \--signing-key-file stake.skey \--out-file tx.signed
If you inspect the transaction, you'll notice that the 'withdrawals' field contains reward withdrawal details:
cardano-cli debug transaction view --tx-file tx.signed
{ "auxiliary scripts": null, "certificates": null, "collateral inputs": [], "era": "Babbage", "fee": "180593 Lovelace", "inputs": [ "5b8e81604aa60f82337986c0db4e0078282309ca054aa2690315451ec47ce1eb#0" ], "metadata": null, "mint": null, "outputs": [ { "address": "addr_test1qrpw2fzut0s7mexgl05lmjdajr00lvlvlufg3qamc0d3mmhtfz9fxvxscec2ujfcdck0pqlkxe3mtx07ft2h3c03mh7q72p248", "address era": "Shelley", "amount": { "lovelace": 680164451802 }, "network": "Testnet", "payment credential key hash": "c2e5245c5be1ede4c8fbe9fdc9bd90deffb3ecff128883bbc3db1dee", "reference script": null, "stake reference": { "stake credential key hash": "eb488a9330d0c670ae49386e2cf083f63663b599fe4ad578e1f1ddfc" } } ], "redeemers": {}, "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": [ { "address": "stake_test1ur453z5nxrgvvu9wfyuxut8ss0mrvca4n8ly44tcu8camlqaz98mh", "amount": "10534638802 Lovelace", "network": "Testnet", "stake credential key hash": "eb488a9330d0c670ae49386e2cf083f63663b599fe4ad578e1f1ddfc" } ], "witnesses": [ { "key": "VKey (VerKeyEd25519DSIGN \"842402e9a35b8818d35f556ba59df2929e3bee72c8e9bfdaa1894faed0a3b2d5\")", "signature": "SignedDSIGN (SigEd25519DSIGN \"31c84cc7e0b770f76acb3682c7d2e5b13c00405a0fd1fbaf3ff545be42458fb3e89c3da20162ea262a73d35f04e18257c175d8e0849d51922b8185c11920800b\")" }, { "key": "VKey (VerKeyEd25519DSIGN \"8d2128537a643b7327fb07ef01fd8cd2f4911e0b3d096a4575d4cd4d73471896\")", "signature": "SignedDSIGN (SigEd25519DSIGN \"06fe930ce8d2f63fd62ab1354b2a85283fe4e6fdfc29ef605644c3f92505cd25165c2e40d4b0139240c06c86e06e835eee0d57a6783142ef5138cacad27d4d08\")" } ]}
Submitting the transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#submitting-the-transaction "Direct link to Submitting the transaction")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cardano-cli conway transaction submit \ --tx-file tx.signed Transaction successfully submitted.
If you query the stake address details again, you'll notice that it has been emptied, and the funds were sent to the payment address.
cardano-cli conway query stake-address-info --address $(< stake1.addr)[ { "address": "stake_test1ur453z5nxrgvvu9wfyuxut8ss0mrvca4n8ly44tcu8camlqaz98mh", "delegationDeposit": 2000000, "rewardAccountBalance": 0, "stakeDelegation": "pool17xgtj7ayvsaju4clums0mfusla4pmtfm6t4fj6guqqlsvne2mwm", "voteDelegation": "scriptHash-59aa3f091b3bcef254abfb89aea64973a61b78fdb2ac44839c7ccba8" }]
* [Querying the stake address balance](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#querying-the-stake-address-balance)
* [Building the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#building-the-transaction)
* [Signing the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#signing-the-transaction)
* [Submitting the transaction](https://developers.cardano.org/docs/get-started/cardano-cli/get-started/withdraw-rewards/#submitting-the-transaction)
---
# Understanding the Relay and Block Producer topology | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/stake-pool-networking/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
Before we start with the stake pool installation and configuration, it is essential to understand the logical topology of stake pools. Typically every stake pool has one block producer and at least one relay node. To ensure fast propagation of blocks the pool produces, it is recommended to have relays in different geographical locations. To secure the block producer from the internet it should only connect to its own relays, or relays you trust. The relays then connect to the rest of the Cardano network. To minimise the risk of [height battles](https://forum.cardano.org/t/how-to-figure-out-when-pool-wins-slot-battles-or-causes-height-battles/90639)
, it is recommended to regularly monitor the propagation time of the relays. We will talk more on this topic in our pool monitoring section later.
In the example below, one block producer is connected to three relays and they are connected to other relays of the Cardano network.

For the operation of a stake pool, some additional nodes in the topology might be useful. For example, a back-up node for block producer is helpful in case the main block producer has an issue e.g. during an upgrade. Depending on the number of stake pools that are being managed, a monitoring node can be used to monitor them and generate alarms. Stake pool operators also need a [air-gapped system](https://developers.cardano.org/docs/get-started/air-gap)
to store the pool cold keys. Some pool operators use a hardware wallet for storing the pool pledge.
A logical topology of all the components, without considering firewalls and other security aspects can be shown as follows.

---
# Get Started with cardanocli-js | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardanocli-js/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
cardanocli-js wraps the cardano-cli in JavaScript and makes it possible to interact with the cli-commands much faster and more efficient.
Prerequisites[](https://developers.cardano.org/docs/get-started/cardanocli-js/#prerequisites "Direct link to Prerequisites")
------------------------------------------------------------------------------------------------------------------------------
* `cardano-node >= 1.26.1`
* `node.js >= 12.19.0`
Install[](https://developers.cardano.org/docs/get-started/cardanocli-js/#install "Direct link to Install")
------------------------------------------------------------------------------------------------------------
#### NPM[](https://developers.cardano.org/docs/get-started/cardanocli-js/#npm "Direct link to NPM")
npm install cardanocli-js
#### From source[](https://developers.cardano.org/docs/get-started/cardanocli-js/#from-source "Direct link to From source")
git clone https://github.com/Berry-Pool/cardanocli-js.gitcd cardanocli-jsnpm install
Get started[](https://developers.cardano.org/docs/get-started/cardanocli-js/#get-started "Direct link to Get started")
------------------------------------------------------------------------------------------------------------------------
const CardanocliJs = require("cardanocli-js");const shelleyGenesisPath = "/home/ada/mainnet-shelley-genesis.json";const cardanocliJs = new CardanocliJs({ shelleyGenesisPath });const createWallet = (account) => { cardanocliJs.addressKeyGen(account); cardanocliJs.stakeAddressKeyGen(account); cardanocliJs.stakeAddressBuild(account); cardanocliJs.addressBuild(account); return cardanocliJs.wallet(account);};const createPool = (name) => { cardanocliJs.nodeKeyGenKES(name); cardanocliJs.nodeKeyGen(name); cardanocliJs.nodeIssueOpCert(name); cardanocliJs.nodeKeyGenVRF(name); return cardanocliJs.pool(name);};const wallet = createWallet("Ada");const pool = createPool("Berry");console.log(wallet.paymentAddr);console.log(pool.vrf.vkey);
For testnets for example this is the working version[](https://developers.cardano.org/docs/get-started/cardanocli-js/#for-testnets-for-example-this-is-the-working-version "Direct link to For testnets for example this is the working version")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
const CardanocliJs = require("cardanocli-js");const shelleyGenesisPath = "../..//tconfig/testnet-shelley-genesis.json";const options={}options.shelleyGenesisPath = shelleyGenesisPathoptions.network = "testnet-magic 1097911063"const cardanocliJs = new CardanocliJs(options);const createWallet = (account) => { try{ paymentKeys = cardanocliJs.addressKeyGen(account); stakeKeys = cardanocliJs.stakeAddressKeyGen(account); stakeAddr = cardanocliJs.stakeAddressBuild(account); paymentAddr = cardanocliJs.addressBuild(account,{ "paymentVkey": paymentKeys.vkey, "stakeVkey": stakeKeys.vkey }); return cardanocliJs.wallet(account); } catch(err){ console.log(err) }};const createPool = (name) => { cardanocliJs.nodeKeyGenKES(name); cardanocliJs.nodeKeyGen(name); cardanocliJs.nodeIssueOpCert(name); cardanocliJs.nodeKeyGenVRF(name); return cardanocliJs.pool(name);};const wallet = createWallet("Ada");const pool = createPool("Berry");console.log(wallet.paymentAddr);console.log(pool.vrf.vkey);
Visit [cardanocli-js](https://github.com/miguelaeh/cardanocli-js/)
to see the complete API documentation.
* [Prerequisites](https://developers.cardano.org/docs/get-started/cardanocli-js/#prerequisites)
* [Install](https://developers.cardano.org/docs/get-started/cardanocli-js/#install)
* [Get started](https://developers.cardano.org/docs/get-started/cardanocli-js/#get-started)
* [For testnets for example this is the working version](https://developers.cardano.org/docs/get-started/cardanocli-js/#for-testnets-for-example-this-is-the-working-version)
---
# Plutus scripts | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
This tutorial covers the basics of using the Cardano CLI to create transactions that involve executing Plutus scripts. Please checkout [Plutus user guide](https://plutus.cardano.intersectmbo.org/docs/)
to learn how to write Plutus scrtipts.
Basic validator plutus script[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#basic-validator-plutus-script "Direct link to Basic validator plutus script")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
For this tutorial we borrowed a simple validator script from the [Plutus Pioneer Program](https://iog-academy.gitbook.io/plutus-pioneers-program-fourth-cohort)
. We will use the [FortyTwoTyped.hs](https://github.com/input-output-hk/plutus-pioneer-program/blob/fourth-iteration/code/Week02/lecture/FortyTwoTyped.hs)
script. You can download the serialized script form [this link](https://github.com/input-output-hk/plutus-pioneer-program/blob/fourth-iteration/code/Week02/assets/fortytwotyped.plutus)
.
FortyTwoTyped.hs
The relevant part of this Plutus script is:
-- This validator succeeds only if the redeemer is 42-- Datum Redeemer ScriptContextmk42Validator :: () -> Integer -> PlutusV2.ScriptContext -> Boolmk42Validator _ r _ = traceIfFalse "expected 42" $ r == 42
The type signature of **mk42Validator** tells us that it takes three arguments and returns a Bool:
mk42Validator :: () -> Integer -> PlutusV2.ScriptContext -> Bool
As hinted by the comment line, these three arguments correspond to **Datum, Redeemer and Script Context**.
On the function definition we see that it does not care about the Datum and the Script Context and only cares about the redeemer.
mk42Validator _ r _ = traceIfFalse "expected 42" $ r == 42
The underscores (`_`) in the datum and script context positions mean that the function will accept anything for these values and completely ignore them in the function body. The function does not use these values. In the end, the result only depends on the redeemer value `r`. The script succeeds when the correct redeemer is provided (`r == 42`) and fails with any other redeemer value.
So, the general plan for using this script is:
1. Lock some funds in the script address.
2. Attempt to spend the locked funds. The script will only permit the spending if the correct redeemer is provided.
### Get the compiled script.[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#get-the-compiled-script "Direct link to Get the compiled script.")
Compiling the script is out of the scope of this tutorial, we can get the compiled version with:
wget https://raw.githubusercontent.com/input-output-hk/plutus-pioneer-program/fourth-iteration/code/Week02/assets/fortytwotyped.plutus
{ "type": "PlutusScriptV2", "description": "", "cborHex": "5907ac5907a901000032323322323232323232323232323233223232323232222323253353232325335333573466e1c009205401c01b101c13357389210b65787065637465642034320001b3333573466e1cd55cea80224000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd405c060d5d0a80619a80b80c1aba1500b33501701935742a014666aa036eb94068d5d0a804999aa80dbae501a35742a01066a02e0446ae85401cccd5406c08dd69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b5d69aba15002302e357426ae8940088c98c80c0cd5ce01981801709aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a816bad35742a004605c6ae84d5d1280111931901819ab9c03303002e135573ca00226ea8004d5d09aba2500223263202c33573805e05805426aae7940044dd50009aba1500533501775c6ae854010ccd5406c07c8004d5d0a801999aa80dbae200135742a00460426ae84d5d1280111931901419ab9c02b028026135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00860226ae84d5d1280211931900d19ab9c01d01a018375a00a6666ae68cdc39aab9d375400a9000100c11931900c19ab9c01b018016101713263201733573892010350543500017135573ca00226ea800448c88c008dd6000990009aa80b111999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00b80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00e00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007806c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573803002a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355013223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01301000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01301000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00f00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00680500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00b00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae7003c0300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801801200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7003402802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000200723263200633573801200c00800626aae74dd5000a4c240022440042440029210350543100112323001001223300330020020011"}
### Build the script address:[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#build-the-script-address "Direct link to Build the script address:")
cardano-cli address build \--payment-script-file fortytwotyped.plutus \--out-file script.addr
cat script.addraddr_test1wzqvkn6myu8ay080wdsju4s4mzuzgwwv9rxsz2xuc8ycaus9zk46q
Lock funds in the script address[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#lock-funds-in-the-script-address "Direct link to Lock funds in the script address")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Let's lock 10 ADA in the script.
### Prepare the Datum:[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#prepare-the-datum "Direct link to Prepare the Datum:")
To do this, we must create a transaction that sends 10 ADA to the script address and attach a datum. This particular script does not care about the content of the Datum, so we will use Haskell's unit data type.
The unit data type is represented by (). It is a special type that has only one value, also written as (). This type is analogous to void in other programming languages, but it is a proper type with a single value.
We can create the file `datum.json` with the following content:
{"constructor":0,"fields":[]}
### Submit the the transaction to lock the funds:[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#submit-the-the-transaction-to-lock-the-funds "Direct link to Submit the the transaction to lock the funds:")
When building the transaction, it is important to use the `--tx-out-inline-datum-file` flag immediately after the `--tx-out` option to which the datum should be attached. The order of these options matters.
cardano-cli conway transaction build \--tx-in $(cardano-cli conway query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \--tx-out $(< script.addr)+10000000 \--tx-out-inline-datum-file datum.json \--change-address $(< payment.addr) \--out-file lock.tx>Estimated transaction fee: Coin 171969
Sign the transaction with the payment.skey
cardano-cli conway transaction sign \--tx-file lock.tx `\-signing-key-file payment.skey \--out-file lock.tx.signed
Submit the transaction
cardano-cli conway transaction submit \--tx-file lock.tx.signed >Transaction successfully submitted.
### Query the utxos in the script address[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#query-the-utxos-in-the-script-address "Direct link to Query the utxos in the script address")
cardano-cli query utxo --address $(< script.addr) --output-json{ "4c31734468d4f5957328f8fcbb612201c2f774b4ef2bde09b0c6e12cb7ce3f10#0": { "address": "addr_test1wzqvkn6myu8ay080wdsju4s4mzuzgwwv9rxsz2xuc8ycaus9zk46q", "datum": null, "inlineDatum": { "constructor": 0, "fields": [] }, "inlineDatumhash": "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec", "referenceScript": null, "value": { "lovelace": 10000000 } }}
Perfect, we have locked 10 ada on the script address, the only way to spend it is by executing the script providing the correct redeeemer.
### Attempt to spend the funds passing the wrong redeemer:[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#attempt-to-spend-the-funds-passing-the-wrong-redeemer "Direct link to Attempt to spend the funds passing the wrong redeemer:")
We could say that failing is the primarily duty of a Plutus script. Let's check that our script fails if we pass the wrong redeemer.
cardano-cli conway transaction build \--tx-in $(cardano-cli conway query utxo --address $(< script.addr) --output-json | jq -r 'keys[0]') \--tx-in-collateral $(cardano-cli conway query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \--tx-in-script-file fortytwotyped.plutus \--tx-in-inline-datum-present \--tx-in-redeemer-value 57 \--change-address $(< payment.addr) \--out-file unlock.tx
We will explain this command in detail below, for now lets focus on the fact that we are passing the Integer **57** as redeemer using the flag `--tx-in-redeemer-value 57`. When we hit Enter, the `build` command will try to construct the transaction body, running the script in the process.
Command failed: transaction build Error: The following scripts have execution failures:the script for transaction input 0 (in ascending order of the TxIds) failed with: The Plutus script evaluation failed: An error has occurred:The machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.Script debugging logs: expected 42PT5
The script failed to run. It threw the programmed error message "expected 42" and the [error code (PT5)](https://plutus.cardano.intersectmbo.org/docs/troubleshooting#error-codes)
at `build` time. This indicates that the script failed because we passed the wrong redeemer.
If we really wanted, we could use `build-raw` to construct the same transaction and bypass this failure on `build`. However, we would get the same error on `submit`. This transaction can never make it to the chain because it is being rejected by the local node.
### Attempt to spend the funds passing the correct redeemer:[](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#attempt-to-spend-the-funds-passing-the-correct-redeemer "Direct link to Attempt to spend the funds passing the correct redeemer:")
Let's re-use the `build` command from above, this time we pass the correct redeemer value `--tx-in-redeemer-value 42`.
cardano-cli conway transaction build \--tx-in $(cardano-cli conway query utxo --address $(< script.addr) --output-json | jq -r 'keys[0]') \--tx-in-collateral $(cardano-cli conway query utxo --address $(< payment.addr) --output-json | jq -r 'keys[0]') \--tx-in-script-file fortytwotyped.plutus \--tx-in-inline-datum-present \--tx-in-redeemer-value 42 \--change-address $(< payment.addr) \--out-file unlock.tx
Lets break down the command:
* `--tx-in $(cardano-cli conway query utxo --address $(< script.addr) --output-json | jq -r 'keys[0]')`
We use the first UTxO on the script address as input for the transaction. So we are trying to spend the locked funds.
* `--tx-in-collateral $(cardano-cli conway query utxo --address $(< payment.addr)`
`--output-json | jq -r 'keys[0]')`
Since we are running a Plutus script, we must provide a collateral. We use the first utxo of payment address.
* `--tx-in-script-file fortytwotyped.plutus`
We supply the script file.
* `--tx-in-inline-datum-present`
We need to supply a datum. When we locked the funds a few steps above we put the datum inline with _\--tx-out-inline-datum-file datum.json_ this allows us to not supply the datum when trying to spend the funds from the script, instead we are telling the node that the utxo on the script address has the inline datum and the node should get the datum from there.
* `--tx-in-redeemer-value 42`
We pass the Integer 42 as redeemer
* `--change-address $(< payment.addr)`
If sucesfull, the 10 ada locked on the script will be sent to payment.addr. Note that we will pay the transactin fee from this UTXO so payment address should receive a little under 10 ada.
* `--out-file unlock.tx`
We save the transaction body as `unlock.tx`.
When running the command we get
Estimated transaction fee: Coin 300777
This time, the node validated the transaction and successfully ran the script. The transaction should succeed if we provide the correct witness for the collateral. Let's do that.
cardano-cli conway transaction sign \--tx-file unlock.tx \--signing-key-file payment.skey \--out-file unlock.tx.signed
cardano-cli conway transaction submit -\-tx-file unlock.tx.signed> Transaction successfully submitted.
For tracking purposes, lets find our transaction id
cardano-cli conway transaction txid --tx-file unlock.tx.signed 74c856f90276315a14bd2bd35b3a2f803b763a1bdfa2648ec30a85a129048131
Query the UTXOs on both addresses. The script address is now empty
cardano-cli query utxo --address $(< script.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------
and the payment address shows the expected utxo **74c856f90276315a14bd2bd35b3a2f803b763a1bdfa2648ec30a85a129048131#0** with the funds we unlocked from the script.
cardano-cli query utxo --address $(< payment.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------4c31734468d4f5957328f8fcbb612201c2f774b4ef2bde09b0c6e12cb7ce3f10 1 89522687 lovelace + TxOutDatumNone74c856f90276315a14bd2bd35b3a2f803b763a1bdfa2648ec30a85a129048131 0 9699223 lovelace + TxOutDatumNonec0e5fe9a87290b137d0acc995f13493eb423f831c8edaa54e6c86f381a31caf3 1 5898934190 lovelace + TxOutDatumNone
* [Basic validator plutus script](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#basic-validator-plutus-script)
* [Get the compiled script.](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#get-the-compiled-script)
* [Build the script address:](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#build-the-script-address)
* [Lock funds in the script address](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#lock-funds-in-the-script-address)
* [Prepare the Datum:](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#prepare-the-datum)
* [Submit the the transaction to lock the funds:](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#submit-the-the-transaction-to-lock-the-funds)
* [Query the utxos in the script address](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#query-the-utxos-in-the-script-address)
* [Attempt to spend the funds passing the wrong redeemer:](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#attempt-to-spend-the-funds-passing-the-wrong-redeemer)
* [Attempt to spend the funds passing the correct redeemer:](https://developers.cardano.org/docs/get-started/cardano-cli/plutus-scripts/#attempt-to-spend-the-funds-passing-the-correct-redeemer)
---
# Native assets | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
From the Mary ledger upgrade and onwards, Cardano supports [multi-assets](https://github.com/intersectmbo/cardano-ledger/releases/download/cardano-ledger-spec-2023-01-18/mary-ledger.pdf)
, also referred to as a _native tokens_ feature. This feature extends the ledger’s accounting infrastructure (originally designed for processing ada-only transactions) to accommodate transactions using a range of assets. These assets include ada and a variety of user-defined token types, the mixture of which can be transacted in a single tx output. Note that native tokens cannot exist on its own at a UTXO, a minimum number of lovelace is required at the UTXO to support the native tokens.
What are Native assets?[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#what-are-native-assets "Direct link to What are Native assets?")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Native assets are user-defined, custom tokens. They are supported natively, which means that the ledger handles the accounting and tracking of token-related activities. This offers distinct advantages for developers as there is no need to create smart contracts to mint or burn custom tokens, removing a layer of added complexity and potential for manual errors.
An asset is uniquely identified by an _asset ID_, which is a pair of both the _policy ID_ and an _asset name_:
* _PolicyID_ - the unique identifier that is associated with a minting policy (hash of the minting policy).
* _Asset name_ - an (immutable) property of an asset that is used to distinguish different assets within the same policy. Unlike the policyID, the asset name does not refer to any code or set of rules. It is a hex encoded arbitrary sequence of bytes. For example, `hex("couttscoin") = "636f75747473636f696e"`.
echo -n "couttscoin" | xxd -ps636f75747473636f696e
Tokens that have the same asset ID have the property of being fungible with each other, and are not fungible with tokens that have a different asset ID.
Further reading:
* [Native token explainers](https://cardano-ledger.readthedocs.io/en/latest/)
Before you start, you should:
* have the [latest version of the node](https://github.com/intersectmbo/cardano-node/releases)
* configure the node to communicate with the [testnet environment](https://book.world.dev.cardano.org/environments.html)
* A [running cardano-node](https://developers.cardano.org/docs/get-started/cardano-node/running-cardano)
on the desired network.
* Cardano-cli installed
### Syntax for expressing values in a transaction output[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#syntax-for-expressing-values-in-a-transaction-output "Direct link to Syntax for expressing values in a transaction output")
Lovelace values can be specified in two ways:
* `${quantity} lovelace` (where quantity is a signed integer)
* `${quantity}` (where quantity is a signed integer)
* `${assetName}` (where assetName is hex-encoded 61737365744e616d65)
Values for other assets can be specified as:
* `${quantity} ${policyId}.${assetName}`
* `${quantity} ${policyId}`
Where `quantity` is a signed integer and `policyId` is a hex-encoded policy ID \[a script hash\], and `assetName` is a hex-encoded assetName.
### Syntax of native asset values[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#syntax-of-native-asset-values "Direct link to Syntax of native asset values")
The `cardano-cli` can specify native asset values in transaction outputs and when minting or burning tokens. The syntax for these values has been designed to be backwards-compatible with the previous ada-only syntax (`address+lovelace`):
* ada values are defined as integer (INT) lovelace, e.g. `42 lovelace`
* native asset values can be defined as:
* `INT policyid.assetName`, e.g. `42 $MYPOLICY.61737365744e616d65`
* `INT policyid`, e.g. `42 $MYPOLICY` (No assetName specified)
* `policyid.assetName`, e.g `$MYPOLICY.61737365744e616d65` (This will mint only one of `assetName`)
* Multiple assets can be combined in the same transaction output using the `+` operator, e.g:
`100 lovelace + 42 $MYPOLICY.666f6f + -2 $MYPOLICY.626172 + 10 lovelace`
**Negating individual values**
Any individual value can be negated using the `-` prefix operator. For example:
* `-42 $MYPOLICY`
* `-72191 $MYPOLICY.666f6f`
* `-100`
* `-920 lovelace`
**Combining individual values**
Values can be combined using the binary operator `+`. For example:
* `42 lovelace + -1 (this would result in a Value of 41 lovelace)`
* `20 $MYPOLICY + 12 $MYPOLICY.666f6f + -2 $MYPOLICY.626172`
* `201 4$MYPOLICY.666f6f + 12 + -1 + 9 lovelace + 10 $MYPOLICY`
### Creating a transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#creating-a-transaction "Direct link to Creating a transaction")
The native tokens syntax can be used in the following contexts:
* `cardano-cli conway transaction build-raw --tx-out="..."`
* `cardano-cli conway transaction build-raw --mint="..."`
The CLI command `cardano-cli conway transaction build-raw` creates the transaction body. The `--tx-out` option specifies the transaction output in the usual way _(This is expressed as address+lovelace, where address is a Bech32-encoded address, and lovelace is the amount in lovelace)_, and the `--mint` option specifies the value to be minted or burnt.
### Transaction outputs (TxOuts)[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#transaction-outputs-txouts "Direct link to Transaction outputs (TxOuts)")
The syntax for TxOut values has been extended to include multi-asset tokens. These values can be specified in two different ways:
* `$address $value`
* `${address}+${value}`
(where _address_ is a Cardano address and _value_ is a value). The second form is provided for backwards compatibility with earlier versions of the node.
To receive tokens, you just need to specify any address. It is not necessary to use special addresses to hold multi-asset tokens.
To inspect the values in an address, you need to query your node for the UTXOs associated to that address using:
cardano-cli query utxo --address "$ADDRESS"
Token minting policies[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#token-minting-policies "Direct link to Token minting policies")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Token minting policies are written using multi-signature scripts. This allows the asset controller to express conditions such as the need for specific token issuers to agree to mint new tokens, or to forbid minting tokens after a certain slot if [token locking](https://developers.cardano.org/docs/get-started/cardano-cli/simple-scripts/#type-before)
is also used.
Here’s an example of a very simple minting policy, which grants the right to mint tokens to a single key:
{ "keyHash": "fe38d7...599", "type": "sig"}
This minting policy requires any transaction that mints tokens to be witnessed by the key with the hash `fe38d7...599`. More involved examples can be found in the [multi-signature simple scripts documentation](https://developers.cardano.org/docs/get-started/cardano-cli/simple-scripts/#json-script-syntax)
.
### Minting a new native token[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#minting-a-new-native-token "Direct link to Minting a new native token")
#### Overview[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#overview "Direct link to Overview")
This section describes how to manually mint a new native token ('customcoin') using cardano-cli, and send a transaction of this newly minted token to a new address.
#### Pre-requisites[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#pre-requisites "Direct link to Pre-requisites")
1. Download the latest version of [cardano-node from the releases page](https://github.com/intersectmbo/cardano-node/releases)
and config files for the public testnet from the [Cardano World](https://book.world.dev.cardano.org/environments.html)
2. Run the cardano-node:
cardano-node run --topology topology.json --database-path db --port 3001 --config config.json --socket-path node.socketexport CARDANO_NODE_SOCKET_PATH=~/node.socket
3. Generate a verification key and a signing key:
cardano-cli address key-gen \ --verification-key-file payment.vkey \ --signing-key-file payment.skey
The code should output something similar to this:
$ cat payment.skey { "type": "PaymentSigningKeyShelley_ed25519", "description": "Payment Signing Key", "cborHex": "58206c7c578e06f9175e20e63353b9beac984183f47ea7778960def47974435829f3"}$ cat payment.vkey { "type": "PaymentVerificationKeyShelley_ed25519", "description": "Payment Verification Key", "cborHex": "5820e70b3f8c2c18cdacc46efee076963029ca22c853d58e99cbe78f9a8e64c8c85f"}
4. Generate the payment address:
cardano-cli address build \--payment-verification-key-file payment.vkey \--out-file payment.addr
This code produces the following payment address:
$ cat payment.addraddr_test1vp6jzppqqegyvjnwc25dg853eam2xmxvydjntfw6d8x4p7qrnsnj9
5. Check the balance of the payment address:
cardano-cli query utxo --address
The response should show no funds:
TxHash TxIx Amount--------------------------------------------------------------------------------------
6. Fund the address:
Use the [testnet faucet](https://docs.cardano.org/cardano-testnets/tools/faucet/)
to fund your address,
and check again:
cardano-cli query utxo --address $(< payment.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------503c699e81d4abc3f8a1d2681425aee1e2ac5770a5be5b9314339591a7158f34 0 10000000000 lovelace + TxOutDatumNone
#### Start the minting process[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#start-the-minting-process "Direct link to Start the minting process")
1. Create a policy script:
mkdir policycardano-cli address key-gen \ --verification-key-file policy.vkey \ --signing-key-file policy.skeytouch policy.script && echo "" > policy.script echo "{" >> policy.script echo " \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy.vkey)\"," >> policy.script echo " \"type\": \"sig\"" >> policy.script echo "}" >> policy.script cat policy.script { "keyHash": "3c293ef7fa09577e8a656016d59abe042ed9fe38cdfd9d81568450c6", "type": "sig"}
2. Generate the policy ID and the hex encoded asset name.
The policyID is the script hash of the `policy.script`:
cardano-cli hash script --script-file policy.script 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74
get the asset name in hex, our token will be named "melcoin":
echo -n "customcoin" | xxd -ps 637573746f6d636f696e
#### Build the asset-minting transaction[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#build-the-asset-minting-transaction "Direct link to Build the asset-minting transaction")
1. Query the protocol parameters:
cardano-cli query protocol-parameters --out-file pparams.json
2. Calculate the minimum utxo size required to hold the desired number of native assets. Let's mint 1000 `customcoin`:
cardano-cli conway transaction calculate-min-required-utxo \--protocol-params-file pparams.json \--tx-out addr_test1vp6jzppqqegyvjnwc25dg853eam2xmxvydjntfw6d8x4p7qrnsnj9+"1000 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e"Coin 1051640
This means that we need at least 1051640 lovelace at the utxo to support the 1000 `customcoin`. To give ourselves some room for future transactions where we might send `custocoin` to different addresses we will send 10 ada on the minting transaction.
1. This transaction will mint 1000 "customcoin", with asset id `11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e`
cardano-cli conway transaction build \--tx-in 503c699e81d4abc3f8a1d2681425aee1e2ac5770a5be5b9314339591a7158f34#0 \--tx-out $(< payment.addr)+10000000+"1000 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e" \--mint="1000 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e" \--mint-script-file policy.script \--change-address $(< payment.addr) \--out-file mint-tx.rawEstimated transaction fee: Coin 175621
#### Sign the transaction:[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#sign-the-transaction "Direct link to Sign the transaction:")
cardano-cli conway transaction sign \--tx-file mint-tx.raw \--signing-key-file policy.skey \--signing-key-file payment.skey \--out-file mint-tx.signed
#### Submit the transaction:[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#submit-the-transaction "Direct link to Submit the transaction:")
cardano-cli conway transaction submit --tx-file mint-tx.signedTransaction successfully submitted.
cardano-cli query utxo --address $(< payment.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------d4b158e58cb58da28b25837300f6ef8f9f7d67fd5a5ce07648d17a6fae31b88a 0 10000000 lovelace + 1000 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e + TxOutDatumNoned4b158e58cb58da28b25837300f6ef8f9f7d67fd5a5ce07648d17a6fae31b88a 1 9989824379 lovelace + TxOutDatumNone
### Transferring tokens[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#transferring-tokens "Direct link to Transferring tokens")
Tokens can be sent just like ada by any token holder, just remember that it is not possible to send _only_ native-assets in a transaction, some ada always needs to be included in each output. The minimum amount is determined by the `utxoCostPerByte` protocol parameter. Also note that, currently, the `build` command cannot automatically balance native assets. This is, we need to manually balance native assets with `--tx-out` flags and use `--change-address` to automatically balance ada-only utxos.
For example, to send 1 `customcoin` to the address `addr_test1vp9khgeajxw8snjjvaaule727hpytrvpsnq8z7h9t3zeuegh55grh` we do:
cardano-cli conway transaction calculate-min-required-utxo \--protocol-params-file pparams.json \--tx-out addr_test1vp9khgeajxw8snjjvaaule727hpytrvpsnq8z7h9t3zeuegh55grh+"1 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e"Coin 1043020
and build the transaction with:
cardano-cli conway transaction build \--tx-in d4b158e58cb58da28b25837300f6ef8f9f7d67fd5a5ce07648d17a6fae31b88a#0 \--tx-in d4b158e58cb58da28b25837300f6ef8f9f7d67fd5a5ce07648d17a6fae31b88a#1 \--tx-out addr_test1vp9khgeajxw8snjjvaaule727hpytrvpsnq8z7h9t3zeuegh55grh+1043020+"1 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e" \--tx-out $(< payment.addr)+8956980+"999 11375f8ee31c280e1f2ec6fe11a73bca79d7a6a64f18e1e6980f0c74.637573746f6d636f696e" \--change-address $(< payment.addr) \--out-file tx.raw
cardano-cli conway transaction sign --tx-file tx.raw --signing-key-file policy.skey --signing-key-file payment.skey --out-file tx.signed
cardano-cli conway transaction submit --tx-file tx.signedTransaction successfully submitted.
### Buying and spending tokens[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#buying-and-spending-tokens "Direct link to Buying and spending tokens")
Token holders “buy” tokens from a token issuer. This will usually involve sending some ada to a specific address that has been set up by the token issuer and informing the token issuer about the address where the tokens should be sent. The token issuer will then set up a transaction that will transfer a multi-asset token to the specified address.
Tokens that have been issued to a token holder can be “spent” by returning them to a token issuer (i.e. by redeeming the tokens). This is done using a normal transaction. The token issuer will then provide the token holder with the agreed object in return (which may be an item of value, a service, a different kind of token, some ada, etc).
cardano-cli conway transaction build-raw ... --out-file txbody cardano-cli conway transaction sign ... --tx-body-file txbody --out-file txcardano-cli conway transaction submit ... --tx-file tx
### Destroying (burning) tokens[](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#destroying-burning-tokens "Direct link to Destroying (burning) tokens")
Tokens can be destroyed by a token issuer according to the token policy by supplying a negative value in the `--mint` field. That allows acquiring tokens in the UTXO entry in the input of a transaction, without adding them to one of the outputs, effectively destroying them. For example, tokens created in the previous section can be destroyed as follows:
TXID1=$(cardano-cli conway transaction txid --tx-body-file "$TX_BODY_FILE_1")TX_BODY_FILE_2=...TX_FILE_2=... cardano-cli conway transaction build-raw \--fee 0 \--tx-in "$TXID1"#0 \--tx-out="$ADDR+$LOVELACE" \--mint="-5 $POLICYID.637573746f6d636f696e" \--out-file "$TX_BODY_FILE_2" cardano-cli conway transaction sign \--signing-key-file "$SPENDING_KEY" \--signing-key-file "$MINTING_KEY" \--script-file "$SCRIPT" \--tx-body-file "$TX_BODY_FILE_2" \--out-file "TX_FILE_2" cardano-cli conway transaction submit --tx-file "$TX_FILE_2"
> Note: Destroying tokens requires both the payment credential for using the UTXO entry with the tokens, _and_ a credential for the minting policy script.
* [What are Native assets?](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#what-are-native-assets)
* [Syntax for expressing values in a transaction output](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#syntax-for-expressing-values-in-a-transaction-output)
* [Syntax of native asset values](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#syntax-of-native-asset-values)
* [Creating a transaction](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#creating-a-transaction)
* [Transaction outputs (TxOuts)](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#transaction-outputs-txouts)
* [Token minting policies](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#token-minting-policies)
* [Minting a new native token](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#minting-a-new-native-token)
* [Transferring tokens](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#transferring-tokens)
* [Buying and spending tokens](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#buying-and-spending-tokens)
* [Destroying (burning) tokens](https://developers.cardano.org/docs/get-started/cardano-cli/native-assets/#destroying-burning-tokens)
---
# Minimum hardware requirements to run a stake pool | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/hardware-requirements/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
The latest technical specifications and supported platforms can be found on the [Cardano Node release page](https://github.com/IntersectMBO/cardano-node/releases)
.
Currently the following specifications are recommended on Mainnet:
* Servers: 1 for block producer node + at least 2 for relay nodes
* CPU: An Intel or AMD x86 processor with two or more cores at 2GHz or faster
* Memory: 24GB of RAM
* Storage: 150GB of free storage (250GB recommended for future growth)
* Operating system: 64-bit Linux (Ubuntu 18.04+, Mint 19.3+, Debian 10.3+)
* Broadband: a good network connection with about 1 GB of bandwidth per hour on a public IP4 address
* [Air-gapped environment](https://developers.cardano.org/docs/get-started/air-gap)
for key security
For testnet pools, some requirements are smaller:
* Memory: 4GB of RAM
* Storage: 20GB of free storage
* Air-gapped environment not required
---
# On-Chain Polls | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
In the 8.0.0 version of Cardano-node, we incorporated a new group of commands to facilitate voting among stake pool operators. An "official" poll is characterized by being endorsed with a genesis delegate key.
important
This tutorial requires cardano-node 8.0.0
[https://github.com/IntersectMBO/cardano-node/releases/tag/8.0.0](https://github.com/IntersectMBO/cardano-node/releases/tag/8.0.0)
CIP-0094 - Poll participation[](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#cip-0094---poll-participation "Direct link to CIP-0094 - Poll participation")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Pre-requisites[](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#pre-requisites "Direct link to Pre-requisites")
For this guide, you require a Cardano-cli that has the `governance poll` subcommands. You can use anything from the Cardano-node [release v8.0.0](https://github.com/IntersectMBO/cardano-node/releases)
or a specially [backported 1.35.7 version](https://github.com/CardanoSolutions/cardano-node/releases/tag/1.35.7%2Bcip-0094)
. Once a Genesis Delegate Key holder has signed and posted a new poll question on the chain, it will appear in this Cardano Foundation [CIP-0094-polls repository](https://github.com/cardano-foundation/CIP-0094-polls)
.
You can find the JSON file containing the poll question in CBOR format by navigating into the specific subfolder.
For instance, the first [PreProd network Test question](https://github.com/cardano-foundation/CIP-0094-polls/tree/main/networks/preprod/d8c1b1d871a27d74fbddfa16d28ce38288411a75c5d3561bb74066bcd54689e2)
appears like this: **poll.json**
{ "type": "GovernancePoll", "description": "An on-chain poll for SPOs: How satisfied are you with the current rewards and incentives scheme?", "cborHex": "a1185ea200827840486f77207361746973666965642061726520796f752077697468207468652063757272656e74207265776172647320616e6420696e63656e74697665732073636568656d653f0183816c646973736174697366696564816a6e6f206f70696e696f6e8169736174697366696564"}
info
The signature from the genesis delegate key isn't included in this metadata but is employed as an additional signatory on the initiating transaction.
Download this file to your node.
Creating answer[](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#creating-answer "Direct link to Creating answer")
----------------------------------------------------------------------------------------------------------------------------------------------
From that point, you can generate a metadata entry to respond to the poll using the `governance answer-poll` command in the following way:
$ cardano-cli governance answer-poll --poll-file poll.json
This command will invite an interactive response from you. If you prefer not to respond interactively, you can employ `--answer` along with the index of the answer.
Executing this command will present the survey in a format easy to comprehend and will ask for your answer, as demonstrated below:
How satisfied are you with the current rewards and incentives scheme?[0] dissatisfied[1] no opinion[2] satisfiedPlease indicate an answer (by index): _
You can move forward by entering one of the possible answer indices (in this case, `0`, `1`, or `2`) followed by a newline. This will generate witnessed metadata in the form of a detailed JSON schema, which should be subsequently posted on-chain in any transaction and **signed with your stake pool's cold key**: ideally, this is achieved by constructing a basic transaction directed to yourself that carries the metadata.
Here is a sample of metadata where the answer `2` is selected:
**answer.json**
{ "94": { "map": [ { "k": { "int": 2 }, "v": { "bytes": "62c6be72bdf0b5b16e37e4f55cf87e46bd1281ee358b25b8006358bf25e71798" } }, { "k": { "int": 3 }, "v": { "int": 2 } } ] }}
Publishing answer[](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#publishing-answer "Direct link to Publishing answer")
----------------------------------------------------------------------------------------------------------------------------------------------------
From this point, you can utilize the `transaction build` command to generate a transaction for posting on-chain. You will require a signing key linked to a UTxO possessing sufficient funds to facilitate the transaction (approximately 0.2 Ada if you're making a basic transaction to yourself).
Assuming you have stored the metadata generated from the previous step in a file named `answer.json`, the command to construct the transaction would appear as follows:
$ cardano-cli conway transaction build \ --babbage-era \ --cardano-mode \ --mainnet \ --tx-in $TXID#$IX \ --change-address $ADDRESS \ --metadata-json-file answer.json \ --json-metadata-detailed-schema \ --required-signer-hash $POOL_ID \ --out-file answer.tx
caution
Please be aware that adding `--required-signer-hash` is crucial for the response to be considered valid for the survey; this serves as your identification as a stake pool operator.
You can produce the `$POOL_ID` hash from the Bech32 formatted pool ID using the Bech32 command:
$ bech32 <<< pool1....
To submit the response to the chain, you need to provide the respective values for `--tx-in` & `--change-address` from one of your wallets.
From this point, you can sign `answer.tx` using your stake pool's cold key and any necessary payment key, then submit the result as usual. If everything proceeds correctly, the cardano-cli should present a transaction id that you can monitor on-chain to confirm your survey response was correctly published.
SPO-Poll Dashboards where your transaction should now be visible:
* Cardanoscan.io \[[PreProd](https://preprod.cardanoscan.io/spo-polls/)\
\] \[[Mainnet](https://cardanoscan.io/spo-polls/)\
\]
Verifying Answers[](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#verifying-answers "Direct link to Verifying Answers")
----------------------------------------------------------------------------------------------------------------------------------------------------
Lastly, you can validate answers observed on-chain using the `governance verify-poll` command. The term 'verify' here has a dual meaning:
* It verifies that an answer is valid in the context of a specific survey
* It provides a list of the signatory key hashes found in the transaction; in the case of a valid submission, one key hash will correspond to a recognized stake pool id.
Assuming you still have the original `poll.json` file, and a signed transaction carrying a survey answer as `answer.signed`, you can confirm its validity using:
$ cardano-cli governance verify-poll \ --poll-file poll.json \ --tx-file answer.signed
Upon successful execution, this should produce something like:
Found valid poll answer, signed by:[ "f8db28823f8ebd01a2d9e24efb2f0d18e387665770274513e370b5d5"]
Alternatively, the command will identify a problem with the answer and/or poll.
References[](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#references "Direct link to References")
-------------------------------------------------------------------------------------------------------------------------------
* [Entering Voltaire: on-chain poll for SPOs](https://forum.cardano.org/t/entering-voltaire-on-chain-poll-for-spos/117330?u=adatainment)
* [Cardano Node 8.0.0 release](https://github.com/IntersectMBO/cardano-node/releases/tag/8.0.0)
* [Cardano Node documentation: Governance](https://github.com/input-output-hk/cardano-node-wiki/wiki/cardano-governance)
* [CIP-0094 - Poll participation](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#cip-0094---poll-participation)
* [Pre-requisites](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#pre-requisites)
* [Creating answer](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#creating-answer)
* [Publishing answer](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#publishing-answer)
* [Verifying Answers](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#verifying-answers)
* [References](https://developers.cardano.org/docs/operate-a-stake-pool/on-chain-polls/#references)
---
# Authenticating users with their Cardano wallet | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Overview[](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#overview "Direct link to Overview")
----------------------------------------------------------------------------------------------------------------------------------
This guide is a walkthrough on how to implement the _message signing_ described in [CIP-08](https://cips.cardano.org/cip/CIP-0008)
in order to authenticate users on the web with just their [CIP-30](https://cips.cardano.org/cip/CIP-0030)
\-compatible wallet app.
note
There are 2 components used in this guide — the front-end and the back-end. In order to implement this example, a [nodejs](https://nodejs.org/)
server is needed to run the back-end component that will receive and process the signed message submitted by the user.
Use cases[](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#use-cases "Direct link to Use cases")
-------------------------------------------------------------------------------------------------------------------------------------
The following are a just some examples of where this implementation can be used:
1. Authenticating holders of a specific native token in order to grant access to exclusive content or service
2. Authenticating wallet or stake address owners for registration to some whitelist
3. Authenticating wallet or stake address owners when claiming native token rewards
Time to code[](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#time-to-code "Direct link to Time to code")
----------------------------------------------------------------------------------------------------------------------------------------------
As mentioned above, there are 2 components in this example - the front-end and the back-end. Our front-end code will handle our interaction with the user, to prompt them to sign some message with their wallet. The signed message will then be submitted to our back-end component which will parse the message and verify the user's signature.
In this example, we will be asking the user to sign a simple text message containing the string `account:` , followed by their wallet's bech32 stake address. For example:
`account: stake1uynpv0vlulhufm8txwry0da9qq6tn9wn42mxltq65pw403qvdcveh`
Our purpose in this case is for the user to prove their ownership of the given stake address.
Also for simplicity, we will be interacting with [Typhon Wallet](https://typhonwallet.io/)
only, in this example. But the concepts shown here should work with any other [CIP-30](https://cips.cardano.org/cip/CIP-0030)
\-compliant wallet app.
### Front-end[](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#front-end "Direct link to Front-end")
For brevity, our front-end component will just be an HTML page containing a single button which will start the process, when clicked by the user.
index.html
Authenticating users with their Cardano wallet
The logic to handle the click event on the above button will be in a separate Javascript file. This is what we will really be working on for the front-end component. Let's start with the following:
userWalletAuth.js
window.addEventListener("load", () => { const loginBtn = document.querySelector("#login-btn"); loginBtn.addEventListener("click", authenticate);})async function authenticate(){ //}
For now, we just attached an event listener to our button, which will call the function `authenticate` when clicked.
Before we go on to add functionality to `authenticate` and anything else, we have to first import a couple of dependencies. Let's add the following to the top of `userWalletAuth.js`:
userWalletAuth.js
import { Buffer } from "buffer";let csl, wallet;async function loadCsl(){ csl = await import("@emurgo/cardano-serialization-lib-browser/cardano_serialization_lib");};loadCsl();...
With the above lines, we just made available to the rest of our script, the [Buffer](https://www.npmjs.com/package/buffer)
package and the [Cardano Serialization Library](https://developers.cardano.org/docs/get-started/cardano-serialization-lib/overview)
. Also, we just declared the top-level variable `wallet` there for convenience later. We will set its value in the following steps.
Now, let's make the `authenticate` function actually do some things:
userWalletAuth.js
...async function authenticate(){ if (!csl) await loadCsl(); // make sure CSL is loaded before doing anything else. wallet = await window.cardano.typhoncip30.enable(); const [stakeAddrHex, stakeAddrBech32] = await getStakeAddress(); const messageUtf = `account: ${stakeAddrBech32}`; const messageHex = Buffer.from(messageUtf).toString("hex"); const sigData = await wallet.signData(stakeAddrHex, messageHex); const result = await submitToBackend(sigData); alert(result.message);}
Our `authenticate` function now gets the user's stake address both in hex and bech32 format. It then puts together the message that we'll ask the user to sign. After converting the message into a hex string, we call the `signData` method on the user's wallet to prompt the user to sign. When we get the signed message, we send it to our backend component to be processed and verified.
You'll notice that we called two more functions from the `authenticate` function. We have to add them to our code also:
userWalletAuth.js
...async function getStakeAddress(){ const networkId = await wallet.getNetworkId(); const changeAddrHex = await wallet.getChangeAddress(); // derive the stake address from the change address to be sure we are getting // the stake address of the currently active account. const changeAddress = csl.Address.from_bytes( Buffer.from(changeAddrHex, 'hex') ); const stakeCredential = csl.BaseAddress.from_address(changeAddress).stake_cred(); const stakeAddress = csl.RewardAddress.new(networkId, stakeCredential).to_address(); return [stakeAddress.to_hex(), stakeAddress.to_bech32()];}async function submitToBackend(sigData){ const result = await fetch(`http://localhost:8081/login`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(sigData), }); return result.json();}
That completes our front-end code. It can be viewed in full [here](https://github.com/inimrod/cardano-message-signing-demo/blob/main/frontend/js/userWalletAuth.js)
.
### Back-end[](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#back-end "Direct link to Back-end")
For our back-end, let's create a file named `server.js` and first, we will import the dependencies we need:
server.js
const { Buffer } = require("buffer");const { COSESign1, COSEKey, BigNum, Label, Int } = require("@emurgo/cardano-message-signing-nodejs");const { Ed25519Signature, RewardAddress, PublicKey, Address } = require("@emurgo/cardano-serialization-lib-nodejs");const express = require("express");const cors = require("cors");
Here, we will be creating just a simple [Express JS](https://expressjs.com/)
server that can receive our `POST` request from our front-end. Along with the others, we imported a few required classes from the `cardano-message-signing` and `cardano-serialization-lib` packages.
Now let's add a sample list of "registered users" of our app, identified by their stake addresses:
server.js
...const registeredUsers = [ "stake1uyzu7upg082rqajwasmwgam09fe7yj2cm3fkdfecqgptg8cwuze7s", "stake1u8k7mwu8gdqyvgved89996cy6g8d9vw36w7j05qy2etanxgmgl5s7", "stake1uynpv0vlulhufm8txwry0da9qq6tn9wn42mxltq65pw403qvdcveh", "stake1uxa2x4andawqtcqxw9gy4mamdx6extq5g5grqq6pf7zpxxge4aa7l", "stake1ux8yttnhy6qm9lkehvnmlhufnx38ef2q8vl6xyu8gyk0zwc83nvxh", "stake1uykkptznwz0jd3flwa442a0cdmfrpwhg8pa9ypytf4cwacqw2085c"]
Next, we create our `express` server with one endpoint to receive the request from our front-end:
server.js
...const app = express();app.use(express.json());app.options("*", cors());app.use(cors({ origin: "*"}));app.post("/login", authenticate);app.listen(8081, () => console.log("Backend component listening on port 8081!"),);
The above code adds the `/login` endpoint which fires up the `authenticate` handler function. Now let's add that function:
server.js
...async function authenticate(req, res) { const sigData = req.body; const decoded = COSESign1.from_bytes( Buffer.from(sigData.signature, "hex") ); const headermap = decoded.headers().protected().deserialized_headers(); const addressHex = Buffer.from( headermap.header( Label.new_text("address") ).to_bytes() ) .toString("hex") .substring(4); const address = Address.from_bytes( Buffer.from(addressHex, "hex") ); const key = COSEKey.from_bytes( Buffer.from(sigData.key, "hex") ); const pubKeyBytes = key.header( Label.new_int( Int.new_negative(BigNum.from_str("2")) ) ).as_bytes(); const publicKey = PublicKey.from_bytes(pubKeyBytes); const payload = decoded.payload(); const signature = Ed25519Signature.from_bytes(decoded.signature()); const receivedData = decoded.signed_data().to_bytes(); const signerStakeAddrBech32 = RewardAddress.from_address(address).to_address().to_bech32(); const utf8Payload = Buffer.from(payload).toString("utf8"); const expectedPayload = `account: ${signerStakeAddrBech32}`; // reconstructed message // verify: const isVerified = publicKey.verify(receivedData, signature); const payloadAsExpected = utf8Payload == expectedPayload; const signerIsRegistered = registeredUsers.includes(signerStakeAddrBech32); const isAuthSuccess = isVerified && payloadAsExpected && signerIsRegistered; res.send({ success: isAuthSuccess, message: isAuthSuccess ? "✅ Authentication success!" : "❌ Authentication failed." })}
Let's unpack what happened there.
First, we decoded the serialized signature that was submitted by the user. From the headers of this decoded data, we got the address of the signer. We later convert it back to its bech32 format to reconstruct our expected message string.
We then created a `PublicKey` instance of the `key` that came together with the signature sent by the user. We later use this to verify the submitted signature.
We also parsed the `payload` from the decoded signature data. After reconstructing our expected message string, we compare it with the `payload` we actually received.
Since we already have the signer's stake address, we also checked it against our `registeredUsers` list.
Lastly, we send a response back to the user with a success message if all three checks where passed and a failure message if otherwise.
That completes our backend component. The full code can be viewed [here](https://github.com/inimrod/cardano-message-signing-demo/blob/main/backend/server.js)
.
### Demo project repository[](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#demo-project-repository "Direct link to Demo project repository")
For quick and convenient testing of the above code, a demo project is available [here](https://github.com/inimrod/cardano-message-signing-demo)
that can be cloned and quickly run.
* [Overview](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#overview)
* [Use cases](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#use-cases)
* [Time to code](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#time-to-code)
* [Front-end](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#front-end)
* [Back-end](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#back-end)
* [Demo project repository](https://developers.cardano.org/docs/integrate-cardano/user-wallet-authentication/#demo-project-repository)
---
# Receiving payments (Blockfrost API) | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Welcome to the documentation of a Point of Sale (POS) application built using Cardano APIs. This guide will walk you through the key features and functionalities of the application.

### Getting Started[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#getting-started "Direct link to Getting Started")
In this tutorial, we will guide you through the process of building a fully functional Point of Sale application on top of the Cardano blockchain. To get started, you will need to fork the [starting point repository](https://github.com/fill-the-fill/cardano-pos-starting-point)
, which contains all the necessary files and configurations to begin building your own Point of Sale application.
The [starting point repository](https://github.com/fill-the-fill/cardano-pos-starting-point)
already provides simple CSS and logic behind inputs, props passing and other things, so in this guide, we will mostly focus on connecting APIs and retrieving data from them to create a fully functional Point of Sale application using Cardano.
note
Make sure to run the command `npm install` in your terminal to install all the necessary dependencies.
Use the command `npm run dev` and your project will be up and running.
### Structure of the project[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#structure-of-the-project "Direct link to Structure of the project")
src├── constants├── components├── pages│ ├── api| └── index.js├── styles│ ├── pos.modules.css├── .env.local├── .env.example├── README.md
### Project structure rundown[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#project-structure-rundown "Direct link to Project structure rundown")
* `/constants/` - Contains various constant links and values that are used throughout application.
* `/components/` - Contains various reusable components that can be used throughout application.
* `/pages/` - Contains pages and APIs.
* `/styles/` - Contains all of the styling files.
* `.env.local` - Contains API keys.
* `.env.example` - Contains example of how your API keys should be stored.
### Requirements[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#requirements "Direct link to Requirements")
We'll need to obtain API keys for both services. These API keys will allow us to access the data and functionality we need to build and test our application.
note
Please refer to `.env.example` in the repo and create `.env.local` file. Your keys should be stored there.
#### Get Blockfrost Key[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#get-blockfrost-key "Direct link to Get Blockfrost Key")
1. Please follow [Get Started with Blockfrost](https://developers.cardano.org/docs/get-started/blockfrost/get-started)
to obtain Blockfrost API key
2. In the code, go to environment file `.env.local` and put the key into `BLOCKFROST_API_KEY`.
#### Get CoinMarketCap Key[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#get-coinmarketcap-key "Direct link to Get CoinMarketCap Key")
1. Go to [CoinMarketCap](https://pro.coinmarketcap.com/login/)
and sign in to your account.
2. Once you're signed in, navigate to your dashboard.
3. Copy API Key.
4. In the code, go to environment file `.env.local` and put the key into `COINMARKETCAP_API_KEY`.
### Adding Constants[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#adding-constants "Direct link to Adding Constants")
Before creating any API requests, it is important to add constants such as base URLs and endpoints. These constants will be used throughout the project and will make it easier to make changes or updates in the future.
Navigate to `constants` folder, create `links.js` file and insert the following based on network you will be using:
* Preview
* Pre-Production
* Mainnet
export const LINKS = { CARDANO_SCAN: "https://preview.cardanoscan.io/address/", BLOCKFROST_ADDRESS: "https://cardano-preview.blockfrost.io/api/v0/addresses/", COINMARKETCAP_ADA_USD_PAIR: "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ADA&convert=USD",};
export const LINKS = { CARDANO_SCAN: "https://preprod.cardanoscan.io/address/", BLOCKFROST_ADDRESS: "https://cardano-preprod.blockfrost.io/api/v0/addresses/", COINMARKETCAP_ADA_USD_PAIR: "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ADA&convert=USD",};
export const LINKS = { CARDANO_SCAN: "https://cardanoscan.io/address/", BLOCKFROST_ADDRESS: "https://cardano-mainnet.blockfrost.io/api/v0/addresses/", COINMARKETCAP_ADA_USD_PAIR: "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ADA&convert=USD",};
### Creating API files[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#creating-api-files "Direct link to Creating API files")
In `api` folder create `blockfrost.js` file and insert the following code:
import { LINKS } from "../../constants/links";export default async function handler(req, res) { const { address } = req.query; const projectId = process.env.BLOCKFROST_API_KEY; const url = LINKS.BLOCKFROST_ADDRESS + address + "/total"; const response = await fetch(url, { headers: { "Content-Type": "application/json", project_id: projectId, }, }); const data = await response.json(); res.status(200).json({ value: data });}
In this file, we are creating an API request to `Blockfrost` using personal key. We use constant link address and submit `projectId` to get a `data` response.
Now let’s do the same with CoinMarketCap. Add `coinmarketcap.js` file into `api` folder to receive pair data:
import { LINKS } from "../../constants/links";export default async function handler(req, res) { const url = LINKS.COINMARKETCAP_ADA_USD_PAIR; const response = await fetch(url, { headers: { "X-CMC_PRO_API_KEY": process.env.COINMARKETCAP_API_KEY, }, }); const data = await response.json(); const adaPrice = data.data.ADA.quote.USD.price; res.status(200).json({ value: adaPrice });}
In this file, we are creating another API request to `CoinMarketCap` to receive price of 1 ada in USD.
### Connecting APIs[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#connecting-apis "Direct link to Connecting APIs")
Now that all of the APIs are set up and ready to be used, it's time to move onto the `index.js` file and start adding the necessary functionalities and API requests.
To fetch the `ada-usd` price upon loading the page, we need to add the `fetchAdaPrice` and `useEffect` functions to the `index.js` file:
// Fetch ada price from CoinMarketCap const fetchAdaPrice = async () => { fetch("/api/coinmarketcap") .then((response) => { if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); }) .then((data) => setAdaValue(data.value)) .catch((error) => console.error("Error:", error)); }; useEffect(() => { const fetchPrice = async () => { await fetchAdaPrice(); }; fetchPrice(); }, []);
This code will make an API request to retrieve the current price and display it on the page for the user to see. The `fetchAdaPrice` function will perform an API request to CoinMarketCap and set the `adaValue` state with the current value. Later on, in the return statement, the calculated value based on the input amount will be displayed as:
{amount} $ = {(amount / adaValue).toFixed(2)} ₳
Connecting Blockfrost API to Popup[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#connecting-blockfrost-api-to-popup "Direct link to Connecting Blockfrost API to Popup")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Next, we will add some Blockfrost API requests to the popup to compare the inserted address balance and see if the transaction went through successfully.
Navigate to `components` folder into `popup.js`. The current popup generates a QR code for users to scan, which redirects with a [CIP-13](https://cips.cardano.org/cip/CIP-0013)
URI guidelines and automatically fills in the details for the transaction, such as the address and the amount to be sent. For now, the application does not connect to the API, so we need to add a few functions to ensure application able to retrieve the necessary data from the API.
First, lets add `fetchAddressQuantityOnOpen` function to fetch balance of the address:
// Fetch balance of ada in the address when opening popup const fetchAddressQuantityOnOpen = async () => { address.length && fetch(`/api/blockfrost?address=${address}`) .then((response) => { if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); }) .then((data) => { if (data.value.received_sum) { setBalance(data.value.received_sum[0].quantity / 1000000); } }) .catch((error) => console.error("Error:", error)); };
This function will store current balance in the store called `balance`.
Now let’s create another function called `CompareQuantity` that fetches address balance but checks it every few seconds:
// Fetch balance of ada in the address every few seconds to compare it with the initial balance from fetchAddressQuantityOnOpen() const CompareQuantity = async () => { fetch(`/api/blockfrost?address=${address}`) .then((response) => { if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); }) .then((data) => { if (data.value.received_sum) { setNewBalance(data.value.received_sum[0].quantity / 1000000); } }) .catch((error) => console.error("Error:", error)); }; // Fetch ada balance every 3 seconds useEffect(() => { address && fetchAddressQuantityOnOpen(address); const interval = address && setInterval(() => { const result = CompareQuantity(address); return result; }, 3000); return () => clearInterval(interval); }, [address]);
This function will store new balance in the store called `newBalance` state and using `useEffect` will continue fetching data every few seconds.
Later on in the code, we compare `balance` and `newBalance` states. If `newBalance` is greater or equal by the `amount` requested, the `Waiting for payment…` will be changed to `Payment received successfully`
Here it how it looks:
{newBalance - balance >= amount ? ( Payment received successfully ) : ( Waiting for payment... )}
#### Adding CardanoScan Redirect[](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#adding-cardanoscan-redirect "Direct link to Adding CardanoScan Redirect")
To add a redirect to CardanoScan in the `href` attribute of our popup component, we need to add the following code into our application.
import { LINKS } from "../constants/links";
Locate into `return` section and uncomment the following section:
{address.substring(0, 30) + "..."}
Congratulations! Your Point of Sale application using Cardano is now fully functional and ready to use. You can test it by entering an amount and address into the inputs, scanning the generated QR code, performing a transaction and waiting for confirmation on the popup screen.
* [Getting Started](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#getting-started)
* [Structure of the project](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#structure-of-the-project)
* [Project structure rundown](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#project-structure-rundown)
* [Requirements](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#requirements)
* [Adding Constants](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#adding-constants)
* [Creating API files](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#creating-api-files)
* [Connecting APIs](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#connecting-apis)
* [Connecting Blockfrost API to Popup](https://developers.cardano.org/docs/integrate-cardano/point-of-sale/#connecting-blockfrost-api-to-popup)
---
# Simple scripts | Cardano Developer Portal
[Skip to main content](https://developers.cardano.org/docs/get-started/cardano-cli/simple-scripts/#__docusaurus_skipToContent_fallback)
**Apply to Intersect [Developer Advocate Program](https://share-eu1.hsforms.com/1maE1eibKTdOpZuoEdQRPggqare0)
⭐️**
On this page
Cardano is designed to support multiple script languages, and most features that are related to scripts work the same irrespective of the script language (or version of a script language).
Since Shelley era, Cardano supports the **Simple script** language, which can be used for multi-signature addresses.
The Allegra era extends the simple script language with a feature to make scripts conditional on time (token locking). This can be used to make address with "time locks", where the funds cannot be withdrawn from a script address until after a certain point in time.
The Alonzo era brought support for **Plutus scripts**, these are out of the scope of this section.
Script addresses[](https://developers.cardano.org/docs/get-started/cardano-cli/simple-scripts/#script-addresses "Direct link to Script addresses")
----------------------------------------------------------------------------------------------------------------------------------------------------
In general, addresses (both payment addresses and stake addresses) specify the _authorisation conditions_ that must be met for the address to be used. For payment addresses, this means the authorisation conditions for funds to be withdrawn. For stake addresses, this means the authorisation conditions for setting a delegation choice or rewards withdrawal.
Both payment and stake addresses come in two flavours: _single-key based_ or _script based_. The key-based addresses use a single cryptographic key per address. The authorisation condition to use the address is that one holds the secret (signing) part of the cryptographic key (for that address) and thus be able to make a cryptographic signature for that key.
The script-based addresses use a script per address. The authorisation condition to use the address is that the _evaluation_ of the script for the address results in success. The script expresses the authorisation conditions and evaluation of the script tests if those conditions are met. For example, a very simple script might express the condition that one holds a particular cryptographic signing key. The script would express that condition by testing if the transaction has a cryptographic signature from the appropriate cryptographic verification key. Such a script would, of course, be exactly equivalent to an ordinary single-key based address: the authorisation conditions would be the same! Thus, we can see that single-key based addresses are in some sense just a (very common) special case and that script addresses are the general case.
When using an address (payment or stake) in a transaction, the transaction must contain the information needed to show that the authorisation conditions for the use of the address are met. This information is known as a _transaction witness_. We say that it _witnesses_ the validity of the transaction using the address. The addresses themselves have a _credential_ which is information sufficient to check that a witness is the right witness.
Specifically, there are two types of such credentials, for key and script addresses:
* **Key credential** - a key credential is constructed using a _verification key (vk)_ (which has corresponding _signing key (sk)_). The credential is the cryptographic hash of the verification key _H(vk)_.
The transaction witness for a key credential consists of the _verification key vk_ and the signature of transaction body hash using the _signing key sk_.
* **Script credential** - a script credential is the hash of the script.
The transaction witness for a script credential is the script itself. There are no other inputs for the very simple script language introduced in the Shelley era. Scripts in the Plutus language (once that is available) will require additional inputs which will also form part of the witness.
Multi-signature scripts[](https://developers.cardano.org/docs/get-started/cardano-cli/simple-scripts/#multi-signature-scripts "Direct link to Multi-signature scripts")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In Shelley and later eras, multisig scripts are used to make script addresses where the authorisation condition for a transaction to use that address is that the transaction has signatures from multiple cryptographic keys. Examples include M of N schemes, where a transaction can be authorized if at least _M_ distinct keys, from a set of _N_ keys, sign the transaction.
As with all scripts, the transaction witness for a multisig script address includes the script itself. The multisig language is so simple that this is the entire witness: there are no other script data inputs. Although the script itself is the witness, the script has _conditions_ that must be satisfied. The conditions for multisig scripts are that the transaction has other ordinary key witnesses. Which combination of key witnesses are acceptable is, of course, determined by the script.
The multisig script language is an expression language. Its scripts form an expression tree. The evaluation of the script produces either `true` or `false`.
In BNF notation, the script expressions follow the following abstract syntax: