Introduction to the Truffle Suite and Dapp Development Pipeline

Breaking down the Ethereum Dapp Development pipeline using Truffle, Ganache and Drizzle

The Full Package for Dapp Development?

The evolution of the Truffle suite is making dapp development look ever more attractive. Is now a good time for you to jump into this collection of tools? You will have a clear answer after reading this article.

The Truffle suite consists of 3 main tools; Truffle: the all in one Ethereum dapp development environment, Ganache: a personal, configurable development blockchain with its own GUI, and Drizzle: the newest edition of the suite that synchronises contract state, event and transaction data in a redux store for your front end — which unsurprisingly works very well with React.

Now, this is a lot to absorb; decentralised dapp development is a relatively new idiom. With new tools come new workflows, new ways to test, deploy, and update. What we will do here is break down each of the 3 Truffle suite tools, their capabilities, how to install and use them, and finish off with overviewing the Drizzle React project using a Truffle Box — pre-built Truffle boilerplate we can download using the truffle unbox command; more on this later.

This is not a talk on Solidity programming, but as an overview of the entire Dapp development process — if you would like to research more into Solidity specifically, check out my article on the subject aimed as an on-boarding tool for you to start writing Solidity 0.5+ smart contracts:

Understanding Truffle at a High Level

Truffle is a development environment, testing framework and deployment pipeline for Ethereum dapps — or any blockchain using the EVM. This section breaks down what exactly this means. For the sake of simplicity, we will refer to Ethereum (ETH) only, and not “Any EVM blockchain”, as the Ethereum (ETH) mainnet is Truffle’s main target production blockchain.

Truffle is operated in the Terminal, and as such has a range of handy commands for us to use at different stages of developing a dapp.

What might such a development process look like? Let’s break a hypothetical scenario down at a high level to get an initial feel of what it’s like to use Truffle. Let’s start a fresh Truffle based dapp project:

  • Using Truffle’s unbox command, we can firstly download a pre-built boilerplate project to bootstrap our dapp. These pre-built projects range from React with Truffle and Webpack boilerplate to ERC20 smart contract examples and tutorials. To get a feel about boxes at this stage, check them out here.
  • If we wanted to create a project from scratch, truffle init is run in your root project directory. This will create a very bare bones structure for you to work with. Unless your dapp is very niche with absolutely no boilerplate suitable, unboxing is more favourable to truffle init.
  • With the project now unboxed (or inited) and local on our machine, we notice a folder structure within our root project directory; a structure that Truffle adheres to throughout its examples and through the init command; namely contracts/, migrations/ and tests/. As well as these folders, a truffle-config.js file will also be joining the party, acting as a configuration file for Truffle. Let’s visit what these folders consist of.

Truffle Project Structure

contracts/ — hosts your Solidity (.sol) and Vyper (.vy) contract files. All your smart contracts associated with your project are stored in this folder.

migrations/ — hosts your migration files. Let’s stop here and define migrations in more detail. Migrations are files written in Javascript that programatically deploy smart contracts onto an Ethereum blockchain.

A migration is essentially just a set of instructions. The simplest example of a migration looks like the following:

var MyContract = artifacts.require("MyContract");
module.exports = function(deployer) {
// deployment steps
deployer.deploy(MyContract);
};

We are importing the MyContract Solidity file and using a deployer object provided by Truffle to deploy said contract onto a blockchain.

but which blockchain?

It can be either the mainnet, a testnet, or a local private blockchain, which coincidentally Truffle provide 2 of for testing purposes. Truffle provide 2 local blockchain solutions: Truffle Develop and Ganache. Both Truffle Develop and Ganache spawn a blockchain for us to test our code on. But where Truffle Develop only provides us with a CLI, Ganache also gives us a fully-fledged GUI making it more capable and user friendly. We will explore these in more detail further down.

Back to /migrations. Now, in order for Truffle Migrations to work, a Migrations contract is required, the purpose of which is to supply a specific interface for managing Truffle deployments. This contract is automatically generated with truffle init, and should be present in all Truffle boxes.

And because this Migrations contract is required, there is also an 1_initial_migration.js file sitting in your migrations/ folder ready to deploy the contract. The 1_ filename prefix is just for human readability.

As more migrations are introduced to your project, this number should be incremented. In fact this was an intentional design feature of migrations; Truffle remembers which migrations have already been run, and only re-runs every migration when the special --reset flag is used with truffle migrate. It makes sense to order your migrations to keep track of which migration is the latest one, and to observe how your project is evolving.

Truffle provide some great documentation on Migrations. To delve deeper into them now, visit https://truffleframework.com/docs/truffle/getting-started/running-migrations.

The last folder we have not covered is tests/.

tests/ — hosting unit tests for your smart contracts. Tests can be written in Javascript, Typescript, Solidity, and now, Vyper, all of which are stored under the same directory. In Javascript, Truffle uses the Mocha testing framework and Chai for assertions, providing tried and tested tools for the job.

For local development blockchains like Truffle Develop and Ganache, Truffle uses “advanced snapshotting features” ** to ensure that each test is isolated and does not share state with other tests. For testing on clients such as go-ethereum, or other external clients, all your migrations are re-deployed at the beginning of every test file to ensure freshness of contract state.

Running on these clients will take considerably more time to complete tests, whereas Ganache and Truffle Develop take advantage of “special features” to speed up test runtime up to 90%. When considering speed, we can also configure these test blockchains to instantly mine blocks, as well as other optimisations to speed up testing.

** Obscure language taken from the Truffle documentation, further insights of which are not provided in the documentation.

If you are curious about testing in Truffle and would like to get into more details now, start with the documentation here: https://truffleframework.com/docs/truffle/testing/testing-your-contracts


  • By discussing the initial Truffle boilerplate we are now aware of how Truffle handles the deployment and testing of smart contracts. Contracts are developed within the contracts folder, before being migrated onto a blockchain, and then tested using Truffle’s automated testing capabilities. Of course, contracts need to be written, and IDEs such as Sublime Text do indeed provide syntax styling for Solidity. Check out the Sublime Package, named Ethereum, here. Vyper syntax simply adheres to python.
  • Your contracts have been written. We now need to deploy them on a network and connect to that network to access said contracts. (“network” in this context meaning Ethereum blockchain). What is left to explore is how to connect to an Ethereum network in Truffle. This is handled in truffle-config.js, sitting in your project root directory.

Configuring Ethereum Networks inside Truffle Config

truffle.config.js allows us to configure networks we’d like to connect to. The default configuration looks like this:

truffle-config.js:

module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*" // Match any network id
}
}
};

As you can see, a development network has already been configured for localhost. By default Truffle Develop runs on localhost:9545 whereas Ganache runs on localhost:8545. Truffle is ready to communicate with Ganache out of the box. These blockchains are also assigned a random network ID that has no relation to real-world public Ethereum blockchains (the mainnet is network ID 1, for example).

We can expand this config file to include more networks, such as a live mainnet. We are not limited to what we call networks, but Truffle have opted to use live for the mainnet:

module.exports = {
networks: {
development: {
...
},
live: {
host: "<host_ip_address>",
port: 80,
network_id: 1
}
}
};

Now if we wanted to deploy our contracts on the live network, we can call migrate with the --network flag:

truffle migrate --network live

This flexibility allows us to define a range of networks and migrate to them as when we please, which is very useful as you move from local testing blockchains to a mainnet deployment.


  • It is now time to consider the front-end application. Along with the Truffle folders, the front-end app folder structure will also be present in the root directory of the Truffle project. For example, if Create React App is used with Truffle, the React app is also present in the root directory. In this said case, it is residing inside a separate web-app/ folder. Ultimately it is the developer’s decision whether to combine Truffle and front-end project files, or to separate them like the Truffle+CRA project has opted for.
  • As you are building your front end you wish to test communication with your smart contracts via web3. The best way to do this currently is by connecting to your local running Ganache blockchain via MetaMask in the browser. Let’s briefly look at how to do this, before moving onto installing Truffle and visiting Drizzle.

The web3 Provider

By design, web3 looks for a web3 provider — a blockchain client or light node running with the capabilities to handle contract communication and make transactions on an Ethereum blockchain. This provider will vary depending on your preferred plugin or device (MetaMask, Cipher, a full go-ethereum node, etc).

For development purposes web3 will be communicating with our Ganache or Truffle Develop blockchain — whichever one you opt to use for testing.

So when it comes to testing your dapp on a public testnet (Ropsten, Rinkeby, etc), followed by a mainnet launch, your web3 provider must be running that same network in order to access the contracts.

MetaMask makes it easy for us to connect to locally run EVM blockchains such as Ganache and Truffle Develop. The following screenshots demonstrate the process. Select Custom RPC from the Networks dropdown, and enter the local running blockchain URL. The custom network is then added to the list of networks:

Adding a custom RPC in MetaMask connecting to a Ganache blockchain

Now we have a means to test our front end dapp on our privately running blockchain, all running locally.


  • From here your front-end dapp is developed further. It is then built and deployed in a production environment. At the same time, your smart contracts, now thoroughly tested, are deployed to the Ropsten Ethereum testnet. Switching to the Ropsten Network via Metamask allows us to test our production dapp on a public blockchain to help us identify any necessary amendments.
  • Your smart contracts are ready to be migrated to the mainnet. Using truffle migrate again, they are deployed. Switching MetaMask to the Main Ethereum Network now gives us a true production experience of our dapp.

Now our app will be running publicly. Fantastic.

To continue our understanding of the Truffle suite, let’s install Truffle and Ganache.

Installing Truffle and Ganache

Install the latest version of Truffle globally with npm:

npm install -g truffle@latest

In addition, install Ganache from the following web page: https://truffleframework.com/ganache. Check out all the available platforms here.

As mentioned above, Ganache provides a GUI for displaying blockchain state. Upon blockchain instantiation 10 accounts are created, as well as a mnemonic. Your mnemonic is a special secret created for you by Ganache. It’s used to generate the blockchain’s account addresses as well as sign transactions. Do not use your mnemonic outside of development.

Ganache will automatically instantiate a blockchain, accessible via localhost:8545. The network itself can be configured in the settings section.

By default Ganache speeds up the blockchain; blocks are auto-mined and transactions are processed instantly. Private keys are accessible with one click, and blocks and transactions can be browsed through lists provided by the GUI.

Ganache also has a CLI that can be installed with npm install -g ganache-cli allowing interaction directly from your Terminal.

Check out more Ganache documentation here.

What about Truffle Develop?

A Truffle Develop blockchain can be instantiated by running truffle develop in your Terminal, and can be configured within truffle-config.js:

module.exports = {
networks: {
...
develop: {
accounts: 5,
defaultEtherBalance: 500,
blockTime: 3
}
}
};

Remember, a Truffle Develop blockchain is spawned on port 9545. But like Ganache, 10 accounts are spawned with 10 private keys, as well as a mnemonic, all of which are displayed in the Terminal.

Get started using Truffle Develop from the official documentation here.

It is useful at this point to familiarise yourself with some Truffle commands. The Truffle documentation has a dedicated page that lists the full set of commands. Don’t let “full set” intimidate you; there are a modest range of commands that are relatively easily understood. By now at least their purpose and usage should be mostly understood relative to this talk.

Before wrapping up this introduction let’s briefly visit Drizzle — the latest instalment of the Truffle suite that solves the problem of blockchain state management in-app. Drizzle is still an early stage product, but is a useful addition to any state managed dapp.

Let’s see what Drizzle has to offer, and install the React Drizzle Box.

Drizzle

Why was Drizzle added to the Truffle Suite? It automatically syncs chain data to a Redux store so developers don’t have to worry about doing so while developing a front-end dapp.

Drizzle can be configured to either sync chain data on every block, or only when there are changes to contract data your app is listening to. It covers contract state, events and transactions.

A Truffle Box is available for Drizzle that combines a Create React App setup with Drizzle and Drizzle React Components package. Installation instructions and more information on the box can be found on Truffle boxes. If you’d like to download the box immediately, simply run truffle unbox drizzle.

As this is an introductory article, I will not delve into a technical integration of Drizzle, however I have written a dedicated article introducing Drizzle and how to integrate it in a React project — check it out here:

Next Steps

Do the tools of the Truffle suite sound like something you can adopt for your dapp development? The answer should now be clear to you — and if not please get in touch with queries.

Truffle is the most widely adopted set of tools for Ethereum dapp development by far, and is now on version 5, bringing features like compiling Vyper contracts within the /contracts folder. This is a good sign. For a rapidly evolving ecosystem it’s important that flagship tools add support for emerging standards on a continuous basis.

If you would like to add Vyper support to your contracts within Truffle, I wrote an introductory breaking down the Pythonic smart contract language:

This has been a high level overview of the Truffle pipeline. Thank you for reading!