<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ whitelist - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ whitelist - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 20:15:38 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/whitelist/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Implement a Whitelist in Smart Contracts (ERC-721 NFT, ERC-1155, and others) ]]>
                </title>
                <description>
                    <![CDATA[ By Igor Gaponov In this article I will show you three ways you can create a whitelist in a smart contract. Here's what we'll discuss: On-chain whitelists Digital signatures Merkle trees All methods are available in the repo here. A whitelist is use... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-whitelist-in-smartcontracts-erc-721-nft-erc-1155-and-others/</link>
                <guid isPermaLink="false">66d45f31230dff0166905809</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ digital-signature ]]>
                    </category>
                
                    <category>
                        <![CDATA[ merkle tree ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Smart Contracts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ whitelist ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 12 Oct 2022 14:12:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/whitelist-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Igor Gaponov</p>
<p>In this article I will show you three ways you can create a whitelist in a smart contract.</p>
<p>Here's what we'll discuss:</p>
<ul>
<li>On-chain whitelists</li>
<li>Digital signatures</li>
<li>Merkle trees</li>
</ul>
<p>All methods are available in the <a target="_blank" href="https://github.com/gapon2401/smartcontract-whitelist">repo here</a>.</p>
<p>A whitelist is useful if you want to restrict access to a certain function or want to grant privileges to a certain group of users. </p>
<p>To compare these methods, I'm going to use very minimalistic smart contracts to reduce the unnecessary spending of gas. </p>
<p>Let's dive into it.</p>
<h2 id="heading-how-to-create-an-on-chain-whitelist">How to Create an On-Chain Whitelist</h2>
<p>The main idea is to store all whitelist addresses in the smart contract.</p>
<p>Take a look at this schema:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Untitled--3-.png" alt="On-chain whitelist" width="600" height="400" loading="lazy">
<em>On-chain whitelist</em></p>
<p>When user calls the smart contract function, it checks if the address is in the whitelist. If it is, the function executes. </p>
<p>If you want to add or remove addresses from the whitelist, you can do it in the smart contract with additional <code>external</code> functions.</p>
<p>Pros:</p>
<ul>
<li>easy to implement</li>
<li>all addresses are stored in the smart contract and only the owner can edit them</li>
</ul>
<p>Cons: </p>
<ul>
<li>it's the most expensive method</li>
<li>you have to spend gas to add and remove the addresses</li>
</ul>
<p>Here's what the smart contract looks like:</p>
<pre><code class="lang-js">contract OnChainWhitelistContract is Ownable {

    mapping(<span class="hljs-function"><span class="hljs-params">address</span> =&gt;</span> bool) public whitelist;

    <span class="hljs-comment">/**
     * @notice Add to whitelist
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addToWhitelist</span>(<span class="hljs-params">address[] calldata toAddAddresses</span>) 
    <span class="hljs-title">external</span> <span class="hljs-title">onlyOwner</span>
    </span>{
        <span class="hljs-keyword">for</span> (uint i = <span class="hljs-number">0</span>; i &lt; toAddAddresses.length; i++) {
            whitelist[toAddAddresses[i]] = <span class="hljs-literal">true</span>;
        }
    }

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@notice </span>Remove from whitelist
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">removeFromWhitelist</span>(<span class="hljs-params">address[] calldata toRemoveAddresses</span>)
    <span class="hljs-title">external</span> <span class="hljs-title">onlyOwner</span>
    </span>{
        <span class="hljs-keyword">for</span> (uint i = <span class="hljs-number">0</span>; i &lt; toRemoveAddresses.length; i++) {
            <span class="hljs-keyword">delete</span> whitelist[toRemoveAddresses[i]];
        }
    }

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@notice </span>Function with whitelist
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">whitelistFunc</span>(<span class="hljs-params"></span>) <span class="hljs-title">external</span>
    </span>{
        <span class="hljs-built_in">require</span>(whitelist[msg.sender], <span class="hljs-string">"NOT_IN_WHITELIST"</span>);

        <span class="hljs-comment">// Do some useful stuff</span>
    }
}
</code></pre>
<p>All addresses will be stored in the <code>whitelist</code> variable.</p>
<p>The function <code>addToWhitelist</code> allows the owner to add an array of addresses. Keep in mind that each address in the list will spend about 22904 gas units. To call that function costs 23994 gas units.</p>
<p>The function <code>removeFromWhitelist</code> allows you to remove addresses from the whitelist.</p>
<p>And the function <code>whitelistFunc</code> checks if the address belongs to the whitelist.</p>
<p>Gas spending:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/on-chain-gas.jpg" alt="Gas spending for on-chain whitelist" width="600" height="400" loading="lazy">
<em>Gas spending for on-chain whitelist</em></p>
<h2 id="heading-how-to-create-a-digital-signature-whitelist">How to Create a Digital Signature Whitelist</h2>
<p>The main idea is to create signatures for addresses and check them inside the smart contract.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Digital-signature-1.png" alt="Digital signature whitelist" width="600" height="400" loading="lazy">
<em>Digital signature whitelist</em></p>
<p>You store the whitelist on your server. Before making a call to the smart contract, you should check if the address is in the whitelist or not. If yes, create a signature for the address and pass that signature to the smart contract. Inside the smart contract you have to validate that signature.</p>
<p>Pros:</p>
<ul>
<li>No gas for adding or removing addresses from the whitelist.</li>
<li>No need to interact with the smart contract about the whitelist</li>
</ul>
<p>Cons:</p>
<ul>
<li>Whitelist is located in a database that can be compromised. If the audience trusts the owner of the project, then this is not a problem</li>
<li>The most expensive price for contract deployment and whitelist validating</li>
</ul>
<p>Here's the smart contract:</p>
<pre><code class="lang-js"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.14</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/utils/cryptography/ECDSA.sol"</span>;

contract DigitalSignatureWhitelistContract is Ownable {

    using ECDSA <span class="hljs-keyword">for</span> bytes32;

    <span class="hljs-comment">/**
     * @notice Used to validate whitelist addresses
               Replace this wallet address to your own!
     */</span>
    address private signerAddress = <span class="hljs-number">0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266</span>;

    <span class="hljs-comment">/**
     * @notice Verify signature
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">verifyAddressSigner</span>(<span class="hljs-params">bytes memory signature</span>) <span class="hljs-title">private</span> 
    <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">bool</span>) </span>{
        bytes32 messageHash = keccak256(abi.encodePacked(msg.sender));
        <span class="hljs-keyword">return</span> signerAddress == messageHash.toEthSignedMessageHash().recover(signature);
    }

     <span class="hljs-comment">/**
     * <span class="hljs-doctag">@notice </span>Function with whitelist
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">whitelistFunc</span>(<span class="hljs-params">bytes memory signature</span>) <span class="hljs-title">external</span>
    </span>{
        <span class="hljs-built_in">require</span>(verifyAddressSigner(signature), <span class="hljs-string">"SIGNATURE_VALIDATION_FAILED"</span>);

        <span class="hljs-comment">// Do some useful stuff</span>
    }
}
</code></pre>
<h3 id="heading-how-to-implement-a-digital-signature">How to implement a digital signature</h3>
<p>First, you'll need to create a new wallet address. It will be signer address.</p>
<p>ATTENTION: Do not send any funds to that wallet. It will be used only for making signatures.</p>
<p>Let's assume, that the signer wallet address is <code>0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266</code></p>
<p>Specify it in the smart contract here:</p>
<pre><code class="lang-js">address private signerAddress = <span class="hljs-number">0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266</span>;
</code></pre>
<p>In the root of your web project, create a <code>.env</code> file with private key of that wallet:</p>
<pre><code>SIGNER_PRIVATE_KEY=<span class="hljs-number">0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80</span>
</code></pre><p>Specify only your own public and private keys, because these are publicly known.</p>
<p>Next, create the whitelist database. It can be PostgreSQL, MySQL, MongoDB – any one you want. You can easily add or remove addresses.</p>
<p>Then when it's time to interact with the smart contract, the user clicks a button on your website. You send the request to your server with the user's address.</p>
<p>If the user is in the whitelist, create the signature for the address on your server:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { ethers } <span class="hljs-keyword">from</span> <span class="hljs-string">'ethers'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-comment">// Whitelist array from you database</span>
  <span class="hljs-keyword">const</span> whitelist = [
    <span class="hljs-string">'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC'</span>,
    <span class="hljs-string">'0x90F79bf6EB2c4f870365E785982E1f101E93b906'</span>,
    <span class="hljs-string">'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65'</span>,
    <span class="hljs-string">'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc'</span>,
    <span class="hljs-string">'0x976EA74026E726554dB657fA54763abd0C3a0aa9'</span>,
  ]

  <span class="hljs-comment">// This variable will contain the signature we need</span>
  <span class="hljs-keyword">let</span> signature = <span class="hljs-string">''</span>

  <span class="hljs-comment">// Parse params passed to server and get user wallet address</span>
  <span class="hljs-keyword">const</span> userWalletAddress = <span class="hljs-string">''</span>

  <span class="hljs-keyword">if</span> (whitelist.includes(userWalletAddress)) {
    <span class="hljs-keyword">const</span> signer = <span class="hljs-keyword">new</span> ethers.Wallet(process.env.SIGNER_PRIVATE_KEY!)
    <span class="hljs-keyword">const</span> addressHash = ethers.utils.solidityKeccak256([<span class="hljs-string">'address'</span>], [userWalletAddress.toLowerCase()])
    <span class="hljs-keyword">const</span> messageBytes = ethers.utils.arrayify(addressHash)
    signature = <span class="hljs-keyword">await</span> signer.signMessage(messageBytes)
  }

  <span class="hljs-comment">// Return signature to web</span>
}
</code></pre>
<p>Then pass the signature to the smart contract function, where <code>verifyAddressSigner</code> will validate it according to the sender's address. </p>
<p>Gas spending:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/digital-signature-gas.jpg" alt="Gas spending for digital signature whitelist" width="600" height="400" loading="lazy">
<em>Gas spending for digital signature whitelist</em></p>
<h2 id="heading-how-to-create-a-merkle-tree-whitelist">How to Create a Merkle Tree Whitelist</h2>
<p>What is the Merkle tree?</p>
<blockquote>
<p>Merkle tree is a tree in which every "leaf" (node) is labelled with the cryptographic hash of a data block, and every node that is not a leaf (called a branch, inner node, or inode) is labelled with the cryptographic hash of the labels of its child nodes. – <a target="_blank" href="https://en.wikipedia.org/wiki/Merkle_tree">Source</a></p>
</blockquote>
<p>How does it connect to the whitelist problem?</p>
<p>We will use it to hash all addresses into one root hash.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Merkle-tree-structure.png" alt="Merkle tree" width="600" height="400" loading="lazy">
<em>Merkle tree</em></p>
<p>This is the schema of work:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/Merkle-tree-1.png" alt="Merkle tree whitelist" width="600" height="400" loading="lazy">
<em>Merkle tree whitelist</em></p>
<p>Like in the digital signature method, you need a database for the whitelisted addresses. When you are ready to start the sale or something else, you need to create the Merkle root hash and save it in the smart contract. This hash will validate all the addresses.</p>
<p>When the user wants to make a request to the smart contract, you need to create a Merkle proof for him, based on the Merkle tree of all addresses. Then you need to send proof to the smart contract. You can store the tree locally. </p>
<p>After editing the whitelist you should update the Merkle root hash and rewrite it to the smart contract. You should also update the local Merkle tree. </p>
<p>Pros:</p>
<ul>
<li>Deployment of the smart contract is much cheaper than the digital signature method</li>
<li>Validating addresses in the smart contract is also cheaper</li>
<li>No gas for adding or removing addresses from whitelist, until you start a sale</li>
</ul>
<p>Cons:</p>
<ul>
<li>After the sale has started, it will be complicated to change the whitelist. You will need to update the smart contract and Merkle tree each time. Therefore, gas will be spent.</li>
<li>You need to know how to create a Merkle root and update the smart contact. It's impossible to change the whitelist without interacting with the smart contract.</li>
</ul>
<p>Here's the smart contract:</p>
<pre><code class="lang-js"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.14</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"</span>;

contract MerkleTreeWhitelistContract is Ownable {

    <span class="hljs-comment">/**
     * @notice Merkle root hash for whitelist addresses
     */</span>
    bytes32 public merkleRoot = <span class="hljs-number">0x09485889b804a49c9e383c7966a2c480ab28a13a8345c4ebe0886a7478c0b73d</span>;

    <span class="hljs-comment">/**
     * @notice Change merkle root hash
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setMerkleRoot</span>(<span class="hljs-params">bytes32 merkleRootHash</span>) <span class="hljs-title">external</span> <span class="hljs-title">onlyOwner</span>
    </span>{
        merkleRoot = merkleRootHash;
    }

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@notice </span>Verify merkle proof of the address
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">verifyAddress</span>(<span class="hljs-params">bytes32[] calldata _merkleProof</span>) <span class="hljs-title">private</span> 
    <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">bool</span>) </span>{
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        <span class="hljs-keyword">return</span> MerkleProof.verify(_merkleProof, merkleRoot, leaf);
    }

    <span class="hljs-comment">/**
     * <span class="hljs-doctag">@notice </span>Function with whitelist
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">whitelistFunc</span>(<span class="hljs-params">bytes32[] calldata _merkleProof</span>) <span class="hljs-title">external</span>
    </span>{
        <span class="hljs-built_in">require</span>(verifyAddress(_merkleProof), <span class="hljs-string">"INVALID_PROOF"</span>);

        <span class="hljs-comment">// Do some useful stuff</span>
    }
}
</code></pre>
<h3 id="heading-how-to-implement-a-merkle-tree-on-the-web">How to implement a Merkle tree on the web</h3>
<p>First, create the whitelist database. It can be PostgreSQL, MySQL, MongoDB or any other you want. You can easily add or remove addresses.</p>
<p>When it's time to interact with the smart contract, create a Merkle root hash:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { ethers } <span class="hljs-keyword">from</span> <span class="hljs-string">'ethers'</span>
<span class="hljs-keyword">import</span> { MerkleTree } <span class="hljs-keyword">from</span> <span class="hljs-string">'merkletreejs'</span>

<span class="hljs-comment">// Your whitelist from database</span>
<span class="hljs-keyword">const</span> whitelist = [
  <span class="hljs-string">'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC'</span>,
  <span class="hljs-string">'0x90F79bf6EB2c4f870365E785982E1f101E93b906'</span>,
  <span class="hljs-string">'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65'</span>,
  <span class="hljs-string">'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc'</span>,
  <span class="hljs-string">'0x976EA74026E726554dB657fA54763abd0C3a0aa9'</span>,
]

<span class="hljs-keyword">const</span> { keccak256 } = ethers.utils
<span class="hljs-keyword">let</span> leaves = whitelist.map(<span class="hljs-function">(<span class="hljs-params">addr</span>) =&gt;</span> keccak256(addr))
<span class="hljs-keyword">const</span> merkleTree = <span class="hljs-keyword">new</span> MerkleTree(leaves, keccak256, { <span class="hljs-attr">sortPairs</span>: <span class="hljs-literal">true</span> })

<span class="hljs-comment">// Save this value to smartcontract</span>
<span class="hljs-keyword">const</span> merkleRootHash = merkleTree.getHexRoot()
<span class="hljs-comment">// 0x09485889b804a49c9e383c7966a2c480ab28a13a8345c4ebe0886a7478c0b73d</span>
</code></pre>
<p> Then save the Merkle root hash in the smart contract. </p>
<p>Specify it before the deployment:</p>
<pre><code class="lang-js">bytes32 public merkleRoot = <span class="hljs-number">0x09485889b804a49c9e383c7966a2c480ab28a13a8345c4ebe0886a7478c0b73d</span>;
</code></pre>
<p>Or use a function <code>setMerkleRoot</code> for it:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setMerkleRoot</span>(<span class="hljs-params">bytes32 merkleRootHash</span>) <span class="hljs-title">external</span> <span class="hljs-title">onlyOwner</span>
</span>{
    merkleRoot = merkleRootHash;
}
</code></pre>
<p>When the user clicks a button on your website, you send the request to your server with the user's address. If the user is in the whitelist, create the Merkle proof on your server:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { ethers } <span class="hljs-keyword">from</span> <span class="hljs-string">'ethers'</span>
<span class="hljs-keyword">import</span> { MerkleTree } <span class="hljs-keyword">from</span> <span class="hljs-string">'merkletreejs'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-comment">// Whitelist array from you database</span>
  <span class="hljs-keyword">const</span> whitelist = [
    <span class="hljs-string">'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC'</span>,
    <span class="hljs-string">'0x90F79bf6EB2c4f870365E785982E1f101E93b906'</span>,
    <span class="hljs-string">'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65'</span>,
    <span class="hljs-string">'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc'</span>,
    <span class="hljs-string">'0x976EA74026E726554dB657fA54763abd0C3a0aa9'</span>,
  ]

  <span class="hljs-comment">// This variable will contain the signature we need</span>
  <span class="hljs-keyword">let</span> proof = []

  <span class="hljs-comment">// Parse params passed to server and get user wallet address</span>
  <span class="hljs-keyword">const</span> userWalletAddress = <span class="hljs-string">''</span>

  <span class="hljs-keyword">if</span> (whitelist.includes(userWalletAddress)) {
    <span class="hljs-keyword">const</span> { keccak256 } = ethers.utils
    <span class="hljs-keyword">let</span> leaves = whitelist.map(<span class="hljs-function">(<span class="hljs-params">addr</span>) =&gt;</span> keccak256(addr))
    <span class="hljs-keyword">const</span> merkleTree = <span class="hljs-keyword">new</span> MerkleTree(leaves, keccak256, { <span class="hljs-attr">sortPairs</span>: <span class="hljs-literal">true</span> })
    <span class="hljs-keyword">let</span> hashedAddress = keccak256(userWalletAddress)
    proof = merkleTree.getHexProof(hashedAddress)
  }

  <span class="hljs-comment">// Return proof to web</span>
}
</code></pre>
<p>Then pass proof to the smart contract function, where <code>verifyAddress</code> will validate it according to the sender's address. </p>
<p>Gas spending:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/merkle-tree-gas.jpg" alt="Gas spending for Merkle tree whitelist" width="600" height="400" loading="lazy">
<em>Gas spending for Merkle tree whitelist</em></p>
<h2 id="heading-summary">Summary</h2>
<p>Below you will find a comparison table of the gas units these different methods spend:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Property</td><td>On-chain</td><td>Digital signature</td><td>Merkle tree</td></tr>
</thead>
<tbody>
<tr>
<td>Deployment</td><td>329 724</td><td>486 182</td><td>352 790</td></tr>
<tr>
<td>Add to whitelist 1 address</td><td>46 898</td><td>0</td><td>28 986</td></tr>
<tr>
<td>Add to whitelist 10 addresses</td><td>253 010</td><td>0</td><td>28 986</td></tr>
<tr>
<td>Remove from whitelist</td><td>24 930</td><td>0</td><td>28 986</td></tr>
<tr>
<td>Call function with whitelist</td><td>23 443</td><td>29 365</td><td>26 065</td></tr>
</tbody>
</table>
</div><p>Long story short:</p>
<ul>
<li>An on-chain whitelist easy to implement, but expensive to use. I would not recommend using it.</li>
<li>A digital signature whitelist is a universal tool that does not require additional interactions with the smart contract. You can easily edit the whitelist at any time. But you have to pay for versatility. Deployment and function with the whitelist are the most expensive. If your addresses change frequently, then use digital signature. </li>
<li><p>Merkle tree is the best option if your whitelist addresses will not change after you start presale or whatever you want. For example, it costs nothing to collect addresses and edit them in your database. When the sale starts, you stop editing the whitelist, create the root hash, save it to the smart contract and that's it. In that case the Merkle tree is better than digital signature. </p>
<p>What exactly to use is up to you!</p>
</li>
</ul>
<p>Finally, I want to show you how to calculate gas price.</p>
<h3 id="heading-how-to-calculate-gas-price">How to calculate gas price</h3>
<p>Use the following formula:</p>
<pre><code>(gas units) * (gas price per unit) = gas fee <span class="hljs-keyword">in</span> gwei
</code></pre><p>Use <a target="_blank" href="https://ethgasstation.info/">https://ethgasstation.info/</a> or any other website to find gas price per unit. At the moment of writing this article, gas price is 22.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/gas-price.jpg" alt="Gas price per unit" width="600" height="400" loading="lazy">
<em>Gas price per unit</em></p>
<p>The value can change depending on the time of day.</p>
<p>Let's calculate how much it will cost to deploy a digital signature smart contract.</p>
<pre><code class="lang-js">Deployment = <span class="hljs-number">486</span> <span class="hljs-number">182</span> * <span class="hljs-number">22</span> = <span class="hljs-number">10</span> <span class="hljs-number">696</span> <span class="hljs-number">004</span> gwei = <span class="hljs-number">0</span>,<span class="hljs-number">010696004</span> ETH
</code></pre>
<p>Now since the ETH/USD price is $1,324, it means that deployment to the Mainnet will cost about $14.</p>
<p>Maybe you want to convert the comparison table to USD?<br> <code>Gas price per unit</code> = 22, <code>ETH</code> = $1,324</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Property</td><td>On-chain</td><td>Digital signature</td><td>Merkle tree</td></tr>
</thead>
<tbody>
<tr>
<td>Deployment</td><td>$9.6</td><td>$14.16</td><td>$10.28</td></tr>
<tr>
<td>Add to whitelist 1 address</td><td>$1.37</td><td>0</td><td>$0.84</td></tr>
<tr>
<td>Add to whitelist 10 addresses</td><td>$7.37</td><td>0</td><td>$0.84</td></tr>
<tr>
<td>Remove from whitelist</td><td>$0.73</td><td>0</td><td>$0.84</td></tr>
<tr>
<td>Call function with whitelist</td><td>$0.68</td><td>$0.86</td><td>$0.76</td></tr>
</tbody>
</table>
</div><p>Thank you for reading! ❤</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
