Sample Contracts

This chapter describes how to write and deploy smart contracts using truffle.

Creating Smart Contracts

This chapter describes how to create and distribute smart contracts using Truffle.

How to use Truffle

1. Installation

Install truffle using NPM, the Node Package Manager. Please refer to the following link for how to install npm: https://www.npmjs.com/

$ npm install --g truffle

2. Initialization

$ truffle init

When truffle init is performed, a truffle project is created. The Truffle project consists of build/contracts, contracts, migrations, tests, and truffle-config.js.

  • build/contracts: The result of compiling the contract written in solidity (abi, bytecode) is saved

  • contract: smart contract solidity files

  • migrations: deploy code(js format)

  • test: test code(js format)

  • truffle-config.js: Configuration such as solidity compiler version setting, network setting, etc

Performing truffle init, the example solidity code called Migrations.sol is created as follows in the contract folder. To deploy the written smart contract, the user must first compile the written smart contract.

pragma solidity >=0.4.22 <0.9.0;

contract Migrations {
  address public owner = msg.sender;
  uint public last_completed_migration;

  modifier restricted() {
    require(
      msg.sender == owner,
      "This function is restricted to the contract's owner"
    );
    _;
  }

  function setCompleted(uint completed) public restricted {
    last_completed_migration = completed;
  }
}

3. Settings

You must modify the truffle-config.js file for compilation and deployment.

3.1 Account Settings

Add HDWalletProvider and privKeys in the Truflle-config.js file for settings for the account you want to use for deployment. Private keys can be imported after creating an account through the Web Wallet (https://wallet.test.wemix.com).

const HDWalletProvider = require('@truffle/hdwallet-provoder');
const privKeys = ["privatekey from Web Wallet"];

3.2 Network Settings

To use the WEMIX3.0 Testnet, add the network settings as follows:

networks: {
  wemix_testnet: {
    provider: ()=> new HDWalletProvider(privKeys, "https://api.test.wemix.com"),
    network_id: 1112,
    maxFeePerGas: 100000000010,
    maxPriorityFeePerGas: 100000000000
  }
},

3.3 Compiler Settings

Set the last Solidity compiler version you want to use. The current version is 0.8.x, and the example uses 0.8.11. If it is installed directly on the operating system using the compiler, you can comment on the docker setting just like the initial setting. To install using docker, set "docker: true" as shown below and docker should be installed. If you use the optimizer, you can un-annotate and set the appropriate settings.

compilers: {
    solc: {
      version: "0.8.11",    // Fetch exact version from solc-bin (default: truffle's version)
      docker: true,         // Use "0.5.1" you've installed locally with docker (default: false)
      // settings: {          // See the solidity docs for advice about optimization and evmVersion
      //  optimizer: {
      //    enabled: false,
      //    runs: 200
      //  },
      //  evmVersion: "byzantium"
      }
    }

4. Write a Solidity code

Here is a simple smart contract example that increments or decrements the count variable and retrieves its value. Save it as Counter.sol.

pragma solidity ^0.8.0;

contract Counter {
    uint256 count;
    
    constructor(uint256 _count) {
        count = _count;
    }
    
    function get() public view returns (uint256) {
        return count;
    }
    
    function inc() public {
        count += 1;
    }
    
    function dec() public {
        count -= 1;
    }
}

5. compile a Solidity code

When truffle compile <file name> is performed in the truffle project folder, it compiles the target solidity file. The compiled solidity contracts are stored in the build/contracts folder as <contract name>.json format.

truffle compile <file name>
ex) truffle compile Counter.sol

6. Deploy a smart contract

To distribute the compiled contract file to the blockchain, write the script and save it as 2_deploy_contracts.js:

var Counter = artifacts.require("./Counter.sol");

module.exports = function(deployer) {
  deployer.deploy(Counter, 10)
    .then(() => Counter.deployed());
};

Deploy a contract individually by loading them as artifacts.require (<artifacts file name stored in build/contracts>) and performing developer.deploy(contract_artifacts, {constructor arguments}).

truffle migrate <file name>
ex) truffle migrate 1_initial_migration.js

The deployment script can be executed with the truffle migrate <file name>. If not used, it is performed in numerical order used in the script name.

The results of the deployment on WEMIX3.0 Testnet are as follows: For deployment, the account that you want to use for deployment must have WEMIX. You can receive the required WEMIX from WEMIX-Faucet at https://wallet.test.wemix.com.

❯ truffle migrate --reset --network wemix_testnet

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


Starting migrations...
======================
> Network name:    'wemix_testnet'
> Network id:      1112
> Block gas limit: 105000000 (0x6422c40)


1_initial_migration.js
======================

   Replacing 'Migrations'
   ----------------------
   > transaction hash:    0x8f57dc573afbf1e33b75b2f05282aac9152be70cee292c31c94877397cf27d82
   > Blocks: 0            Seconds: 0
   > contract address:    0x09C38aaf3AF7Dba9Cc2B755d75Acccf4A5b7bECC
   > block number:        428504
   > block timestamp:     1658480854
   > account:             0x435AaB89A2878102fDf894dA3e5F3b4454FF9772
   > balance:             9.926666599999266666
   > gas used:            250142 (0x3d11e)
   > gas price:           100.000000001 gwei
   > value sent:          0 ETH
   > total cost:          0.025014200000250142 ETH

   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:     0.025014200000250142 ETH


2_deploy_contracts.js
=====================

   Deploying 'Counter'
   -------------------
   > transaction hash:    0x893fcc06e298b95ff145c90311c5d36a3f8c511470e73a753d13195ea9dae051
   > Blocks: 0            Seconds: 0
   > contract address:    0x76F3A4DFD8741E765Bf27Cd0BaaE26f64c192765
   > block number:        428508
   > block timestamp:     1658480857
   > account:             0x435AaB89A2878102fDf894dA3e5F3b4454FF9772
   > balance:             9.904089499999040895
   > gas used:            179858 (0x2be92)
   > gas price:           100.000000001 gwei
   > value sent:          0 ETH
   > total cost:          0.017985800000179858 ETH

   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:     0.017985800000179858 ETH

Summary
=======
> Total deployments:   2
> Final cost:          0.04300000000043 ETH

7. Test a smart contract

The deployed contract can be tested through the javascript file as follows.

const migration = artifacts.require("Migrations");

contract("Migration", async () => {
    describe("Migration test", async () => {
        it("setCompleted", async () => {
            const migrations = await migration.deployed();
            await migrations.setCompleted(0);
        });
    });
});
  • contract : test target contact

  • describe : test case set

  • it : Individual test case

truffle test <test file name>

When the test code is completed, save the test file as <testName.test.js> format in the test folder, and perform the truffle test <testName.test.js> to perform the test.