A Solidity smart contract that enables users to create time-locked messages on the Ethereum blockchain. Perfect for storing messages that can only be retrieved after a specified time period has elapsed.
- Create time-locked messages (capsules)
- Retrieve messages only after the lock period expires
- View capsule details including lock time and retrieval status
- Gas-efficient implementation
- Comprehensive test coverage
- Solidity ^0.8.0
- Hardhat Development Environment
- Ethers.js
- Chai for testing
The contract implements a simple but effective time-locking mechanism using the following structure:
struct Capsule {
string message;
uint256 unlockTime;
bool retrieved;
}-
createCapsule(string calldata _message, uint256 _lockTime)- Creates a new time-locked capsule
- Validates that user doesn't have an existing capsule
- Sets unlock time based on current block timestamp
-
retrieveCapsule()- Retrieves the message after the lock period
- Implements multiple security checks
- Marks capsule as retrieved to prevent multiple retrievals
-
viewCapsule()- Returns capsule details without modifying state
- Useful for checking lock status and message availability
- Implements checks-effects-interactions pattern
- Uses require statements for input validation
- Time-based operations account for block.timestamp
- Single capsule per address to prevent spam
- Retrieved status tracking to prevent multiple retrievals
The contract includes a comprehensive test suite written in JavaScript using the Hardhat testing framework. To run the tests:
npm install
npx hardhat testTests cover:
- Capsule creation
- Time-lock enforcement
- Retrieval mechanics
- Edge cases and error conditions
// Deploy contract
const TimeCapsule = await ethers.getContractFactory("TimeCapsule");
const timeCapsule = await TimeCapsule.deploy();
await timeCapsule.deployed();
// Create a capsule
const lockTime = 3600; // 1 hour in seconds
const message = "Message from 2025!";
await timeCapsule.createCapsule(message, lockTime);
// Retrieve after lock period
await timeCapsule.retrieveCapsule();The contract emits events for important actions:
CapsuleCreated(address indexed sender, uint256 unlockTime)CapsuleRetrieved(address indexed sender, string message)
The contract is optimized for gas efficiency:
- Uses mapping for O(1) access
- Implements struct packing
- Minimizes storage operations
- Uses calldata for string inputs
This project is licensed under the MIT License - see the LICENSE file for details.
Created with 💙 by Gautam Manchandani(me🙋♂️)
Feel free to connect with me on GitHub