Education Content Licensing

What it does:
Manages licensing, usage rights, and royalty distribution for educational content on-chain.

Why it matters:
Ensures content creators are fairly compensated, prevents unauthorized use, and provides transparent licensing history.

How it works:

  • Content creators register educational materials on-chain with metadata and IP rights

  • License terms (duration, fees, usage limits) are defined at registration

  • Institutions or learners can request a license and pay fees on-chain

  • Smart contract automatically grants license and tracks usage rights

  • Royalties or usage fees are distributed automatically to creators

  • All transactions, licenses, and revocations are immutable and auditable

  • Can integrate with Academic NFT, Lifelong Learning Wallet, or Crowdfunding DAO for content monetization

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

/**
 * @title EducationContentLicensing
 * @author Nam
 * @notice On-chain licensing and royalty distribution for educational content
 */
contract EducationContentLicensing {

    address public admin;
    uint256 public contentCount;

    struct Content {
        string metadataHash; // IPFS or encrypted content reference
        address payable creator;
        uint256 licenseFee; // in wei
        uint256 licenseDuration; // in seconds
        mapping(address => uint256) activeLicenses; // licensee => expiration timestamp
    }

    mapping(uint256 => Content) public contents;

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

    event ContentRegistered(uint256 indexed contentId, address indexed creator, uint256 licenseFee, uint256 licenseDuration);
    event LicensePurchased(uint256 indexed contentId, address indexed licensee, uint256 expiration);
    event LicenseRevoked(uint256 indexed contentId, address indexed licensee);

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

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

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

    constructor() {
        admin = msg.sender;
    }

    // -------------------- CONTENT MANAGEMENT --------------------

    function registerContent(string calldata _metadataHash, uint256 _licenseFee, uint256 _licenseDuration) external {
        require(_licenseFee > 0, "Fee must be >0");
        require(_licenseDuration > 0, "Duration must be >0");

        contentCount += 1;
        Content storage c = contents[contentCount];
        c.metadataHash = _metadataHash;
        c.creator = payable(msg.sender);
        c.licenseFee = _licenseFee;
        c.licenseDuration = _licenseDuration;

        emit ContentRegistered(contentCount, msg.sender, _licenseFee, _licenseDuration);
    }

    function purchaseLicense(uint256 _contentId) external payable {
        Content storage c = contents[_contentId];
        require(msg.value == c.licenseFee, "Incorrect fee");

        c.activeLicenses[msg.sender] = block.timestamp + c.licenseDuration;
        c.creator.transfer(msg.value);

        emit LicensePurchased(_contentId, msg.sender, c.activeLicenses[msg.sender]);
    }

    function revokeLicense(uint256 _contentId, address _licensee) external {
        Content storage c = contents[_contentId];
        require(msg.sender == c.creator || msg.sender == admin, "Not authorized");
        require(c.activeLicenses[_licensee] > 0, "No active license");

        c.activeLicenses[_licensee] = 0;
        emit LicenseRevoked(_contentId, _licensee);
    }

    function checkLicense(uint256 _contentId, address _licensee) external view returns (bool valid) {
        Content storage c = contents[_contentId];
        return c.activeLicenses[_licensee] > block.timestamp;
    }

    receive() external payable {}
}