What is Ethereum Truffle? A Detailed Guide
Smart contracts for Ethereum are usually developed using the Solidity programming language. All that is required for such a development task is a text editor and a Solidity compiler. However, smart contracts are different from other programs, in that they are meant to be deployed on blockchains. Testing smart contracts efficiently and deploying them onto an Ethereum network can be surprisingly difficult without additional tool support. The Ethereum Truffle framework is designed to make the testing of smart contracts, and the deployment of smart contracts onto an Ethereum network, a much simpler process.
Although simple contracts can be tested and deployed using a browser-based development environment such as Remix, this becomes cumbersome for larger projects that may consist of multiple contracts and have dependencies on external libraries.
In such a scenario, it is best to use a development framework that integrates code compilation, testing, and deployment, and also allows workflows to be automated.
Ethereum Truffle Framework
The Truffle Suite consists of three components that together provide such a development framework:
- The Ethereum Truffle Framework is the actual development toolchain, integrating compilation, testing and deployment.
- Ganache is a locally deployed blockchain simulator with a graphical user interface that can be used to simulate blockchain networks and live-test contracts without having to set up real test networks or having to deploy to a remote network.
- Drizzle is a collection of frontend libraries aimed at providing components for building web applications that can connect to the smart contracts developed.
In this article, we will focus on the former two components, as these are typically used together to develop smart contracts for the Ethereum blockchain.
Ethereum Truffle is based on JavaScript, in that configuration, deployment scripts, and tests are written in JavaScript. Although, tests can also be written directly in Solidity.
Installation and Getting Started
It is very easy to install the Ethereum Truffle framework. As with most JavaScript-based tools, the npm package manager is used:
- npm install -g truffle
Once the framework is installed, it also makes sense to download and install the Ganache blockchain simulator. As this is an application with a graphical user interface, the official Ganache website provides installers for most popular platforms.
Once Truffle has been installed, a project can be initialized in two ways. A bare project can be created by typing:
- truffle init
Alternatively, the truffle unbox command can be used to create a project with some existing code. For example, a very simple token can be created with:
- truffle unbox metacoin
The above creates the project from a so-called Truffle box. These contain boilerplate code and configurations upon which projects can build to get started quickly. A number of these Truffle boxes can be found on the official website.
Many programmers will use Truffle in combination with additional npm-installed libraries, for example, Open Zeppelin’s comprehensive smart contracts library. In this case, the required dependencies file, package.json, can be created at this point with:
- npm init
Of course, this optional step can be left out or substituted with the equivalent command for other package managers that may be used to handle dependencies.
Development and Deployment
Using the above-mentioned metacoin boilerplate, created with truffle unbox metacoin, results in the following directory structure:
├── LICENSE
├── contracts
│ ├── ConvertLib.sol
│ ├── MetaCoin.sol
│ └── Migrations.sol
├── migrations
│ ├── 1_initial_migration.js
│ └── 2_deploy_contracts.js
├── test
│ ├── TestMetacoin.sol
│ └── metacoin.js
└── truffle-config.js
The contracts directory is where developers should place their solidity source files. The Migrations.sol file is a contract created by Ethereum Truffle and is used as part of the deployment process. In most cases, this file can be left untouched.
The migrations directory holds files developers can use to configure which contracts should be deployed. We will get to this later.
The test directory should hold JavaScript and Solidity test files. Again, the Metacoin boilerplate includes examples for this.
The truffle-config.js is a configuration file used to define how Truffle can connect to different Ethereum networks, and to specify details, such as the compiler version to be used.
This very simple configuration is sufficient to connect to Ganache running on the local host:
module.exports = {
networks: {
test: {
host: “127.0.0.1”,
port: 7545,
network_id: “*”
}
}
};
Note that Ganache typically uses port 7545 to expose the Ethereum JSON-RPC interface. It is fairly obvious from the file format how a connection to a different network could be set up, for example, through a local Ethereum node on a different port.
Once contracts have been written they can be compiled using the command:
- truffle compile
Adding the –all flag forces a rebuild of all contracts.
Compiled contracts end up in a build directory.
In order for a contract to be deployed, the deployment rules need to be specified in the numbered files in the migrations directory. These are executed in ascending order, according to the number the file name begins with.
Let’s look at the 2_deploy_contracts.js file in the Metacoin example:
const ConvertLib = artifacts.require(“ConvertLib”);
const MetaCoin = artifacts.require(“MetaCoin”);
module.exports = function(deployer) {
deployer.deploy(ConvertLib);
deployer.link(ConvertLib, MetaCoin);
deployer.deploy(MetaCoin);
};
The code deploys two contracts, a library contract and a consuming contract, and links them. Linking in this context means that the MetaCoin contract consumes the ConvertLib library, for which it needs to know its address after deployment. Truffle deals with this complexity internally.
As already explained, Ganache is a local test and simulation environment, on which contracts can be deployed. Once started, the following user interface is visible:
As can be seen, a number of accounts are automatically created for testing.
With Ganche running and the example configuration shown above, the Metacoin contracts can be deployed using the following command:
- truffle migrate
It is sometimes necessary to force re-deployment with the –reset flag. The deployment transactions should be visible in the Ganache user interface instantly.
Testing
Testing smart contracts is where the advantages of Ethereum Truffle really become apparent.
One way of simply interacting with a contract deployed on Ganache (or other networks) is to use Truffle’s JavaScript console. This console provides Ethereum’s web3.js interface and also Truffle’s own abstraction, truffle-contract.
This allows simple contract interactions such as the following example sequence (based again on Metacoin):
truffle(ganache)> let instance = await MetaCoin.deployed()
undefined
truffle(ganache)> let balance = await instance.getBalance(accounts[0])
undefined
truffle(ganache)> balance.toNumber()
10000
Note that the above capture includes the command prompt and the replies.
More advanced tests can be defined in the test directory in JavaScript or Solidity and executed with the command:
- truffle test
JavaScript-based testing is arguably more powerful in some situations. Truffle uses the popular Mocha JavaScript testing framework in combination with the Chai assertion library. Explaining the syntax is beyond the scope of this article, but looking at the Metacoin example tests should give an idea of how powerful the framework can be for automated testing.
Conclusion
Of course, we have only scratched the surface on Truffle’s possibilities in this article. Configurations can be adapted to allow for deployments onto different networks for production and testing, using different compilers and optimization parameters.
It is also possible to integrate external tools, such as static code analyzers into the automated workflow.
Further details on these advanced cases can be found in the official Truffle documentation.