How to work with Truffle and Ganache

This post will teach you how to work with Truffle and Ganache. It is a simple guide on how to start mastering these two very useful tools.

In this tutorial, for demonstration purposes, we will work on a simple Hello World smart contract. Following each step will help you understand how to start developing and testing your own smart contracts using Truffle and Ganache.

What are we going to cover?

  • Structure of the Truffle environment
  • Compilation and Deployment
  • Testing with Ganache

Truffle development environment

Truffle is a top solution for smart contracts development. It provides you with a simple to understand environment for developing an Ethereum application using the Solidity programming language. It allows you to:

  • Compile and deploy your smart contracts
  • Automatically test your code using JavaScript or Solidity
  • Link your contracts
  • Deploy on test networks and the Ethereum main network

To install truffle follow the Set up your first Smart Contracts project post.

To start your Truffle project, create a new folder and navigate to it from the terminal. Then type the command truffle init which will create the following set of files in your folder:

Let’s have a look at what these files mean and the purpose of each folder.

1. Contracts

Here you can create all your .sol smart contracts. The Migrations.sol contract is given by Truffle and it handles the migration history. You should not play with this file.

2. Migrations

What is a migration? Migrations are used for the deployment of your code. They automatically push your contracts to the blockchain, link them together and pass any parameters the constructor requires.

Here you will find the files that help you deploy your smart contracts.

The 1_initial_migartion.js file deploys the Migrations.sol contract. Additionally, you can further create new .js migration files for your new contracts. It is important that they have increasing prefixes (e.g. 2_name_file.js) as Truffle will run the migration in ascending order in terms of the prefix.

3. Test

Here you can create your test files. Truffle provides you with an automated testing framework that allows you to test your contracts in two different ways: using Solidity or Javascript.

You can use the Javascript approach for “external” interaction with the contracts. The Solidity method helps you to see how the code acts when used internally by other contracts.

4. Build 

After compiling your contracts, a build folder will be automatically created.

The files you will find here will contain low-level details of each of your contracts such as the ABI and bytecode. You will need this information when trying to reference your contract from outside the truffle environment (e.g. when building your JS web interface). After deployment, you can also find the address of your contracts in the build files.

5. Truffle Config

The truffle-config.js file sets up your project’s configurations. The most important elements here are network and compilers

You can set your network to either the Ganache local blockchain, a test network like Ropsten, the main network or a more personalised one.

When deploying your contracts you can specify the network as follows:

truffle deploy --network yourNetwork

In terms of compilers, you can modify the solc compiler configurations (if needed) or opt for an external compiler.

Write and Deploy

Now that we understand the overall structure of the project, let’s write some code.

1. Write the contract

For demonstration purposes, I chose a very simple contract. I called it HelloWorld.sol.

The constructor takes as a parameter a string and assigns its value to the global variable name. The name can be changed using the function changeName(string) which acts as a setter, while getName() acts as a getter. 

pragma solidity >=0.4.22 <0.9.0;

contract HelloWorld {

  string public name;

  constructor(string memory yourName) public{
    name = yourName;
  }

  function changeName(string memory yourName) public{
    name = yourName;
  }

  function getName() public returns(string memory){
    return name;
  }
}

Remember, this contract has to be placed inside the contracts folder.

2. Set-up the Migration

Now let’s write the migration file which will allow you to deploy this contract.

The 1_initial_migartion.js file is a good example of how your migration file should look. Next, create a new file in the migrations folder with a prefix greater than 1, for example, 2_hello_migartion.js.

To deploy the HelloWorld.sol contract, we need the following code:

const HelloWorld = artifacts.require("HelloWorld");

module.exports = function (deployer) {
  const yourName = "Ioana";
  deployer.deploy(HelloWorld, yourName);
};

The artifacts.require() tells Truffle which contract you want to interact with. 

Notice that the deployer.deploy() function is given two parameters. The second one refferes to the parameter we need to pass to the constructor, which is the initial name. 

If your constructor does not have parameters, only pass the contract abstraction. If it has more parameters, add them with a comma in between.

3. Compile and deploy

You can compile your contract to see if there are any syntax mistakes using this command:

truffle compile

Notice that a “build” file was created.

To work with Truffle and Ganache combined (to deploy and test your contract) you need to have the Ganache app opened. Simply pick “QuickStart” and leave it open.

Next, you need to let Truffle know which network to deploy on. Go to truffle-config.js and modify the network details. Next, uncomment the “development” section but make sure the RPC server port from Ganache matches the port number in the configurations.

networks: {
    development: {
     host: "127.0.0.1",    
     port: 7545,            
     network_id: "*",      
    }
}

Now that everything is set up, you can work with Truffle and Ganache combined. Go to the terminal and write:

truffle deploy --network development

After the deployment transactions are confirmed, the terminal will give you a few details about the contracts like their address and the block information.

Testing

Let’s try testing the contracts using JavaScript.

Firstly, create a test file with the .js prefix in the test folder. The tests I wrote for the HelloWorld.sol contract look like this:

// to interact with the contract
const HelloWorld = artifacts.require("HelloWorld");

contract('HelloWorld', () => {

  // initialise the contract instance before running tests
  let contractInstance = null;
  before(async () => {
    contractInstance = await HelloWorld.deployed();
  });

  // TEST 1
  it('initial name should be Ioana', async () => {
    // call contract's function
    const currentName = await contractInstance.getName.call();
    // check condition
    assert.equal(currentName, "Ioana", "the name is not Ioana");
  });

  // TEST 2
  it('should change name in John', async () => {
    // change name in contract
    await contractInstance.changeName("John");
    // get the current name
    const currentName = await contractInstance.getName.call();
    // check condition
    assert.equal(currentName, "John", "the name is not John");
  });

});

The before() function executes before the tests so that we can initialise the contract instance. 

The 1st test verifies if the contract was deployed with the right parameter for the constructor. It calls the getter method of the HelloWorld.sol contract and uses assert to check the equality.

The second test changes the name and checks if it was done according to the expectations.

Notice that for calling the function getName we used call(). This is because otherwise it would have returned the transaction receipt. call() is used when the method does not modify the state variables of the contract. This is why we don’t use it for the changeName method call.

Secondly, go back to the terminal and try running your tests:

truffle test

It should say something like:

Contract: HelloWorld

     initial name should be Ioana

     should change name in John (73ms)

  2 passing (144ms)

…..

Lastly, after you run your tests, you should see some movement in the Ganache interface such as a few confirmed transactions. Also, there will be less than 100 ETH in the 1st account as this is the address from where we deployed and called the contract’s functions.

Nice job! I hope you got a sneak peek of how to work with Truffle and Ganache. You deployed your first smart contract and your tests were successful.

You can also look at the Truffle docs for more information.


I hope this was helpful. Any suggestions are more than welcomed in the comments!

6 Comments Add yours

Leave a Reply