How To deploy your first smart contract on the XDC Network using Truffle

Use Truffle to deploy a Smart Contract.

🧭 Table of contents

📰 Overview

Truffle is a blockchain development environment, which you can use to create and test smart contracts by leveraging an Ethereum Virtual Machine.

What you will learn

This guide aims at teaching how to create a smart contract using Truffle and deploying it on the XDC Network.

What you will do

  • Install and set up Truffle

  • Deploy a contract on the XDC Network

  • Check the deployment status on xinfin.network.

🚀 Setting up the development environment

There are a few technical requirements before we start. Please install the following:

Once you have installed those, you only need one command to install Truffle:

npm install -g truffle

To verify that Truffle is installed properly, type truffle version on a terminal. You should see something like:

Truffle v5.5.27 (core: 5.5.27)
Ganache v7.4.0
Solidity v0.5.16 (solc-js)
Node v16.16.0
Web3.js v1.7.4

If you see an error instead, make sure that your npm modules are added to your path.

⚒ Starting a new Truffle Project

You can start by setting up your folder. In this example, we are creating a project called Pizza. Create your new Pizza folder by running the following on terminal:

mkdir Pizza && cd Pizza

Next, you can run truffle init. If truffle is correctly installed on your local environment, you should see the following message:

Starting init...
================

> Copying project files to /home/your/path/to/Pizza

Success!

Next, try these scaffold commands to get started:
  $ truffle create contract YourContractName # scaffold a contract
  $ truffle create test YourTestName         # scaffold a test

http://trufflesuite.com/docs

Your folder files will look like this:

⚒ Configuring XDC Mainnet and Apothem Testnet on Truffle

In order to get started deploying new contracts on the XDC Mainnet and/or Apothem, you will need to install two new dependencies that will be used in the truffle-config.js file. These dependencies are @truffle/hdwallet-provider and dotenv. First, choose your preferred package manager. In this example we are using yarn but you can also use npm.

If you never used yarn before, you might need to install it first. You can skip this step if you already have yarn installed.

npm install --global yarn

Initialize your package manager in your folder and install the required dependencies:

yarn init -y
yarn add @truffle/hdwallet-provider dotenv

You will also need a 24-Word Mnemonic Phrase. To configure your wallet, create a new .env file and write your mnemonic by running:

touch .env
echo MNEMONIC=arm derive cupboard decade course garlic journey blast tribe describe curve obey >> .env

Remember to change the 24-Word Mnemonic above for your own mnemonic. The contents of your .env file should read as follow:

MNEMONIC=arm derive cupboard decade course garlic journey blast tribe describe curve obey

🚨 Do not use the mnemonic in the example above in production or you can risk losing your assets and/or the ownership of your smart contracts! 🚨

And finally, we can configure the truffle-config.js file for both Apothem and the XDC Network by writing:

require('dotenv').config();
const { MNEMONIC } = process.env;
const HDWalletProvider = require('@truffle/hdwallet-provider');

module.exports = {

  networks: {

    xinfin: {
      provider: () => new HDWalletProvider(
        MNEMONIC,
        'https://erpc.xinfin.network'),
      network_id: 50,
      gasLimit: 6721975,
      confirmation: 2,
    },

    apothem: {
      provider: () => new HDWalletProvider(
        MNEMONIC,
        'https://erpc.apothem.network'),
      network_id: 51,
      gasLimit: 6721975,
      confirmation: 2,
    }
  },

  mocha: {
  },

  compilers: {
    solc: {
      version: "0.8.16",
    }
  },
};

⚒ Adding Testnet XDC to Development Wallet

It is possible to list all XDC addresses bound to your mnemonic on Truffle by accessing the Truffle console:

truffle console --network xinfin

Once the truffle console CLI opens, you can run:

truffle(xinfin)> accounts

And the console should log all accounts bound to your mnemonic phrase as follow:

[
  '0xA4e66f4Cc17752f331eaC6A20C00756156719519',
  '0x0431d52FE37F3839895018272dfa3bA189fcE07E',
  '0x11A6D9727c16064950473a4c8A92dC294190f7fF',
  '0x4464DDF9969E9a8e5CfF02E3706AEB4ccA92A314',
  '0xFa73bE6AA126DEC47ce14a22B7BAaF8BAFaB59Fb',
  '0xEdFFc4e7476f05f43cA3e6f5784349dE6E6373D5',
  '0x07795c732Bb013165FADCE64B884bf9971Bf9636',
  '0x5dF551A53bEaAB8bb2307eF459aA5AAFbb5F73cc',
  '0x910435b01e6Aa66dE22769062998F6AE98566f23',
  '0x573b009b2dE9A95531f82DA10BB0D793050329d2'
]

These accounts are on the Ethereum standard format starting with 0x, but we can simply switch 0x for xdc. By default, the deployment account is the first account from the list above: xdcA4e66f4Cc17752f331eaC6A20C00756156719519.

With this account, we can head to the Apothem Faucet and claim some TXDC for development purposes:

🍕 Writing our first Smart Contract

Lets create a simple Pizza.sol contract on Solidity, the Pizza contract should have:

  • a constructor where the deployer can define the pizza size,

  • a eatSlice method to consume slices available,

  • a bakeNewPizza method to refill all slices only if the previous pizza have been entirely eaten! 😋

You can start by creating the Pizza.sol file:

touch ./contracts/Pizza.sol

And write the following code to Pizza.sol:

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

contract Pizza {
    uint256 public PIZZA_SIZE;
    uint256 public slices;

    constructor(uint256 _pizzaSize) {
        PIZZA_SIZE = _pizzaSize;
        slices = 0;
        slices += PIZZA_SIZE;
    }

    function eatSlice() public {
        require(slices > 0, "No Slices Left. Lets Bake a new Pizza!");
        slices -= 1;
    }

    function bakeNewPizza() public {
        require(slices == 0, "There still slices from a previous Pizza!");
        slices += PIZZA_SIZE;
    }
}

🍕 Compiling

Next, try compiling the Pizza.sol contract by running:

truffle compile

If everything is correctly configured and there are no errors, you will see the following message on your console:

Compiling your contracts...
===========================
> Compiling ./contracts/Pizza.sol
> Artifacts written to /home/your/path/to/Pizza/build/contracts
> Compiled successfully using:
   - solc: 0.8.16+commit.07a7930e.Emscripten.clang

And your folder should look like this:

🍕 Deploying

In order to deploy our newly-compiled contract artifacts to the blockchain, we need to create a deployment script in the migrations folder.

touch ./migrations/1_pizza_migration.js

And write the following migration script:

const Pizza = artifacts.require("Pizza");

// Constructor variables can be declared here
const SLICES = 8;  

module.exports = function (deployer) {
    deployer.deploy(Pizza, [SLICES]);
}

If the migration script has no errors, you can run the command:

truffle migrate --network xinfin

for deployment on XDC mainet. Or you can run:

truffle migrate --network apothem

for deployment on the XDC Apothem Testnet. In either case, you must have enough funds to pay for gas fees on the address that is being used for development.

If the deployment is sucessful, the console should log the following message after migrations complete processing:

1_pizza_migration.js
====================

   Deploying 'Pizza'
   -----------------
   > transaction hash:    0xc523d2fd7ccb9fec01b25d194a7a0edebaf6f9456c649038a7c447df0c09ba47
   > Blocks: 4            Seconds: 9
   > contract address:    0x8C998fa3d75b8c87253D1C97f5dE9BaaBfbbde3e
   > block number:        50305350
   > block timestamp:     1663109646
   > account:             0xA4e66f4Cc17752f331eaC6A20C00756156719519
   > balance:             1124.5120119465
   > gas used:            352214 (0x55fd6)
   > gas price:           0.25 gwei
   > value sent:          0 ETH
   > total cost:          0.0000880535 ETH

   > Saving artifacts
   -------------------------------------
   > Total cost:        0.0000880535 ETH

Summary
=======
> Total deployments:   1
> Final cost:          0.0000880535 ETH

🍕 Interacting with your contract using Truffle Console

Another amazing tool that allow us to try out our contracts straight from our development environment is the truffle console CLI.

To start interacting with you smart contracts you can run:

truffle console --network xinfin

Once the console opens, you can instantiate your Pizza contract by running:

truffle(xinfin)> let instance = await Pizza.deployed() 
// It should log: undefined

Check if this instance points to our deployment on chain by writing:

truffle(xinfin)> instance.address
// It should log: '0xF899E5C79ccfa144fc76261Ad9A9F0300708FF24'

or simply run our eatSlice() method:

truffle(xinfin)> instance.eatSlice()

It should log a transaction confirmation (or rejection) object like this:

{
  tx: '0x0153f15932d79ad7ac0b26df299defa1b55aded33284928b3e441d9fea5c3de7',
  receipt: {
    blockHash: '0x55c565b34efa5403a18ae7793286458347e2e92c154c0f56cdb9cc89d573921b',
    blockNumber: 50307378,
    contractAddress: null,
    cumulativeGasUsed: 28232,
    from: '0xa4e66f4cc17752f331eac6a20c00756156719519',
    gasUsed: 28232,
    logs: [],
    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
    status: true,
    to: '0xf899e5c79ccfa144fc76261ad9a9f0300708ff24',
    transactionHash: '0x0153f15932d79ad7ac0b26df299defa1b55aded33284928b3e441d9fea5c3de7',
    transactionIndex: 1,
    rawLogs: []
  },
  logs: []
}

This transaction is immediately reflected in the corresponding block explorer, as seen here!

🔍 Veryfing Contracts on the Block Explorer

Once you have successfully deployed your smart contract to the blockchain, you may want to verify your contract on XinFin Block Explorer.

First lets check the address our contract is deployed to by running:

truffle networks

If you have a contract already deployed, the console should log something like this:

Network: apothem (id: 51)
  No contracts deployed.

Network: xinfin (id: 50)
  Pizza: 0xF899E5C79ccfa144fc76261Ad9A9F0300708FF24

If your Pizza contract is deployed on the XDC Mainnet at 0xF899E5C79ccfa144fc76261Ad9A9F0300708FF24. You can search for our newly deployed contract on XinFin Block Explorer:

Click in the Verify And Publish option.

You will be redirected to the contract verification page where we need to fill out:

  • Contract Name: Pizza

  • Compiler: Check your truffle-config.js file for Compiler Version

  • Contract Code: Just paste everything from your Pizza.sol file

Once everything is filled out, press Submit!

If everything is correctly filled out, your contract page on the block explorer should display a new tab called Contract:

On this page you can read from, write to, or simply read the information tied to your smart contract on the blockchain:


For more information about Truffle Suite, Please Visit Truffle Suite Documentation. For more information about XinFin Network, Please Visit XDC Network Documentation on GitBook. Resources used during the deployment of the Pizza smart contract can be found at The Pizza Contract Folder.

Last updated