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);
}
}
Build and Grow By Nam Le Thanh