- On-chain cron jobs for DeFi rebalancing and automation
- Time-based vesting and token releases
- Recurring payments and subscriptions
- DAO governance with time-delayed execution
You can take a look at the complete code in the hss-schedule-sc-calls
demo
repository.
Prerequisites
- ECDSA account from the Hedera Portal.
- Basic understanding of Solidity.
Table of Contents
- Setup Project
- Step 1: Configure Hardhat
- Step 2: Create the AlarmClock Smart Contract
- Step 3: Deploy the Contract
- Step 4: Set a One-Shot Alarm
- Step 5: Set a Recurring Alarm
- Step 6: Monitor Alarm Triggers
- Step 7: Run Tests (Optional)
- Conclusion
- Additional Resources
Setup Project
Set up your project by initializing the hardhat project.🚧 What's new: Hardhat 2 → 3
🚧 What's new: Hardhat 2 → 3
Key differences in Hardhat 3:
- compile → build
npx hardhat compileis nownpx hardhat build. This is the big one. The v3 migration guide explicitly shows using thebuildtask. - project init switch
v2 commonly usednpx hardhatornpx hardhat initto bootstrap. In v3 it’snpx hardhat --init.
- keystore helper commands are new
v3’s recommended flow includes a keystore plugin with commands likenpx hardhat keystore set HEDERA_RPC_URLandnpx hardhat keystore set HEDERA_PRIVATE_KEY. These weren’t standard in v2. - Foundry-compatible Solidity tests
In addition to offering Javascript/Typescript integration tests, Hardhat v3 also integrates Foundry-compatible Solidity tests that allows developers to write unit tests directly in Solidity
- Enhanced Network Management
v3 allows tasks to create and manage multiple network connections simultaneously which is a significant improvement over the single, fixed connection available in version 2. This provides greater flexibility for scripts and tests that interact with multiple networks.
HEDERA_RPC_URL, we’ll have https://testnet.hashio.io/api
HEDERA_PRIVATE_KEY, enter the HEX Encoded Private Key for your ECDSA account from the Hedera Portal.
We won’t need any additional dependencies for this tutorial since we’ll be interacting directly with the Schedule Service system contract.
Now let’s remove the default contracts and scripts that come with the Hardhat project:
Install Dependencies
Next, install the required dependencies:github:hashgraph/hedera-smart-contracts. This also gets installed at @hashgraph/smart-contracts so we can easily call these contracts from our own contract.
Step 1: Configure Hardhat
Update yourhardhat.config.tsfile in the root directory of your project. This file contains the network settings so Hardhat knows how to interact with the Hedera Testnet.
hardhat.config.ts
Step 2: Create the AlarmClock Smart Contract
Create a new Solidity file (AlarmClockSimple.sol) in your contracts directory:
contracts/AlarmClockSimple. sol
How It Works
-
Schedule Service System Contract (
0x16b): The contract interacts with the Hedera Schedule Service at the fixed address0x16b, which provides thescheduleCallfunction. -
setAlarm function: When a user calls
setAlarm(recurring, intervalSeconds), the contract:- Creates an
Alarmstruct in storage with the user’s address and target time - Calls
_scheduleAlarmto schedule the future execution
- Creates an
-
_scheduleAlarm (internal): This function:
- Encodes the call data for
triggerAlarm(alarmId) - Calls the Schedule Service at
0x16bwithscheduleCall(... ) - Specifies the target time (
expirySecond), gas limit, and encoded call data - Emits
AlarmScheduledevent
- Encodes the call data for
-
Scheduled Execution: When the scheduled time arrives, the Hedera network automatically executes the scheduled transaction, calling
triggerAlarm(alarmId)on the contract. -
triggerAlarm function: This is called by the network (or can be manually triggered):
- Increments the trigger counter
- Emits
AlarmTriggeredevent - For recurring alarms, schedules the next occurrence by calling
_scheduleAlarmagain
- HBAR Requirement: The contract must hold HBAR to pay for gas when scheduled transactions execute. Each execution (and re-scheduling for recurring alarms) deducts from the contract’s balance.
Step 3: Deploy the Contract
Create a deployment script (deploy.ts) in scripts directory:
scripts/deploy.ts
Critical: Why Does the Contract Need HBAR?Every time a scheduled transaction executes (when the network automatically calls
triggerAlarm), gas fees must be paid. Since the contract itself is the payer for these scheduled executions, it must hold HBAR.For recurring alarms:- Each
triggerAlarmexecution consumes gas - Each
triggerAlarmthen schedules the next alarm (more gas) - If the contract runs out of HBAR, scheduled executions will fail and recurring alarms will stop
- Your
SCHEDULED_CALL_GAS_LIMIT(set to 2,000,000 in this example) - Expected number of alarm executions
- For recurring alarms, estimate how long you want them to run
Copy the deployed contract address and set it as an environment variable for
the next steps.
verify-bundles/AlarmClockSimple/metadata.json file to Hashscan to verify this contract.
Step 4: Set a One-Shot Alarm
Create a script (setOneShot.ts) in your scripts directory to set a one-shot alarm.
scripts/setOneShot.ts
How It Works
- Connects to your deployed
AlarmClockSimplecontract - Calls
setAlarm(false, 10)to schedule a one-shot alarm in 10 seconds - The contract immediately schedules a transaction with the Schedule Service
- After ~10 seconds, the network will automatically execute
triggerAlarm(0) - You can view the
AlarmScheduledandAlarmTriggeredevents on HashScan
Step 5: Set a Recurring Alarm
Create a script (setRecurring.ts) in your scripts directory to set a recurring alarm.
scripts/setRecurring.ts
How Recurring Alarms Work
- You call
setAlarm(true, 10)to set a recurring alarm with a 10-second interval - The contract schedules the first
triggerAlarmcall for 10 seconds from now - When the scheduled time arrives, the network executes
triggerAlarm:- Increments the trigger counter
- Emits
AlarmTriggeredevent - Automatically schedules the next alarm for 10 seconds later
- This creates a self-sustaining on-chain timer!
- The contract runs out of HBAR (scheduled execution fails)
- You modify the contract logic to stop it
- A scheduling error occurs
- DeFi rebalancing strategies
- Periodic token distributions
- Recurring payment systems
- Time-based governance actions
Step 6: Monitor Alarm Triggers
After setting your alarms, you can monitor their execution on HashScan, Hedera’s block explorer.Viewing Events
Navigate to your contract’s events page:Viewing Scheduled Transactions
You can also view the actual scheduled transaction executions on HashScan: Example Flow:-
setAlarm transaction: View on HashScan
- This is when you call
setAlarm() - Emits
AlarmScheduledevent
- This is when you call
-
Scheduled triggerAlarm execution: View on HashScan
- This is the automatic execution by the network
- Notice the transaction was triggered by the schedule service, not by an EOA
- Emits
AlarmTriggeredevent
Understanding the Transaction FlowWhen you look at the scheduled transaction on HashScan on the trace tab, you will notice:
- The “From” address will be the contract itself (or show as scheduled execution)
- The “To” address is the contract address
- The “Function” called is
triggerAlarm(alarmId) - You’ll see the gas consumed by the execution
- No external account initiated this call—it was executed by the network’s Schedule Service
Step 7: Run Tests (Optional)
You can find both types of tests in the hedera-code-snippets repository. You will find the following files:contracts/AlarmClockSimple.t.sol
- Initial state: Verifies contract deploys with
nextAlarmIdstarting at 0. - Alarm creation: Confirms
setAlarmproperly creates alarm structs with correct user, time, and interval values. - Authorization: Ensures only the alarm owner or the contract itself can trigger alarms (non-owners are rejected).
- One-shot enforcement: Validates that one-shot alarms can only be triggered once and revert on subsequent attempts.
- HBAR handling: Verifies the contract can receive HBAR via
receive()function for funding scheduled executions.
test/AlarmClockSimple.ts
- Deployment and setup: Deploys the contract with 10 HBAR funding, creates a separate funded user wallet, and validates initial state.
- One-shot alarms: Sets a one-shot alarm, verifies the
AlarmScheduledevent is emitted, and confirms alarm details are correctly stored. - Recurring alarms: Sets a recurring alarm and validates it’s configured with the recurring flag and proper interval.
- Manual triggering: Tests that users can manually trigger their own alarms and verifies the
AlarmTriggeredevent is emitted with correct data. - Authorization checks: Ensures non-owners cannot trigger someone else’s alarm and that one-shot alarms cannot be triggered twice.
- Network integration: All tests run against Hedera testnet as the Schedule Service precompile (
0x16b) is not available locally.
Conclusion
You’ve just built an on-chain alarm clock that demonstrates Hedera Schedule Service’s unique capability—scheduling future smart contract calls without any off-chain infrastructure! In this tutorial, you learned how to:- Interact with the Schedule Service system contract
- Schedule one-shot alarms that fire once at a future time
- Create recurring alarms that automatically reschedule themselves
- Monitor scheduled executions on HashScan
- Understand the HBAR requirements for scheduled transactions
Key Takeaways
- Hedera’s Schedule Service enables truly autonomous smart contracts. No off-chain bots or keeper networks required
- Contracts must hold HBAR to pay for scheduled execution gas fees
- Recurring patterns create self-sustaining on-chain automation. Perfect for DeFi, vesting, payments, and governance
- This capability doesn’t exist on most EVM chains. It’s a fundamental difference in what’s possible on Hedera