ERC-5732: Commit Interface
ERC-5732 standardises the commit-reveal pattern for any contract that needs to hide a value publicly until a future block without trusting a third party. Used for:
- Sealed-bid auctions — bidders commit hashed bids; reveals happen after a deadline so no front-running.
- NFT trait reveals — minters commit to a random seed; reveals after mint to prevent rare-trait sniping.
- Voting — voters commit hashed votes; reveal after voting closes to prevent strategy-shifting.
- Random-number generation — multi-party commit-reveal RNG schemes.
Required Interface
solidity
interface IERC5732 {
event Committed(bytes32 indexed commitId, address indexed committer, bytes32 commitHash);
event Revealed(bytes32 indexed commitId, address indexed committer, bytes value, bytes32 salt);
function commit(bytes32 commitHash, bytes32 commitId) external;
function reveal(bytes calldata value, bytes32 salt, bytes32 commitId) external;
function commitOf(bytes32 commitId, address committer) external view returns (bytes32);
}The committer hashes keccak256(value, salt) and submits via commit; later, calls reveal(value, salt, commitId) — the contract recomputes the hash, verifies it matches, and exposes the value.
Neo Equivalent: Standalone Commit Contract or Per-NFT Storage
csharp
public static void Commit(ByteString commitId, ByteString commitHash)
{
var committer = Runtime.CallingScriptHash;
if (!Runtime.CheckWitness(committer)) throw new Exception("CMT:NoAuth");
var key = CommitKey(commitId, committer);
if (Storage.Get(Storage.CurrentContext, key) is not null)
throw new Exception("CMT:AlreadyCommitted");
Storage.Put(Storage.CurrentContext, key, commitHash);
OnCommitted(commitId, committer, commitHash);
}
public static void Reveal(ByteString commitId, ByteString val, ByteString salt)
{
var committer = Runtime.CallingScriptHash;
if (!Runtime.CheckWitness(committer)) throw new Exception("CMT:NoAuth");
var key = CommitKey(commitId, committer);
var stored = Storage.Get(Storage.CurrentContext, key);
if (stored is null) throw new Exception("CMT:NoCommit");
var computedHash = (ByteString)CryptoLib.Sha256(val.Concat(salt));
if (!stored.Equals(computedHash)) throw new Exception("CMT:HashMismatch");
OnRevealed(commitId, committer, val, salt);
Storage.Delete(Storage.CurrentContext, key);
}| ERC-5732 (Ethereum) | Neo Equivalent | Notes |
|---|---|---|
commit(hash, commitId) | Commit(commitId, hash) committer-witness-checked | |
reveal(value, salt, commitId) | Reveal(commitId, value, salt) recomputes Sha256 | |
keccak256 for hashing | Sha256 (Neo native) | Hash function differs |
commitOf(commitId, committer) | CommitOf(commitId, committer) view | |
| Optional ranking / selection | Application-defined consume of revealed values | Direct port |
Composition
- ERC-2981 — royalties. Sealed-bid auctions using commit-reveal still pay standard royalties.
- ERC-6105 — direct NFT trading. Sealed-bid variant uses commit-reveal for bid pricing.
- ERC-5805 — voting. Commit-reveal voting prevents strategy adjustments.
Migration Notes
For sealed-bid / commit-reveal use cases:
- Hashing: Neo uses
Sha256(256-bit) instead of Ethereum'skeccak256— different hashes for the same input. The committer computesSha256(value || salt)for commits. - Committers should use a high-entropy
salt(32 bytes) to prevent pre-image attacks via brute-force. - The application must enforce a commit phase and reveal phase separated by a deadline; the spec doesn't mandate the timing, only the interface.
