Truffle framework cheatsheet

The documentation of the Truffle framework is pretty good, but it can be a bit overwhelming for a beginner. This cheatsheet is a condensed version giving you the bare minimum you need to develop Ethereum Dapps on Truffle

CLI

These commands are the most often used. They must be run at the root of your project

Init a Truffle project

This creates a new Truffle project on your file system:

truffle init

Init a Truffle project WITH code skeleton

This command is a bit like vue-cli or yeoman for Ethereum Dapps. It scaffold your Dapp code using some of these templates, called Truffle boxes. You need to give the name of a Truffle box after unbox:

truffle unbox [name-of-truffle-box-here]

Compile smart contracts

This compiles all your smart contracts to the build/contracts folder:

truffle compile

Deploy smart contracts

This deploys all your smart contracts in the contract folder to the develop network, i.e your local Ganache instance:

truffle migrate --reset

Note 1: The reset flag makes sure that the latest version of your smart contracts will get recompiled. If you don’t put it, you might have problems where Truffle does not recompile the most recent changes. Most of the time, you want to use this reset flag.

Note 2: To deploy to other networks like testnet or mainnet you need to add a --network flag followed by the name of the network, as defined in truffle-config.js:

truffle migrate --reset --network ropsten

Note 3: By default Truffle does a dry-run before deploying for real when you deploy to a testnet or mainnet. If you don’t want this behavior, add a --skipDryRun flag.

Truffle console

The Truffle console is a REPL to interact with your smart contracts. You can also run some commands of the CLI inside the console, like migrate or compile (yes there is no need for the truffle prefix this time)

Start a console

This start a console + Ganache instance

truffle develop

Attach a console

To attach a console to an already running instance of Ganache:

truffle console

Note: Like for migrations, by default it will attach to the develop network, i.e the local Ganache instance. If you want to attach a console to other networks, you can add a --network flag, followed by the name of the network.

Getting a smart contract instance

(Inside the console). This allow you to grab a truffle-contract instance of a deployed smart contract:

truffle (develop)> const myContract = await MyContract.deployed();

Note: This will point to a smart contract deployed in the latest migration. If for some reason you want to point to a smart contract deployed in previous migrations or deployed manually before in the console, you will need to use the at() method instead:

truffle (develop)> const myContract = await MyContract.at(//Address of smart contract here);

Interacting with a smart contract

truffle (develop)> const result = await myContract.myReadOnlyFunction('myArg');
truffle (develop)> const txReceipt = await myContract.myTransactionFunction('myArg').send({from:  '0x900...'})

Note: Optionally, you can add a .call({from: '0x900...', ...}) suffix when you call a read-only function. If you don’t, Truffle will assume that you want to do a call, and not a transaction.

Migration files

By default, all contracts inside the contracts folder will be compiled by the truffle compile and truffle deploy commands, but it’s not enough to deploy a smart contract. When you run the truffle deploy command, only smart contracts specified in a migration inside the migrations folder will be deployed. By the way, you can take the migration of the Migration smart contract as a template. That’s a contract used by Truffle internally. Oh, and also you shouldn’t touch it.

By the way, quick tip that most people don’t now. You can use the CLI to create migrations: `truffle create migration [name-of-migration]

Simple migrations

This will deploy the smart contract called MyContract when you run truffle migrate. Note that for MyContract the Solidity name of the smart contract matters, not the file name.

const MyContract = artifacts.require('MyContract');

module.exports = function(deployer) {
    deployer.deploy(MyContract);
}

Complex migrations

This is a more complex migration involving:

  • giving arguments to smart contract constructor
  • deploying 2 smart contracts
  • Using address of first deployed smart contract to second (also requires using async/await to wait for first deployment)
  • Deploying a smart contract with a custom address. By default, the first address
  • Using extra arguments of the deployment functions (network and accounts)
    const MyContract = artifacts.require('MyContract'); 
    const MyOtherContract = artifacts.require('MyOtherContract');

    module.exports = function(deployer, _network, accounts) { 
        await deployer.deploy(MyContract, 'arg1', 'arg2'); 
        if(network === 'develop') { 
            const myContract = MyContract.deployed(); 
            deployer.deploy(MyOtherContract, myContract.address, {from: accounts[1][2]}); 
         } 
    }

Configuration file

Truffle has a configuration file called truffle-config.js. That’s where you define the configurations for the different networks, as well as other parameters used by Truffle. By default Truffle print some commented documentation inside, but this section will highlight the most important configurations.

Note: If you have an older Truffle version, you will likely have 2 configuration files: one called truffle.js, and another one called truffle-config.js. This was for solving a bug on windows. You can delete truffle.js and only work with truffle-config.js.

Specifying a different Solidity compiler

By default, Truffle uses Solidity 0.5.0. You can change this version to a newer or older version with

compilers: {
    solc: {
      version: <string>, //"0.5.2"
   }
}

Specifying a different build directory

When you want to integrate a Dapp frontend using framework like React, Vue or Angular, you will probably use webpack to bundle the contract ABI and the address, using ES6 import statements. Certain webpack configuration like create-react-app do not allow to import files outside the folder containing the source code of the frontend. To get around this, you can change the build directory of truffle with:

contracts_build_directory: 'client/src/build'

Enabling Solidity optimizations

By default, Truffle does not activate any optimizations for Solidity. It’s faster to compile, but the resulting bytecode is not as gas efficient. This is better for development, but worst for production (mainnet). To enable Solidity optimization, add this:

compilers: { 
  //Other compiler settings 
  settings: {  
    optimizer: { enabled: true runs: 200 // Optimize for how many times you intend to run the code 
   }, 
}

Adding testnet / mainnet networks

The develop network running a local Ganache blockchain is already configure on port 9545. However, if you want to deploy your smart contracts to other networks like public testnet (ropsten / Kovan) or mainnet you need to first add a manual configuration to the networks key in `truffle-config.js.

For these networks, you will also need to sign your transactions (unlike with Ganache where you can have unlocked accounts). That’s why we need to use the truffle-hdwallet-provider npm package, as well as the mnemonic of the deployment wallet.

And finally, for these networks in most case we will use a publicly available Ethereum node to send our transactions. In this example we use infura, but you can replace this url by whatever service you are using.

const HDWalletProvider = require("truffle-hdwallet-provider"); 
const mnemonic = process.env.MNEMONIC; const projectId = process.env.INFURA_PROJECT_ID

module.exports = { 
...
networks: {
  ropsten: {
    provider: function() {
      return new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/${projectId}`);
    },
    network_id: '3',
  },
  test: {
    provider: function() {
      return new HDWalletProvider(mnemonic, "http://127.0.0.1:8545/");
    },
    network_id: '*',
  },
}

Leave a Reply

Your email address will not be published. Required fields are marked *