Very very interesting. I have thought about directly saving data in smart contract as I have started developing on a very cheap gas blockchain. This is the first practical approach I have found. Thank you a lot
Really nice tutorial Artur, it allows to store SVGs that may be XSS vulnerable, been trying this on Kovan and was successfull :) and yea Tibia is such a nice game, have minted Spike Sword from Rookgard :D
Hello Artur, great video! Sweet and easy to understand! I just wanna ask: What happens if I have a large set of unique, complex 64x64 SVGs with multiple layers? What would be the best way to store/generate these NFTs on-chain? I've already tried storing them on-chain and it was simply too big for the contract to even compile. Cheers, Ashton
Is this code outdated? I am launching my NFT on polygon mumbai- the json looks fine when I call for the tokenUri and decode it... but OpenSea does not display any image nor recognize any of the attributes... 😢
Is there any way to include just the minter’s address in the NFT but not render the image as an SVG? I’m deploying Manifold contracts so 0 solidity knowledge.
I know that IFPS is public by nature, but are there any methods or solutions for locking data like an SVG so only the owner of an associated NFT can access it? Piñata is offering a solution they're calling submarining, but it relies on a third party. Is there any talk in the NFT world of developments that could restrict data to everyone but NFT holders? BTW, great video!
im curious to know what logic would you use to animate an svg in real time .. lets say a loading screen with a chosen nft that we dont know until user selects from MetaMask. appreciate any feedback.. your a an awesome dev.. im studying coding now and love your vids.. keep them coming thanks
Hey Artur, Great video, can you make a video on how to create land token and visualize it on our own website? for example: sandbox and decentraland land tokens are fit in the map.
artur I hope you can answer. I wanted to ask if i can make the image be dynamic where I can change the ipfs link to be unique for each given token. I dont want to use a SVG file
Can the data is only read by owner or with some salt key from web3? for example if we wanna store metadata such date birth or our another personal information? I just research about store personal information into blockchain. thanks great video!
Metadata in NFT by design should be publicly available. However if you want to add some kind of "access control" then you can customize the code. You may check the msg.sender and based on that include/hide some information.
Hi man! Thanks for the video 👍 I was wondering if as a developer you find this solution truly viable, due to the amount of data that has to be stored and computed on-chain. This may be ‘valid’ for a very simple and light svg file, but it becomes unfeasible with other types of graphic files. I would like to have your opinion on this. Thanks!
It's just an option / fun fact. For most of the projects, it doesn't make sense. But if somebody is building on Polygon and wants to have truly on-chain metadata I see no other option at the moment.
Great video @Artur Chmaro ! I was wondering if you know how to store partially on-chain metadata so it can be read by OpenSea? I'm trying to store 99% as pre-made jsons on IPFS, and then two properties on-chain, so it can be edited by token owner: eg. Name. Do you know how can I go about this?
Since the metadata is in a struct on chain, does it in any way become less secure than if it was stored on IPFS? Could someone interact with the contract in a way they can change the NFT metadata struct?
Changing on-chain metadata by someone is not possible. Just make sure that you do not have any bug in the code. Especially check the address of caller in functions that may edit metadata
Hi. I want to develop farming game. And I want to mint the farm asset. Each NFTs (farm asset) have different characteristics : 1) Limited 2) Infinity 3) Mint by stages So, using ERC 1155, the smart contract have to deployed all once or seperately?
I think you can use the same contract. However you have to customize ERC1155 and introduce "type" of token, so your token minting rules works like you want: 1. Limited = no problem with that. ERC1155 already supports it 2. Infinity = not sure how to implement it, but maybe just setting total amount of token to maximum value of uint256 would be sufficient ;) 3. Stages = probably you need to customize mint function and just allow to mint/add more tokens based on some constraints (fixed amount that may be added, certain time frame since last batch added)
Tried code from github.Getting these compilation errors TypeError: Function has override specified but does not override anything. --> contracts/SwordNFT.sol:170:9: | 170 | override(ERC721, ERC721Enumerable) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: Invalid contracts specified in override list: "ERC721" and "ERC721Enumerable". --> contracts/SwordNFT.sol:170:9: | 170 | override(ERC721, ERC721Enumerable) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Note: This contract: --> @openzeppelin/contracts/token/ERC721/ERC721.sol:19:1: | 19 | contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { | ^ (Relevant source part starts here and spans across multiple lines). Note: This contract: --> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:14:1: | 14 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { | ^ (Relevant source part starts here and spans across multiple lines). TypeError: Derived contract must override function "_beforeTokenTransfer". Two or more base classes define function with same name and parameter types. --> contracts/SwordNFT.sol:132:1: | 132 | contract SwordNft is ERC721, ERC721Enumerable, Ownable { | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "ERC721": --> @openzeppelin/contracts/token/ERC721/ERC721.sol:467:5: | 467 | function _beforeTokenTransfer( | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "ERC721Enumerable": --> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:60:5: | 60 | function _beforeTokenTransfer( | ^ (Relevant source part starts here and spans across multiple lines). TypeError: Wrong argument count for function call: 3 arguments given but expected 4. --> contracts/SwordNFT.sol:172:9: | 172 | super._beforeTokenTransfer(from, to, tokenId); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error HH600: Compilation failed For more info go to hardhat.org/HH600 or run Hardhat with --show-stack-traces Thomas.Kavalakkatt@USMFLQ3QY43Q hardhat-tutorial % npx hardhat clean Thomas.Kavalakkatt@USMFLQ3QY43Q hardhat-tutorial % npx hardhat compile TypeError: Function has override specified but does not override anything. --> contracts/SwordNFT.sol:170:9: | 170 | override(ERC721, ERC721Enumerable) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: Invalid contracts specified in override list: "ERC721" and "ERC721Enumerable". --> contracts/SwordNFT.sol:170:9: | 170 | override(ERC721, ERC721Enumerable) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Note: This contract: --> @openzeppelin/contracts/token/ERC721/ERC721.sol:19:1: | 19 | contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { | ^ (Relevant source part starts here and spans across multiple lines). Note: This contract: --> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:14:1: | 14 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { | ^ (Relevant source part starts here and spans across multiple lines). TypeError: Derived contract must override function "_beforeTokenTransfer". Two or more base classes define function with same name and parameter types. --> contracts/SwordNFT.sol:132:1: | 132 | contract SwordNft is ERC721, ERC721Enumerable, Ownable { | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "ERC721": --> @openzeppelin/contracts/token/ERC721/ERC721.sol:467:5: | 467 | function _beforeTokenTransfer( | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in "ERC721Enumerable": --> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:60:5: | 60 | function _beforeTokenTransfer( | ^ (Relevant source part starts here and spans across multiple lines). TypeError: Wrong argument count for function call: 3 arguments given but expected 4. --> contracts/SwordNFT.sol:172:9: | 172 | super._beforeTokenTransfer(from, to, tokenId); | ^^^^^^^^^^^^^^^^^^^^^^^^
🛠 Web3 Starter for JS Devs (email course): bit.ly/web3starter
You’re the man!
Very very interesting. I have thought about directly saving data in smart contract as I have started developing on a very cheap gas blockchain.
This is the first practical approach I have found. Thank you a lot
Glad it was helpful!
thanks for the video! It helped a lot!
You're welcome!
Really nice tutorial Artur, it allows to store SVGs that may be XSS vulnerable, been trying this on Kovan and was successfull :) and yea Tibia is such a nice game, have minted Spike Sword from Rookgard :D
Hello Artur, great video! Sweet and easy to understand!
I just wanna ask: What happens if I have a large set of unique, complex 64x64 SVGs with multiple layers? What would be the best way to store/generate these NFTs on-chain?
I've already tried storing them on-chain and it was simply too big for the contract to even compile.
Cheers,
Ashton
Is this code outdated? I am launching my NFT on polygon mumbai- the json looks fine when I call for the tokenUri and decode it... but OpenSea does not display any image nor recognize any of the attributes... 😢
Please try Polygon Mainnet or Rinkeby. Mumbai sometimes doesn't work on OpenSea in good manner :/
@@ArturChmaro hmmm actually when I use EXACTLY your svg and json code I can see it in OpenSea… so the issue is probably just me and not mumbai 😅
@@jimlynchcodes check your json in json validator, maybe you have syntax problem with it
beautiful tutorial
Thanks!
Is there any way to include just the minter’s address in the NFT but not render the image as an SVG? I’m deploying Manifold contracts so 0 solidity knowledge.
I know that IFPS is public by nature, but are there any methods or solutions for locking data like an SVG so only the owner of an associated NFT can access it? Piñata is offering a solution they're calling submarining, but it relies on a third party. Is there any talk in the NFT world of developments that could restrict data to everyone but NFT holders?
BTW, great video!
You may hide some content in functions that can be called just be token owners.
Thank you very much sir.
Welcome!
great stuff, thanks
My pleasure!
SICK!
Hi, When different prop attributes of the game are stored on the chain, does the player consume a lot of gas cost for minting NFT?
Costs of deploying are definitely higher than with regular contracts. Just a trade-off to have metadata on-chain.
Would be sooo cool if additional attributes will generate (custom / randomly) into metadata
im curious to know what logic would you use to animate an svg in real time .. lets say a loading screen with a chosen nft that we dont know until user selects from MetaMask.
appreciate any feedback.. your a an awesome dev.. im studying coding now and love your vids.. keep them coming thanks
Does it matter what the image dimension is set to? Eg. 64x64, will it be upscaled on Opensea's item page or show up as a small image.
They recommend using a 350 x 350 image
Hey Artur,
Great video, can you make a video on how to create land token and visualize it on our own website? for example: sandbox and decentraland land tokens are fit in the map.
artur I hope you can answer. I wanted to ask if i can make the image be dynamic where I can change the ipfs link to be unique for each given token. I dont want to use a SVG file
Just wondering why you implemented the function _beforeTokenTransfer?
It's a part of ERC1155/ERC721 standard
Can the data is only read by owner or with some salt key from web3? for example if we wanna store metadata such date birth or our another personal information? I just research about store personal information into blockchain. thanks great video!
Metadata in NFT by design should be publicly available. However if you want to add some kind of "access control" then you can customize the code. You may check the msg.sender and based on that include/hide some information.
Hi man! Thanks for the video 👍 I was wondering if as a developer you find this solution truly viable, due to the amount of data that has to be stored and computed on-chain. This may be ‘valid’ for a very simple and light svg file, but it becomes unfeasible with other types of graphic files. I would like to have your opinion on this. Thanks!
It's just an option / fun fact. For most of the projects, it doesn't make sense. But if somebody is building on Polygon and wants to have truly on-chain metadata I see no other option at the moment.
Is there anyway we can get the json metadata stored in ipfs within our smart contract? Or it has to be stored on chain?
Thank you for the video.
Smart contract / Solidity can't contact or fetch data from IPFS.
Great video @Artur Chmaro ! I was wondering if you know how to store partially on-chain metadata so it can be read by OpenSea?
I'm trying to store 99% as pre-made jsons on IPFS, and then two properties on-chain, so it can be edited by token owner: eg. Name.
Do you know how can I go about this?
OpenSea supports it for some collections but no documentation on how to achieve it...
Since the metadata is in a struct on chain, does it in any way become less secure than if it was stored on IPFS? Could someone interact with the contract in a way they can change the NFT metadata struct?
Changing on-chain metadata by someone is not possible. Just make sure that you do not have any bug in the code. Especially check the address of caller in functions that may edit metadata
Can this be used for cardano to mint nft on chain?
I'm afraid not. This will work only for EVM chains (Ethereum, Polygon, BSC, Optimism and many others)
Hi. I want to develop farming game. And I want to mint the farm asset.
Each NFTs (farm asset) have different characteristics :
1) Limited
2) Infinity
3) Mint by stages
So, using ERC 1155, the smart contract have to deployed all once or seperately?
I think you can use the same contract. However you have to customize ERC1155 and introduce "type" of token, so your token minting rules works like you want:
1. Limited = no problem with that. ERC1155 already supports it
2. Infinity = not sure how to implement it, but maybe just setting total amount of token to maximum value of uint256 would be sufficient ;)
3. Stages = probably you need to customize mint function and just allow to mint/add more tokens based on some constraints (fixed amount that may be added, certain time frame since last batch added)
I would like to ask what will happen if I upload collection without a smart contract?
What do you mean? How do you want to have NFT without contract?
Does anyone know if it is possible to do it on Solana ? Thanks !
No exp with Solana, sorry
Tried code from github.Getting these compilation errors
TypeError: Function has override specified but does not override anything.
--> contracts/SwordNFT.sol:170:9:
|
170 | override(ERC721, ERC721Enumerable)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Invalid contracts specified in override list: "ERC721" and "ERC721Enumerable".
--> contracts/SwordNFT.sol:170:9:
|
170 | override(ERC721, ERC721Enumerable)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: This contract:
--> @openzeppelin/contracts/token/ERC721/ERC721.sol:19:1:
|
19 | contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: This contract:
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:14:1:
|
14 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
| ^ (Relevant source part starts here and spans across multiple lines).
TypeError: Derived contract must override function "_beforeTokenTransfer". Two or more base classes define function with same name and parameter types.
--> contracts/SwordNFT.sol:132:1:
|
132 | contract SwordNft is ERC721, ERC721Enumerable, Ownable {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC721":
--> @openzeppelin/contracts/token/ERC721/ERC721.sol:467:5:
|
467 | function _beforeTokenTransfer(
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC721Enumerable":
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:60:5:
|
60 | function _beforeTokenTransfer(
| ^ (Relevant source part starts here and spans across multiple lines).
TypeError: Wrong argument count for function call: 3 arguments given but expected 4.
--> contracts/SwordNFT.sol:172:9:
|
172 | super._beforeTokenTransfer(from, to, tokenId);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error HH600: Compilation failed
For more info go to hardhat.org/HH600 or run Hardhat with --show-stack-traces
Thomas.Kavalakkatt@USMFLQ3QY43Q hardhat-tutorial % npx hardhat clean
Thomas.Kavalakkatt@USMFLQ3QY43Q hardhat-tutorial % npx hardhat compile
TypeError: Function has override specified but does not override anything.
--> contracts/SwordNFT.sol:170:9:
|
170 | override(ERC721, ERC721Enumerable)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Invalid contracts specified in override list: "ERC721" and "ERC721Enumerable".
--> contracts/SwordNFT.sol:170:9:
|
170 | override(ERC721, ERC721Enumerable)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: This contract:
--> @openzeppelin/contracts/token/ERC721/ERC721.sol:19:1:
|
19 | contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: This contract:
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:14:1:
|
14 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
| ^ (Relevant source part starts here and spans across multiple lines).
TypeError: Derived contract must override function "_beforeTokenTransfer". Two or more base classes define function with same name and parameter types.
--> contracts/SwordNFT.sol:132:1:
|
132 | contract SwordNft is ERC721, ERC721Enumerable, Ownable {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC721":
--> @openzeppelin/contracts/token/ERC721/ERC721.sol:467:5:
|
467 | function _beforeTokenTransfer(
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC721Enumerable":
--> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:60:5:
|
60 | function _beforeTokenTransfer(
| ^ (Relevant source part starts here and spans across multiple lines).
TypeError: Wrong argument count for function call: 3 arguments given but expected 4.
--> contracts/SwordNFT.sol:172:9:
|
172 | super._beforeTokenTransfer(from, to, tokenId);
| ^^^^^^^^^^^^^^^^^^^^^^^^
Also getting the same errors, did you manage to solve them?