Project 01
Counter
The smallest possible stateful contract. If Module 04's hello-world.compact taught you to store a value, this teaches you to change one, on-chain, and read it back after each change.
What you'll learn
- How public ledger state updates across multiple transactions, not just one
- The difference between deploying a contract and calling a circuit on an already-deployed one
- Reading current state before deciding what the next state should be
The contract
Save this as contracts/counter.compact:
pragma language_version >= 0.23;
import CompactStandardLibrary;
export ledger count: Uint<32>;
export circuit increment(): [] {
count = count + 1;
}
export circuit reset(): [] {
count = 0;
}Notice what's different from Module 04
There's no witness and no disclose() here, on purpose. Not every contract needs privacy; count is public by design, since a counter that hides its own value isn't useful. Knowing when not to reach for privacy is as important as knowing how to use it.
Build it yourself
Same workflow as Module 04:
compact compile contracts/counter.compact contracts/managed/counter
Then deploy and call increment() a few times in a row before reading the ledger state back. Watch count go up by exactly 1 each time, never more, even if you call it rapidly, since Midnight processes transactions against state sequentially.