๐Ÿ” Commit-Reveal: Prevent Manipulation

Learn the classic pattern for fair randomness generation

Generate provably fair random numbers on-chain

Commit-Reveal Schemes

**Commit-reveal** is a two-phase cryptographic protocol that prevents participants from changing their input after seeing others' choices. Users first commit to a value by submitting its hash, then reveal the actual value later. This ensures fairness in scenarios like voting, auctions, and random number generation.

The commitment phase locks in choices without revealing them. The reveal phase proves what was committed. If anyone tries to change their value, the hash won't matchโ€”making manipulation cryptographically impossible.

๐Ÿ”’ Two-Phase Protocol

Phase 1: Commit

Each participant submits H(value + salt) where H is a hash function (keccak256)

Salt prevents rainbow table attacks. Commitments are stored on-chain with a deadline.

Phase 2: Reveal

Participants reveal their value and salt. Contract verifies H(value + salt) == commitment

Invalid reveals are rejected. Final randomness = XOR of all revealed values.

Interactive: Commit-Reveal Demo

Experience how commit-reveal prevents cheating in a simple guessing game.

Phase: 1 - Commit

Step 1
Commit
Submit hash of secret
Step 2
Reveal
Show actual value
Step 3
Verify
Check hash matches
๐ŸŽฒ Secret number selected (hidden from you)
42

Use Cases

๐ŸŽฎ Blockchain Gaming

Players commit to their moves before reveal. Prevents front-running in poker, rock-paper-scissors, or strategy games.

Example: Mental Poker protocols for provably fair card games

๐Ÿ—ณ๏ธ On-Chain Voting

Voters commit to choices without revealing preferences. Final tally revealed after deadline.

Example: Snapshot uses commit-reveal for private voting

๐Ÿ’ฐ Sealed-Bid Auctions

Bidders commit to bid amounts. Highest bidder revealed after all commits submitted.

Example: ENS domain auctions used commit-reveal (Vickrey auction)

๐ŸŽฒ Multi-Party Randomness

Each party commits to random value. Final randomness = XOR of all revealed values.

Example: RANDAO in Ethereum beacon chain (validator randomness)

Implementation Example

// Solidity commit-reveal pattern
mapping(address => bytes32) public commitments;
mapping(address => uint256) public reveals;
function commit(bytes32 _commitment) external {
require(commitments[msg.sender] == 0, "Already committed");
commitments[msg.sender] = _commitment;
}
function reveal(uint256 _value, bytes32 _salt) external {
bytes32 commitment = keccak256(abi.encodePacked(_value, _salt));
require(commitment == commitments[msg.sender], "Invalid reveal");
reveals[msg.sender] = _value;
}

โš ๏ธ Security Considerations

  • โ€ขLast revealer advantage: Last person can decide not to reveal if outcome is unfavorable
  • โ€ขPenalty for non-reveal: Require deposits that are slashed if users don't reveal
  • โ€ขTime limits: Enforce strict deadlines for both commit and reveal phases
  • โ€ขSufficient entropy: Use strong random salt (32 bytes minimum) to prevent brute-force