Transaction

B43BF557956B73…257EE7DC196F

Block 26,002 · index 0 · indexed

Summary

Hash
B43BF557956B731B749A95C60D129AFA3D95EAA4ED82EAEA0360257EE7DC196F
Block
26,002
Size
6172 bytes
Gas used
11,288,593 / 13,546,371
Fee
1000000ugnot
Memo
gnopublish
Status
success

Messages

Arguments · 9

  1. #1commitrevealdemo
  2. #2README.md
  3. #3# `gno.land/r/moul/x/daily/commitrevealdemo/v0` **Live demo of [`p/moul/x/daily/commitreveal`](https://github.com/moul/gno-contracts/tree/main/p/moul/x/daily/commitreveal/v0).** A thin, stateless realm: it holds no state of its own and contains none of the library's logic — `Render` just exercises the package and shows the result. Because it is stateless, the rendered page is identical on every call and on every node. Render it at [`/r/moul/x/daily/commitrevealdemo/v0`](https://gno.land/r/moul/x/daily/commitrevealdemo/v0). The library README explains the design and the trade-offs; this realm is the worked example. <!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) --> --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. **Dependency graph:** ![gno.land/r/moul/x/daily/commitrevealdemo/v0 dependency graph](https://raw.githubusercontent.com/moul/gno-contracts/main/_assets/gno.land/r/moul/x/daily/commitrevealdemo/v0/deps.png) > 🧪 **Highly experimental — potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md). <!-- END GNOCONTRACTS FOOTER -->
  4. #4commitrevealdemo.gno
  5. #5// Package commitrevealdemo is a small gnoweb demo of the commit-reveal scheme // provided by the [p/moul/x/daily/commitreveal](/p/moul/x/daily/commitreveal/v0) // library: the two phases, and what the salt is for. // // It contains no crypto of its own. Stateless, so Render is deterministic — // which is precisely what the library is for. package commitrevealdemo import ( "strings" "gno.land/p/moul/x/daily/commitreveal/v0" ) // Render renders the demo for gnoweb. func Render(path string) string { var b strings.Builder b.WriteString("# Commit–Reveal\n\n") b.WriteString("Bind to a choice without disclosing it, demoing the ") b.WriteString("[`p/moul/x/daily/commitreveal`](/p/moul/x/daily/commitreveal/v0) library.\n\n") b.WriteString("## The problem\n\n") b.WriteString("A transaction is public before it executes. In a sealed-bid auction or ") b.WriteString("a simultaneous-move game, whoever moves last reads everyone else's ") b.WriteString("move and wins for free.\n\n") aliceSalt := "alice-secret-salt-1" bobSalt := "bob-secret-salt-0001" aliceCommit := commitreveal.MustCommit("rock", aliceSalt) bobCommit := commitreveal.MustCommit("paper", bobSalt) b.WriteString("## Phase 1 — commit\n\n") b.WriteString("Each player publishes only `H(value ‖ salt)`. Nothing about the move ") b.WriteString("leaks, but neither can change it later.\n\n") b.WriteString("| player | commitment |\n|---|---|\n") b.WriteString("| alice | `" + short(aliceCommit) + "` |\n") b.WriteString("| bob | `" + short(bobCommit) + "` |\n") b.WriteString("\n## Phase 2 — reveal\n\n") b.WriteString("Now the values and salts are published and checked against the ") b.WriteString("commitments recorded earlier:\n\n") b.WriteString("| check | result |\n|---|---|\n") row(&b, "alice opens with `rock`", commitreveal.Open(aliceCommit, "rock", aliceSalt)) row(&b, "bob opens with `paper`", commitreveal.Open(bobCommit, "paper", bobSalt)) row(&b, "bob tries `scissors` instead", commitreveal.Open(bobCommit, "scissors", bobSalt)) row(&b, "bob claims alice's commitment", commitreveal.Open(aliceCommit, "rock", bobSalt)) b.WriteString("\nBob cannot switch his move after seeing Alice's, and cannot pass off ") b.WriteString("her commitment as his own.\n\n") b.WriteString("## Why the salt is mandatory\n\n") b.WriteString("Rock-paper-scissors has three possible moves. Without a salt there are ") b.WriteString("exactly three possible hashes, and hashing all three breaks the scheme ") b.WriteString("outright. The library refuses a salt shorter than `") b.WriteString(itoa(commitreveal.MinSaltLen) + "` bytes rather than leaving that as advice:\n\n") _, err := commitreveal.Commit("rock", "tooshort") b.WriteString("- `Commit(\"rock\", \"tooshort\")` → `") if err != nil { b.WriteString(err.Error()) } b.WriteString("`\n\n") b.WriteString("The salt also keeps two players who pick the *same* move from ") b.WriteString("publishing the same commitment:\n\n") one := commitreveal.MustCommit("rock", "salt-one-0123456789") two := commitreveal.MustCommit("rock", "salt-two-0123456789") b.WriteString("| same move, different salt | commitment |\n|---|---|\n") b.WriteString("| player 1 | `" + short(one) + "` |\n") b.WriteString("| player 2 | `" + short(two) + "` |\n") b.WriteString("\n## Two details that are easy to get wrong\n\n") b.WriteString("- **Length-prefixed hashing.** With plain concatenation `(\"ab\",\"cd…\")` ") b.WriteString("and `(\"abc\",\"d…\")` hash identically, so one commitment could be opened ") b.WriteString("two different ways.\n") b.WriteString("- **Constant-time comparison.** A short-circuiting check leaks, through ") b.WriteString("timing, how many leading bytes of a guess were right — enough to rebuild ") b.WriteString("a commitment byte by byte.\n") return b.String() } func row(b *strings.Builder, label string, err error) { b.WriteString("| " + label + " | ") if err == nil { b.WriteString("✅ accepted") } else { b.WriteString("❌ `" + err.Error() + "`") } b.WriteString(" |\n") } func short(c string) string { return c[:16] + "…" } func itoa(i int) string { if i == 0 { return "0" } s := "" for i > 0 { s = string(rune('0'+i%10)) + s i /= 10 } return s }
  6. #6gnomod.toml
  7. #7module = "gno.land/r/moul/x/daily/commitrevealdemo/v0" gno = "0.9"
  8. #8/gno.MemPackageType
  9. #9 MPUserProd

Result log

msg:0,success:true,log:,events:[]

← Back to block 26,002