Skip to content

DApp Development: Contract

Mobin Mohanan edited this page Oct 8, 2024 · 8 revisions

Writing Smart Contract

The first step in developing a decentralized application is to design and code the smart contract. The use case scenario is to develop a DApp for issuing and delivering certificates for the students who pass the various courses of a university.

Let's develop our smart contract.

Go to Remix - Ethereum IDE and create a new file named 'Cert.sol'.

From the discussion with the university, we have pointed out the key requirements, which are as follows:

  • Store each certificate details, including candidate name, course name, grade, and date of issue, and these details should be mapped against the certificate ID.
  • Only an authorized person (University) can store details regarding the certificate on the blockchain.
  • Retrieve the certificate's details using the certificate ID.

Now, let's define our contract. We will start by specifying the license, under which this program will be, let's use MIT.

// SPDX-License-Identifier: MIT

Now, let's specify which version of solidity language we will be using; we will go with 0.8.20.

pragma solidity 0.8.20;

Let's call the contract cert.

contract Cert {
}

Now, let's define a struct for storing the certificate details.

struct Certificate {
    string name;
    string course;
    string grade;
    string date;
}

Our requirement is to retrieve the certificate details using the certificate ID, so the best way is to map the struct certificate to the certificate ID which will be an unsigned integer. We will set it as uint256.

mapping (uint256 => Certificate) public Certificates;

There are no restrictions to access/read the certificate details, so we will set the mapping as public, generating a getter function of the same name as the mapping. So, provide it with the certificate ID and retrieve the certificate data.

Now, let's create our function to store the details of the certificate on the blockchain.

function issue (
    uint256 _id,
    string memory _name,
    string memory _course,
    string memory _grade,
    string memory _date) public {
        Certificates[_id] = Certificate(_name, _course, _grade, _date);
}

The issue function adds the certificate data to the mapping, using the certificate ID as an index for each entry.

Remember, we need an additional feature; only the University admin should be able to execute the issue function, so we need to restrict calls from accounts that are not the University's. From the discussion with the University, we know that the University has an account, and they will be deploying the contract from that particular account. So we can set this as the admin account, a.k.a. an authorized account. Let's define the constructor and store the deploying address to a state variable to do that.

constructor() {
    admin = msg.sender;
}

Now we need to check if the caller account is the same as the one in the admin state variable whenever a call to execute the issue function comes and execute the function only if it passes this check. This can be achieved using a modifier.

modifier onlyAdmin {
    require(msg.sender == admin, "Access Denied");
    _;
}

We will add this modifier to the issue function. The entire source code for the contract is given below.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract Cert {

  address admin;

  constructor() {
    admin = msg.sender;
  }

  modifier onlyAdmin {
      require(msg.sender == admin, "Access Denied");
      _;
  }

  struct Certificate {
      string name;
      string course;
      string grade;
      string date;
  }

  mapping (uint256 => Certificate) public Certificates;

  function issue (
      uint256 _id,
      string memory _name,
      string memory _course,
      string memory _grade,
      string memory _date) public onlyAdmin {
          Certificates[_id] = Certificate(_name, _course, _grade, _date);
      }
}

Installing Node.js

Run an Ethereum Simulation

Now that we have written our contract and designed our frontend, the next step is to compile and deploy the contract.

The next step is to run a simulated Ethereum node, which you can run using the 'Hardhat' framework.

For that, we first initialize a 'Node.js' project.

npm init

Install Hardhat.

npm install -D hardhat

Initialize a Hardhat project afterwards

npx hardhat init

Choose the option 'Create an empty hardhat.config.js'. This will create a 'hardhat.config.js' file in the root folder. Now run the Hardhat node simulation.

npx hardhat node

This will start our development node with twenty pre-funded accounts each having 10000 Test ETH.

Compile and Deploy the Contract

Now open the Remix IDE.

  • Compile the contract.
  • Connect to the Hardhat node client using the 'Hardhat Provider' in Remix IDE and deploy the contract.
  • Issue and retrieve certificates using the deployed instance.


Clone this wiki locally