Commit-Reveal
The Commit-Reveal pattern is a fundamental blockchain pattern that enables to:
- Commit to a value without revealing it (commit phase)
- Reveal the value later to prove they knew it in advance (reveal phase)
Some use cases:
- Blind Auctions: Bidders commit to their bids first, then reveal them after the bidding period
- Voting Systems: Voters commit their votes early, revealing them only after voting ends
- Knowledge Proofs/Attestations: Proving you knew information at a specific time without revealing it immediately
- Fair Random Number Generation: Players commit to random numbers that get combined later, making it harder to manipulate the outcome
How It Works
-
Commit Phase:
- User generates a value (
secret
) - User creates a hash of this value
- User submits only the hash on-chain (
commit
)
- User generates a value (
-
Reveal Phase:
- User submits the original value (
reveal
) - Contract verifies that the hash of the submitted value matches the previously committed hash
- If it matches then it proves that the user knew the value at the commitment time
- User submits the original value (
Minimal commit-reveal contract:
#[starknet::contract]
pub mod CommitmentRevealTraits {
use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess};
use core::hash::HashStateTrait;
use core::pedersen::PedersenTrait;
#[storage]
struct Storage {
commitment: felt252,
}
#[abi(embed_v0)]
impl CommitmentRevealTrait of super::ICommitmentRevealTrait<ContractState> {
fn commit(ref self: ContractState, commitment: felt252) {
self.commitment.write(commitment);
}
fn reveal(self: @ContractState, secret: felt252) -> bool {
let hash = PedersenTrait::new(secret).finalize();
self.commitment.read() == hash
}
}
}
Usage example:
// Off-chain, compute the commitment hash for secret
let secret = 'My secret';
let offchain_commitment = PedersenTrait::new(secret).finalize();
// Commit on-chain
contract.commit(offchain_commitment);
// Reveal on-chain and assert the result
let reveal_result = contract.reveal(secret);
Some considerations:
- The commit phase must complete before any reveals can start
- Users might choose not to reveal if the outcome is unfavorable (consider adding stake/slashing mechanics to ensure reveals)