Separate Sale Contract from NFT contract

Hi, I have created a ERC721 contract to Mint and also do the sell of the NFT token. The contract is working fine and is doing what is supposed to do, but I would like to separate the Sale contract from the NFT contract. I would like to know if somebody can help me on what to do for this.
This is how the contract looks like:

contract MyToken is AccessControl,ERC721  {
    using Counters for Counters.Counter;
    event TokenSold(uint256 _tokenId);
    event Minted(string tokenURI);
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    Counters.Counter private _tokenIdTracker;
    mapping(uint256 => uint256) internal tokenPrices;
    mapping(uint256 => uint256) internal tokenRoyalties;
    mapping(uint256 => address) internal tokenCreators;

   constructor() public ERC721("MyToken", "TEST") {
        _setBaseURI("https://ipfs.io/ipfs/");
      ....
   }

   function mint(address to, string memory tokenURI, uint256 _price, uint256 _royalty) public virtual {...}

   function sellToken (uint256 _tokenId) public payable{...}

   function setTokenPrice(uint256 _tokenId, uint256 _price) public virtual {...}
    
   function setTokenRoyalty(uint256 _tokenId, uint256 _price) public virtual {...}
}

I would like to know which function I need to migrate to the Sell contract.
And how can I do the transfer of the tokens on that other contract.
Thanks.

You can try moving these 3:

The Sell contract would need to receive the tokens. They can either be minted directly there or transferred. Once there, I suppose you could call sellToken to register it for sale, check that it’s owned by the Sell contract, and so on.

Thanks for the Reply Frangio,
All this is as per request of my client for his Market place (OpenSea or other external marketplace is not an option).
I would explain a little more what i’m doing to see if makes sense:
My current contract has a mint function (that will be called from the server using the contract owner account). When somebody want to Mint a NFT from the marketplace they will need to pass the price, royalties, their connected ETH address and the digital asset (they will need to pay the Minting fees using a CreditCard). After that the server will do the Minting and assign the NFT token to the customer ETH address.
The contract also has a sellToken (payable) function, that can be call for anybody (except the owner of the token), and that function will transfer the ETH price of the token to Owner (also transfer a small fee for the market place), and at the end will transfer the Token to the buyer.
All of this is working as supposed to on the rinkeby network. Now I would like to separate sale functionality into another Contract.

On your reply you recommend to have the sellToken, and the Price and Royalties functions/code in the Sell Contract. And mint or transfer the tokens to the Sale contract, and then use the sellToken function on there. I’m sorry, but I’m still a little bit confused on how to do this, is this correct:

When somebody mint a NFT, I would call the Mint function on the NFT contract, and also call a mint function on the sale contract (only with the Price, token id, and royalties).
Then when somebody call the payable sellToken function on the Sell Contract, I will transfer the eth prices and fees, and then I will call the transfer function on the NFT contract to assign the token to the new owner. (This last part of transfer the NFT token is confused to me).

I’m really sorry again for the confusion.

I will like to finish all this (and do all the proper testing) to start the auditing with OpenZeppelin.

In order for the separate Sell contract to work, it needs to be able to transfer the NFT. One way you could do this is by having the NFT owner approve the Sell contract for the tokenId that they want to sell.

Perfect!! Thanks again for the help.

Just to be clear, this is what I will need to do:

When somebody wants to create a NFT I will call the Mint function on the NFT contract, that function will create the token and also _approve() the sell contract for that tokenId. Also, I will call the mint on the sale contract using the NFT tokenid, price and royalties.
Then, when somebody wants to buy the token, they will call the payable sellToken function, and this function will transfer the ETH and fees, and at the end will call the transfer function on the NFT contract to transfer the token.

It is ok to call the internal _approve() inside the NFT contract Mint function?

Sorry for all this questions but I want to make sure that there is no flaw in all this.

That sounds right! Using internal _approve sounds good.

The only odd thing is what you’re calling “minting” on the sale contract. I think that name is confusing, since the token is minted in the NFT. A name like “offer” or “sell” would be more appropriate for the function that puts a token up for sale, on the sale contract.

Awesome!!! I got it, thanks again for the fast response.

1 Like