For Ganache, there are several solutions.
What about Hardhat? They implemented their own local blockchain, Hardhat Network, which is different to Ganache.
Ethereum Stack Exchange is a question and answer site for users of Ethereum, the decentralized application platform and smart contract enabled blockchain. It only takes a minute to sign up.
Sign up to join this communityFor Ganache, there are several solutions.
What about Hardhat? They implemented their own local blockchain, Hardhat Network, which is different to Ganache.
The easiest way to do this is to use the time helpers in Hardhat Network Helpers.
Install them with:
npm install @nomicfoundation/hardhat-network-helpers
And then you can use them like this:
import { time } from "@nomicfoundation/hardhat-network-helpers";
async function main() {
// advance time by one hour and mine a new block
await helpers.time.increase(3600);
// mine a new block with timestamp `newTimestamp`
await helpers.time.increaseTo(newTimestamp);
// set the timestamp of the next block but don't mine a new block
await helpers.time.setNextBlockTimestamp(newTimestamp);
}
main();
You can check the reference here.
There are two relevant RPC methods here: evm_increaseTime
and evm_setNextBlockTimestamp
. In both cases, they affect the next block but don't mine one.
evm_increaseTime
receives a number of seconds that will be added to the timestamp of the latest block. evm_setNextBlockTimestamp
receives an absolute UNIX timestamp (again, in seconds), and so it's not affected by the current block.
// suppose the current block has a timestamp of 01:00 PM
await network.provider.send("evm_increaseTime", [3600])
await network.provider.send("evm_mine") // this one will have 02:00 PM as its timestamp
await network.provider.send("evm_setNextBlockTimestamp", [1625097600])
await network.provider.send("evm_mine") // this one will have 2021-07-01 12:00 AM as its timestamp, no matter what the previous block has
Keep in mind that Hardhat Network validates that the new timestamp is bigger than the previous one, so you can't send any value.
ethers.provider
rather than network.provider
? I used both and they both seem to work.
Jan 31, 2022 at 19:51
network.provider
is "just" an EIP-1193 provider object. ethers.provider
also implements that interface, but it has more functionality. I wrote about that at length here if you're interested: hackmd.io/@fvictorio/hardhat-networks-and-providers
Feb 2, 2022 at 0:05
A new update to Ganache has added a time parameter to the evm_mine
command. Now the best way to move time is
await ethers.provider.send("evm_mine", [newTimestampInSeconds]);
It is better because you only make 1 RPC call instead of 2 in the accepted solution.
Note that you can't move time backwards in Hardhat.
evm_mine
just say same as ganache
which lead me to believe hardhat reuses some parts of ganache-cli. I am using the solution in my tests with hardhat, and they work perfectly :) hardhat.org/hardhat-network/reference/…
Nov 5, 2021 at 8:49
const { expect } = require("chai");
const { ethers } = require('hardhat');
const sevenDays = 7 * 24 * 60 * 60;
const blockNumBefore = await ethers.provider.getBlockNumber();
const blockBefore = await ethers.provider.getBlock(blockNumBefore);
const timestampBefore = blockBefore.timestamp;
await ethers.provider.send('evm_increaseTime', [sevenDays]);
await ethers.provider.send('evm_mine');
const blockNumAfter = await ethers.provider.getBlockNumber();
const blockAfter = await ethers.provider.getBlock(blockNumAfter);
const timestampAfter = blockAfter.timestamp;
expect(blockNumAfter).to.be.equal(blockNumBefore + 1);
expect(timestampAfter).to.be.equal(timestampBefore + sevenDays);
For any future wanderers:
Hardhat added a network-helpers library with convenient JS interface:
Among other things, there are functions to change network time: https://hardhat.org/hardhat-network-helpers/docs/reference#time-helpers.
Some examples copied from the reference:
// advance time by one hour and mine a new block
await helpers.time.increase(3600);
// advance time to specific timestamp and mine a new block
await helpers.time.increaseTo(newTimestamp);
// set the timestamp of the next block but don't mine a new block
await helpers.time.setNextBlockTimestamp(newTimestamp);
What I've been using with typescript and hardhat:
import { ethers, waffle } from 'hardhat';
const time = now + 86400
await ethers.provider.send('evm_setNextBlockTimestamp', [now]);
await ethers.provider.send('evm_mine');
evm_mine
argument since its required.Logging out thee result of the evm_mine
call is 0x0
now
instead of (await ethers.provider.getBlock(await ethers.provider.getBlockNumber())).timestamp
?
Adding to Franco's answer, there is a plugin that abstracts some of the complexities of handling time directly.
You can look its documentation in https://www.npmjs.com/package/@atixlabs/hardhat-time-n-mine
evm_increaseTime
and additionally they haveevm_setNextBlockTimestamp
.