<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Tiny Jasmini</title>
        <link>https://paragraph.com/@tiny-jasmini</link>
        <description>I'm Yasmin Seidel. I'm a tiny puddy crypto brony making tiny good projects! ^~^</description>
        <lastBuildDate>Thu, 23 Apr 2026 15:50:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Tiny Jasmini</title>
            <url>https://storage.googleapis.com/papyrus_images/c72cebd2a97caa70752526c300db8a83c79a60a16704ec208a4887397d6fc9b8.jpg</url>
            <link>https://paragraph.com/@tiny-jasmini</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[How does an NFT really work?]]></title>
            <link>https://paragraph.com/@tiny-jasmini/how-does-an-nft-really-work</link>
            <guid>wnAVMbq05PtSJN9FzN0l</guid>
            <pubDate>Sun, 26 May 2024 15:47:07 GMT</pubDate>
            <description><![CDATA[Welcome to the tiny NFT class made by tiny me! Today we will learn how a NFT really works! I’m going to use my image gallery as an example where I host the drawings of my characters from my fic. This NFT is a token ERC-721. Exemple of a NFT code on the blockchain https://polygonscan.com/address/0xc322b221237473c75bb9e0bea85f47e847f5c703#code The NFT module template: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol The source code:// Contract...]]></description>
            <content:encoded><![CDATA[<p>Welcome to the tiny NFT class made by tiny me! Today we will learn how a NFT really works! I’m going to use my image gallery as an example where I host the drawings of my characters from my fic. This NFT is a token ERC-721.</p><p>Exemple of a NFT code on the blockchain <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://polygonscan.com/address/0xc322b221237473c75bb9e0bea85f47e847f5c703#code">https://polygonscan.com/address/0xc322b221237473c75bb9e0bea85f47e847f5c703#code</a></p><p>The NFT module template: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol">https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol</a></p><p>The source code:</p><pre data-type="codeBlock" text="// Contract based on https://docs.openzeppelin.com/contracts/4.x/erc721
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import &quot;@openzeppelin/contracts/token/ERC721/ERC721.sol&quot;;
import &quot;@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol&quot;;
import &quot;@openzeppelin/contracts/utils/Counters.sol&quot;;
import &quot;@openzeppelin/contracts/access/Ownable.sol&quot;;

contract PonyDrilandNFT is ERC721URIStorage, Ownable {
   
   using Counters for Counters.Counter;
   Counters.Counter private _tokenIds;

   constructor() ERC721(&quot;Pony Driland&quot;, &quot;PDL&quot;) {}

   function mintNFT(address recipient, string memory tokenURI)
       public onlyOwner
       returns (uint256)
   {
       _tokenIds.increment();

       uint256 newItemId = _tokenIds.current();
       _mint(recipient, newItemId);
       _setTokenURI(newItemId, tokenURI);

       return newItemId;
   }

}
"><code><span class="hljs-comment">// Contract based on https://docs.openzeppelin.com/contracts/4.x/erc721</span>
<span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.12;</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/ERC721.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/utils/Counters.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">PonyDrilandNFT</span> <span class="hljs-keyword">is</span> <span class="hljs-title">ERC721URIStorage</span>, <span class="hljs-title">Ownable</span> </span>{
   
   <span class="hljs-keyword">using</span> <span class="hljs-title">Counters</span> <span class="hljs-title"><span class="hljs-keyword">for</span></span> <span class="hljs-title">Counters</span>.<span class="hljs-title">Counter</span>;
   Counters.Counter <span class="hljs-keyword">private</span> _tokenIds;

   <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) <span class="hljs-title">ERC721</span>(<span class="hljs-params"><span class="hljs-string">"Pony Driland"</span>, <span class="hljs-string">"PDL"</span></span>) </span>{}

   <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mintNFT</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> recipient, <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> tokenURI</span>)
       <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">onlyOwner</span>
       <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>)
   </span>{
       _tokenIds.increment();

       <span class="hljs-keyword">uint256</span> newItemId <span class="hljs-operator">=</span> _tokenIds.current();
       _mint(recipient, newItemId);
       _setTokenURI(newItemId, tokenURI);

       <span class="hljs-keyword">return</span> newItemId;
   }

}
</code></pre><p>This is the base code when you prepare to deploy an NFT. The information is few because the code that really makes everything work is inside the import modules, here you have full control over the NFT while at a NFT Marketplace the source code is managed by the website.</p><p>When a NFT Marketplace will show a collection of NFT which was originally deployed by you is just download your NFT to be displayed on the website.</p><p>Now let’s explain every part of this code:</p><pre data-type="codeBlock" text="address recipient, string memory tokenURI
"><code><span class="hljs-keyword">address</span> recipient, <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> tokenURI
</code></pre><p>When you deploy an NFT gallery, it’s like you’re creating a drawing&apos;s gallery on the Deviantart , so it’s important to remember that each NFT collection is like a collection of a certain virtual item or drawing.</p><p>The entire process of creating an NFT takes place within this single function: <strong>mintNFT</strong>.</p><p><strong>tokenURI</strong> is where you put the IPFS protocol link of your NFT. Can you put a link from a website? Yes, but this is considered illegal by some NFT communities. The logic of you using an IPFS protocol is the file does not depend on a DNS domain that may someday become offline doing NFT completely useless.</p><p>The recipient is which crypto wallet you want to send your newly created NFT to. It can be for yourself or anyone’s wallet you want. But the data inside the NFT will continue to register you as the original creator of the collection.</p><p>The other functions are external functions that belong to the imports I mentioned earlier. They are the ones who really make all the magic happen. Within this code I can also add more other scripts if I want to make a custom NFT. Example: an online game item.</p><p>Yep! You can add more values and customize unlimitedly. But the goal of this tutorial is only to explain the simple parts. Be aware that this freedom also allows you to create NFTs malware to steal cryptocurrencies from other users. Be very careful with that!</p><pre data-type="codeBlock" text="import &quot;@openzeppelin/contracts/utils/Counters.sol&quot;;
"><code><span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/utils/Counters.sol"</span>;
</code></pre><p>This is the module to work the ID counter codes for each NFT created. This works identically to an integer value of a primary number in an SQL.</p><pre data-type="codeBlock" text="import &quot;@openzeppelin/contracts/access/Ownable.sol&quot;;
"><code><span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;
</code></pre><p>This is another optional module that stores the resources to change the owner that manages this NFT collection. This is mostly used when the person is migrating from crypto wallet to a new one.</p><pre data-type="codeBlock" text="import &quot;@openzeppelin/contracts/token/ERC721/ERC721.sol&quot;;
import &quot;@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol&quot;;
"><code><span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/ERC721.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"</span>;
</code></pre><p>These other two modules are what really belong in the NFT itself for everything to work. This is a token ERC-721. There are multiple versions of the base code to create an NFT. Currently there are only two most popular ones. The ERC-721 and the ERC-1155.</p><p>If you have heard about other names like ERC-20. This is a crypto token for virtual currencies, not for NFTs. (Remember that when you are talking more technically, crypto tokens and cryptocurrencies are not the same thing)</p><h1 id="h-erc-721-source-code" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">ERC-721 Source code</h1><p>Now let’s check more closely the original module that composes all the algorithm of the NFT itself. This is where things really get interesting and you start to understand how a NFT actually works.</p><pre data-type="codeBlock" text="import &quot;./IERC721.sol&quot;;
import &quot;./IERC721Receiver.sol&quot;;
import &quot;./extensions/IERC721Metadata.sol&quot;;
import &quot;../../utils/Address.sol&quot;;
import &quot;../../utils/Context.sol&quot;;
import &quot;../../utils/Strings.sol&quot;;
import &quot;../../utils/introspection/ERC165.sol&quot;;
"><code><span class="hljs-keyword">import</span> <span class="hljs-string">"./IERC721.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./IERC721Receiver.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./extensions/IERC721Metadata.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"../../utils/Address.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"../../utils/Context.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"../../utils/Strings.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"../../utils/introspection/ERC165.sol"</span>;
</code></pre><p>We’ll find even more modulos in here. You must have already realized that the source code reminds the Java. But this programming language is Solidity. I will not teach here how to deploy a smart contract, but if you are interested, search for Ethereum Remix.</p><p>Well. Back to the tiny NFTs!</p><pre data-type="codeBlock" text="    // Mapping from token ID to owner address
    mapping(uint256 =&gt; address) private _owners;

    // Mapping owner address to token count
    mapping(address =&gt; uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 =&gt; address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address =&gt; mapping(address =&gt; bool)) private _operatorApprovals;
"><code>    <span class="hljs-comment">// Mapping from token ID to owner address</span>
    <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">uint256</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">address</span>) <span class="hljs-keyword">private</span> _owners;

    <span class="hljs-comment">// Mapping owner address to token count</span>
    <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">uint256</span>) <span class="hljs-keyword">private</span> _balances;

    <span class="hljs-comment">// Mapping from token ID to approved address</span>
    <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">uint256</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">address</span>) <span class="hljs-keyword">private</span> _tokenApprovals;

    <span class="hljs-comment">// Mapping from owner to operator approvals</span>
    <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">bool</span>)) <span class="hljs-keyword">private</span> _operatorApprovals;
</code></pre><p>If you know how code mapping works, you may already understand everything that is happening here. But for those who are confused, here is the storage of values of everything that happens within this NFT.</p><p>Token Id is the NFT registered in the collection. Address is the crypto wallet address. Balance is the token balance of the address.</p><p>Yep. the code is small, simple to understand. I don’t need to teach what each one does. That’s reason I’m wanting to jump precisely to the approvals, because this is really the most differentiated part.</p><p>The basic functions of a vanilla NFT code are just the storage, the creator address, and the system of transferring the NFT between users.</p><p>Everyone here has already realized that there is nothing related to buying or selling NFT. Because this functionality does not really exist within an NFT code. What will really make an NFT be sold will be an external web3 application.</p><p>When you are actually the creator of an NFT inside a blockchain, the marketplace has no control over your NFT. MarketPlace can only download your NFT data. This for example makes it easier to create Deviantart-indentical websites where you just do a kind of image gallery synchroniser no need to re-upload each drawing.</p><p>For a marketplace to actually control your NFT, this marketplace needs your permission to do so. And this permission system happens precisely in this function: <strong>approve()</strong></p><pre data-type="codeBlock" text="    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, &quot;ERC721: approval to current owner&quot;);

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            &quot;ERC721: approve caller is not token owner or approved for all&quot;
        );

        _approve(to, tokenId);
    }
"><code>    <span class="hljs-comment">/**
     * @dev See {IERC721-approve}.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">approve</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> to, <span class="hljs-keyword">uint256</span> tokenId</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> <span class="hljs-title"><span class="hljs-keyword">override</span></span> </span>{
        <span class="hljs-keyword">address</span> owner <span class="hljs-operator">=</span> ERC721.ownerOf(tokenId);
        <span class="hljs-built_in">require</span>(to <span class="hljs-operator">!</span><span class="hljs-operator">=</span> owner, <span class="hljs-string">"ERC721: approval to current owner"</span>);

        <span class="hljs-built_in">require</span>(
            _msgSender() <span class="hljs-operator">=</span><span class="hljs-operator">=</span> owner <span class="hljs-operator">|</span><span class="hljs-operator">|</span> isApprovedForAll(owner, _msgSender()),
            <span class="hljs-string">"ERC721: approve caller is not token owner or approved for all"</span>
        );

        _approve(to, tokenId);
    }
</code></pre><p>Due to the marketplace only downloading your NFT collection (often without your permission), it is common for you to sometimes find your NFT on more than one website at the same time. You can even manage the visibility of your NFT inside this marketplace, but the marketplace is still not allowed to sell your NFT. Selling permission only happens when this function is invoked.</p><p>When you invoke this function, you are practically giving permission to another smart contract to manage your NFT Collection. It is within the smart contract of a marketplace that everything really happens about buying and selling. Since you do not invoke these permissions, nothing will happen with your NFTs collection, and all of this is recorded in the blockchain audit.</p><p>Crypto wallet apps usually come with a page for you to manage these permissions. Yep, you are not required to maintain these permissions. In the same way that you can remove permission from an app inside Discord to have access to your account, you can do the same thing inside the web3 with your NFTs and any other crypto token.</p><p>What is the conclusion of this? NFTs are not natively to be sold or bought, that’s just a resource that belongs in the marketplace. So it’s always important to be careful which marketplace you’re giving these permissions to in the same way you give an app permission to access your Discord account.</p><h1 id="h-what-about-nfts-created-within-a-marketplace-what-really-happens" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What about NFTs created within a marketplace? What really happens?</h1><p>The first thing we need to understand is that to create an NFT, you need to pay a small gas fee for the amount of processing that will be used. Does the marketplace have enough cryptocurrency to pay the fee for everyone trying to use it for free?</p><p>Answer: <strong>no</strong></p><p>What will actually happen is that first… this NFT will not really be controlled by you, who controls this NFT is the smart contract of the marketplace because it was this dapp that was used to create your NFT.</p><p>Second. These NFTs created in the marketplace, they only enter the blockchain after they are bought or sold. (yep. SUS can already start to be detected here)</p><p>Then comes the magic question. Okay. If an NFT created in a marketplace is not yet an NFT, how do these NFTs exist there?</p><p>It has a term. We call it Lazy NFT. It is an NFT that was “created” within the marketplace website’s database to only be placed on the blockchain after they are sold.</p><p>That’s reason this type of NFT only appears in the marketplace it was created, it doesn’t appear anywhere else. If you really want to host an NFT, use IPFS Protocol and look to use an NFT deployment directly in the blockchain instead of using marketplaces of third parties. These websites will even try to profit from your works by charging fees.</p><h1 id="h-how-do-you-detect-a-lazy-nft" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">How do you detect a Lazy NFT?</h1><p>You just have to get the address of the smart contract from the marketplace and see if there is an NFT token inside the blockchain.</p><p>I have a simple example of a test I did on OpenSea:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/assets/ethereum/0x495f947276749ce646f68ac8c248420045cb7b5e/69127646911502286443745060318492950152047840159273240060427221806677659484161">https://opensea.io/assets/ethereum/0x495f947276749ce646f68ac8c248420045cb7b5e/69127646911502286443745060318492950152047840159273240060427221806677659484161</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x495f947276749ce646f68ac8c248420045cb7b5e?source=post_page-----10dc4f4a710a--------------------------------">https://etherscan.io/address/0x495f947276749ce646f68ac8c248420045cb7b5e?source=post_page-----10dc4f4a710a--------------------------------</a></p><p>Here you can already see the smart contract address of an NFT. TokenID is the numerical value of this NFT stored within the collection.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/2c9c3ff781a351db2826cdc1eb3c31ad9bbc8e78cbb3c42e3b6183313b4b92b7.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/nft/0x495f947276749ce646f68ac8c248420045cb7b5e/69127646911502286443745060318492950152047840159273240060427221806677659484161?source=post_page-----10dc4f4a710a--------------------------------">https://etherscan.io/nft/0x495f947276749ce646f68ac8c248420045cb7b5e/69127646911502286443745060318492950152047840159273240060427221806677659484161?source=post_page-----10dc4f4a710a--------------------------------</a></p><p>Put the NFT Token ID inside the URL with the smart contract ID and you will see that the NFT does not exist.</p><p>When the NFT exists. Something like this needs to happen:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/nft/0x495f947276749ce646f68ac8c248420045cb7b5e/111742181400930061902510359858657921591493830882442799692376905920228081270785?source=post_page-----10dc4f4a710a--------------------------------">https://etherscan.io/nft/0x495f947276749ce646f68ac8c248420045cb7b5e/111742181400930061902510359858657921591493830882442799692376905920228081270785?source=post_page-----10dc4f4a710a--------------------------------</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://polygonscan.com/token/0x5309906b7029777423ce73e767e71292ac7efb30?a=7&amp;source=post_page-----10dc4f4a710a--------------------------------#inventory">https://polygonscan.com/token/0x5309906b7029777423ce73e767e71292ac7efb30?a=7&amp;source=post_page-----10dc4f4a710a--------------------------------#inventory</a></p><p>The page does not need to display the NFT itself, what needs to happen at least is to say that that token exists. Then comes the other question. Are global NFT marketplaces just for making money?</p><p>Answer: Yes</p><p>Solution: Don’t create your NFTs on a marketplace, learn to create NFTs yourself so you can really do what you want with this NFT. Whether to create just a decentralized drawing gallery to share on the community, or to make some good application on the internet. What is the best use of a NFT?</p><h1 id="h-what-is-the-best-use-of-a-nft" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What is the best use of a NFT?</h1><p>1 — You can create a decentralized drawing gallery with the help of the IPFS protocol. This can also be used as a drawing record audit to help you protect against plagiarism or people trying to steal your art.</p><p>Remember that within the blockchain the registration of your drawing can’t be dropped, and you don’t have to worry about websites disappearing from existence.</p><p>2 — If you work in a fandom, this is the best way you create a sales audit of character adopts. Even if someone else tries to replicate your NFT, remember that the blockchain audit will always show you were the first to create the project.</p><p>3 — You can use as an audit of commissions and ychs produced by you. If your customers use crypto as a payment method, in addition to having the authorship, you will always receive payment in full amount without being discounted fees for third-party companies.</p><p>4 — Use as a reward system for the people you like most. You can deliver these rewards for free to these people.</p><p>5 — Infinite possibilities that remain in your imagination. Just do not abuse this tool.</p><h1 id="h-bad-use-examples" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Bad use examples</h1><p>1 — Algoritim avatar systems. (that’s what you’ll find most currently at this time that I’m writing this article)</p><p>2 — No sense pictures.</p><p>3 — Put malware inside the source code to steal crypto.</p><h2 id="h-banner-credits" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><strong>Banner Credits</strong></h2><p>Art: Pony Diffusion V6 XL | Image fixes and edits: JasminDreasond</p>]]></content:encoded>
            <author>tiny-jasmini@newsletter.paragraph.com (Tiny Jasmini)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/40fed12759eaa5c8e557e979f647f5dea80fe9fc4b64edae50855504ee927761.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>