How To Use Ganache GUI With Truffle? | Episode 14

Julien Klepatch

Ganache CLI is an Ethereum client used for developing smart contracts and dapps. It is a command-line tool but it also comes with a user interface called Ganache GUI.

In the last video we learned how to install GUI, and in this video we will learn how to use it.

Although Ganache GUI is a great tool there are not many tutorials available This article will teach you:

  • How to use it?
  • How to configure it?
  • How to integrate it with Truffle?

Download example smart contract

First download this Truffle project from the Eat The Blocks repo on GitHub. It contain a smart contract that we will use to illustrate how to use Ganache GUI.

Start Ganache GUI

Go to the root directory of the Ganache GUI code that you downloaded (If you don’t know what I am talking about, please watch the video on How To Install Ganache GUI first.

Simply run:

npm run

And a new window containing Ganache GUI should open:


Configure Ganache GUI

Although Ganache GUI can automatically start Ganache CLI, it does not let you configure it. Also, you might want to connect to an already existing instance of Ganache CLI.

For example, when running the truffle develop command of Truffle, Truffle starts its own instance of Ganache CLI. It would be really great to be able to connect this instance to Ganache GUI. Let’s configure Ganache GUI to work with Ganache CLI in this case.

You need to configure 2 parameters:

  • the port number used by Ganache CLI
  • the seed phrase used by Ganache CLI

Let’s first configure the port number.

In the Ganache GUI window, go to the Configuration settings (cog icon on upper right corner), and in PORT NUMBER, input 9545.


Let’s now configure the seed phrase.

First, In a terminal window, start the truffle console and Ganache CLI:

truffle develop

It will produce some output, including the seed phrase used by Ganache CLI to create accounts. Copy this seed phrase.

In the Ganache GUI window, go to the ACCOUNTS & KEYS menu and update the seed phrase to the one you just copied:


Finally, restart Ganache GUI to take into consideration the new settings, by clicking on the “restart” button on the upper right corner of the window.

Deploy smart contract

In you terminal window, go the root of the Truffle project you copied before and deploy the smart contract ToDo.sol:

truffle(develop)> migrate

Go back to the window of Ganache GUI, in the ACCOUNTS menu. It shows a list of all the accounts created by Ganache CLI, with different fields:

  • address
  • balance
  • transaction count

For example we can see that the first account have spent some of its initial 100 ethers (account comes pre-funded with 100 ethers with Ganache CLI), and has already done 3 transactions:


If you now go to the TRANSACTIONS menu, you will see in more the transactions that were done by the first account:


For each of these transactions, you can see different fields such as:

  • transaction hash
  • from address
  • to address, or address of contract created
  • gas used
  • value transferred
  • Nature of transaction: contract call or contract creation

Wait a second? Shouldn’t we just have one transaction, since we deployed only one contract? Well, We actually deployed 2 contracts:

  • Migrations.sol, used internally by Truffle to keep track of migrations that have been run
  • ToDo.sol, our example smart contract

When you run the migrate command for the first time, the Migrations.sol contract is deployed is deployed for the first time. For each of your own contract that you deploy, 2 operations will take place:

  • a transaction an internal reference in Migration.sol. This reference keeps track of which migrations have been run
  • a transaction to deploy your contract (in our case ToDo.sol)

Let’s check that the information we see on Ganache GUI is correct.

Go back to your terminal window where you started truffle develop and get a variable pointing to the deployed instance of ToDo.sol:

truffle(develop)> let todo = {};
truffle(develop)> ToDo.deployed().then((_todo) => todo = _todo);

Access the address field of the todo variable:

truffle(develop)> todo.address

Compare this to what you see in the CREATED CONTRACT ADDRESS field of the contract deployment transaction in Ganache GUI. It should be the same.

Write data (transaction)

Let’s see how we can observe transaction in Ganache GUI.

Still in the truffle console, let’s create a transaction:

truffle(develop)> todo.addTask("Buy vegetables");

This will produce an output with the hash of the transaction. We will compare this transaction with what we see in Ganache GUI:


Now let’s switch to the window Ganache GUI, menu TRANSACTIONS, you should see the transaction we just created in the first row, with the same transaction hash:


Read data

Let’s now only read data, without doing any transaction, to see if we can still this in Ganache GUI.

In Truffle console, type this:

truffle(develop)> todo.getTask(0);

You should see the task you created before:

truffle(develop)> todo.getTask(0);
'Buy vegetables'

However in Ganache GUI we don’t see any new transaction. That’s normal. We just read data, it didn’t create any transaction.

Can we still see a trace of the read action in Ganache GUI? Yes. Go to the LOGS menu and you will see an entry for eth_call, at the bottom of the screen.


A word of caution here: these logs are NOT smart contract logs. They are the regular logs of the Ganache CLI client. Every time Ganache CLI receives an API call, it will log it here.


  1. Adrian Vynar
    January 21, 2019

    Hello! I made all recomended steps: till command on terminal truffle(develop)> migrate included. Everething was going well: information on terminal and on ganache GUI windows as shown here. BUT next two commands on terminal gone in wrong way: 1.truffle(develop)> let todo = {};
    let todo = {};
    SyntaxError: Identifier 'todo' has already been declared
    2. truffle(develop)> ToDo.deployed().then((_todo) => todo = _todo);
    ToDo.deployed().then((_todo) => todo = _todo);
    ReferenceError: ToDo is not defined
    at evalmachine.:0:1
    at sigintHandlersWrap
    at Script.runInContext
    What is the problem? Can you help me?(I use Ganache v.1.2.3)

    • jklepatch
      July 21, 2019

      You should have a single declaration for todo variable, let todo = {}, thats it.

      • Frida
        July 17, 2020

        Hi there!
        your tutorials are really helpful.
        could this tutorial still be cloned ?THe links sends me to 404 not found
        i also get the Reference error : todo is not defined

        could you tell me what could be wrong?


Leave a Reply

More great articles

Crud – Part II

We are going to continue our CRUD smart contract and finish the main features. You will learn: "Update" and "Destroy"…

Read Story

Simple storage – Part II

In this video, we are going to finish our simple storage smart contract, which can set and get the value…

Read Story

Syntax vs runtime vs logic errors in solidity

A lot of people are confused about debugging in general and don't know the difference between a syntax error and…

Read Story

Never miss a minute

Get great content to your inbox every week. No spam.
[contact-form-7 id="6" title="Footer CTA Subscribe Form"]