Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
b744c1a
Move the Beginner example under beginner/ and repoint its imports
paulobressan Aug 19, 2026
bffb8a6
Give extractRegion a #replace directive and tidy its helpers
paulobressan Aug 19, 2026
885da92
Add the vault example: an Aiken contract and a Mesh app
paulobressan Aug 19, 2026
bd6aab8
Add Intermediate lectures 1 to 9
paulobressan Aug 19, 2026
3943444
Replace the Blockfrost handler with a Vite proxy rule
paulobressan Aug 19, 2026
7512c6d
Quiet the offline tests and drop their unused import
paulobressan Aug 19, 2026
5af78d2
Trim example comments the lecture already makes
paulobressan Aug 19, 2026
22635d5
Add a Vercel entry point for the Blockfrost proxy
paulobressan Aug 19, 2026
76779ea
Tighten lecture 9 and correct its claims
paulobressan Aug 19, 2026
c939acc
Apply the review feedback on the Intermediate lectures
paulobressan Aug 25, 2026
f7c73bd
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
dcf4406
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
e1e91ed
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
8d61c89
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
a321cba
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
1fb0045
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
22b1dd5
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
7964f27
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
d807d98
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
97ad912
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 26, 2026
fecdf0d
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 26, 2026
b681ae6
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 26, 2026
0b8aa30
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
3212c58
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
1f287df
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
848bc16
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
afab14b
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
b819c9b
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 26, 2026
6da929c
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 26, 2026
12345ff
Merge remote-tracking branch 'origin/staging' into 1921-onboarding-in…
paulobressan Aug 26, 2026
482f377
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
2aaa605
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
89e594f
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
14b1a59
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
c648e40
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
b162bc4
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
1f18fae
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
8a45c7f
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
c655c35
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
1901770
Update docs/developers/onboarding/lectures/intermediate/6-testing.md
paulobressan Aug 27, 2026
6842d41
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 27, 2026
4456e2b
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 27, 2026
fcf2e2b
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 27, 2026
a42b326
Update docs/developers/onboarding/lectures/intermediate/3-what-is-a-v…
paulobressan Aug 27, 2026
9a6fe35
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
658d494
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
abac7c6
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
59f5ffa
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
0ae7176
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
9c9f302
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
1aeb386
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
90c377a
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
67ee991
Update docs/developers/onboarding/lectures/intermediate/4-datum-and-r…
paulobressan Aug 27, 2026
050f0eb
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
caa90d1
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
fd4c924
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
1935838
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
f63919f
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
674a6ca
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
01ef877
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
6f6aece
Update docs/developers/onboarding/lectures/intermediate/5-transaction…
paulobressan Aug 27, 2026
cf6b71d
Merge branch '1921-onboarding-intermediate-lectures' of github.com:ca…
paulobressan Aug 27, 2026
fa67444
Improve intermediate lectures and split the vault's mint policy into …
paulobressan Aug 30, 2026
fd3a862
Merge branch 'new-onboarding' into 1921-onboarding-intermediate-lectures
paulobressan Aug 31, 2026
879202e
Update docs/developers/onboarding/lectures/intermediate/7-parameters.md
paulobressan Aug 31, 2026
bd96abf
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
96c2301
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
20dea1b
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
5429f49
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
109f069
Update docs/developers/onboarding/lectures/intermediate/7-parameters.md
paulobressan Aug 31, 2026
16755d9
Update docs/developers/onboarding/lectures/intermediate/7-parameters.md
paulobressan Aug 31, 2026
69f5a47
Update docs/developers/onboarding/lectures/intermediate/7-parameters.md
paulobressan Aug 31, 2026
96f0521
Update docs/developers/onboarding/lectures/intermediate/7-parameters.md
paulobressan Aug 31, 2026
3ea6fb8
Update docs/developers/onboarding/lectures/intermediate/7-parameters.md
paulobressan Aug 31, 2026
4cd791a
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
e61a6a4
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
2358297
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
2df7eb0
Update docs/developers/onboarding/lectures/intermediate/8-validator-p…
paulobressan Aug 31, 2026
6243257
Rework the intermediate vault around a service admin key
paulobressan Sep 1, 2026
2ad294d
Merge branch '1921-onboarding-intermediate-lectures' of github.com:ca…
paulobressan Sep 1, 2026
e30a8e8
Spell it policy ID across the intermediate track
paulobressan Sep 1, 2026
1d3b48b
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
10d3bc5
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
4ec6a6d
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
cbd4b97
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
03d4ad2
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
63f18e2
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
c71a87f
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
40dd466
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
72f32c4
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
be53a5c
Update docs/developers/onboarding/lectures/intermediate/9-frontend-in…
paulobressan Sep 2, 2026
14439b5
Apply PR review feedback to intermediate lecture 9
paulobressan Sep 2, 2026
05083a7
Add mint and burn flows and move the app into off-chain/
paulobressan Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";
import extractRegion from "@site/src/utils/extractRegion";
import SendAda from "!!raw-loader!@site/examples/onboarding/lectures/mesh/src/send-ada.ts";
import SendAda from "!!raw-loader!@site/examples/onboarding/lectures/beginner/mesh/src/send-ada.ts";

# UTxOs & Transactions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";
import extractRegion from "@site/src/utils/extractRegion";
import SendWithDeadline from "!!raw-loader!@site/examples/onboarding/lectures/mesh/src/send-with-deadline.ts";
import SendWithDeadline from "!!raw-loader!@site/examples/onboarding/lectures/beginner/mesh/src/send-with-deadline.ts";

# Time on Cardano

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";
import extractRegion from "@site/src/utils/extractRegion";
import NativeScript from "!!raw-loader!@site/examples/onboarding/lectures/mesh/src/native-script.ts";
import SendWithMetadata from "!!raw-loader!@site/examples/onboarding/lectures/mesh/src/send-with-metadata.ts";
import NativeScript from "!!raw-loader!@site/examples/onboarding/lectures/beginner/mesh/src/native-script.ts";
import SendWithMetadata from "!!raw-loader!@site/examples/onboarding/lectures/beginner/mesh/src/send-with-metadata.ts";

# Native scripts & metadata

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";
import extractRegion from "@site/src/utils/extractRegion";
import MintToken from "!!raw-loader!@site/examples/onboarding/lectures/mesh/src/mint-token.ts";
import MintToken from "!!raw-loader!@site/examples/onboarding/lectures/beginner/mesh/src/mint-token.ts";

# Tokens: fungible & NFTs

Expand Down
4 changes: 2 additions & 2 deletions docs/developers/onboarding/lectures/beginner/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ From lecture 2 onwards you run real transactions on Cardano's free test network.
You'll need **[Lace](https://www.lace.io/)** on the **Preview** network with a little test ADA, which is what [lecture 1](/docs/developers/onboarding/lectures/beginner/wallets-keys-addresses) sets up. Then grab the app (no need to clone the whole repo) and start it:

```bash
npx giget@latest gh:cardano-foundation/developer-portal/examples/onboarding/lectures/mesh lectures-mesh
cd lectures-mesh
npx giget@latest gh:cardano-foundation/developer-portal/examples/onboarding/lectures/beginner/mesh beginner-mesh
cd beginner-mesh
npm install
npm run dev
```
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
title: "On-chain vs off-chain"
sidebar_label: "On-chain vs off-chain"
description: "What a dApp is made of, and the line between off-chain code that builds transactions and an on-chain contract that enforces the rules."
---

# On-chain vs off-chain
Comment thread
paulobressan marked this conversation as resolved.

Welcome to the Intermediate track. In Beginner you moved value around. Now you will make the chain **enforce rules** about how that value moves. That is a **smart contract**.

## What a dApp is

An app built on a blockchain is called a **dApp**, short for decentralized application. A few separate pieces make one up:

- **A frontend**: the page people see and click.
- **Off-chain code**: normally part of that same page. It reads the chain and builds the transactions.
- **A [provider](/docs/developers/onboarding/lectures/beginner/providers-and-explorers)**: how the dApp reads the chain, and how it gets a finished transaction out to the network.
- **A wallet**: holds the keys and signs. On the web it is usually a browser extension, like the Lace you installed in Beginner.
- **A smart contract**: the rule the network enforces.

You built the first four in Beginner, and **[a transaction, step by step](/docs/developers/onboarding/lectures/beginner/providers-and-explorers#a-transaction-step-by-step)** shows them working together. The smart contract is what this track adds.

Two of those pieces do completely different jobs:

- **Off-chain** is the code that runs **in your browser or on a server** (your app, plus an off-chain SDK). It reads the chain, **builds transactions**, and asks the wallet to sign them. This is the same work you did for the [send](/docs/developers/onboarding/lectures/beginner/utxos-and-transactions) and [mint](/docs/developers/onboarding/lectures/beginner/tokens-fungible-and-nfts) transactions in Beginner. It **prepares**.
- **On-chain** is the **smart contract (logic) and data that lives on the blockchain**. A Cardano smart contract is code that runs on the blockchain and checks whether the transaction is allowed. It either **approves or rejects** the transaction. It **enforces**.

The apps you built [in Beginner](/docs/developers/onboarding/lectures/beginner/introduction) had only off-chain code.

Think of applying for a permit to build something. Your app is the person applying: it decides what it wants to build, fills in every field, and hands the form in. The contract is the officer who reads the form and either approves it or rejects it. The person can ask for anything, and the officer decides what is allowed.

```mermaid
flowchart LR
subgraph OFF["Off-chain: runs on your machine"]
App["your app + SDK<br/>builds the transaction"] --> Wallet["wallet<br/>signs it"]
end

subgraph ON["On-chain: runs on the network"]
Chain[("Cardano<br/>network")] -->|runs the contract| Validator{"validator<br/>yes / no"}
Validator -->|yes| Done["recorded on the chain"]
Validator -->|no| Rejected["rejected, nothing changes"]
end

Wallet -->|submits| Chain
```

As soon as the transaction is sent, control passes to the chain, and the validator makes the final decision. The contract cannot ask your app for more information, and your app cannot change the answer.

## Who does what

Split any Cardano app along that line and it becomes much easier to understand:

| Off-chain (your server/browser) | On-chain (the network) |
|---|---|
| Read the chain: which UTxOs exist, what's locked where | - |
| Decide what _should_ happen | Check whether it's **allowed** |
| Pick the inputs, build the outputs, balance the fee | - |
| Attach the datum and the redeemer | Read the datum and the redeemer |
| Collect the wallet's signature | See which signatures are on the transaction |
| Submit | Answer **yes** or **no** |

Almost every line is on the left.

## Why the split exists
Comment thread
paulobressan marked this conversation as resolved.

The chain has to reach the **same answer for everyone, forever**. A node checking your transaction today and a node checking that same block ten years from now must both decide the same way. If they did not, they would disagree about who owns what. So a contract may only look at things that are **written down**: the transaction itself, the outputs it spends, and the validity window it declares.

That single requirement explains most of what feels strange at first:

- **A contract cannot call an API**, read a price feed, or fetch anything. Two nodes asking the same server could get two different answers.
- **A contract cannot read a clock.** This is why time became a **slot window** that you declare in advance, back in [Time on Cardano](/docs/developers/onboarding/lectures/beginner/time-on-cardano).
- **A contract keeps no variables of its own between runs.** This does not mean nothing is saved. On Cardano, state lives **on the UTxOs** rather than inside the contract, and everything the validator needs to know must reach it through the transaction context. The next two lectures show how.
- **A contract cannot start anything.** Nothing on Cardano happens because a contract decided to act. Someone has to build a transaction first.

You get something valuable in return: your transactions are **deterministic**. A validator only ever looks at information that is local to the transaction and cannot change once it is written, so running it twice gives the same answer twice, on your machine and on every node. That is why your app can run the contract before sending anything, and know whether the contract approves the transaction and what running it will cost.

That is a promise about the **contract's answer**, not about the transaction getting in. Somebody else may spend the same UTxO first, and then the ledger refuses yours before the contract is even consulted. So the guarantee is: **if** your transaction is accepted, it does exactly what you predicted. Not that it is certain to be accepted.
Comment thread
paulobressan marked this conversation as resolved.

There is a practical reason for the split as well. Everything on-chain is stored by every node and re-checked forever, so moving the transaction building there too would grow the chain faster than most people could afford to keep up with, and a chain only a few can verify is not decentralized.

## Where the contract runs, and what it can do

**The contract does not run on your computer.** You write it, compile it, and read it in your editor, so it is easy to think of it as part of your app. Your app carries the compiled contract **inside the transaction**, and the **network** runs it when that transaction is checked. The answer is the same for everyone, forever.

**The contract cannot _do_ anything.** Every movement of value in this track is done by a **transaction your off-chain code built**. All the contract ever adds is a yes or a no.

## Try it

**Make the folder you will work in for the rest of the track:**

```bash
mkdir cardano-vault
cd cardano-vault
mkdir on-chain
mkdir off-chain
```

:::note Which terminal, and where you are
These commands work as written on macOS and Linux, and in **PowerShell** on Windows. If you use the older Windows `cmd` prompt, one command later in the track differs: `rm` is `del`.

If a command ever answers **"no such file or directory"**, run `pwd` and check which folder you are standing in.
:::

```
cardano-vault/
├── on-chain/ <- the rules. Compiled, hashed, enforced by every node.
└── off-chain/ <- the app. Runs on your machine and builds transactions. Enforces nothing.
```

The next lecture puts a contract project in `on-chain/` and leaves you working inside it. `off-chain/` stays empty until **[frontend integration](/docs/developers/onboarding/lectures/intermediate/frontend-integration)**, which is the one place in the track you change folder again.

Keep the name or pick your own, and read `cardano-vault/` as "wherever you put it".

Code in `off-chain/` can be wrong, or replaced. The network does not care, because it checks every transaction against what is in `on-chain/`.

For the vault you are about to build, the split runs like this. Off-chain builds a transaction that sends ADA to the contract's address, which locks it. Later, off-chain builds a second transaction that tries to spend it back, so on-chain, the validator runs and answers yes or no, and only a "yes" allows the spend.

Stuck? The finished code is in the playground. See the **[introduction](/docs/developers/onboarding/lectures/intermediate/introduction#the-playground)**.

## Go deeper

- [Smart Contracts (overview)](/docs/developers/curriculum/smart-contracts/overview): the on-chain/off-chain split in full.
- [Lock and Spend](/docs/developers/curriculum/smart-contracts/lock-and-spend): the lock-then-spend flow end to end.
- [Cardano for Ethereum developers](/docs/developers/cardano-for-ethereum-developers): the account-model habits that don't carry over: no `msg.sender`, no contract storage, no execution order.
- [The Extended UTXO Model](/docs/developers/curriculum/fundamentals/core-concepts/eutxo): the ledger model that makes this split possible.

Next: **[Set up your tools](/docs/developers/onboarding/lectures/intermediate/tools)**.
106 changes: 106 additions & 0 deletions docs/developers/onboarding/lectures/intermediate/2-tools.md
Comment thread
paulobressan marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: "Set up your tools"
sidebar_label: "Set up your tools"
description: "The compiler for the on-chain half, and the contract project everything else in this track fills."
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Set up your tools

The on-chain half needs a **compiler and supporting tooling**, because a contract has to become a program the network can run. The off-chain half needs a **library, a provider, and a way to interact with a wallet**, because your app has to read the chain, build transactions, get them signed, and submit them.

**You only need the first set now.** The next six lectures are the contract and nothing else: you write it, compile it and test it. The off-chain half then arrives all at once in **[frontend integration](/docs/developers/onboarding/lectures/intermediate/frontend-integration)**.

## The on-chain toolchain

You write the contract in a high-level language and **compile** it into the code the network runs. Several languages do this for Cardano:

- **[Aiken](https://aiken-lang.org/)** is a language made from scratch to write Cardano contracts. It is a small language with a fast compiler and built-in tests, and it is the easiest place to start.
- **[Scalus](https://scalus.org/)** lets teams who already use Scala write contracts in the language they know.
- Others exist for Haskell, Python and TypeScript teams. The [handbook compares them](/docs/developers/curriculum/smart-contracts/choose-a-language), and **[Builder Tools](/tools)** lists them all.

They all compile to the same low-level program, and they all describe it in the same file format, the **CIP-57 blueprint**. Your off-chain code reads that file and never needs to know which language made it.

## The off-chain toolchain

**The SDK** builds Cardano transactions for you. Without one, every transaction would cost you a lot of time and a lot of code. There are SDKs for JavaScript, Python, Haskell, Java, Go and more, and **[Builder Tools](/tools)** lists them all.

Nothing in these lectures depends on the one you pick: the contract is the same, the transaction is the same, only the function names change. Every code block that needs an SDK sits in a tab, so you can read the track in whichever one you use, and more will be added over time.

**The provider** reads the chain for you and submits your transactions because your app cannot reach the network on its own unless you run your own Cardano node. Beginner used one already. This track leans on it harder, for two reasons:

- **You read UTxOs that are not yours.** Locked funds sit at a contract's address. Your wallet knows nothing about them, so the provider is the only way to find them.
- **A script transaction has to declare its cost.** Running a validator uses CPU and memory, and the transaction carries the budget it expects to use, written next to the redeemer. You also pay for that budget in the fee. So something has to run the contract first, against your unsigned transaction, to find the real number. Your SDK can do that on your machine, or hand the job to a provider that offers it. Either way the answer arrives before you send anything, which is why a contract that says no usually fails in your app rather than on the chain.

You made a free **[Blockfrost](https://blockfrost.io/)** Preview key during setup. Others are listed in **[Builder Tools](/tools)**, and some of them you can run yourself.

**The wallet** holds the keys and signs. Your app never sees a private key: it hands the finished transaction to the wallet, the wallet asks the user, and the user approves. Here that is **[Lace](https://www.lace.io/)** on Preview.

Keep your Blockfrost key and your Lace wallet where they are. Neither is touched again until **[frontend integration](/docs/developers/onboarding/lectures/intermediate/frontend-integration)**, which sets all three of these up in one go.

## Try it

**Set up the contract project.** No contract in it yet, **[the next lecture](/docs/developers/onboarding/lectures/intermediate/what-is-a-validator)** writes that.

<Tabs groupId="onchain">
<TabItem value="aiken" label="Aiken" default>

Install Aiken from the **[installation guide](https://aiken-lang.org/installation-instructions)**. It takes about a minute. Then build the contract project **inside the on-chain half**, so it lands where it belongs instead of being moved there afterwards:

```bash
cd on-chain
aiken new my-name/vault
cd vault
```

`aiken new` creates the folder in whichever folder you run it from, and fills it with a working project: `aiken.toml` for the settings and dependencies, and `validators/` for your contracts. "Smart contract" is the general word, and the thing you actually write is a **validator**, which is why that folder has the name it does. **[The next lecture](/docs/developers/onboarding/lectures/intermediate/what-is-a-validator)** writes your first one. The name is `{organisation}/{repository}`, the same form as the dependencies you will add later, so `my-name/` is a label you can set to anything and `vault` is what the project is called.

Aiken's commands run in the project you're in, so the next six lectures all run from inside `on-chain/vault/`.

`aiken new` leaves a sample validator behind. You do not need it, and it would end up in your compiled output, so delete it:

```bash
rm validators/placeholder.ak
```

Check that the project works:

```bash
aiken check
```

It compiles and reports `0` tests, because the project is empty.

</TabItem>
<TabItem value="scalus" label="Scalus">

A [Scalus](https://scalus.org/) version is coming soon. The idea is identical, only the tooling differs.

</TabItem>
</Tabs>

Your workspace:

```
cardano-vault/
├── on-chain/
│ └── vault/ <- you are here, and stay here until lecture 9
│ ├── aiken.toml
│ └── validators/ <- your contracts
└── off-chain/ <- still empty, filled in lecture 9
```

Stuck? The finished code is in the playground. See the **[introduction](/docs/developers/onboarding/lectures/intermediate/introduction#the-playground)**.

## Go deeper

- [Choose a Smart Contract Language](/docs/developers/curriculum/smart-contracts/choose-a-language): Aiken, Scalus and the rest, and why they all compile to the same core.
- [Choose your tools](/docs/developers/curriculum/start-building/choose-your-tools): how to pick an off-chain library.
- [Builder Tools](/tools): every SDK, library and API on the portal.
- [Use a provider](/docs/developers/curriculum/production/use-a-provider): hosted, self-hosted, and local options.
- [Query the chain](/docs/developers/curriculum/start-building/query-the-chain): reading addresses, UTxOs and datums.
- [Testing](/docs/developers/curriculum/smart-contracts/testing): unit tests, property tests, and how far you can get before touching a chain.

Next: **[What a validator is](/docs/developers/onboarding/lectures/intermediate/what-is-a-validator)**.
Loading
Loading