Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

render_example_test.gno

2.30 Kb · 54 lines
 1package commitrevealdemo
 2
 3// ExampleRender pins the realm's Render output as a testable example.
 4func ExampleRender() {
 5	print(Render(""))
 6	// Output:
 7	// # Commit–Reveal
 8	//
 9	// Bind to a choice without disclosing it, demoing the [`p/moul/x/daily/commitreveal`](/p/moul/x/daily/commitreveal/v0) library.
10	//
11	// ## The problem
12	//
13	// 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.
14	//
15	// ## Phase 1 — commit
16	//
17	// Each player publishes only `H(value ‖ salt)`. Nothing about the move leaks, but neither can change it later.
18	//
19	// | player | commitment |
20	// |---|---|
21	// | alice | `11811a2d4eede29f…` |
22	// | bob | `db066e8c917e07d5…` |
23	//
24	// ## Phase 2 — reveal
25	//
26	// Now the values and salts are published and checked against the commitments recorded earlier:
27	//
28	// | check | result |
29	// |---|---|
30	// | alice opens with `rock` | ✅ accepted |
31	// | bob opens with `paper` | ✅ accepted |
32	// | bob tries `scissors` instead | ❌ `commitreveal: reveal does not match the commitment` |
33	// | bob claims alice's commitment | ❌ `commitreveal: reveal does not match the commitment` |
34	//
35	// Bob cannot switch his move after seeing Alice's, and cannot pass off her commitment as his own.
36	//
37	// ## Why the salt is mandatory
38	//
39	// 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:
40	//
41	// - `Commit("rock", "tooshort")` → `commitreveal: salt is shorter than MinSaltLen`
42	//
43	// The salt also keeps two players who pick the *same* move from publishing the same commitment:
44	//
45	// | same move, different salt | commitment |
46	// |---|---|
47	// | player 1 | `a5d84fa94157acca…` |
48	// | player 2 | `ccbc5d0b7ab1e84d…` |
49	//
50	// ## Two details that are easy to get wrong
51	//
52	// - **Length-prefixed hashing.** With plain concatenation `("ab","cd…")` and `("abc","d…")` hash identically, so one commitment could be opened two different ways.
53	// - **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.
54}