Using Truffle framework in an advanced way

NodeFactory
Coinmonks

--

If you are a blockchain developer or becoming one then you have probably heard of the Ethereum-Swiss-Knife framework called Truffle. Ethereum is in it’s early stages and doesn’t have many advanced tools like you got used to in regular web development. However, using Truffle you get to do things easier and faster because it offers automated contract testing that is almost a requirement (more like necessity) now during development. Also, it is the only tool that has some kind of debug feature.

Here are a few things that we needed during development and that came really handy. If you are a beginner and using Truffle for the first time then come back here later, you will probably need this.

Linking and initializing contracts on deploy automatically

First, you should get familiar with the truffle migrate command that helps you deploy your contracts but also upgrade and redeploy the changed contracts only.

But what about the contracts that depend on other contracts that you are deploying as well? Contracts that are dependencies should be updated with the newly deployed address. You can do this manually during production but what about tests? Let’s dive into a solution.

For example, we have a smart contract called Application that interacts with Storage smart contract. The goal is to deploy them both and update Application contract with the Storage contract’s address.

Here is our Application.sol file:

Example of Application smart contract

And our migration file:

Deployment of Application and Storage smart contracts

The code above creates 4 transactions:

  1. Deployment of the Application contract
  2. Deployment of the Storage contract
  3. Updating storage address in Application contract
  4. Updating Truffle’s Migrations contract that tracks migrations onchain

To save up some gas, you could add constructor to Application contract which would accept address of storage contract as function parameter. Then our example would look like this:

Upgraded Application smart contract

Migration of Storage contract:

Simple deployment of Storage smart contract

And migration of Application contract:

Simple deployment of Application smart contract

This way we will make one transaction less than before and thus save some gas.

Testing time based functions

Often you will find yourself writing time-dependent code i.e. checking if a certain time has passed before withdraw/deposit. If you are using ganache-cli (ex. testrpc) for local network and testing, then you can use special RPC function evm_increasetime during your tests.

Here is how it can be used:

Helper function to increase network timestamp

To wait during tests for 24 hours you can call it:

await utils.increaseTime(24 * 60 * 60);

Mocha multi reporters

If you are like us and you use some sort of CI (Continuous Integration) like CircleCi, you would probably want your test results in some common format. Most CI tools require test results in JUnit XML format.

Truffle by default uses spec reporter which nicely formats test result onto console window. You could easily change this to mocha-junit-reporter, it’s just matter of running “npm install mocha-junit-reporter” and adding following mocha config entry in your truffle.js file:

Added parameter for mocha in truffle.js file

This solution is nice for CI but it’s not very user friendly when it comes to running test locally and then checking xml file for test results. Luckily there is something called mocha-multi-reporters .

For configuring multi reporters, first install dependencies:

  • npm install - -save-dev mocha-multi-reporters mocha-junit-reporter

Add following mocha configuration to your truffle.js:

Upgraded parameter for mocha in truffle.js file

You’ve probably notices that we are using mocha-reporter-config.json. Using this file, we can configure multi reporter to use both spec and mocha-junit-reporter.

Example of mocha-reporter-config.json file

As you probably noticed, you can even decide where you want your test results to be stored.

Developing dApps on ethereum requires complex setup with whole bunch of frameworks and tools. Because of these we created starter repository which has all tools and frameworks configured for you to develop smart contracts with Node.Js as backend server. Everything is put in containers using Docker so with only one command you can start your private network, deploy contracts, run (database) migrations, run web server, tests and whatever you like.

If you want to try it, you can check it out here:

You can let us know if you would like some more features in this repo or feel free to contribute!

--

--