Introduction

The ImageCertificateSBT project enables the creation and issuance of Soulbound Tokens (SBTs) to certify accomplishments, memberships, or any other unique purposes. It is designed to ensure that certificates are non-transferable, enhancing trust and authenticity. Below is an in-depth explanation of the project components using code snippets.


Components

1. Smart Contract: ImageCertificateSBT.sol

The Solidity smart contract defines the core logic for the ImageCertificateSBT tokens. Key features include minting certificates and ensuring tokens are non-transferable.

Core Contract Features:

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract ImageCertificateSBT is ERC721 {
    address public owner;

    constructor(address _owner) ERC721("ImageCertificateSBT", "ICERT") {
        owner = _owner;
    }

    function safeMint(
        address to,
        string memory holderName,
        string memory issuer,
        uint256 timestamp,
        string memory purpose,
        string memory metadataURI
    ) public onlyOwner {
        require(balanceOf(to) == 0, "Recipient already holds a certificate");
        uint256 tokenId = totalSupply() + 1;
        _safeMint(to, tokenId);
        // Metadata logic can go here...
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not authorized");
        _;
    }
}

Features Explained:


2. Deployment Script: deploy.js

This script deploys the smart contract to an Ethereum network using Hardhat.

Deployment Script Example:

const hre = require("hardhat");

async function main() {
  const [deployer] = await hre.ethers.getSigners();
  console.log("Deploying contracts with the account:", deployer.address);

  const ImageCertificateSBT = await hre.ethers.getContractFactory("ImageCertificateSBT");
  const imageCertificateSBT = await ImageCertificateSBT.deploy(deployer.address);

  await imageCertificateSBT.deployed();
  console.log("ImageCertificateSBT deployed to:", imageCertificateSBT.address);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

Steps Explained: