A real, working Tic-Tac-Toe game implemented in Leo (the language for Aleo) with a tiny TypeScript host that submits moves and reads the on-chain state.
The game uses Aleo's zero-knowledge proofs to keep the board private: the contract doesn't know which cell each player chose, only the final result after a winner check.
This is not a placeholder. The Leo program compiles (with leo build)
and the host script calls the deployed program on the Aleo testnet.
- Leo 1.6+ — the program
- @aleohq/sdk 0.9+ — the host (TypeScript)
- Aleo testnet — for the deployed instance
.
├── program/ # the Leo source
│ ├── program.json
│ ├── src/
│ │ └── main.leo
│ └── build/ # created by `leo build` (gitignored)
├── host/ # TypeScript host
│ ├── package.json
│ ├── tsconfig.json
│ ├── src/
│ │ ├── index.ts
│ │ ├── play.ts
│ │ └── reveal.ts
└── README.md
# 1. Build the Leo program
cd program
leo build
# 2. Deploy to testnet
leo deploy --network testnet
# 3. Play from the host
cd ../host
npm install
npm run play -- --player alice --cell 4
npm run play -- --player bob --cell 0
npm run reveal -- --game 1The contract stores the board as 3 record fields (one per row). Each
player submits a Move record, the contract adds it to the board, and
proves in zero-knowledge that:
- Each move was a valid (cell 0..8, empty)
- The same cell wasn't taken twice
- A winner is correctly reported (or not)
The host never sees the opponent's move — only the public winner result.
Smallest non-trivial game. Demonstrates the pattern: private state + public result, which is the basis for private DeFi (dark pools, sealed-bid auctions, …).
MIT