Virtual Land Ownership Contract

What it does:
Enables users to mint, buy, sell, and manage virtual land parcels as NFTs, providing verifiable ownership and automated royalty distribution for creators or developers.

Why it matters:
Ensures transparency in virtual property ownership, prevents fraud, allows monetization through sales or development, and supports metaverse ecosystems.

How it works:

  • Virtual land parcels are minted as NFTs with metadata (location, size, features)

  • Ownership can be transferred or sold, with automated royalties for creators

  • Developers can define usage rules or build structures on parcels

  • Integrates with Gaming Asset Ownership, NFT Marketplaces, or Play-to-Earn Reward Engine

  • Dashboards show parcel ownership, transaction history, and development rights

  • Supports cross-platform virtual land marketplaces and verifiable provenance

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title VirtualLandOwnership
 * @author Nam
 * @notice Manages virtual land parcels as NFTs with ownership and royalty management
 */
contract VirtualLandOwnership is ERC721, Ownable {

    struct LandParcel {
        string metadataURI;
        address creator;
        uint256 royaltyPercent; // e.g., 5 for 5%
    }

    mapping(uint256 => LandParcel) public landParcels;
    uint256 public parcelCount;

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

    event LandMinted(uint256 indexed parcelId, address owner, string metadataURI, uint256 royaltyPercent);
    event LandTransferred(uint256 indexed parcelId, address from, address to, uint256 salePrice, uint256 royaltyPaid);

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

    constructor() ERC721("VirtualLand", "VLAND") {}

    // -------------------- LAND MANAGEMENT --------------------

    function mintLand(string calldata _metadataURI, uint256 _royaltyPercent) external {
        require(_royaltyPercent  0) {
            payable(lp.creator).transfer(royaltyAmount);
        }

        payable(msg.sender).transfer(sellerAmount);

        _safeTransfer(msg.sender, _to, _parcelId, "");

        emit LandTransferred(_parcelId, msg.sender, _to, _salePrice, royaltyAmount);
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function getLandParcel(uint256 _parcelId) external view returns (LandParcel memory) {
        return landParcels[_parcelId];
    }

    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        return landParcels[tokenId].metadataURI;
    }
}