Introducing Truffle, a Blockchain Smart Contract Suite
In the early days of smart contract development (circa 2016) the way to go was to write smart contracts in your favorite text editor and deploy them by directly calling geth
and solc
.
The way to make this process a little bit more user friendly was to make bash scripts which could first compile and then deploy the contract … which was better, but still pretty rudimentary — the problem with scripting, of course, being the lack of standardization and the suboptimal experience of bash scripting.
The answer came in two distinct flavors — Truffle and Embark — with Truffle being the more popular of the two (and the one we’ll be discussing in this article).
To understand the reasoning behind Truffle, we must understand the problems it’s trying to solve, which are detailed below.
Compilation
Multiple versions of the solc
compiler should be supported at the same time, with a clear indication which one is used.
Environments
Contracts need to have development, integration and production environments, each with their own Ethereum node address, accounts, etc.
Testing
The contracts must be testable. The importance of testing software can’t be overstated. For smart contracts, the importance is infinitely more important. So. Test. Your. Contracts!
Configuration
Your development, integration and production environments should be encapsulated within a config file so they can be committed to git and reused by teammates.
Web3js Integration
Web3.js is a JavaScript framework for enabling easier communication with smart contracts from web apps. Truffle takes this a step further and enables the Web3.js interface from within the Truffle console, so you can call web functions while still in development mode, outside the browser.
Installing Truffle
The best way to install Truffle is by using the Node Package Manager (npm). After setting up NPM on your computer, install Truffle by opening the terminal and typing this:
npm install -g truffle
Note: the sudo
prefix may be required on Linux machines.
Getting Started
Once Truffle is installed, the best way to get a feel for how it works is to set up the Truffle demo project called “MetaCoin”.
Open the terminal app (literally Terminal on Linux and macOS, or Git Bash, Powershell, Cygwin or similar on Windows) and position yourself in the folder where you wish to initialize the project.
Then run the following:
mkdir MetaCoin
cd MetaCoin
truffle unbox metacoin
You should see output like this:
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!
Commands:
Compile contracts: truffle compile
Migrate contracts: truffle migrate
Test contracts: truffle test
If you get some errors, it could be that you’re using a different version of Truffle. The version this tutorial is written for is Truffle v4.1.5
, but the instructions should stay relevant for at least a couple of versions.
The Truffle Project Structure
Your Truffle folder should look a little bit like this:
.
├── contracts
│ ├── ConvertLib.sol
│ ├── MetaCoin.sol
│ └── Migrations.sol
├── migrations
│ ├── 1_initial_migration.js
│ └── 2_deploy_contracts.js
├── test
│ ├── TestMetacoin.sol
│ └── metacoin.js
├── truffle-config.js
└── truffle.js
Contracts folder
This is the folder where you will put all of your smart contracts.
In your contracts folder, there’s also a Migrations.sol
file, which is a special file — but more about that in the following section.
When Truffle compiles the project, it will go through the contracts
folder and compile all the compatible files. For now, the most used files are Solidity files with the .sol
extension.
In the future, this might transition to Vyper or SolidityX (both better for smart contract development, but less used for now).
Migrations Folder
What is a truffle migration? In essence it’s a script which defines how the contracts will be deployed to the blockchain.
Why do we need migrations?
As your project becomes more and more complex, the complexity of your deployments becomes more and more complex accordingly.
Let’s take an example:
- You have smart contracts
One
,Two
andThree
- The smart contract
Three
contains a reference to the smart contractOne
and requires the address of contractTwo
in its constructor.
This example requires that contracts not only to be deployed sequentially, but also that they cross reference each other. Migrations, in a nutshell, enable us to automate this process.
A rough overview of how you would do this would be as follows:
var One = artifacts.require("One");
var Two = artifacts.require("Two");
var Three = artifacts.require("Three");
module.exports = function(deployer) {
deployer.deploy(One).then(function() {
deployer.deploy(Two).then(function() {
deployer.deploy(Three, One.address);
})
});
};
Beyond that, migrations allow you to do a lot of other cool things like:
- set max gas for deployments
- change the
from
address of deployments - deploy libraries
- call arbitrary contract functions
Initial migration
As you’ve noticed in your MetaCoin
project, you have a file called 1_initial_migration.js
. What this file does is deploy the Migrations.sol
contract to the blockchain.
Usually you don’t have to do anything to this file once it’s initialized, so we won’t focus too much on this.
Test Folder
As I’ve said: YOU! MUST! TEST! SMART! CONTRACTS! No buts, no ifs, no maybes: you MUST do it.
But if you’re going to do it, it would be cool to have an automatic tool to enable you to do it seamlessly.
Truffle enables this by having a built-in testing framework. It enables you to write tests either in Solidity or JavaScript.
The examples in the MetaCoin project speak for themselves basically, so we won’t get too much into this.
The key is, if you’re writing Solidity tests, you import your contracts into the tests with the Solidity import
directive:
import "../contracts/MetaCoin.sol";
And if you’re writing them in JavaScript, you import them with the artifacts.require()
helper function:
var MetaCoin = artifacts.require("./MetaCoin.sol");
Configuration File
The configuration file is called either truffle.js
or truffle-config.js
. In most cases it’ll be called truffle.js
, but the fallback is there because of weird command precedence rules on Windows machines.
Just know that, when you see truffle.js
or truffle-config.js
, they’re the same thing, basically. (Also, don’t use CMD on windows; PowerShell is significantly better.)
The config file defines a couple of things, detailed below.
Environments
Develop, TestNet, Live (Production). You can define the address of the Geth note, the network_id
, max gas for deployment, the gas price you’re willing to pay.
Project structure
You can change where the files are built and located, but it isn’t necessary or even recommended.
Compiler version and settings
Fix the solc
version and set the -O
(optimization) parameters.
Package management
- Truffle can work with EthPM (the Ethereum Package Manager), but it’s still very iffy.
- You can set up dependencies for EthPM to use in your Truffle project.
Project description
Who made the project, what is the project name, contact addresses etc.
License
Use GPLv3.
Running the Code
In order to compile your contracts, run this:
truffle compile
In order to run migrations, you can just use this:
truffle migrate
Or you can do it by specifying an environment:
truffle migrate --network live
In order to test your contracts run this:
truffle test
Or you can run a specific test by running this:
truffle test ./path/to/FileTest.sol
Conclusion
Truffle is a very handy tool that makes development in this brand new ecosystem a little easier. It aims to bring standards and common practices from the rest of the development world into a little corner of blockchain experimentation.
This quick tutorial has demonstrated and explained the basics, but to truly understand Truffle, you’ll need to dive in deeper and experiment on actual projects. That’s what we’ll explore throughout SitePoint’s blockchain hub. We next take a look in a bit more detail at testing smart contracts and Truffle migrations.