How to Test Solidity Smart Contracts Locally

In order to write your own Solidity smart contracts on your local machines, you'll need to follow the below steps;

  1. Install Truffle Suite
  2. Launch your Ganache Network
  3. Configure your truffle-config.js to use the local network
  4. Write Migration files
  5. Test

Example Smart Contracts

In this example, let's use a simple for-loop example. This is taken from CryptoZombies Lessons 3. Loop.getEvens() should return [2, 4, 6, 8, 10].

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;

contract Loop {
    function getEvens() external pure returns (uint256[] memory) {
        uint256[] memory evens = new uint256[](5);
        uint256 counter = 0;
        for (uint256 i = 1; i <= 10; i++) {
            if (i % 2 == 0) {
                evens[counter] = i;
                counter++;
            }
        }
        return evens;
    }
}

1. Install Truffle Suite

Truffle CLI

truffle CLI is necessary to compile, migrate, and run unit tests of your smart contracts.

Read the latest installation guide. As of writing this blog, and if you don't care installing into your global NPM binaries, npm install -g truffle does the job for you.

Ganache Network

Ganache offers local networks for your smart contracts to be deployed. It offers GUI.

Read the latest installation guide.

2. Launch your Ganache Network

Once you download your Ganache Network, you can launch your own network. Just click the QUICKSTART button and checks which port your network is running on.

In my case, the RPC server launched and was running at the following port:

HTTP://127.0.0.1:7545

3. Configure your truffle-config.js

Now you can configure your truffle directory.

truffle init

Then go to truffle-config.js, and configure the local network as follows. Don't forget to check the compiler version as well. That should be aligned with your pragma solidity header in your smart contract files.

module.exports = {
    networks: {
        development: {
            host: "127.0.0.1",     // Localhost (default: none)
            port: 7545,            // Standard Ethereum port (default: none)
            network_id: "*",       // Any network (default: none)
        },
    },
    compilers: {
        solc: {
            version: "0.8.17" // Fetch exact version from solc-bin (default: truffle's version)
        },
    },
}

Then you locate your own smart contracts at contracts/ directory. In my example, I located the loop contract with loop.sol file.

contracts/
    \- loop.sol

4. Write Migration Files

You then are expected to locate the migration files at migrations/ directory.

var Loop = artifacts.require("Loop")
module.exports = function(deployer) {
    deployer.deploy(Loop)
}

Now you're ready to migrate onto your local network.

truffle compile && truffle migrate

5. Test

Now your smart contracts are on! Try truffle console to connect to the local network and check if it works as expected.

$ truffle console
truffle(development)> let instance = await Loop.deployed()
truffle(development)> instance.getEvens()

You may want to write unit tests instead of manually testing every time you make changes to your contracts. You can add a unit test, for example loop.test.js, under test/ directory.

const Loop = artifacts.require("Loop")

contract('Loop', (accounts) => {
    let loop = undefined

    before(async () => {
        loop = await Loop.deployed()
    })

    it('should return even numbers', async () => {
        const evens = await loop.getEvens()
        // format results
        const result = evens.map((res) => res.words[0], 10)
        assert.deepEqual(result, [2, 4, 6, 8, 10])
    })
})

Only command you need to type is truffle test.

$ truffle test
Using network 'development'.


Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.


  Contract: Loop
    ✔ should return even numbers (58ms)


  1 passing (104ms)

Summary

Truffle Suite makes your smart contracts development fairly easy.

2022-10-24