Academic Record NFT
What it does:
Mints diplomas, transcripts, and academic achievements as NFTs, providing tamper-proof, transferable proof of education.
Why it matters:
Enables instant verification of academic records, reduces fraud, and allows students to share achievements easily while retaining ownership and control.
How it works:
-
Universities or accredited institutions are registered as authorized issuers
-
Student academic records are minted as NFTs with metadata pointing to encrypted or IPFS-stored documents
-
Students hold the NFTs in their wallets as verifiable proof of credentials
-
Employers, institutions, or third parties verify the NFT on-chain
-
Institutions can update, revoke, or issue additional academic NFTs
-
All minting, transfers, and revocations are logged immutably
-
NFTs can be used in combination with credential DAOs or micro-credential contracts
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title AcademicRecordNFT
* @author Nam
* @notice Mints academic records as NFTs for verifiable, tamper-proof credentials
*/
contract AcademicRecordNFT is ERC721, Ownable {
uint256 public tokenCount;
struct Record {
string metadataHash; // IPFS / encrypted transcript or diploma
address issuer;
bool valid;
}
mapping(uint256 => Record) public academicRecords;
mapping(address => bool) public authorizedInstitutions;
// -------------------- EVENTS --------------------
event InstitutionAuthorized(address indexed institution);
event AcademicNFTMinted(uint256 indexed tokenId, address indexed student, address issuer);
event AcademicNFTRevoked(uint256 indexed tokenId);
// -------------------- CONSTRUCTOR --------------------
constructor() ERC721("AcademicRecordNFT", "ARNFT") {}
// -------------------- INSTITUTION MANAGEMENT --------------------
function authorizeInstitution(address _institution) external onlyOwner {
require(_institution != address(0), "Invalid address");
authorizedInstitutions[_institution] = true;
emit InstitutionAuthorized(_institution);
}
// -------------------- NFT MANAGEMENT --------------------
function mintAcademicNFT(address _student, string calldata _metadataHash) external {
require(authorizedInstitutions[msg.sender], "Not authorized institution");
require(_student != address(0), "Invalid student");
tokenCount += 1;
_mint(_student, tokenCount);
academicRecords[tokenCount] = Record({
metadataHash: _metadataHash,
issuer: msg.sender,
valid: true
});
emit AcademicNFTMinted(tokenCount, _student, msg.sender);
}
function revokeAcademicNFT(uint256 _tokenId) external {
Record storage r = academicRecords[_tokenId];
require(msg.sender == r.issuer, "Not issuer");
require(r.valid, "Already revoked");
r.valid = false;
emit AcademicNFTRevoked(_tokenId);
}
function verifyAcademicNFT(uint256 _tokenId) external view returns (
string memory metadataHash,
address issuer,
bool valid
) {
Record memory r = academicRecords[_tokenId];
return (r.metadataHash, r.issuer, r.valid);
}
}