DEV Community

Cover image for Deploy NFTs with Truffle, IPFS OpenSea & Polygon

Deploy NFTs with Truffle, IPFS OpenSea & Polygon

Archie Smyth on September 12, 2021

Intro to me. My first post Hello, I have been learning Information Technology all my life (21 now), it's my profession. For the past 18 ...
Collapse
 
jayaych profile image
Jeremy H

Amazing post man! Incredibly helpful for someone new to blockchain development. One quick question:

If I'm deploying a whole folder of NFTs, can I put the metadata for each one in one JSON file? Or would they have to exist in separate JSON files?

Collapse
 
yournewempire profile image
Archie Smyth

Hi Jeremy. I would keep the JSONs as separate, as I know this way works for sure. Thanks.

Collapse
 
pipolo profile image
thiagochiaro

I also would to like know this. Did you figure it out?

Collapse
 
imkane profile image
Kane

Thank you for this tutorial! Have you ever tried transferring tokens on the Matic network?

I'm having trouble using 'maticjs', and was wondering if you knew another option :)
github.com/maticnetwork/matic.js/d...

Collapse
 
yournewempire profile image
Archie Smyth

Hey Kane. This is a brief reply, as I am not at my PC right now. I would recommend using web3js or ethers, then calling the safeTransferFrom method on the erc 1155 contact. Thanks.

Collapse
 
imkane profile image
Kane

I tried using web3 but no luck. I scoured the internet looking for some sample code, but alas nothing :(

I don't know how to use web3 to select the contract (using the private key passed in from the command line). There's some ABI requirements apparently, but I have no idea how that works.

Ughhh.

Thread Thread
 
yournewempire profile image
Archie Smyth

I will follow you on here now. Then i shall dm you about what you are unsure about

Thread Thread
 
imkane profile image
Kane

Wow, really? You sir, are a gentleman and a scholar 😀

It's been so hard to find sample code for this.

Collapse
 
drjacky profile image
Hossein Abbasi

Nice article!
Could we upload new NFTs to the existing collection?

Collapse
 
yournewempire profile image
Archie Smyth

Hello Hossein.

I have had a quick search in the IPFS forums and it looks like there are possible ways of doing this, but my knowledge with IPFS CLI is very little, albeit I used Pinata as third-party in this tutorial.

What I would do is override the virtual _baseURI() function from the inherited ERC-721 contracts, but importantly, have it return a variable. This variable would be have to be added to the NFT contract and should be mutated with a 'setBaseURI' function. Then, one would upload a new folder to IPFS with added content, and update the base URI with the new 'setBaseURI' function. With that, the mintItem function I wrote should be rewritten so that, you would not need to pass a URI string to every mint, and instead it just mints with the token ID. Then when you want token metadata from the inherited tokenURI function, it will conditionally check if there is a baseURI and if so, just return the baseURI concatenated with the ID.

I would recommend inspecting the ERC721URIStorage.sol and ERC721.sol files and all of the methods as I have done, and then finding a way around these kind of situations.

Have a look at this great article by Rounak Banik where this is actually implemented.

I hope I answered the question to a good standard.

Collapse
 
drjacky profile image
Hossein Abbasi

I use ERC1155. So, I need to figure it out somehow.

And do you have the answer for my second question? "Is that possible to list them while we're uploading them?"

Thanks!

Thread Thread
 
yournewempire profile image
Archie Smyth

Oh sorry I missed that one. Have a look at Benm4nn's comments on this discussion. We were talking about the fact that OpenSea.js SDK does not support Polygon listings at this time. Which leads us to listing the items on OpenSea's front end. I have been looking around for a solution, still nothing other than listing old school. Best of luck finding a solution.

Thread Thread
 
yournewempire profile image
Archie Smyth

Hi again Hossein. The best solution for this listing problem would be writing a minter function and a constant variable for price of payable mint function.

Collapse
 
drjacky profile image
Hossein Abbasi

And my second question is,
Is that possible to list them while we're uploading them?

Collapse
 
vnxz profile image
vnxz • Edited

can use infura for API key ?without using mumbai network.and also dont use pinata , by using IPFS directly .some not clear .you made collection json and nft json. and bith uplaod to pinata , and use only collection hash .right?also made two conflict . why collection json hash return in one place and why nft json hash in other place.

Collapse
 
benm4nn profile image
benm4nn

Great post Archie, creating the contract worked well, but when it came to minting I had problems. Not with your code but because I was trying to combine it with OpenSea's meta-transactions sample code, so the minting function could not longer be set to Ownable.
Please can you update your code sample to include Meta transactions too? It's making my head hurt trying to combine the two!
Thanks

Collapse
 
yournewempire profile image
Archie Smyth

Hello benm4nn. Thanks for the kind words. I have been planning on adding this. However, I was running into some issues, and couldn't finish it. For one, you will need to outdate the solidity compiler version, and all of your contracts down to 0.6.6 for use of the ContextMixin.sol from the @maticnetwork/pos-portal package, which is needed for the opensea tx's. I shall give it another go today, and I will get back to you. Thanks for the constructive talk.

Collapse
 
yournewempire profile image
Archie Smyth

Hey check out my new post. I was able to find the sample code from OpenSea.

Collapse
 
artiface profile image
artiface

Thanks for this great post. I've been trying to work through it, but the very last step of node scripts/mint.js fails. It says minted, then says 'gas required exceeds allowance (0)'.

I'm not sure where to set the gas allowance? it looks like there is no allowance set. I did set gas in the truffle-config.js
mumbai: {
provider: function () {
return new HDWalletProvider(MNEMONIC, https://rpc-mumbai.maticvigil.com/v1/${API_KEY});
},
network_id: 80001,
gas: 5000000,
gasPrice: 5000000000,
confirmations: 2,
skipDryRun: true,
},

but that did not seem to resolve. How do I set the gas allowance so I can mint the token? Thanks!

Collapse
 
yournewempire profile image
Archie Smyth

Hey. Have you tried running the script again? With gas and gas price on 'auto' string might work. Im not sure about this error message either unfortunately.

Collapse
 
hamza33 profile image
hamza33

Hi archie, thanks for the tutorial, i keep on getting this error when i try to 'migrate --network mumbai' or 'matic', my .env is perfect and ive tried both seed phrase and private key. any advice? thanks.

Error: Unknown arguments format passed to new HDWalletProvider. Please check your configuration and try again
at Object.getOptions (C:\Users\zaina\OneDrive\Documents\CryptOud\Truffle-Tutorial-ERC721\node_modules\@truffle\hdwallet-provider\src\constructor\getOptions.ts:143:11)
at new HDWalletProvider (C:\Users\zaina\OneDrive\Documents\CryptOud\Truffle-Tutorial-ERC721\node_modules\@truffle\hdwallet-provider\src\index.ts:71:9)
at Object.provider (C:\Users\zaina\OneDrive\Documents\CryptOud\Truffle-Tutorial-ERC721\truffle-config.js:45:16)
at Object.getProvider (C:\Users\zaina\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\provider\index.js:20:1)
at Object.create (C:\Users\zaina\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\provider\index.js:13:1)
at TruffleConfig.get as provider
at Object.detect (C:\Users\zaina\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\environment\environment.js:19:1)
at Object.module.exports as run
at Command.run (C:\Users\zaina\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\command.js:189:1)

the migrate --network development shows this

Could not connect to your Ethereum client with the following parameters:
- host > localhost
- port > 7545
- network_id > *
Please check that your Ethereum client:
- is running
- is accepting RPC connections (i.e., "--rpc" or "--http" option is used in geth)
- is accessible over the network
- is properly configured in your Truffle configuration file (truffle-config.js)

Collapse
 
yournewempire profile image
Archie Smyth

Hey Hamza.

I can't really pin down what's wrong here. I would suggest double checking the steps in which you spin up truffle. Ensuring you have ran truffle develop, but then, I am sure you have done these steps. If you do find the solution to this, it would be great to learn more amongst us, here in the discussion. I feel my lack of knowledge has perhaps let you down here.

I have just updated the top of this post with the new repositories, which are now using Hardhat. I would suggest trying out the Hardhat repo instead, as Truffle and the HD wallet provider can be intermittent in specific environments. That's not to say Hardhat has its caveats too, but I have preferred the Hardhat suite in a new repo. I will not be removing the Truffle repo from my GH and you are more than welcome to keep hacking away.

Apologies for this late reply and I wish you the best in solving this issue or finding a work around.

Collapse
 
benm4nn profile image
benm4nn • Edited

Great post. Hoping you can update the code with the removal of gas fees on sales. I've tried but not sure if I've got it right.
Meanwhile I created the contract OK but getting the error when I try minting...
tried googling but found nothing at all on it...

TypeError: nftContract.methods.mintItem is not a function
at main (/Users/randb/Documents/GitHub/Polygon-NFT-ERC721/scripts/mint.js:44:8)
at Object. (/Users/randb/Documents/GitHub/Polygon-NFT-ERC721/scripts/mint.js:64:1)

Collapse
 
sixsats profile image
Six

Archie,
Thanks for the tutorial. Really helped in understanding some of the basics. Kind of stuck on meta-transaction piece to implement gasless transaction. Do you know where that can be implemented in this repo? Thanks for all of this.

Collapse
 
bearpunknft profile image
Bearpunknft

What a blog boy. I really love it.
For the first time without any errors, I have created my contract. But my NFT image was not properly uploaded. It's about 3kb. Does the size matter?
And how can we integrate Polygon cotract with Opensea. I saw this tuttorial but not able to understand where to implement it properly.
docs.opensea.io/docs/polygon-basic...

Collapse
 
yournewempire profile image
Archie Smyth

Hi there. Glad to see your response. The size of your image should not matter, providing you dont break the 1gb pinata offers. Can you show me any kind of screenshot of this image issue?

In the next git repo commit, I am planning on using the code from here: github.com/ProjectOpenSea/meta-tra...
or fixing the code from the link you have there,
to integrate with Polygon, so that the contract can delegate Opensea to pay the gas fees for transfers of NFTs. I am not a solidity expert at this point in time, therefore I left this out of the blog post. I don't know if Opensea's tutorials are not reliable, or if I am not reliable, but I am working on this integration.

Collapse
 
bearpunknft profile image
Bearpunknft

Hi Archie,
I am also having issue with NFT metadata. It's not uploading for NFT as well. I have followed everything from your blog but still getting this issue.
Here you can see the issue opensea.io/collection/mycont
I would be glad if you can help me with this.
Thanks.

Thread Thread
 
yournewempire profile image
Archie Smyth

Hey bro. Check that your NFT metadata and jsons are separate, and that the json points to the image with the image property. Could you link me something to see your code and metadata. Thanks

Collapse
 
tas2017 profile image
tas2017

Waiting for the ERC1155 tutorial on Polygon. Excellent content!

Collapse
 
bboynton97 profile image
Brandon Boynton

Hi there! Great tutorial. Do you have any advice for automatically listing batches of polygon NFTs for sale on OpenSea? It seems as though their API doesn't support it

Collapse
 
frdx profile image
frdx

I am getting these errors when trying to migrate, any ideas?

descent_v2\node_modules\@trufflesuite\web3-provider-engine\subproviders\rpc.js:57
const err = new Error(msg)
^
Error: PollingBlockTracker - encountered an error while attempting to update latest block:
Error: Unknown Error: invalid project id

at Request._callback (D:\eth\descent_v2\node_modules\@trufflesuite\web3-provider-engine\subproviders\rpc.js:57:23)
at Request.self.callback (D:\eth\descent_v2\node_modules\request\request.js:185:22)
at Request.emit (events.js:315:20)
at Request.<anonymous> (D:\eth\descent_v2\node_modules\request\request.js:1154:10)
at Request.emit (events.js:315:20)
at IncomingMessage.<anonymous> (D:\eth\descent_v2\node_modules\request\request.js:1076:12)
at Object.onceWrapper (events.js:421:28)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (_stream_readable.js:1221:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
at PollingBlockTracker._performSync (D:\eth\descent_v2\node_modules\eth-block-tracker\src\polling.js:51:24)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
Enter fullscreen mode Exit fullscreen mode

UnhandledRejections detected
Promise {

Collapse
 
yournewempire profile image
Archie Smyth

Hey, sorry for a very late reply. I have been super busy/stressed this week.

RPC is a request-response protocol that web3 or ethers can use to call nodes/servers. 'invalid project id' should be your matic app-id suggests the following:
You may have incorrectly configured the .env file:
This could be that you have copied the app id over incorrectly (missed a character or something).
Or you have named your env vars differently. For example, the var name in the env file is different to the 'process.env.var_name' in your code.

We know the error is when you are trying to migrate. I would check the truffle-config.js carefully. Look at your env vars and how they are passed into the networks object.

Look forward to your response. All the best in your dev adventures!

Collapse
 
mmintel profile image
Marc Mintel

hey there, nice article! one question though: if you pass the URI to the mint function it's possible for anybody to inject ANY metadata to your contract. How would you avoid this?

Collapse
 
yournewempire profile image
Archie Smyth

Hi Marc. The mint function can only be called by you, the owner of the contract, as programmed by the modifier 'onlyOwner'. You could set your own customised modifiers. Perhaps I have misunderstood you.