// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; contract TimeCapsuleReceipt { struct Receipt { bytes32 hash; uint256 revealBlock; address sealer; bool revealed; } mapping(uint256 => Receipt) private receipts; uint256 private nextId; event Sealed(uint256 indexed id, bytes32 indexed hash, uint256 revealBlock, address indexed sealer); event Revealed(uint256 indexed id, bytes data); error NotFuture(); error AlreadyRevealed(); error TooEarly(); error HashMismatch(); function seal(bytes32 _hash, uint256 _revealBlock) external returns (uint256 id) { if (_revealBlock <= block.number || _hash == bytes32(0)) revert NotFuture(); unchecked { id = nextId++; } receipts[id] = Receipt(_hash, _revealBlock, msg.sender, false); emit Sealed(id, _hash, _revealBlock, msg.sender); } function unseal(uint256 id, bytes calldata data) external { Receipt storage r = receipts[id]; if (r.revealed) revert AlreadyRevealed(); if (block.number < r.revealBlock) revert TooEarly(); if (keccak256(data) != r.hash) revert HashMismatch(); r.revealed = true; emit Revealed(id, data); } }