# Understanding the Commit Reveal Scheme (with Solidity examples)

Ever wanted to store a piece of information on-chain but keep it a secret until later? In this quick post, we'll explore the **commit-reveal scheme** and provide an example of how you can implement it within a smart contract using Solidity.

## What is the Commit Reveal Scheme?

The commit-reveal scheme is a type of [commitment scheme](https://en.wikipedia.org/wiki/Commitment_scheme) that can be used to store values in a smart contract and keep them secret until you choose to reveal them later.

One common example of this is [Delayed reveal NFT collections](https://portal.thirdweb.com/glossary/delayed-reveal); where users mint NFTs, but the underlying data (such as the image, name, traits, etc.) of those NFTs are not revealed until later.

In this post, we'll use the popular [rock paper scissors game](https://en.wikipedia.org/wiki/Rock_paper_scissors) as an example of how and why you might want to implement this paradigm into your smart contracts.

## How Does the Commit Reveal Scheme Work?

As the name suggests, the commit reveal scheme uses a two-step process:

1. **Commit**: write the data to the smart contract, but keep it *hidden*; by hashing the data itself along combined with a secret phrase, i.e. `hash(data, secret)`.
    
2. **Reveal**: later, reveal the data by providing the same `data` and `secret` values. If the hash of the newly provided `data` and `secret` value is equal to the hash of the original `data` and `secret` value, then the data is revealed.
    

For example, in a game of rock paper scissors, we want to submit our move inside a transaction without the other player knowing what move we made; otherwise, they could easily win every game by inspecting the move from our transaction.

Instead, we create a secret key or password and hash the combination of these two values. Using solidity, we can achieve this by using `keccak256` and `abi.encodePacked`:

```solidity
// Generate a hash of the combination of the data and secret
bytes32 hash = keccak256(
    abi.encodePacked(
        "scissors" // Our move
        bytes32("player1-secret") // Our secret key or password
    )
);
```

Now, we can safely store this information inside of the smart contract. Other people will be able to see the `hash` value, however, they *won't* be able to decode it; as they don't know our secret value.

Only users who know both our original move and our secret key will be able to **reveal** our **commitment** at a later time; since the hash output of `data` and `secret` will always be the same value.

This also means we cannot change our `data` later; for example, we can't change our move from scissors to paper, since the output of `hash(paper,secret)` will be different to `hash(scissors,secret)`; i.e. we "committed" to our answer.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719735117444/2f16f13d-053a-4fae-9f7a-4132290f8aac.png align="center")

Later, for example, when both players have committed their move in rock paper scissors, we can safely reveal our commitment; by providing both the original data and the secret key to produce the same hash, for example:

```solidity
// Produce a new hash by providing the value and secret we did originally
bytes32 newHash = keccak256(
  abi.encodePacked(newMove, newSecret)
);

// If hash(newMove, newSecret) == hash(originalMove, originalSecret), reveal!
require(
  hash == newHash, "Wrong move or wrong pasword: Hashes do not match."
);
```

At this point, if the two hashes match, the move provided in the reveal phase *(*`newMove` *in the code snippet above)* is the "revealed" data; the user has decoded their hash by proving that they know the secret as well as the original move.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719735150343/a04eb6e6-be3b-457c-ba00-70257a6e9da8.png align="center")

To summarise, the commit-reveal scheme is a two-step process effective for storing data in a smart contract in a hidden manner that can be revealed later using hashing:

1. **Commit:** Store a hash of a combination of the data + a secret key
    
2. **Reveal:** Provide the data and the secret key to recompute a new hash. If the hash is the same as the hash from the commit phase, the data is revealed.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719734599378/672230ae-3f4a-4487-ad73-0ae498d9d3c9.png align="center")

## Wrapping Up

That's a quick introduction to the commit-reveal scheme. For a full code example in Solidity, check out the repository below:

%[https://github.com/jarrodwatts/rock-paper-scissors] 

For any questions, feel free to reach out to me on Twitter [@jarrodwattsdev](https://twitter.com/jarrodWattsDev).
