NFT-Based Music Rights

What it does:
Turns music tracks into NFTs that represent ownership, licensing rights, and royalties, enabling transparent trading and automatic revenue distribution.

Why it matters:
Eliminates intermediaries, ensures fair compensation to musicians, allows fans and collaborators to invest in music rights, and provides immutable proof of ownership.

How it works:

  • Musicians mint NFTs representing full or partial rights to a music track

  • NFT metadata includes licensing terms, royalty percentages, and usage rights

  • Buyers or collaborators can purchase or invest in these NFTs on-chain

  • Smart contract automatically splits revenue among rights holders and contributors

  • Licensees can prove rights or access content via NFT ownership

  • Royalties from streaming, resale, or licensing are distributed automatically

  • Full transaction and ownership history is auditable on-chain

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

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

/**
 * @title MusicRightsNFT
 * @author Nam
 * @notice Mint NFTs representing music ownership and manage royalty distribution
 */
contract MusicRightsNFT is ERC721URIStorage {

    uint256 public tokenCount;

    struct Royalty {
        address payable account;
        uint256 share; // in basis points (1% = 100)
    }

    mapping(uint256 => Royalty[]) public royalties;

    event MusicMinted(uint256 indexed tokenId, string tokenURI);
    event RoyaltyPaid(uint256 indexed tokenId, uint256 amount);

    constructor() ERC721("MusicRightsNFT", "MRNFT") {}

    // -------------------- MINTING --------------------

    function mintMusicNFT(string calldata _tokenURI, address[] calldata _royaltyAccounts, uint256[] calldata _royaltyShares) external {
        require(_royaltyAccounts.length == _royaltyShares.length, "Mismatch arrays");

        tokenCount += 1;
        uint256 newTokenId = tokenCount;

        _mint(msg.sender, newTokenId);
        _setTokenURI(newTokenId, _tokenURI);

        uint256 totalShares = 0;
        for (uint256 i = 0; i < _royaltyAccounts.length; i++) {
            royalties[newTokenId].push(Royalty(payable(_royaltyAccounts[i]), _royaltyShares[i]));
            totalShares += _royaltyShares[i];
        }
        require(totalShares  0, "No royalties defined");

        for (uint256 i = 0; i < tokenRoyalties.length; i++) {
            uint256 payment = (amount * tokenRoyalties[i].share) / 10000;
            tokenRoyalties[i].account.transfer(payment);
        }

        emit RoyaltyPaid(tokenId, amount);
    }
}