5

I have a contract that requires that things only happen at certain block numbers. I was wondering if there was a way to "skip" a set number of blocks?

1

To skip blocks create a simple contract that has a function that requires a transaction.

pragma solidity ^0.4.0; 
// file: BlockMinder.sol

// used to "waste" blocks for truffle tests
contract BlockMiner {
    uint blocksMined;

    function BlockMiner(){
        blocksMined = 0;
    }

    function mine() {
       blocksMined += 1;
    }
}

After deploying the contract (for instance in migrations/2_migrations_contracts.js)

You can then create a utility js module like so

// file: blockminer.sol
var BlockMiner = artifacts.require("./BlockMiner.sol");

var instance = {};

/**
 * Run through blocks (e.g. so that block number will be greater than target block)
 * @param {address} addr, the address of the user who is transacting
 * @param {number}  numBlocksToMine - how far to move the block count
 * @return Function
 */
instance.mineBlocks = function(addr, numBlocksToMine) {
  return function () {
    return new Promise(function (resolve) {
      BlockMiner.deployed().then(function (blockMiner) {
        var miners = [];
        for (var ii = 0; ii < numBlocksToMine; ii++) {
          miners.push(blockMiner.mine({from: addr}));
        }
        return Promise.all(miners).then(resolve);
      });
    });
  }
};

module.exports = instance;

Then in your tests

// file: mytest.js

const blockMiner = require('../testutil/blockminer');
contract('FooBar', function(accounts) {
   var myContract;
   it('foos the bar', function() {
      return MyContract.deployed().then(function(instance) {
         myContract = instance;
         return myContract.doSomething();
         // mine aka "skip" 42 blocks
      }).then(blockMiner.mineBlocks(accounts[0], 42)).then(function() {
         return myContract.doSomethingMuchLater();
      });
   });
});
0

I used the method evm_mine called by web3.currentProvider.sendAsync as jsonrpc instead, no need to deploy any extra contract:

const waitNBlocks = async n => {
  const sendAsync = promisify(web3.currentProvider.sendAsync);
  await Promise.all(
    [...Array(n).keys()].map(i =>
      sendAsync({
        jsonrpc: '2.0',
        method: 'evm_mine',
        id: i
      })
    )
  );
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.