0

I'm developing a marketplace to buy my own nfts on my website. I've the contract to create the nft and everything works very well. Now I want to create the buy() and sell() functions, but when creating a new contract and importing the nft contract, an empty nft array is always returned as if it were linked to another parent contract.

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

import "../goblin.sol";

contract MarketPlace is GoblinNFT {

    GoblinNFT goblin = GoblinNFT(0xf8e81D47203A594245E36C48e151709F0C19fBe8);

    function sellGoblin(uint goblinId, uint price) public isGoblinOwner(goblinId) {
        require(!goblins[goblinId].selling);
        Goblin storage _goblin = goblins[goblinId];
        _goblin.price = price * 10 ** 18;
        _goblin.selling = true;
    }

    function buyGoblin(uint goblinId) public payable isNotGoblinOwner(goblinId) {
        require(goblins[goblinId].selling, "Not selling");
        Goblin storage _goblin = goblins[goblinId];
        uint _price = _goblin.price;
        address _goblinOwner = goblinToOwner[goblinId];
        require(blueGem.balanceOf(msg.sender) >= _price);
        require(blueGem.transferFrom(msg.sender, _goblinOwner, _price));
        _transfer(_goblinOwner, msg.sender, _goblin.tokenId);
        goblinToOwner[goblinId] = msg.sender;
        _goblin.selling = false;
        _goblin.price = 0;
    }

    modifier isGoblinOwner(uint goblinId) {
        require(goblinToOwner[goblinId] == msg.sender);
        _;
    }

    modifier isNotGoblinOwner(uint goblinId) {
        require(goblinToOwner[goblinId] != msg.sender);
        _;
    }

}

If I put the sellGoblin() function inside the nft contract, everything works fine, but when inheriting from that contract, it always gives me the error "revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information." because the nfts array is empty as if the parent contract did not exist or there were no nfts created

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

import "./BlueGem.sol";

contract GoblinNFT is ERC721 {

    BlueGem blueGem = BlueGem(0xd9145CCE52D386f254917e481eB44e9943F39138);

    enum Rarity { Common, Uncommon, Rare, Epic }

    address public owner;

    event NewGoblin(Rarity rarity, uint8 bags, uint32 readyTime, uint tokenId);

    uint counterA;

    uint tokenIdDigits = 16;
    uint tokenIdModulus = 10 ** tokenIdDigits;
    uint cooldownTime = 1 days;

    struct Goblin {
        Rarity rarity;
        uint8 bags;
        uint32 readyTime;
        uint tokenId;
        uint price;
        uint contractStartDate;
        uint contractDurationInDays;
        bool selling;
    }

    Goblin[] public goblins;

    mapping (uint => address) public goblinToOwner;
    mapping (address => uint) ownerGoblinCount;

    mapping (address => bool) ownerApprovedToken;

    uint goblinCount;

    constructor() ERC721("Goblin", "GBL") { owner = msg.sender;}

}

I think that what is happening is that, it is not linking to the correct parent contract, how can I link it to the corresponding parent contract? Since I'm doing tests on remix testnet and I'm constantly deploying new contracts fixing bugs, how does the child contract know which is the current parent?

1 Answer 1

0

It seems you are confusing having 1 contract which is both the NFT and marketplace and having 2 contracts 1 being the NFT and 1 being the marketplace.

In your given example, when you deploy the Marketplace contract you are deploying 1 brand new contract which combines the functionality of the Marketplace and NFT contracts. This is because the Marketplace inherits from the NFT contract.

This is why when you deploy your contract, when looking at the goblins array you don't see any values because it is a completely new contract unrelated to anything else deployed on the chain.

In the marketplace contract there is a reference to another contract:

GoblinNFT goblin = GoblinNFT(0xf8e81D47203A594245E36C48e151709F0C19fBe8);

However this state variable is never used within the contract and so isn't actually doing anything. But this is on the right track!

What I would recommend is to separate the NFT contract from the marketplace as they provide two distinct functionalities. Then the marketplace should handle all the buying and selling state variables and call to the NFT contract via the goblin state variable as you have already defined.

So for example for the sell function, I would change the selling bool on the NFT itself to a mapping of ID's to selling data (price, enabled) located in the marketplace.

Essentialy decouple the marketplace data from the NFT data. Hope this helps :)

1
  • But in theory, by inheriting from a parent contract, I can access its variables, which help me, such as knowing if the id of that goblin belongs to the person who sends the request. I used the variable with the contract address to do a test, that's why I don't use it at the moment. I also have the selling variable within the nft contract and not decoupled from the market because it is useful for other functions, such as if the goblin is being sold it cannot be used to fight.
    – Shadow
    Commented Apr 24, 2023 at 10:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.