Skill Endorsement Blockchain

What it does:
Allows peers, educators, or employers to endorse a learner’s skills on-chain, creating verifiable and tamper-proof endorsements.

Why it matters:
Provides a trustworthy, immutable record of skills, enhances credibility for hiring or academic purposes, and reduces fraud in skill claims.

How it works:

  • Learners register their skills on-chain, optionally linked to credentials or certificates

  • Authorized endorsers (peers, teachers, or employers) submit endorsements for a skill

  • Smart contract records each endorsement along with endorser identity and timestamp

  • Endorsement counts and reputations are tracked for each learner

  • Learners can share on-chain proof with employers, educational institutions, or DAOs

  • All endorsements are auditable, preventing tampering or fraudulent claims

  • Can integrate with Academic Record NFT, Student Reputation DAO, or Lifelong Learning Wallet

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

/**
 * @title SkillEndorsement
 * @author Nam
 * @notice Records verified skill endorsements for learners on-chain
 */
contract SkillEndorsement {

    address public admin;
    uint256 public skillCount;

    struct Skill {
        string name;
        address learner;
        uint256 endorsementCount;
        mapping(address => bool) endorsers;
    }

    mapping(uint256 => Skill) public skills;

    // -------------------- EVENTS --------------------

    event SkillRegistered(uint256 indexed skillId, address indexed learner, string skillName);
    event SkillEndorsed(uint256 indexed skillId, address indexed endorser);

    // -------------------- MODIFIERS --------------------

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

    // -------------------- CONSTRUCTOR --------------------

    constructor() {
        admin = msg.sender;
    }

    // -------------------- SKILL MANAGEMENT --------------------

    function registerSkill(address _learner, string calldata _skillName) external onlyAdmin {
        require(_learner != address(0), "Invalid learner");

        skillCount += 1;
        Skill storage s = skills[skillCount];
        s.name = _skillName;
        s.learner = _learner;
        s.endorsementCount = 0;

        emit SkillRegistered(skillCount, _learner, _skillName);
    }

    function endorseSkill(uint256 _skillId) external {
        Skill storage s = skills[_skillId];
        require(!s.endorsers[msg.sender], "Already endorsed");

        s.endorsers[msg.sender] = true;
        s.endorsementCount += 1;

        emit SkillEndorsed(_skillId, msg.sender);
    }

    function getSkill(uint256 _skillId) external view returns (string memory name, address learner, uint256 endorsements) {
        Skill storage s = skills[_skillId];
        return (s.name, s.learner, s.endorsementCount);
    }
}