Skip to content

Getting started with Truffle

The behemoth of all Toolkits for Ethereum Blockchain Development is Truffle. Its a heavyweight, the oldest and quite intense in terms of setup, usage, but also rich of features.

Without it being explicitly mentioned on the Truffle Suite Website, its made for larger teams and large sets of smart contracts. This is where it really shines. Let's install truffle and bring out smart contract over and run through some commands, so you'll see for yourself what I mean.

Truffle Setup

nstalling Truffle is actually quite easy.

Open a Terminal (here with Ubuntu 20.04 in WSL2) and install Truffle globally.

npm install -g truffle

It will install truffle in your global npm directory. On Linux that's in ~/.npm-global/lib/node_modules/truffle, and in a similar directory on Windows and Linux. As these are in the global path you can then simply type in "truffle" from anywhere on the system.

Truffle Setup
Truffle Setup

First Truffle Project Initialization

Let's now create an empty folder and get directly into the VSCode Environment. As we're doing Truffle, Hardhat and Foundry let's create a subdirectory for Truffle in our NFT-Project:

nft-project
 |_ /truffle
 |_ /hardhat
 |_ /foundry

So, lets create the first folder for truffle:

mkdir -p nft-project/truffle
code nft-project/truffle

You should have an empty VSCode Project. Hit "Terminal" -> "New Terminal" (Here on my German Keyboard its Ctrl+Shift+ΓΆ)

Open new Terminal VSCode
Open new Terminal VSCode

Type in

truffle init

and truffle will download a scaffolding project from github and initialize the directory with the default folder structure:

Truffle Scaffolding Project

Truffle Default Folder Structure

In (almost) every truffle project, there's the same folder structure. As Truffle was the first Solidity Development Toolkit, other Toolkits adopted the same naming convention (or because its very self-explanatory somehow).

  1. There's a contracts folder, which contains the Smart Contracts
  2. There is a migrations folder, which contains scripts to deploy the contracts
  3. There is a tests folder, which contains the unit tests
  4. There is a config file named truffle-config.js which contains sensible defaults.

Adding our NFT

As truffle builds itself upon nodejs and npm, we can also initialize the folder with npm init -y to add a package.json and add additional packages, such as the openzeppelin contracts:

npm init -y
echo "node_modules" > .gitignore
npm install --save @openzeppelin/contracts

Add Openzeppelin Contracts to Truffle
Add Openzeppelin Contracts to Truffle

What you get is the openzeppelin contracts in node_modules/@openzeppelin/contracts. This way we can import them now into our own contract.

Let's create a new file in contracts called "Spacebears.sol" and copy and paste our contract from Remix, but replace the contracts@4.7.3 with just contracts:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract Spacebear is ERC721, ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("Spacebear", "SBR") {}

    function _baseURI() internal pure override returns (string memory) {
        return "https://ethereum-blockchain-developer.com/2022-06-nft-truffle-hardhat-foundry/nftdata/";
    }

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
}

then simply type in

truffle compile

and it should compile. After compilation, you should have a build/contracts folder, containing contract artifacts.

Info

If you run into compiler version problems, open truffle-config.js, on the bottom, there is the compiler version defined. At the time of writing we're using version 0.8.16.

Truffle Contracts

But what's going on here exactly?

  1. Truffle downloads a solidity compiler in the background (the version is defined in truffle-config).
  2. Then it looks in the contracts folder for all solidity files and runs them through the solidity compiler.
  3. From the compiled contracts it creates json-artifacts, which contain not only the ABI, but also the bytecode and the AST and much more.
  4. When we deploy the code using truffle migrations, it will also contain the contract address on a specific network. Truffle will take care of this.

Let's do just that in the next lab. Let's deploy our token, because there are so many options to choose from, it might be a bit confusing.