54

For Ganache, there are several solutions.

What about Hardhat? They implemented their own local blockchain, Hardhat Network, which is different to Ganache.

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143

6 Answers6

85

Using Hardhat Network Helpers

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.

Using raw JSON-RPC calls

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.

Examples

evm_increaseTime

// 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

evm_setNextBlockTimestamp

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.

Franco Victorio
  • 2,862
  • 17
  • 27
  • When using this with hardhat I got this issue: Error: Transaction reverted and Hardhat couldn't infer the reason. Please report this to help us improve Hardhat. – Julien Kode Mar 07 '21 at 17:16
  • Did anyone face the same issue ? – Julien Kode Mar 07 '21 at 17:16
  • @Franco this way also works: await network.provider.send("evm_mine", [timestampInSeconds]); – Russo Oct 01 '21 at 09:27
  • What's the difference between using ethers.provider rather than network.provider? I used both and they both seem to work. – Adrian D. Jan 31 '22 at 19:51
  • For low-level JSON-RPC calls like these, they are the same. 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: https://hackmd.io/@fvictorio/hardhat-networks-and-providers – Franco Victorio Feb 02 '22 at 00:05
11

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.

Pang
  • 299
  • 1
  • 3
  • 7
Arjun Nemani
  • 211
  • 2
  • 3
  • Thanks for your answer! But this question was about Hardhat, not Ganache. – Paul Razvan Berg Nov 03 '21 at 20:06
  • 2
    My answer was written for hardhat in mind, I linked to the ganache update since hardhat docs for 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 :)

    https://hardhat.org/hardhat-network/reference/#special-testing-debugging-methods

    – Arjun Nemani Nov 05 '21 at 08:49
  • 1
    https://github.com/trufflesuite/ganache/pull/13/files

    Found the ticket from the active ganache repo

    – andy4thehuynh Dec 16 '21 at 20:27
8
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);
luckyyang
  • 81
  • 1
  • 2
6

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);
Vsevolod
  • 61
  • 1
  • 3
3

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');

Anton Cheng
  • 623
  • 6
  • 9
  • This doesn't seem to work for me in hardhat currently, if I log out the result of the first call, I get the new time I'm trying to set to, but further assertions down the line don't seem to respect that new time. Also, I had to add an empty array after the evm_mine argument since its required.Logging out thee result of the evm_mine call is 0x0 – snkashis May 26 '21 at 19:02
  • 1
    Is there a simple way to get now instead of (await ethers.provider.getBlock(await ethers.provider.getBlockNumber())).timestamp? – Martian Dec 18 '21 at 09:22
  • @Martian just use "latest" instead of fetching the last block number. But other than that change, this is about as short as it gets. – Chris Cashwell Jan 24 '22 at 20:54
-1

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