Skip to main content

Smart Contracts

You arrive able to build transactions, mint under policies you wrote, and delegate stake and votes. Until now most rules you enforced were the ledger's own; this module generalizes the policy idea into validator scripts that guard any UTXO with logic you define.

What are smart contracts?

Smart contracts are agreements defined in code that enforce their terms automatically, without intermediaries. On Cardano they work differently from account-based chains, and the key to understanding them is the eUTXO model: a smart contract is a validator script that guards UTXOs locked at its address. You lock a UTXO at the script's address, and from then on it can only be spent by a transaction the script approves.

Smart contracts are validators, not actors

Mental model shift

The most important shift when coming from other blockchains: a smart contract cannot take actions. It can only approve or reject a proposed transaction.

A Cardano validator cannot send tokens, call another contract imperatively, initiate anything on its own, make network requests, read external data directly, generate random numbers, or loop forever (execution budgets enforce termination). Instead it validates: users propose a transaction, and the validator approves or rejects it against the logic you wrote. These limits are features. They make validators deterministic (the same inputs always produce the same result), which is the foundation of Cardano's predictability.

On-chain and off-chain

A contract has two halves:

  • On-chain (the validator): the immutable logic that runs on every node and approves or rejects spends from the contract address. It runs once per script input in a transaction.
  • Off-chain: the application that finds the locked UTXOs and builds transactions the validator will approve. It can be written in any language and handles the UI, data fetching, and transaction building.
The lawyer and the judge

Think of off-chain code as the lawyer drafting a contract and on-chain code as the judge reviewing it. The lawyer does the creative work of figuring out what the agreement should look like; the judge only checks whether it complies with the rules. This is why on-chain execution stays cheap, off-chain code can be in any language, and you can test the two halves independently.

Sending a UTXO to the script address initialises a contract instance. Anyone can send a UTXO there (with any datum, or none); the validator decides what can leave.

The validator's inputs

A validator is a function of three arguments:

Validator function signature
f(datum, redeemer, context) = success | failure
  • Datum: state attached to the locked UTXO, set when it is created (the "e" in eUTXO).
  • Redeemer: the argument the spender supplies to unlock it, naming the action they want.
  • Context: the transaction the validator is judging, its inputs, outputs, signatures, mint, and validity range, so the script can assert facts about the whole transaction, not just the one UTXO it guards.
Deep dive

This is the quick tour. The full reference, the complete transaction context, the ScriptPurpose, inline-vs-hash datums, and the patterns they enable, is Datum, redeemer & context.

Script addresses and purposes

A script address is derived from the hash of the validator, so the rules are bound to the address. UTXOs sent there can only be spent when the script approves the spending transaction. The hash includes a language tag (0x01 PlutusV1, 0x02 PlutusV2, 0x03 PlutusV3), so identical code under different versions yields different addresses.

Address collision

The same contract code always produces the same address within the same Plutus version. If you deploy code someone else already deployed, you get the same address, and there may already be history there.

Unlike key-controlled addresses, a script address is governed by code: anyone can send funds to it, but only a transaction that satisfies the validator can spend them.

A script also has a purpose, the kind of action it guards:

Script purposeValidates
SpendConsuming a UTXO. The most common, and the only purpose that receives a datum.
MintToken creation and destruction (minting policies).
PublishCertificates: stake delegation, pool and DRep registration, committee changes.
WithdrawStake reward withdrawals.
VoteGovernance votes (Conway).
ProposeGovernance proposals (Conway).
NativeThe pre-Plutus scripting language for simple multisig and time-locks (all-of, any-of, before/after).

How scripts execute

A transaction that includes scripts is validated in two phases:

  • Phase 1 checks the transaction structure: inputs exist, signatures are valid, the transaction balances.
  • Phase 2 runs the scripts. Each gets a budget of execution units (ExUnits), priced into the fee.

Because phase-2 work is real, a script transaction also carries collateral: ADA-only UTXOs the node consumes only if a script fails phase 2. Honest transactions that succeed never lose it, while flooding the network with failing scripts becomes expensive. The full rules live in collateral; setting it in practice is covered in Lock and spend, and the SDKs select it for you.

Deterministic validation

Validation depends only on the transaction and its context, never on live network state. That determinism lets you compute a transaction's outcome and its exact cost before you submit it, unlike chains where gas and ordering shift under load. It also means a validator cannot generate randomness; getting a verifiable random number despite that is its own topic, covered in on-chain randomness.

The contract lifecycle

In practice a stateful contract moves through three steps, shown here with a counter that only increments:

  1. Write the validator: it approves a spend only when the new datum is a valid transition from the old one (here count + 1) and the right party signed.
  2. Lock: send a UTXO to the script address with the initial datum (count: 0).
  3. Unlock and update: spend that UTXO with a redeemer (increment); the validator checks the transition, and a new UTXO carries the updated datum (count: 1) while the old one is consumed.

The hands-on version, with Evolution, Mesh, and cardano-cli, is in Lock and spend.

What makes Cardano contracts different

A few ledger features shape how you design contracts:

  • Reference inputs (CIP-31): read a UTXO's data without spending it, so many contracts can read one oracle feed at once.
  • Inline datums (CIP-32): store the datum in the output itself instead of a hash. See Datum, redeemer & context.
  • Reference scripts (CIP-33): deploy a script once and reference it from later transactions. The transaction shrinks, and the referenced bytes carry a per-byte fee well below the cost of inlining. See Lock and spend.
  • Collateral output (CIP-40): return excess collateral to an address you choose.

A validator's rules cannot be changed after deployment, and the compiled code cannot be turned back into source.

That permanence runs one way only. On-chain code keeps working unchanged for as long as the chain exists, across hard forks and new ledger eras. Off-chain code is the opposite: it depends on details that shift between eras, such as fee parameters and how transactions are assembled, so it has to be kept current and re-tested as the network evolves. The validator you deployed years ago still judges by the same rules; the code that builds transactions against it may need maintenance to keep up.

Choose a language

Validators can be written in several languages that all compile to the same on-chain bytecode (UPLC). The examples in this module are written in Aiken. See Choose a language for the full comparison (Aiken, Plinth, Plutarch, OpShin, Scalus, Pebble, Marlowe).

Key takeaways

  • Smart contracts are validators, not programs. They check whether a transaction is allowed; they do not perform its logic.
  • On-chain validates; off-chain constructs. This keeps on-chain execution cheap and lets you write and test the two halves independently.
  • Determinism is the superpower. You know a transaction's outcome and cost before submitting it, which removes wasted fees and the fee-auction form of front-running.
  • Script addresses lock UTXOs under code, replacing key-based authorization with arbitrary rules.
  • The eUTXO model extends UTXOs with datums, redeemers, and context, enabling full contract logic while preserving determinism and parallelism.

Next steps

This module builds up from here, in order:

  1. Datum, redeemer & context: the three arguments every validator receives, in depth.
  2. Choose a language: pick how you'll write validators.
  3. Write a validator: the on-chain code itself, purpose by purpose.
  4. Lock and spend: build the off-chain transactions that interact with a contract.
  5. Testing: verify validators with mock transactions before you deploy.
  6. Contract library: audited, open-source contracts to read or start from.
  7. Security: what the eUTXO model protects you from, what it leaves to you, and how contracts are verified, with the vulnerability reference and the CTF beneath it.
  8. Advanced: design patterns, UPLC, CBOR debugging, optimization, and the cryptographic primitives. Reference material, read when you need it.

Then Build a dApp, the next module, where your contracts meet users.