Migrating from Truffle to Buidler
And why you should probably keep both.
Why Buidler?
Proper debugging is a pain with Truffle. Events are way too difficult to use as logging and they don't even work for reverted transactions (when you would need them most). Buidler gives you a console.log
for your contracts which is a game changer. And you'll also get stack traces within your contracts.
Gone are the days where you have to guess the revert line in your contracts.
Gone are the days of trying to figure out the content of variables during runtime, just console.log
them.
How to add Buidler
Alright, so you want to start using Buidler in your Truffle project? You don't actually have to restart from scratch as buidler has a plugin that allows you to keep your current setup. First let's install the required packages.
npm install @nomiclabs/buidler @nomiclabs/buidler-truffle5 --save-dev
Create a buidler.config.js file in the root of your project and add usePlugin("@nomiclabs/buidler-truffle5"); to the start:
usePlugin("@nomiclabs/buidler-truffle5");
module.exports = {};
Now you have two options, you either change all your existing tests to avoid using .deployed()
functions as they don't work with Buidler. Or better, you simply create a fixture file which helps Buidler to support .deployed()
calls. Then you won't need any changes to your existing tests.
If you want to add the fixtures, create a test/truffle-fixture.js
file.
This Truffle migration file:
const MyContract = artifacts.require("MyContract");
const MyLib = artifacts.require("MyLib");
module.exports = function(deployer) {
deployer.deploy(MyLib);
deployer.link(MyLib, MyContract);
deployer.deploy(MyContract);
// do all other migration stuff if required
};
Becomes this Buidler truffle-fixture file:
const MyContract = artifacts.require("MyContract");
const MyLib = artifacts.require("MyLib");
module.exports = function(deployer) {
const myLib = await MyLib.new();
MyLib.setAsDeployed(myLib);
MyContract.link(myLib);
const myContract = await MyContract.new();
MyContract.setAsDeployed(myContract);
// do all other migration stuff if required
};
If you want to use the web3 instance in your tests, you only have to install a few more packages:
npm install @nomiclabs/buidler-web3 web3 --save-dev
That's it. Happy buidling! Use the command npx buidler test
to run tests via Buidler.
Stack traces will now be shown within your contracts. And you may now import the console.log file using import "@nomiclabs/buidler/console.sol";
Running tests inside VS Code
If you are using VS Code, you can install the Mocha Test Explorer. Simply add a .mocharc.json file to your root:
{
"require": ["@nomiclabs/buidler/register"],
"timeout": 20000,
"recursive": "test"
}
That's all. You'll now be able to run individual tests directly within your editor and you'll bet a test explorer, see image above.
And you'll also be able to debug tests directly with breakpoints, see image on the left.
The case for keeping Truffle
Now do we need Truffle still? In most cases I would say keep it for two reasons:
- Deployments
- Plugins
Technically Buidler now has a deployment plugin, the buidler-deploy plugin. However it's very new, less powerful than Truffle and more steps required to make it work.
Buidler also has a wide range of plugins. But once again, those plugins are mostly cloned from the respective Truffle plugins and so they are often behind in terms of features and bugs. And some plugins only exists for Truffle. For those reasons I would just recommend keeping them both and you'll have the best of both worlds.
Solidity Developer