Select a file to view its exact on-chain source. Sorted README → gnomod → sources → tests.
Render(path string) string
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
# Commit–Reveal
Bind to a choice without disclosing it, demoing the [`p/moul/x/daily/commitreveal`](/p/moul/x/daily/commitreveal/v0) library.
## The problem
A transaction is public before it executes. In a sealed-bid auction or a simultaneous-move game, whoever moves last reads everyone else's move and wins for free.
## Phase 1 — commit
Each player publishes only `H(value ‖ salt)`. Nothing about the move leaks, but neither can change it later.
| player | commitment |
|---|---|
| alice | `11811a2d4eede29f…` |
| bob | `db066e8c917e07d5…` |
## Phase 2 — reveal
Now the values and salts are published and checked against the commitments recorded earlier:
| check | result |
|---|---|
| alice opens with `rock` | ✅ accepted |
| bob opens with `paper` | ✅ accepted |
| bob tries `scissors` instead | ❌ `commitreveal: reveal does not match the commitment` |
| bob claims alice's commitment | ❌ `commitreveal: reveal does not match the commitment` |
Bob cannot switch his move after seeing Alice's, and cannot pass off her commitment as his own.
## Why the salt is mandatory
Rock-paper-scissors has three possible moves. Without a salt there are exactly three possible hashes, and hashing all three breaks the scheme outright. The library refuses a salt shorter than `16` bytes rather than leaving that as advice:
- `Commit("rock", "tooshort")` → `commitreveal: salt is shorter than MinSaltLen`
The salt also keeps two players who pick the *same* move from publishing the same commitment:
| same move, different salt | commitment |
|---|---|
| player 1 | `a5d84fa94157acca…` |
| player 2 | `ccbc5d0b7ab1e84d…` |
## Two details that are easy to get wrong
- **Length-prefixed hashing.** With plain concatenation `("ab","cd…")` and `("abc","d…")` hash identically, so one commitment could be opened two different ways.
- **Constant-time comparison.** A short-circuiting check leaks, through timing, how many leading bytes of a guess were right — enough to rebuild a commitment byte by byte.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.