For the complete documentation index, see llms.txt
Battleship tutorial
Prerequisites: work through the private tip jar example first. This tutorial assumes you can already compile a contract, run a local devnet and read a MidnightJS test.
This tutorial is about defensive programming. Every circuit in a Compact contract is a public entry point: anyone can call it, in any order, with any arguments, and with any witness implementation they like. The contract has to defend itself.
Battleship makes that concrete. Each player's ships are private and the shots are public.
A dishonest player has every reason to claim a MISS when a shot was in fact a HIT, or to
move a ship mid-game. The contract stops both, without trusting either player. You will see
four techniques, each one an assert in the contract and a test that proves it:
- A state machine. Explicit
TurnState,BoardStateandWinStatevalues open exactly one circuit at a time, so no one can act out of turn. - Role checks. Each player is identified by a DApp-specific public key derived from a private secret, and every circuit checks that the caller holds the right role.
- On-chain verification of off-chain data. Players commit to their ships with a hash on the ledger. When they later report a HIT or MISS from their private state, the contract rehashes the shot and checks the claim against that commitment.
- Cheat-check tests. The test suite plays the game on a devnet and deliberately cheats: it shoots out of turn and rewrites a player's private state, and expects each attempt to be rejected.
The source for this tutorial is
examples/battleship
in midnight-examples.
Set up
Clone midnight-examples, install the workspace and compile every contract:
git clone https://github.com/midnightntwrk/midnight-examples.git
cd midnight-examples
yarn install && yarn compile
Then move into the example:
cd examples/battleship
You'll start the local network in the second part, when you run the tests.