Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
7.5 kB
22
Indexable
Never
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

interface IGamingEcosystemNFT {
    function mintNFT(address to) external;
    function burnNFT(uint256 tokenId) external;
    function transferNFT(uint256 tokenId, address from, address to) external;
    function ownerOf(uint256 tokenId) external view returns (address);
    function approve(address to, uint256 tokenId) external;
}

contract BlockchainGamingEcosystem {

    struct Player {
        string username;
        uint256 tokens;
        uint256 playerCredits;
    }
    
    struct Game {
        uint256 gameID;
        string gameName;
    }

    struct GameAsset {
        uint256 assetsBought;
        uint256 currentPrice;
        uint256 previousPrice;
    }

    struct Asset {
        address player;
        string gameName;
        uint256 price;
    }

    struct Store {
        address[] players;
        uint256[] amounts;
        uint256[] tokens;
    }

    uint256 constant initialPrice = 250;

    address public owner;
    IGamingEcosystemNFT public nftContract;
    uint256 tokenID;

    mapping(address => Player) public players;
    mapping(uint256 => Game) games;
    mapping(uint256 => GameAsset) gameAssets;
    mapping(uint256 => Asset) assets;
    mapping(uint256 => Store) stores;
    mapping(uint256 => bool) blacklisted;
    

    // lookups
    mapping(address => bool) public isRegistered;
    mapping(string => bool) public userNameExists;
    mapping(string => bool) public gameNameCheck;
    mapping(uint256 => bool) public gameIDCheck;
    mapping(uint256 => uint256) tokenIdToGameId;
    mapping(address => uint256) debt;
    
    constructor(address _nftAddress) {
        owner = msg.sender;
        nftContract = IGamingEcosystemNFT(_nftAddress);
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this function");
        _;
    }

    modifier onlyPlayer() {
        require(isRegistered[msg.sender]);
        _;
    }

    // Function to register as a player
    function registerPlayer(string memory userName) public {
        require(msg.sender != owner, "Owner can't register");
        require(!isRegistered[msg.sender], "Player already registered");
        require(!userNameExists[userName], "Choose unique username");

        bytes memory stringBytes = bytes(userName);
        require(stringBytes.length >= 3);

        isRegistered[msg.sender] = true;
        userNameExists[userName] = true;

        players[msg.sender].username = userName;
        players[msg.sender].playerCredits = 1000;
    }

    // Function to create a new game
    function createGame(string memory gameName, uint256 gameID) public onlyOwner {
        require(!gameNameCheck[gameName], "choose unique game name");
        require(!gameIDCheck[gameID], "choose Unique gameId");

        gameNameCheck[gameName] = true;
        gameIDCheck[gameID] = true;

        games[gameID].gameID = gameID;
        games[gameID].gameName = gameName;
        gameAssets[gameID].currentPrice = 250;
    }
    
    // Function to remove a game from the ecosystem
    function removeGame(uint256 gameID) public onlyOwner {
        require(gameIDCheck[gameID], "Game doesn't exist");
        
        uint256 len = stores[gameID].players.length;

        for(uint256 i; i<len; i++) {
            address _player = stores[gameID].players[i];
            uint256 _amount = stores[gameID].amounts[i];
            uint256 _tokenID = stores[gameID].tokens[i];

            if (!blacklisted[tokenID] && nftContract.ownerOf(_tokenID) != address(0)) {
                nftContract.burnNFT(_tokenID);
                players[_player].playerCredits += _amount;
                players[_player].tokens--;
                assets[_tokenID].player = address(0);
                blacklisted[_tokenID] = true;
            }
        }

        gameIDCheck[gameID] = false;
        gameNameCheck[games[gameID].gameName] = false;
    }
    
    // Function to allow players to buy an NFT asset
    function buyAsset(uint256 gameID) public onlyPlayer {
        require(gameIDCheck[gameID], "game doesn't exist");
        uint256 currentPrice = gameAssets[gameID].currentPrice;
        
        require(players[msg.sender].playerCredits >= currentPrice, "Insufficient credits");
 
        players[msg.sender].playerCredits -= currentPrice;

        nftContract.mintNFT(msg.sender);
        // nftContract.approve(owner, tokenID);
        
        assets[tokenID].player = msg.sender;
        assets[tokenID].gameName = games[gameID].gameName;
        assets[tokenID].price = currentPrice;

        stores[gameID].players.push(msg.sender);
        stores[gameID].amounts.push(currentPrice);
        stores[gameID].tokens.push(tokenID);

        tokenIdToGameId[tokenID] = gameID;

        tokenID++;
        players[msg.sender].tokens++; 
        
        gameAssets[gameID].previousPrice = currentPrice;

        uint256 nextPrice = currentPrice + ((currentPrice * 10) / 100);
        gameAssets[gameID].currentPrice = nextPrice;
        gameAssets[gameID].assetsBought++;
    }

	// Function to allow players to sell owned assets
    function sellAsset(uint256 _tokenID) public onlyPlayer {
        require(nftContract.ownerOf(_tokenID) == msg.sender, "Only nft owner can sell");
        
        uint256 gameID = tokenIdToGameId[_tokenID];
        uint256 currentPrice = gameAssets[gameID].currentPrice;

        blacklisted[_tokenID] = true;
        
        players[msg.sender].playerCredits += currentPrice;
        players[msg.sender].tokens--;
        assets[_tokenID].player = address(0);

        nftContract.burnNFT(_tokenID);
    }

    // Function to transfer asset to a different player
    function transferAsset(uint256 _tokenID, address to) public onlyPlayer {
        require(nftContract.ownerOf(_tokenID) == msg.sender, "Only nft owner can transfer");
        require(isRegistered[to], "User not registered");
        require(to != msg.sender, "self transfer disabled");
        
        blacklisted[_tokenID] = true;
        players[msg.sender].tokens--;
        players[to].tokens++;

        assets[_tokenID].player = to;
        nftContract.transferNFT(_tokenID, msg.sender, to);
    }

    // Function to view a player's profile
    function viewProfile(address playerAddress) public view returns (string memory userName, uint256 balance, uint256 numberOfNFTs) {
        require(msg.sender == owner || isRegistered[msg.sender], "Unauthorized access");
        require(isRegistered[playerAddress], "Player exists");
        userName = players[playerAddress].username;
        balance = players[playerAddress].playerCredits;
        numberOfNFTs = players[playerAddress].tokens;
    }

    // Function to view Asset owner and the associated game
    function viewAsset(uint256 _tokenID) public view returns (address _owner, string memory gameName, uint price) {
        require(msg.sender == owner || isRegistered[msg.sender], "Unauthorized access");
        require(assets[_tokenID].player != address(0), "Asset burnt");
        require(nftContract.ownerOf(_tokenID) != address(0), "NFT doesn't exist or burnt");
        _owner = assets[_tokenID].player;
        gameName = assets[_tokenID].gameName;
        price = assets[_tokenID].price;
    }
}