ProjectOpenSea / opensea-creatures

Example non-fungible collectible, to demonstrate OpenSea integration
https://docs.opensea.io
MIT License
1.17k stars 793 forks source link

Factory contract and mumbai testnetwork (Polygon) #149

Open vzherebetskyi opened 2 years ago

vzherebetskyi commented 2 years ago

The problem is that the Factory contract works fine for the Rinkeby testnetwork. Token minting works fine. However, there are some problems with mumbai testnetwork (Polygon). The factory contract is deployed but after that, when I try minting tokens the transaction is reverted by EVM. If I comment these lines in the mint function minting works for mumbai testnetwork as well:

 ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
        assert(
            address(proxyRegistry.proxies(owner())) == _msgSender() ||
                owner() == _msgSender()
        );

I am still lokking for the reason of this strange behavior but maybe somebody can help?

Hugogo22 commented 2 years ago

If you comment these lines out, anyone can use the mint function. Are you sure you're sending the transaction from the address you used to deploy the contract? Also I'm pretty sure OpenSea's proxy regristry contract will not work because it's not the same on polygon and etherum but I don't think it should impact your ability to mint tokens. If you plan to use a factory contract to sell nfts on OpenSea without having to mint them beforehand, I'm not sure it's possible because I've tried and I haven't managed to make it work.

vzherebetskyi commented 2 years ago

Actually I would like anyone to use the mint function because it’s a factory contract with the ownership transfer. I want to use it for the crowdsale. And on the Rinkeby test network I suppose anyone could use the factory contract with those lines uncommented. Moreover, I used the polygon Proxyaddress when deployed. In particular, 0x58807baD0B376efc12F5AD86aAc70E78ed67deaE

Hugogo22 commented 2 years ago

If anyone can use the mint function, anyone can mint nfts without paying so you need those lines, or at least similar ones. I guess OpenSea uses your proxy address to mint nfts when someone buys an nft. However, I don't think their proxy works the same way on etherum and polygon because of the way they use it in their documentation (https://docs.opensea.io/docs/polygon-basic-integration) but there is no way to know as their contract is not verified on polygonscan. But putting all of this aside, if you have deployed the contract from the address you are using to mint the nfts and you haven't transfered the ownership, it should still work. Have you changed something else in the contract ?

vzherebetskyi commented 2 years ago

Actually I deployed the factory contract to which I transfered the ownership on the Creature contract. In the factory contract I have these lines in the mint function. The idea here is that anyone can call the mint function but it will check whether the money were sent. Then mint function creates an instance of the Creature contract and mints an nft. However, I think I also could add this check to Creature contract itself (however, I don't know whether it is good practive or not)

function mint(address _toAddress) public virtual payable {
        require(msg.value >= 1000000000000000000, "Not enough Polygon sent; check price!");
        require(canMint());

        Creature creatureNFT = Creature(nftAddress);
        creatureNFT.mintTo(_toAddress);
         address payable _owner = payable(address(uint160(myaddress)));
        _owner.transfer(address(this).balance);
    }
edkevbrin commented 2 years ago

@vzherebetskyi have you had a chance to sort out this problem with factory contract? Feel have the same issue - at rinkeby works perfect, but it deployed at polygon it's not visible on opensea, minting function also doesn't work

raoulsullivan commented 2 years ago

Encountered exactly the same problems mentioned by @edkevbrin and @vzherebetskyi:

  1. To get the sample factory contract mint methods working on Mumbai, I had to remove all references to ProxyRegistry. Otherwise calls to the mint methods resulted in a reverted transaction.
  2. When the sample factory contract (minus the ProxyRegistry stuff) is deployed to Mumbai it's not visible in testnets.opensea.io. The same contract can be deployed to Rinkeby and is then visible in testnets.opensea.io.
KIRIN178 commented 2 years ago

I also have problems of a deployed factory contract on Mumbai not visible in testnets.opensea.io Does anyone have the solution? Thank you.

cyrexx commented 2 years ago

I have the same issue with my factory contract for minting ERC721 token on mumbai testnet. Everything works flawless on rinkeby testnet, but when i deploy to polygon's mumbai testnet i get the following error:

Gas estimation failed Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? Internal JSON-RPC error. { "code": -32000, "message": "execution reverted" }"

Example Project on Github: https://github.com/vzoo/ERC721-with-EIP2981-and-reusable-factory-for-OpenSea/blob/c68e2a389cac78ff6502a07f320989106fc652e3/contracts/VZOOFactory.sol#L154 Example factory contract on OS (rinkeby): https://testnets.opensea.io/collection/vzoo-public-sale-v2

Have you guys found any working examples for deploying a factory contract on Polygon Matic/Mumbai? Or do you have any idea what's wrong with the code - is it the proxy part? Thankful for any hints

stpoa commented 2 years ago

@cyrexx @vzherebetskyi have you solved it? I have the same problem.

KIRIN178 commented 2 years ago

No. My consequence is that factory contract is not supported in Mumbai.

slaweks @.***> 於 2022年5月23日 週一 下午2:50寫道:

@cyrexx https://github.com/cyrexx have you solved it? I have the same problem.

— Reply to this email directly, view it on GitHub https://github.com/ProjectOpenSea/opensea-creatures/issues/149#issuecomment-1134251422, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKLORGEZNUGIWDV6N442JETVLMTBTANCNFSM5HAZBXGQ . You are receiving this because you commented.Message ID: @.***>

vzherebetskyi commented 2 years ago

@cyrexx @vzherebetskyi have you solved it? I have the same problem.

I decided to remove the ProxyRegistry and just added a check on whether the funds were paid (example is above). It works fine, NFTs are minted and ownership is correctly transferred. BUT, I am not an expert in this so I am not 100% sure whether such design of the contract leads to vulnerabilities/ flaws or not. My point here is that you can design a contract without ProxyRegistry and it will work with OpenSea

stpoa commented 2 years ago

Thank you for reply. Is it possible to sell from this contract without minting first? How do you connect such contract to OpenSea? For me it is not visible when using url opensea.io/assets/{factoryAddress}/0

vzherebetskyi commented 2 years ago

As far as I know there is no need to connect the contract directly with OpenSea, however, you have to follow their instructions regarding metadata.

I do not understand what do you mean under sell without minting. If you want to sell some nfts which are not on blockchain yet you can use OpenSea's options like creating a collection

stpoa commented 2 years ago

As far as I know there is no need to connect the contract directly with OpenSea, however, you have to follow their instructions regarding metadata.

I do not understand what do you mean under sell without minting. If you want to sell some nfts which are not on blockchain yet you can use OpenSea's options like creating a collection

I meant that buyers pay for minting. Can you create a collection based on your factory contract? Is your factory available under: opensea.io/assets/{factoryAddress}/0?

Using Rinkeby I just prepared a nft contract with factory contract, deployed it and it was available under: testnets.opensea.io/assets/{factoryAddress}/0

Now when I deploy both contracts using Polygon I cannot access my contract factory under opensea.io/assets/{factoryAddress}/0

Thanks for your help :)

stpoa commented 2 years ago

As far as I know there is no need to connect the contract directly with OpenSea, however, you have to follow their instructions regarding metadata. I do not understand what do you mean under sell without minting. If you want to sell some nfts which are not on blockchain yet you can use OpenSea's options like creating a collection

I meant that buyers pay for minting. Can you create a collection based on your factory contract? Is your factory available under: opensea.io/assets/{factoryAddress}/0?

Using Rinkeby I just prepared a nft contract with factory contract, deployed it and it was available under: testnets.opensea.io/assets/{factoryAddress}/0

Now when I deploy both contracts using Polygon I cannot access my contract factory under opensea.io/assets/{factoryAddress}/0

Thanks for your help :)

I would be super grateful if you could answer @vzherebetskyi

vzherebetskyi commented 2 years ago

@stpoa I believe that answer to your question is yes, you can create a collection based on your factory contract but you will need to modify the example factory contract provided by OpenSea.

what I would suggest to do is to test your contract and test what it is doing under the hood. Try to modify it in different ways, deploy it and to make it actually mint some tokens. Try to open your tokens at opensea.io/assets/{matic|mumbai}/{factoryAddress}/1 or opensea.io/assets/{matic|mumbai}/{factoryAddress}/2

zhenmu commented 2 years ago

same problems.

Finally, I added the function:

function supportsInterface(bytes4 interfaceId) public view virtual returns (bool)

such as:

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

or


    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        bytes4 _ERC165_ = 0x01ffc9a7;
        bytes4 _ERC721_ = 0x80ac58cd;
        bytes4 _ERC2981_ = 0x2a55205a;
        bytes4 _ERC721Metadata_ = 0x5b5e139f;
        return interfaceId == _ERC165_ 
            || interfaceId == _ERC721_
            || interfaceId == _ERC2981_
            || interfaceId == _ERC721Metadata_;
    }