<?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[ Blockchain - 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[ Blockchain - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 04:43:18 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/blockchain/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Fix the Python ENOENT Error When Setting Up MCP Servers – A Complete Guide ]]>
                </title>
                <description>
                    <![CDATA[ Getting the "spawn python ENOENT" error while setting up an MCP (Model Context Protocol) server on macOS can be frustrating. But don't worry – in this tutorial, I'll guide you through fixing it by rebuilding your Python virtual environment. By the en... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-fix-the-python-enoent-error-when-setting-up-mcp-servers-a-complete-guide/</link>
                <guid isPermaLink="false">68963890790ac4491c15b00a</guid>
                
                    <category>
                        <![CDATA[ mcp server ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Beginner Developers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ macOS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Idris Olubisi ]]>
                </dc:creator>
                <pubDate>Fri, 08 Aug 2025 17:49:04 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754675334533/6a05e45a-9703-49c0-b427-6c4960c01d86.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Getting the "spawn python ENOENT" error while setting up an MCP (Model Context Protocol) server on macOS can be frustrating. But don't worry – in this tutorial, I'll guide you through fixing it by rebuilding your Python virtual environment.</p>
<p>By the end, you'll have a fully functional MCP server integrated with Claude Desktop in about 10 minutes. This solution applies to any MCP setup facing this standard error after Python upgrades.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-causes-the-enoent-error">What Causes the ENOENT Error?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-diagnose-your-broken-virtual-environment">How to Diagnose Your Broken Virtual Environment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-completely-rebuild-your-virtual-environment">How to Completely Rebuild Your Virtual Environment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-mcp-server-dependencies">How to Install MCP Server Dependencies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-locate-your-server-files">How to Locate Your Server Files</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-test-your-server-setup">How to Test Your Server Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-claude-desktop">How to Configure Claude Desktop</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-restart-claude-desktop-and-test-integration">How to Restart Claude Desktop and Test Integration</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-mcp-server-capabilities">Understanding MCP Server Capabilities</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-alternative-installation-methods">Alternative Installation Methods</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-method-1-direct-package-installation">Method 1: Direct Package Installation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-method-2-using-uv-package-manager">Method 2: Using UV Package Manager</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-prevent-future-enoent-errors">How to Prevent Future ENOENT Errors</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-troubleshooting-common-issues">Troubleshooting Common Issues</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-what-causes-the-enoent-error">What Causes the ENOENT Error?</h2>
<p>The ENOENT (Error NO ENTry) error means your system can’t locate the Python executable at the specified path. This occurs when the file is missing or inaccessible.</p>
<p>On macOS, this typically happens when:</p>
<ul>
<li><p>You've upgraded Python through Homebrew</p>
</li>
<li><p>The <code>brew cleanup</code> command removed old Python versions</p>
</li>
<li><p>Your virtual environment's symlinks now point to non-existent files</p>
</li>
</ul>
<p>What makes this particularly challenging is that your virtual environment folder still exists – it looks fine from the outside, but the Python executable inside is completely broken.</p>
<p>When MCP servers try to spawn Python processes using these broken paths, you get the dreaded ENOENT error. This affects any Python-based MCP server, whether you're building custom tools, connecting to APIs, or working with file systems.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow this tutorial, you'll need:</p>
<ul>
<li><p>macOS with <a target="_blank" href="https://brew.sh/">Homebrew</a> installed</p>
</li>
<li><p>Python 3.10 or higher</p>
</li>
<li><p>An MCP server repository cloned locally</p>
</li>
<li><p><a target="_blank" href="https://claude.ai/download">Claude Desktop</a> installed</p>
</li>
<li><p>Basic familiarity with terminal commands and Python virtual environments</p>
</li>
</ul>
<p>If you haven't cloned an MCP server repository yet, you can start with any open-source MCP server. For this tutorial, I'll use generic examples that work with any MCP setup:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/your-username/your-mcp-server.git
<span class="hljs-built_in">cd</span> your-mcp-server
</code></pre>
<h2 id="heading-how-to-diagnose-your-broken-virtual-environment">How to Diagnose Your Broken Virtual Environment</h2>
<p>First, you need to confirm that your virtual environment is actually the problem. Open your terminal and navigate to your MCP directory:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /path/to/your/mcp-server
</code></pre>
<p>Now check if your Python executable exists:</p>
<pre><code class="lang-bash">ls -la venv/bin/python*
</code></pre>
<p>If you see broken symlinks or get "No such file or directory" errors, you've found your problem. You might see output like:</p>
<pre><code class="lang-bash">lrwxr-xr-x  1 username  staff  16 Jan  1 12:00 python -&gt; /usr/<span class="hljs-built_in">local</span>/bin/python3.11
lrwxr-xr-x  1 username  staff  16 Jan  1 12:00 python3 -&gt; /usr/<span class="hljs-built_in">local</span>/bin/python3.11
</code></pre>
<p>But when you try to run these Python executables:</p>
<pre><code class="lang-bash">./venv/bin/python --version
</code></pre>
<p>You'll get an error because the target files no longer exist. This confirms your virtual environment is broken and needs rebuilding.</p>
<h2 id="heading-how-to-completely-rebuild-your-virtual-environment">How to Completely Rebuild Your Virtual Environment</h2>
<p>The most reliable solution is to rebuild your virtual environment from scratch. This ensures all paths and dependencies are correctly configured for your current Python installation.</p>
<p>Here's your step-by-step rebuild process:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Make sure you're in the MCP server directory</span>
<span class="hljs-built_in">cd</span> /path/to/your/mcp-server

<span class="hljs-comment"># Remove the corrupted virtual environment</span>
rm -rf venv

<span class="hljs-comment"># Create a fresh virtual environment</span>
python3 -m venv venv

<span class="hljs-comment"># Activate the new environment</span>
<span class="hljs-built_in">source</span> venv/bin/activate
</code></pre>
<p>You should now see <code>(venv)</code> in your terminal prompt, indicating the virtual environment is active. This prefix confirms you're working within the isolated Python environment.</p>
<h2 id="heading-how-to-install-mcp-server-dependencies">How to Install MCP Server Dependencies</h2>
<p>With your fresh virtual environment active, install the MCP server and its dependencies. The exact installation command depends on your specific MCP server, but typically follows one of these patterns:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># For package-based installation</span>
pip install -e .

<span class="hljs-comment"># Or for requirements file</span>
pip install -r requirements.txt

<span class="hljs-comment"># Or for specific MCP frameworks</span>
pip install fastmcp
</code></pre>
<p>Common MCP server dependencies include:</p>
<ul>
<li><p>FastMCP for the server framework</p>
</li>
<li><p>JSON-RPC libraries for communication protocols</p>
</li>
<li><p>HTTP clients for API integrations</p>
</li>
<li><p>File system utilities for local operations</p>
</li>
</ul>
<p>The installation process displays all packages as they install. Don't worry if you see deprecation warnings – they're normal and won't affect functionality.</p>
<h2 id="heading-how-to-locate-your-server-files">How to Locate Your Server Files</h2>
<p>After installation, identify where your main server file lives. Run this command to find all server.py files:</p>
<pre><code class="lang-bash">find . -name <span class="hljs-string">"server.py"</span> -<span class="hljs-built_in">type</span> f
</code></pre>
<p>You may see results like:</p>
<ul>
<li><p><code>./server.py</code> (in the root directory)</p>
</li>
<li><p><code>./src/server.py</code> (in a source directory)</p>
</li>
<li><p><code>./mcp_server/server.py</code> (in a package directory)</p>
</li>
</ul>
<p>Check your current directory structure:</p>
<pre><code class="lang-bash">ls -la
</code></pre>
<p>Look for the main server entry point. Most MCP servers follow standard Python project structures with either a root-level server file or one nested in a package directory.</p>
<h2 id="heading-how-to-test-your-server-setup">How to Test Your Server Setup</h2>
<p>Now you’ll want to test your server to ensure it's working correctly. Start with the main server file you identified:</p>
<pre><code class="lang-bash">python server.py
</code></pre>
<p>If this is the correct server and everything is configured correctly, you'll see output similar to:</p>
<pre><code class="lang-typescript">╭─ MCP Server ───────────────────────────────────────────────────────────────╮
│ 🖥️  Server name: Example-MCP                                              │
│ 📦 Transport: STDIO                                                        │
│ 🤝 Protocol: <span class="hljs-built_in">JSON</span>-RPC                                                      │
╰────────────────────────────────────────────────────────────────────────────╯
[INFO] Starting MCP server <span class="hljs-keyword">with</span> transport <span class="hljs-string">'stdio'</span>
[INFO] Server ready <span class="hljs-keyword">for</span> connections
</code></pre>
<p>This output confirms your MCP server is working correctly. The server uses standard input/output (STDIO) for communication, which is perfect for Claude Desktop integration. You can stop the server with <code>Ctrl+C</code>.</p>
<h2 id="heading-how-to-configure-claude-desktop">How to Configure Claude Desktop</h2>
<p>Now that your server runs properly, configure Claude Desktop to connect to it. The configuration file location depends on your operating system:</p>
<p><strong>For macOS:</strong></p>
<pre><code class="lang-bash">~/Library/Application Support/Claude/claude_desktop_config.json
</code></pre>
<p><strong>For Windows:</strong></p>
<pre><code class="lang-bash">%APPDATA%\Claude\claude_desktop_config.json
</code></pre>
<p><strong>For Linux:</strong></p>
<pre><code class="lang-bash">~/.config/Claude/claude_desktop_config.json
</code></pre>
<p>Create or edit this file with your exact paths. Your configuration should look like this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"mcpServers"</span>: {
    <span class="hljs-attr">"example-mcp"</span>: {
      <span class="hljs-attr">"command"</span>: <span class="hljs-string">"/Users/yourusername/path/to/mcp-server/venv/bin/python"</span>,
      <span class="hljs-attr">"args"</span>: [<span class="hljs-string">"/Users/yourusername/path/to/mcp-server/server.py"</span>],
      <span class="hljs-attr">"cwd"</span>: <span class="hljs-string">"/Users/yourusername/path/to/mcp-server"</span>
    }
  }
}
</code></pre>
<p>Replace <code>/Users/yourusername/path/to/mcp-server/</code> with your actual path. You can get your precise path by running <code>pwd</code> in your MCP server directory.</p>
<p>The configuration tells Claude Desktop:</p>
<ul>
<li><p>Which Python interpreter to use (from your virtual environment)</p>
</li>
<li><p>Where to find the server script</p>
</li>
<li><p>Which directory to run the server from</p>
</li>
</ul>
<h2 id="heading-how-to-restart-claude-desktop-and-test-integration">How to Restart Claude Desktop and Test Integration</h2>
<p>After saving your configuration file, altogether quit Claude Desktop (not just close the window). On macOS, use <code>Cmd+Q</code> or right-click the dock icon and select Quit. Then restart Claude Desktop.</p>
<p>Once Claude Desktop is running again, test your MCP integration. You can verify the connection by:</p>
<ol>
<li><p>Looking for your MCP server name in Claude's interface</p>
</li>
<li><p>Testing basic MCP functionality with prompts like:</p>
<ul>
<li><p>"What MCP tools are available?"</p>
</li>
<li><p>"Can you check the MCP server status?"</p>
</li>
<li><p>"Show me the available MCP commands"</p>
</li>
</ul>
</li>
</ol>
<p>If everything is working correctly, Claude will respond using the MCP server tools, confirming successful integration.</p>
<h2 id="heading-understanding-mcp-server-capabilities">Understanding MCP Server Capabilities</h2>
<p>MCP servers extend Claude's capabilities by providing structured access to external tools and data sources. Common MCP server implementations include:</p>
<ol>
<li><p>File system operations: MCP servers can provide controlled access to local files, allowing Claude to read, analyze, and process documents while maintaining security boundaries.</p>
</li>
<li><p>API integrations: Connect Claude to external services through MCP servers that handle authentication, rate limiting, and data formatting for various APIs.</p>
</li>
<li><p>Database connections: Query databases safely through MCP servers that manage connections, handle credentials securely, and format results for Claude's consumption.</p>
</li>
<li><p>Custom tools: Build specialized tools for your workflow, from code analysis to data processing, all accessible through the standardized MCP interface.</p>
</li>
</ol>
<p>The beauty of MCP is its flexibility – you can create servers for virtually any tool or service you need Claude to interact with.</p>
<h2 id="heading-alternative-installation-methods">Alternative Installation Methods</h2>
<p>If you want more streamlined approaches for future setups, here are two excellent alternatives:</p>
<h3 id="heading-method-1-direct-package-installation">Method 1: Direct Package Installation</h3>
<p>For MCP servers available as packages, you can install directly:</p>
<pre><code class="lang-bash">pip install mcp-server-package
</code></pre>
<p>Then use this simpler configuration:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"mcpServers"</span>: {
    <span class="hljs-attr">"example-mcp"</span>: {
      <span class="hljs-attr">"command"</span>: <span class="hljs-string">"mcp-server-command"</span>
    }
  }
}
</code></pre>
<p>This method works when the MCP server provides a command-line entry point through its setup configuration.</p>
<h3 id="heading-method-2-using-uv-package-manager">Method 2: Using UV Package Manager</h3>
<p>UV provides more robust dependency management – perfect if you're tired of Python version conflicts:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install UV</span>
curl -LsSf https://astral.sh/uv/install.sh | sh

<span class="hljs-comment"># Use UV in your configuration</span>
{
  <span class="hljs-string">"mcpServers"</span>: {
    <span class="hljs-string">"example-mcp"</span>: {
      <span class="hljs-string">"command"</span>: <span class="hljs-string">"uv"</span>,
      <span class="hljs-string">"args"</span>: [
        <span class="hljs-string">"run"</span>,
        <span class="hljs-string">"--with"</span>, <span class="hljs-string">"fastmcp"</span>,
        <span class="hljs-string">"python"</span>,
        <span class="hljs-string">"/path/to/mcp-server/server.py"</span>
      ],
      <span class="hljs-string">"cwd"</span>: <span class="hljs-string">"/path/to/mcp-server"</span>
    }
  }
}
</code></pre>
<p>UV automatically manages Python versions and dependencies, reducing the likelihood of environment-related errors.</p>
<h2 id="heading-how-to-prevent-future-enoent-errors">How to Prevent Future ENOENT Errors</h2>
<p>To avoid this issue in the future, follow these best practices:</p>
<h3 id="heading-1-use-virtual-environment-copies-instead-of-symlinks">1. Use Virtual Environment Copies Instead of Symlinks</h3>
<p>When creating virtual environments, use the <code>--copies</code> flag:</p>
<pre><code class="lang-bash">python3 -m venv venv --copies
</code></pre>
<p>This creates actual copies of files instead of symlinks, making your environment more resilient to Python upgrades.</p>
<h3 id="heading-2-pin-your-homebrew-python-version">2. Pin Your Homebrew Python Version</h3>
<p>Prevent automatic Python upgrades that break environments:</p>
<pre><code class="lang-bash">brew pin python@3.11
</code></pre>
<p>Remember to unpin when you're ready to upgrade intentionally.</p>
<h3 id="heading-3-create-a-health-check-script">3. Create a Health Check Script</h3>
<p>Save this script as <code>health_check.sh</code> in your MCP server directory:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># health_check.sh</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Checking Python virtual environment..."</span>
<span class="hljs-built_in">source</span> venv/bin/activate

python -c <span class="hljs-string">"import sys; print(f'Python: {sys.executable}')"</span>
python -c <span class="hljs-string">"print('✓ Python is working')"</span>

<span class="hljs-comment"># Check for common MCP dependencies</span>
python -c <span class="hljs-string">"import json; print('✓ JSON module available')"</span>
python -c <span class="hljs-string">"import asyncio; print('✓ Asyncio available')"</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Health check complete!"</span>
</code></pre>
<p>Make it executable and run it periodically:</p>
<pre><code class="lang-bash">chmod +x health_check.sh
./health_check.sh
</code></pre>
<h3 id="heading-4-document-your-python-version">4. Document Your Python Version</h3>
<p>Create a <code>.python-version</code> file in your project:</p>
<pre><code class="lang-bash">python --version &gt; .python-version
</code></pre>
<p>This helps you remember which Python version the project was built with.</p>
<h2 id="heading-troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<p>Even with the fix applied, you might encounter these challenges:</p>
<h3 id="heading-import-errors">Import Errors</h3>
<p>If you see import-related errors, ensure all dependencies are installed:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> venv/bin/activate
pip list  <span class="hljs-comment"># Check installed packages</span>
pip install -r requirements.txt  <span class="hljs-comment"># Reinstall if needed</span>
</code></pre>
<h3 id="heading-permission-denied-errors">Permission Denied Errors</h3>
<p>Make sure your server file is executable:</p>
<pre><code class="lang-bash">chmod +x server.py
</code></pre>
<h3 id="heading-claude-desktop-not-finding-the-server">Claude Desktop Not Finding the Server</h3>
<p>Double-check your configuration paths are absolute, not relative:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Good - absolute path</span>
<span class="hljs-string">"/Users/username/projects/mcp-server/server.py"</span>

<span class="hljs-comment"># Bad - relative path</span>
<span class="hljs-string">"./server.py"</span>
</code></pre>
<h3 id="heading-server-starts-but-claude-cant-connect">Server Starts, But Claude Can't Connect</h3>
<p>Verify that the transport method matches between your server and the configuration. Most MCP servers use STDIO, but some might use HTTP or WebSocket transports.</p>
<h3 id="heading-multiple-python-installations">Multiple Python Installations</h3>
<p>If you have multiple Python versions, be explicit about which one to use:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check available Python versions</span>
ls -la /usr/<span class="hljs-built_in">local</span>/bin/python*

<span class="hljs-comment"># Use a specific version</span>
/usr/<span class="hljs-built_in">local</span>/bin/python3.11 -m venv venv
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You've successfully fixed the "spawn python ENOENT" error by rebuilding your Python virtual environment and properly configuring your MCP server for Claude Desktop. You've also learned how to prevent future mistakes and troubleshoot common issues.</p>
<p>With your MCP server running smoothly, you can now:</p>
<ul>
<li><p>Build custom tools that extend Claude's capabilities</p>
</li>
<li><p>Create integrations with your favorite services</p>
</li>
<li><p>Develop specialized workflows for your specific needs</p>
</li>
<li><p>Share your MCP servers with the community</p>
</li>
</ul>
<p>The <a target="_blank" href="https://www.anthropic.com/news/model-context-protocol">MCP</a> ecosystem is growing rapidly, with new servers and tools being developed constantly. Whether you're building file system tools, API integrations, or custom utilities, you now have the foundation to create and maintain robust MCP servers.</p>
<p>Happy building, and enjoy your error-free development journey! For more tutorials, follow my work on <a target="_blank" href="https://github.com/Olanetsoft">GitHub</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Vyper and Python Smart Contracts on Blockchain Course ]]>
                </title>
                <description>
                    <![CDATA[ If you've ever wanted to develop software that runs on a blockchain, now is the perfect time to learn. Whether you're a complete beginner or an experienced programmer, mastering blockchain development can open doors to exciting opportunities in decen... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/vyper-and-python-smart-contracts-on-blockchain-course/</link>
                <guid isPermaLink="false">67a4d3db2175da95f649ece0</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Tue, 04 Feb 2025 05:00:00 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738855360874/ce0b276f-fc25-4bda-bacf-726d1a8d009d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you've ever wanted to develop software that runs on a blockchain, now is the perfect time to learn. Whether you're a complete beginner or an experienced programmer, mastering blockchain development can open doors to exciting opportunities in decentralized finance (DeFi), NFTs, and algorithmic trading.</p>
<p>We just published a course on the <a target="_blank" href="http://freeCodeCamp.org">freeCodeCamp.org</a> YouTube channel that will teach you how to develop smart contracts and blockchain applications using Python and Vyper—even if you have no prior programming experience. This comprehensive course covers everything from the basics of blockchain to advanced smart contract development. You'll learn to write, deploy, and interact with smart contracts while also gaining proficiency in Python scripting. Plus, you'll discover how to leverage AI tools to accelerate your development process. Patrick Collins developed this course.</p>
<h3 id="heading-what-youll-learn-in-this-course">What You’ll Learn in This Course</h3>
<p>By the end of the course, you will be able to:</p>
<ul>
<li><p>Develop smart contracts using Vyper, a Pythonic smart contract language</p>
</li>
<li><p>Script in Python, even if you start with zero experience</p>
</li>
<li><p>Interact with smart contracts using Python and Vyper</p>
</li>
<li><p>Utilize AI tools to enhance development efficiency</p>
</li>
</ul>
<h3 id="heading-topics-covered">Topics Covered</h3>
<p>This course goes beyond the basics, introducing you to key blockchain concepts and practical applications, including:</p>
<ul>
<li><p>Fuzzing – Testing smart contract security</p>
</li>
<li><p>NFTs – Creating and managing non-fungible tokens</p>
</li>
<li><p>Algorithmic Trading – Building automated trading strategies</p>
</li>
<li><p>AI Integration – Using AI for smart contract development</p>
</li>
<li><p>ERC20 Tokens – Developing and interacting with Ethereum-based tokens</p>
</li>
<li><p>DeFi (Decentralized Finance) – Exploring financial applications on the blockchain</p>
</li>
</ul>
<h3 id="heading-course-breakdown">Course Breakdown</h3>
<p>The course is structured into multiple hands-on sections, including:</p>
<ul>
<li><p>Blockchain Basics – Understanding how blockchain and smart contracts work</p>
</li>
<li><p>Python Crash Course – Learning Python from scratch</p>
</li>
<li><p>Web3 Development with Python – Interacting with blockchain via Web3Py</p>
</li>
<li><p>Smart Contract Deployment and Interactions – Using Vyper, Boa, and Moccasin frameworks</p>
</li>
<li><p>NFTs, ERC20 Tokens, and Stablecoins – Building real-world blockchain applications</p>
</li>
<li><p>Algorithmic Trading and AI in Blockchain – Implementing AI-powered trading strategies</p>
</li>
<li><p>Final Project – Applying skills in a real-world blockchain development challenge</p>
</li>
</ul>
<p>This is one of the most in-depth courses available for learning smart contract development with Python and Vyper. Whether you are an aspiring blockchain developer or just curious about Web3, this course will equip you with the essential skills to get started.</p>
<p>Watch the full course now on the <a target="_blank" href="https://youtu.be/nWsLw_1OpE0">freeCodeCamp.org YouTube channel</a> and begin your journey into blockchain development.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/nWsLw_1OpE0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Web3.js Basics – Ethereum Development for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ By Oluwatise Okuwobi Ethereum is one of the major pioneers in the decentralized ecosystem. And Web3.js is an essential tool if you're working on Ethereum-based projects.  To fully understand why this tool is important, we must first take a deeper div... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-web3js-basics/</link>
                <guid isPermaLink="false">66d4608cd1ffc3d3eb89de38</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ethereum ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 27 Nov 2023 22:39:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/11/Learn-Web3.js-Basics---Ethereum-Development.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Oluwatise Okuwobi</p>
<p>Ethereum is one of the major pioneers in the decentralized ecosystem. And Web3.js is an essential tool if you're working on Ethereum-based projects. </p>
<p>To fully understand why this tool is important, we must first take a deeper dive into Ethereum development.</p>
<p>Grab your coffee, young Web3 enthusiast. We're going on a journey that will change your Web3 career forever.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you can carry on with this tutorial, you'll need to understand the basics of JavaScript, and should be able to install npm packages. </p>
<p>If you've worked with JavaScript before, the rest of this tutorial should be a breeze. </p>
<h2 id="heading-what-is-ethereum-development">What is Ethereum Development?</h2>
<p>Ethereum is a decentralized open-source blockchain platform that lets developers build decentralized applications, popularly known as dAPPs. These dApps are built on top of the Ethereum blockchain, harnessing some of the core features of the Ethereum network. </p>
<p>Ethereum is written in Solidity, which is the primary programming language used in the Ethereum ecosystem. You can use Solidity to design smart contracts, which are basically self-executing contracts that power a lot of dApps.</p>
<p>If you want to work in Ethereum development, understanding smart contracts is extremely important. </p>
<p>Smart contracts consist of the terms of the agreement between buyer and seller that are directly written into the lines of code. This code is written in Solidity, which can only exist in the blockchain network.</p>
<p>To become an Ethereum developer, you are going to work mainly around the network, building smart contracts and dApps. </p>
<p>Let's talk about the tools you are going to need:</p>
<ul>
<li>Solidity</li>
<li>Ether.js</li>
<li>JavaScript/React for front-end visual interaction</li>
</ul>
<h2 id="heading-the-world-of-web3js">The World of Web3.js</h2>
<p>Now that you have an idea of what Ethereum development is, we can begin to understand Web3.js a little better. </p>
<p>Web3.js is a collection of libraries that allow you to interact with a local or remote Ethereum node, using HTTP, IPC, or Web Sockets (which is my personal favorite). It is written in JavaScript, and to put it simply, it lets you interact with the blockchain more efficiently.</p>
<p>By reading data from the blockchain, you will be able to make transactions and deploy smart contracts live on the mainnet.</p>
<h2 id="heading-how-to-set-up-web3js">How to Set Up Web3.js</h2>
<p>Web3.js can access blockchain information from both the back end and front end to make transactions and deploy smart contracts. </p>
<p>You are going to need Node.js, which you can easily <a target="_blank" href="https://nodejs.org/en/">download from the official website</a>. The installation process is pretty straightforward. </p>
<p>After you've successfully installed Node and npm (the official package manager for Node), open your command line in the root folder of your project and type the following command:</p>
<pre><code class="lang-javascript">npm install web3 --save
</code></pre>
<p>Then you'll be able to import Web3.js into a Node script using this simple code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Web3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">"web3"</span>)
</code></pre>
<p>We've got some of the hard part locked down. Now we just need our project to communicate directly with the blockchain. </p>
<p>To initiate our Web3 provider, we must instantiate, which just means creating a Web3 instance, and pass a constructor to the URL of the provider. </p>
<p>In this case, we'll have to find an Ethereum node that we can connect to and start crafting magic. </p>
<p>There are multiple node providers like Alchemy, Chainstack, and Moralis, and there's a lot of documentation when it comes to getting a direct access.</p>
<p>You can make use of the Ganache instance as well, which will essentially help you set up the environment for anything you need to work in your local environment.</p>
<p>To understand <a target="_blank" href="https://medium.com/coinmonks/get-started-with-building-ethereum-dapps-and-smart-contracts-d86b9f7bd1c">how to set up Ganache</a>, you can read the linked guide that covers everything you need to know.</p>
<p>You simply place this below your code like so:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Web3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">"web3"</span>)
<span class="hljs-keyword">const</span> web3 = <span class="hljs-keyword">new</span> Web3(<span class="hljs-string">"http://localhost:8545"</span>)
</code></pre>
<p>To test that you have successfully configured everything, you can write some simple code to get the latest block number on the blockchain:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> Web3 = <span class="hljs-built_in">require</span>(<span class="hljs-string">"web3"</span>)
<span class="hljs-keyword">const</span> web3 = <span class="hljs-keyword">new</span> Web3(<span class="hljs-string">"http://localhost:8545"</span><span class="hljs-string">")

web3.eth.getBlockNumber(function (error, result) {
  console.log(result)
})</span>
</code></pre>
<p>This function simply accepts a callback as a parameter, then prints the result as an integer. Running this would just give you a block number on your console. </p>
<p>There are many other functions you can use. The web3 <a target="_blank" href="https://docs.web3js.org/">official documentation</a> provides a comprehensive list of functions that you can learn about and try out.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If you're wanting to get into Ethereum development, Web3.js will be a vital part of your stack. Throughout your journey, you are going to be interacting with the Ethereum node more frequently and Web3.js will come in handy.</p>
<p>There are other alternatives like Ether.js, which also strive to provide a complete library that can interact with the Ethereum node. But Web3 is known to have a larger network of support, a larger community of developers, and more mature documentation that you can refer to regarding problems of any sort.</p>
<p>Hopefully this article has given all of the insights you need for you to start your Ethereum journey. I'm available on <a target="_blank" href="https://www.twitter.com/tiseysoft">Twitter</a>, if you have any questions.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Introducing the Solana Curriculum: Smart Contracts, dApps, and Command Line Tools ]]>
                </title>
                <description>
                    <![CDATA[ The Solana Curriculum is live. You can now learn Solana's blockchain protocol and the Solana tool ecosystem interactively by building a series of projects. This curriculum is made possible by The Solana Foundation, who gave our charity a grant to 100... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solana-curriculum/</link>
                <guid isPermaLink="false">66b0aa4a72aed240a79b249f</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Solana ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tom Mondloch ]]>
                </dc:creator>
                <pubDate>Fri, 15 Sep 2023 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/arturo-castaneyra-7laIG_Xv5FI-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Solana Curriculum is live. You can now learn Solana's blockchain protocol and the Solana tool ecosystem interactively by building a series of projects.</p>
<p>This curriculum is made possible by The Solana Foundation, who gave our charity a grant to 100% fund development of this curriculum.</p>
<h2 id="heading-what-will-this-curriculum-teach-you">What will this curriculum teach you?</h2>
<p>The Solana curriculum contains ten interactive practice projects that will guide you through learning the Solana protocol and their tools.</p>
<p>Through these projects, you will learn how to build and deploy smart contracts, dApps, work with their command line tools, and much more.</p>
<p>There are also five challenging integrated projects to test your knowledge.</p>
<h2 id="heading-how-does-it-work">How does it work?</h2>
<p>The courses will run in a docker container using VS Code and the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=freeCodeCamp.freecodecamp-courses">freeCodeCamp Courses extension.</a></p>
<h3 id="heading-heres-a-sample">Here's a Sample</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/N7r8ja0QEr4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-which-projects-will-you-build-as-part-of-the-solana-curriculum">Which Projects Will You Build as Part of the Solana Curriculum?</h2>
<p>These projects consist of two interactive practice projects and one integrated project. Here are the projects:</p>
<ol>
<li>Learn How to Set Up Solana by Building a Hello World Smart Contract</li>
<li>Learn How to Interact with On-Chain Programs</li>
<li>Build a Smart Contract</li>
<li>Learn Solana's Token Program by Minting a Fungible Token</li>
<li>Learn the Metaplex SDK by Minting an NFT</li>
<li>Build a University Certification NFT</li>
<li>Learn Anchor by Building Tic-Tac-Toe: Part 1</li>
<li>Learn Anchor by Building Tic-Tac-Toe: Part 2</li>
<li>Build an Anchor Leaderboard</li>
<li>Learn How to Build a Client-Side App: Part 1</li>
<li>Learn How to Build a Client-Side App: Part 2</li>
<li>Build a Client-Side App</li>
<li>Learn How to Build for Mainnet</li>
<li>Learn How to Deploy to Devnet</li>
<li>Build and Deploy Your Freeform App</li>
</ol>
<h2 id="heading-how-to-run-the-courses">How to Run the Courses</h2>
<p>Follow the steps below to run the courses</p>
<h3 id="heading-developer-environment-prerequisites">Developer Environment Prerequisites</h3>
<p>Before you get started, make sure you have these installed on your computer:</p>
<ol>
<li><a target="_blank" href="https://docs.docker.com/engine/">Docker Engine</a></li>
<li><a target="_blank" href="https://code.visualstudio.com/download">VS Code</a> and the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers">Dev Containers</a> extension</li>
<li>Git</li>
</ol>
<h3 id="heading-how-to-run-the-curriculum-in-docker">How to Run the Curriculum in Docker</h3>
<p>Follow these instructions to clone the repo and run the courses:</p>
<ol>
<li>Open a terminal and clone the <a target="_blank" href="https://github.com/freeCodeCamp/solana-curriculum">solana-curriculum</a> repo with:<pre><code class="lang-console">git clone https://github.com/freeCodeCamp/solana-curriculum.git
</code></pre>
</li>
<li><p>Navigate to the <code>solana-curriculum</code> directory, and open it in a VSCode workspace with:</p>
<pre><code class="lang-console">code .
</code></pre>
</li>
<li><p>Press <code>Ctrl / Cmd + Shift + P</code> to open the command palette, and run <code>Dev Containers: Rebuild Container and Reopen in Container</code>. VS Code will build the container to run the projects in, it will take a few minutes the first time.</p>
</li>
<li>Once it's finished, press <code>Ctrl / Cmd + Shift + P</code> again and run <code>freeCodeCamp: Run Course</code> to start the courses. This will also take a moment.</li>
<li>The simple browser will open when it's done. If it's a blank white page, use the refresh button to update it and see the courses home page.</li>
<li>Click on one of the available projects to start a project.</li>
<li>Follow the instructions to complete the project.</li>
<li>Have fun!</li>
</ol>
<p>If you want to switch projects, click the freeCodeCamp logo at the top to get back to the home page.</p>
<h2 id="heading-freecodecamp-also-offers-a-more-general-web3-course-that-covers-blockchain-fundamentals">freeCodeCamp Also Offers a More General Web3 Course that Covers Blockchain Fundamentals</h2>
<p>While you are waiting for these courses, you can <a target="_blank" href="https://www.freecodecamp.org/news/web3-curriculum-open-beta">try the Web3 curriculum</a>  which is now in open beta. It will teach you many Web3 and blockchain concepts you will want to know for the Solana curriculum.</p>
<h2 id="heading-where-you-can-learn-more-about-the-solana-foundation">Where you can Learn more about the Solana Foundation</h2>
<p>You can learn more about <a target="_blank" href="https://solana.org/">The Solana Foundation</a> on their website.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Hack Summit 2023 – Developer Conference Focused on Blockchain Development ]]>
                </title>
                <description>
                    <![CDATA[ Hack Summit is one of the largest online developer conferences in history. Across its 5 events over the past decade, more than 130,000 developers have attended. And this year's event should be no different – filled with opportunities to learn from sp... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/hack-summit-2023-developer-conference-focused-on-blockchain-development/</link>
                <guid isPermaLink="false">66b8d38080f2fbfc1b20bbe2</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ conference ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Tue, 14 Mar 2023 08:03:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/hacksummit_fcc.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hack Summit is one of the largest online developer conferences in history. Across its 5 events over the past decade, more than 130,000 developers have attended.</p>
<p>And this year's event should be no different – filled with opportunities to learn from speakers and expand your professional network.</p>
<p>This year, the event is focused on Blockchain Development. It will feature talks on beginner and intermediate topics.</p>
<p>Tickets are free if you use the code "FCC". All proceeds from the conference will go to support 4 partner organizations – one of which is freeCodeCamp.</p>
<p>The 2-day event will take place on March 31 from 9 a.m. to 5 p.m. , and April 1 from 9 a.m. to 2 p.m.</p>
<p>The event will feature both Ethereum founder Vitalik Buterin, and US Securities &amp; Exchange Commissioner Hester Peirce.</p>
<p>It will also feature speakers from several major in the blockchain networks:</p>
<ul>
<li>Solana</li>
<li>Near</li>
<li>Polygon</li>
<li>Maple Finance</li>
<li>Aave</li>
<li>Mysten Labs</li>
<li>Eigenlayer</li>
<li>Cega</li>
<li>Gelato</li>
<li>Starkware</li>
<li>Across</li>
<li>and many more</li>
</ul>
<p>You can sign up at <a target="_blank" href="https://www.hacksummit.org">https://www.hacksummit.org</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Decentralized Identity – Build a Profile with Next.js, Ethereum & Ceramic Network ]]>
                </title>
                <description>
                    <![CDATA[ Long-standing centralized intermediaries, like the government or big companies, are the ones who make and keep your ID information in traditional systems that manage who you are.  But this implies that you have no control over the information relatin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/decentralized-identity-build-a-profile-with-ethereum-ceramic-and-reactjs/</link>
                <guid isPermaLink="false">66b905ce5730a049b6bfea7d</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ decentralization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ethereum ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Idris Olubisi ]]>
                </dc:creator>
                <pubDate>Fri, 17 Feb 2023 22:44:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/Decentralized-Identity--Build-a-Profile-with-NextJs--Ethereum---Ceramic-Network.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Long-standing centralized intermediaries, like the government or big companies, are the ones who make and keep your ID information in traditional systems that manage who you are. </p>
<p>But this implies that you have no control over the information relating to your identification, who has access to <a target="_blank" href="https://www.dol.gov/general/ppii#:~:text=Personal%20Identifiable%20Information%20(PII)%20is,either%20direct%20or%20indirect%20means.">personally identifiable information (PII)</a>, and to what extent.</p>
<p>As a result, Decentralized Identity provides identity-related information that is self-controlled, private, and portable. Decentralized identifiers and attestations serve as the main building pieces. </p>
<p>Thanks to Ceramic's decentralized application databases, application developers can reuse data across applications and automatically make them interoperable.</p>
<p>In this article, you will learn about Decentralized Identity, Decentralized Identifiers, Ceramic network, and how to build a decentralized identity profile with Ethereum on Ceramic Networks.</p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ul>
<li>What is a Decentralized Identity?</li>
<li>What are Decentralized Identifiers?</li>
<li>What is Ceramic Data Network?</li>
<li>Why Ceramic Network?</li>
<li>How to Build a Decentralized Identity Profile with Next.js</li>
<li>Prerequisites</li>
<li>Project Setup and Installation</li>
<li>Install TailwindCSS in Next.js</li>
<li>Authenticate Users</li>
<li>Create/Update User Profile</li>
<li>How to Test the Application</li>
<li>Conclusion</li>
<li>References</li>
</ul>
<h2 id="heading-what-is-a-decentralized-identity">What is a Decentralized Identity?</h2>
<p><a target="_blank" href="https://ethereum.org/en/decentralized-identity/">Decentralized Identity</a> is a digital identification concept where people, companies, and items are in charge of their data and can share it selectively without relying on a centralized authority. </p>
<p>This is made possible by using decentralized technologies, such as blockchain. These give people control and ownership over the information associated with their identities rather than having it stored on a central server or managed by a third party.</p>
<p>A decentralized identity is a self-owned, independent identity that enables trusted data exchange.</p>
<p>Blockchain-based digital wallets, such as those used to store and handle cryptocurrencies, serve as a practical illustration of decentralized identification. Users of these wallets control the private keys that provide them access to their money and can distribute their public keys to others to accept payments from them.</p>
<p>Users who manage their private keys can conduct transactions with others without relying on a central authority, such as a bank, and keep custody of their money.</p>
<h2 id="heading-what-are-decentralized-identifiers">What are Decentralized Identifiers?</h2>
<p>Decentralized identifiers (DIDs) are issued, held, and controlled by individuals. Since they are kept on peer-to-peer networks or distributed ledgers (blockchains), they are globally unique, highly available, and cryptographically verifiable. </p>
<p>Decentralized identifiers can be associated with individuals, groups, or governmental entities.</p>
<p>DIDs are a vital component of the developing decentralized identity ecosystem. They are designed to offer a uniform process for developing, maintaining, and exchanging digital identities unaffiliated with any one company or piece of technology. </p>
<p>This implies that a DID can be maintained and controlled by the person or entity to which it belongs and utilized across various systems and applications.</p>
<p>In recent years, smart contract platforms like Ethereum have demonstrated the utility of decentralized applications (dApps) that can be assembled like blocks to create new applications. This is especially evident in tokens that build upon one another, in DeFi protocols that use one another, and so on.</p>
<p>Thanks to Ceramic, data on the internet can now have the same kind of composability. Any data type, including profiles, social connections, blog posts, identities, reputations, and so on., can be included. You will learn more about Ceramic Network in the section below.</p>
<h2 id="heading-what-is-ceramic-network">What is Ceramic Network?</h2>
<p><a target="_blank" href="https://ceramic.network/">Ceramic</a> is a public, permissionless, open-source protocol that offers computation, state transitions, and consensus for all data structures on the decentralized web. </p>
<p>With the help of stream processing provided by Ceramic, developers can build apps that are strong, safe, trustless, and censorship-resistant using dynamic information – without using unreliable database servers.</p>
<p>Ceramic stores all content in smart documents, which are append-only IPFS logs. Before being anchored in a blockchain for consensus, each commit is verified by a decentralized identification (DID).</p>
<p>All papers in Ceramic are openly discoverable and can be referenced by other documents or queried by any other network user because the system is entirely peer-to-peer.</p>
<h2 id="heading-why-ceramic-network">Why Ceramic Network?</h2>
<p>Data interoperability is one of Ceramic Network's key benefits. This platform features a flexible and modular data schema that enables the decentralized and interoperable sharing and combining of various sorts of data. </p>
<p>Developers now have an easier time creating decentralized identification solutions that can be integrated with other programs and systems.</p>
<p>The infrastructure of Ceramic Network is scalable, fault-tolerant, decentralized, and highly available. This enables developers to create robust decentralized identity systems available to users everywhere.</p>
<p>Ceramic Network also provides a set of developer tools and libraries, making it simple to create decentralized identity apps and services. These tools include SDKs, APIs, developer guides, and an expanding ecosystem of open-source tools and libraries.</p>
<p>Now that you have learnt the theories behind decentralized identity, let's take a practical deep dive and get your hands dirty.</p>
<h2 id="heading-how-to-build-a-decentralized-identity-profile-with-nextjs">How to Build a Decentralized Identity Profile with Next.js</h2>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>To go through this tutorial, you'll need some experience with JavaScript and React.js. Experience with Next.js isn't a requirement, but it's nice to have.</p>
<p>Make sure to have Node.js or npm installed on your computer. If you don't, click <a target="_blank" href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm"><strong>here</strong></a>.</p>
<p>Also, it'll be very useful to have a basic understanding of blockchain technology and Web3 concepts.</p>
<h3 id="heading-project-setup-and-installation">Project Setup and Installation</h3>
<p>Navigate to the terminal and <code>cd</code> into any directory of your choice. Then run the following commands:</p>
<pre><code class="lang-bash">mkdir decentralized-identity-project
<span class="hljs-built_in">cd</span> decentralized-identity-project
npx create-next-app@latest .
</code></pre>
<p>Accept the following options:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676416198416/0b46fd0f-d47a-4533-9450-a79007205efe.png" alt="Image" width="611" height="71" loading="lazy"></p>
<p>Install the <code>@self.id/react</code> and <code>@self.id/web</code> packages using the code snippet below:</p>
<pre><code class="lang-bash">npm install @self.id/web @self.id/react
</code></pre>
<p>Next, start the app using the following command:</p>
<pre><code class="lang-bash">npm run dev
</code></pre>
<p>You should have something similar to what is shown below: the default boilerplate layout for Next.js 13.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676416289117/799cfc73-78b3-49f9-8b72-a407813f7d9c.png" alt="Image" width="1292" height="884" loading="lazy"></p>
<h3 id="heading-install-tailwindcss-in-nextjs">Install TailwindCSS in Next.js</h3>
<p>In this section, you will set up Tailwind CSS in a Next.js project. Install <code>tailwindcss</code> and its peer dependencies via npm, and then run the init command to generate both <code>tailwind.config.js</code> and <code>postcss.config.js</code>.</p>
<pre><code class="lang-bash">npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
</code></pre>
<p>Navigate to the <code>tailwind.config.js</code> file, and add the paths to your template files with the following code snippet.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('tailwindcss').Config}</span> </span>*/</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [
    <span class="hljs-string">"./app/**/*.{js,ts,jsx,tsx}"</span>,
    <span class="hljs-string">"./pages/**/*.{js,ts,jsx,tsx}"</span>,
    <span class="hljs-string">"./components/**/*.{js,ts,jsx,tsx}"</span>,

    <span class="hljs-comment">// Or if using `src` directory:</span>
    <span class="hljs-string">"./src/**/*.{js,ts,jsx,tsx}"</span>,
  ],
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {},
  },
  <span class="hljs-attr">plugins</span>: [],
}
</code></pre>
<p>Delete all the CSS styles inside <code>globals.css</code> . Add the <code>@tailwind</code> directives for each of Tailwind’s layers to your <code>globals.css</code> file.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;
</code></pre>
<h3 id="heading-configure-the-provider-component">Configure the Provider Component</h3>
<p>The <code>Provider</code> component must be placed at the top of the application tree to use the hooks detailed below. You can use it to supply an initial state as well as a specific configuration for the <a target="_blank" href="http://Self.ID">Self.ID</a> clients and queries.</p>
<p>Update the <code>_app.js</code> file under the pages folder with the following code snippet:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Import the Provider component from the "@self.id/react" library.</span>
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"@self.id/react"</span>;

<span class="hljs-comment">// Import the "globals.css" file from the "@/styles" directory.</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"@/styles/globals.css"</span>;

<span class="hljs-comment">// Define the App component as a default export.</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params">{ Component, pageProps }</span>) </span>{

  <span class="hljs-comment">// Render the Provider component, which provides authentication and authorization functionality to the application.</span>
  <span class="hljs-comment">// Pass a client prop to the Provider component, which configures the Ceramic testnet with the "testnet-clay" value.</span>
  <span class="hljs-comment">// Render the Component with its props inside the Provider component, which allows the application to access the authentication and authorization context.</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">ceramic:</span> "<span class="hljs-attr">testnet-clay</span>" }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Component</span> {<span class="hljs-attr">...pageProps</span>} /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
}
</code></pre>
<p>In the code snippet above, we:</p>
<ul>
<li>Imported a context provider component and global CSS styles and then defined an <code>App</code> component that wraps the entire application with the context provider.</li>
<li>Configured the context provider with a Ceramic testnet client, which allows the application to access authentication and authorization functionality.</li>
<li>Finally, the <code>Component</code> is rendered with its props inside the context provider, allowing the application to access the authentication and authorization context.</li>
</ul>
<h3 id="heading-build-the-layout">Build the Layout</h3>
<p>Next, navigate to the <code>index.js</code> file under the <code>pages</code> folder and update it with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Import the Head component from the "next/head" module.</span>
<span class="hljs-keyword">import</span> Head <span class="hljs-keyword">from</span> <span class="hljs-string">"next/head"</span>;

<span class="hljs-comment">// Import the useViewerConnection and useViewerRecord hooks from the "@self.id/react" library.</span>
<span class="hljs-keyword">import</span> { useViewerConnection, useViewerRecord } <span class="hljs-keyword">from</span> <span class="hljs-string">"@self.id/react"</span>;

<span class="hljs-comment">// Import the EthereumAuthProvider component from the "@self.id/web" library.</span>
<span class="hljs-keyword">import</span> { EthereumAuthProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">"@self.id/web"</span>;

<span class="hljs-comment">// Import the useState hook from the "react" module.</span>
<span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;


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

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>
          Decentralized Identity: Build a Profile with NextJs, Ethereum &amp; Ceramic Network
        <span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Generated by create next app"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"icon"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/favicon.ico"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Head</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"min-h-screen bg-gray-200"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gray-600 py-4 px-4 sm:px-6 lg:px-8 lg:py-6 shadow-lg text-white"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container mx-auto px-6 md:px-0"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-2xl font-bold text-white text-center"</span>&gt;</span>
              Decentralized Identity: Build a Profile with NextJs, Ethereum &amp; Ceramic Network
            <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center justify-center pt-20 font-sans overflow-hidden"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-md w-full mx-auto"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-white p-10 rounded-lg shadow-lg"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mb-6"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"block text-gray-700 font-bold mb-2"</span>
                    <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"name"</span>
                  &gt;</span>
                    Name
                  <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"border border-gray-300 p-2 w-full rounded-lg"</span>
                    <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
                    <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span>
                    <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span>
                    <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Your name"</span>
                  /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mb-6"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"block text-gray-700 font-bold mb-2"</span>
                    <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"bio"</span>
                  &gt;</span>
                    Bio
                  <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"border border-gray-300 p-2 w-full rounded-lg"</span>
                    <span class="hljs-attr">name</span>=<span class="hljs-string">"bio"</span>
                    <span class="hljs-attr">id</span>=<span class="hljs-string">"bio"</span>
                    <span class="hljs-attr">rows</span>=<span class="hljs-string">"5"</span>
                    <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Write something about yourself"</span>
                  &gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mb-6"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"block text-gray-700 font-bold mb-2"</span>
                    <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"username"</span>
                  &gt;</span>
                    Username
                  <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"border border-gray-300 p-2 w-full rounded-lg"</span>
                    <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
                    <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span>
                    <span class="hljs-attr">id</span>=<span class="hljs-string">"username"</span>
                    <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Your username"</span>
                  /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center justify-between"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"</span>
                    <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>
                  &gt;</span>
                    Update Profile
                  <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
                    <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"</span>
                    <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
                  &gt;</span>
                    Connect Wallet
                  <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<p>To start the application, run the following command and navigate to localhost:3000 on your browser; you should have something similar to what is shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676418666618/bc0620d9-d7bb-4297-bdb1-6021d08d8d6c.png" alt="Image" width="1544" height="1060" loading="lazy"></p>
<h3 id="heading-how-to-authenticate-users">How to Authenticate Users</h3>
<p>In this section, you will implement user authentication to allow users to connect their wallets and interact with the application.</p>
<p>Update the <code>index.js</code> with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//..</span>

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

  <span class="hljs-comment">// State variables for connection, connect function, and disconnect function</span>
  <span class="hljs-keyword">const</span> [connection, connect, disconnect] = useViewerConnection();


  <span class="hljs-keyword">const</span> [isWindow, setIsWindow] = useState(<span class="hljs-literal">null</span>);


  <span class="hljs-comment">// State variable for viewer's basic profile data</span>
  <span class="hljs-keyword">const</span> record = useViewerRecord(<span class="hljs-string">"basicProfile"</span>);

  <span class="hljs-comment">// Function to create EthereumAuthProvider using window.ethereum provider</span>
  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createAuthProvider</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> addresses = <span class="hljs-keyword">await</span> <span class="hljs-built_in">window</span>.ethereum.request({
      <span class="hljs-attr">method</span>: <span class="hljs-string">"eth_requestAccounts"</span>,
    });
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> EthereumAuthProvider(<span class="hljs-built_in">window</span>.ethereum, addresses[<span class="hljs-number">0</span>]);
  }

  <span class="hljs-comment">// Function to connect to viewer's account using created authProvider</span>
  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">connectAccount</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> authProvider = <span class="hljs-keyword">await</span> createAuthProvider();
    <span class="hljs-keyword">await</span> connect(authProvider);
  }

  <span class="hljs-comment">// Rendered JSX code</span>
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      {/* ... */}
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center justify-between"</span>&gt;</span>
        {/* ... */}

        {/* Conditionally render a button to connect/disconnect user */}
        {connection.status === "connected" ? (
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> disconnect()}
          &gt;
            Disconnect
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        ) : isWindow &amp;&amp; "ethereum" in window ? (
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded"</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
            <span class="hljs-attr">disabled</span>=<span class="hljs-string">{connection.status</span> === <span class="hljs-string">"connecting"</span> || !<span class="hljs-attr">record</span>}
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> {
              connectAccount();
            }}
          &gt;
            Connect Wallet
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        ) : (
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-red-500 text-sm italic mt-2 text-center w-full"</span>&gt;</span>
            An injected Ethereum provider such as{" "}
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://metamask.io/"</span>&gt;</span>MetaMask<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> is needed to
            authenticate.
          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        )}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  )
}
</code></pre>
<p>In the code snippet above,</p>
<ul>
<li>The <code>useViewerConnection</code> hook is used to set up a state variable for the user's connection status, connect and disconnect.</li>
<li><code>isWindow</code> to set the initial state of the the window to avoid <a target="_blank" href="https://nextjs.org/docs/messages/react-hydration-error">React hydration error</a></li>
<li>The <code>useViewerRecord</code> hook is used to retrieve the user's basic profile data.</li>
<li>The <code>createAuthProvider</code> function creates an <code>EthereumAuthProvider</code> object using the <code>window.ethereum</code> provider.</li>
<li>The <code>connectAccount</code> function calls <code>createAuthProvider</code> and connects to the user's account using <code>connect(authProvider)</code>.</li>
<li>The JSX code conditionally renders a button based on the user's connection status and the availability of an <code>ethereum</code> provider in the <code>window</code> object.</li>
<li>If the user is already connected, the button will enable them to disconnect. If the user is not yet connected and an <code>ethereum</code> provider is available, the button will enable them to connect. But if the user is not connected and no <code>ethereum</code> provider is available, a message will be displayed to inform the user that an injected Ethereum provider like MetaMask is required to authenticate.</li>
</ul>
<p>Testing out the authentication functionality, you should have something similar to what is shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676467487656/bc91509c-cd69-479a-80e5-7bc9b680150d.png" alt="Image" width="1561" height="695" loading="lazy"></p>
<h3 id="heading-how-to-create-or-update-a-user-profile">How to Create or Update a User Profile</h3>
<p>In the previous section, you learned how to successfully authenticate users. Next, you will implement functionality to create and update an authenticated user with the following code snippet:</p>
<p><code>pages/index.js</code></p>
<pre><code class="lang-javascript"><span class="hljs-comment">//...</span>


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-comment">// Use the useState hook to create state variables and functions to update them</span>
  <span class="hljs-keyword">const</span> [name, setName] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [bio, setBio] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [username, setUsername] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-comment">//...</span>

<span class="hljs-comment">// Define an asynchronous function called updateProfile to update the profile information</span>
  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateProfile</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// If any of the required fields are empty, return early and do not update</span>
     <span class="hljs-keyword">if</span> (!name || !bio || !username) {
       <span class="hljs-keyword">return</span>;
     }

     <span class="hljs-comment">// Use the merge method to update the record with the new information</span>
     <span class="hljs-keyword">await</span> record.merge({
       name,
       bio,
       username,
     });
   }

  <span class="hljs-comment">// Render the component's UI</span>
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>

    {/* ... */}

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center justify-center pt-20 font-sans overflow-hidden"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-md w-full mx-auto"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-white p-10 rounded-lg shadow-lg"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
               {/* ... */}
              <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            {connection.status === "connected" &amp;&amp; record &amp;&amp; record.content ? (
              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col items-center mt-8"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl font-bold mb-6 text-gray-900"</span>&gt;</span>
                  Profile Information
                <span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"w-full max-w-md bg-white p-8 rounded-lg shadow-lg"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mb-4"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold text-gray-700 mr-2 text-lg"</span>&gt;</span>
                      Name:
                    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>{" "}
                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"nameOutput"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-lg"</span>&gt;</span>
                      {record.content.name || "No name set"}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mb-4"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold text-gray-700 mr-2 text-lg"</span>&gt;</span>
                      Bio:
                    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>{" "}
                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"bioOutput"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-lg"</span>&gt;</span>
                      {record.content.bio || "No bio set"}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold text-gray-700 mr-2 text-lg"</span>&gt;</span>
                      Username:
                    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>{" "}
                    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"usernameOutput"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-lg"</span>&gt;</span>
                      {record.content.username || "No username set"}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
                  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            ) : (
              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mt-8"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-white p-8 rounded-lg shadow-lg"</span>&gt;</span>
                  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>No profile found.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
            )}

          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  ) 
}
</code></pre>
<p>In the code above,</p>
<ul>
<li>The component uses the useState hook to manage the state of three variables: <code>name</code>, <code>bio</code>, and <code>username</code>.</li>
<li>There's an async function called <code>updateProfile</code> that is responsible for merging the current state of the variables into a record.</li>
<li>If any of the variables is empty, the <code>updateProfile</code> function returns without updating the record.</li>
<li>There are three conditional statements that render a different UI based on whether a record is found or not.</li>
<li>The first conditional statement checks whether the record is still loading, and if it is, it displays a <code>Loading...</code> message.</li>
<li>The second conditional statement checks whether there's no record content and the connection status is connected. If this is true, it displays a <code>No profile found.</code> message.</li>
</ul>
<p>The third conditional statement checks whether the record content exists. If it does, it displays the profile information, which includes the user's <code>name</code>, <code>bio</code>, and <code>username</code>.</p>
<p>You are almost there. In the form tag, update the <code>name</code>, <code>bio</code> and <code>username</code> input field with the following code:</p>
<pre><code class="lang-javascript">&lt;div className=<span class="hljs-string">"mb-6"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span>
    <span class="hljs-attr">className</span>=<span class="hljs-string">"block text-gray-700 font-bold mb-2"</span>
    <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"name"</span>
  &gt;</span>
    Name
  <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span></span>
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span>
    //<span class="hljs-attr">...</span>
    <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
      setName(e.target.value);
    }}
  /&gt;</span>
&lt;/div&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mb-6"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
    <span class="hljs-attr">className</span>=<span class="hljs-string">"block text-gray-700 font-bold mb-2"</span>
    <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"bio"</span>
  &gt;</span>
    Bio
  <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span>
    //<span class="hljs-attr">...</span>
    <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
      setBio(e.target.value);
    }}
  &gt;<span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mb-6"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span>
    <span class="hljs-attr">className</span>=<span class="hljs-string">"block text-gray-700 font-bold mb-2"</span>
    <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"username"</span>
  &gt;</span>
    Username
  <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
    //<span class="hljs-attr">...</span>
    <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
      setUsername(e.target.value);
    }}
  /&gt;
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>In the code snippet above, <code>setName</code>, <code>setBio</code>, and <code>setUsername</code> are functions provided by the <code>useState</code> hook that update the state of <code>name</code>, <code>bio</code>, or <code>username</code>.</p>
<p>Next, the <code>Update Profile</code> button.</p>
<pre><code class="lang-xml">//...

 <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
     <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"</span>
     <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>
     <span class="hljs-attr">disabled</span>=<span class="hljs-string">{!record.isMutable</span> || <span class="hljs-attr">record.isMutating</span>}
     <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> updateProfile()}
 &gt;
    {record.isMutating ? "Updating..." : "Update Profile"}
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

//..
</code></pre>
<p>In the code snippet above, the button is disabled when the record is not mutable or is currently mutating. </p>
<p>When the button is clicked, it calls the <code>updateProfile</code> function, which is responsible for updating the user's profile information. If the record mutates, the button will display <code>Updating...</code>. Otherwise, it will display <code>Update Profile</code>.</p>
<p>You can test out the application similar to what is shown below.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.loom.com/share/f2103bcb44c949f7bfdbd5cb531b0c71">https://www.loom.com/share/f2103bcb44c949f7bfdbd5cb531b0c71</a></div>
<p>Kindly find the complete code on <a target="_blank" href="https://github.com/Olanetsoft/decentralized-identity-project">GitHub repository here</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this post, you learn about Decentralized Identity, Decentralized Identifiers, Ceramic networks, why Ceramic network is useful, and how to build a decentralized identity profile with Ethereum on Ceramic Networks.</p>
<h3 id="heading-references">References</h3>
<ul>
<li><a target="_blank" href="https://github.com/ceramicnetwork/ceramic">Ceramic Network</a></li>
<li><a target="_blank" href="https://developers.ceramic.network/reference/">Ceramic Documentation</a></li>
<li><a target="_blank" href="https://ethereum.org/en/decentralized-identity/">Decentralized Identity - Ethereum</a></li>
</ul>
<p>I'd love to connect with you at <a target="_blank" href="https://twitter.com/olanetsoft"><strong>Twitter</strong></a> | <a target="_blank" href="https://www.linkedin.com/in/olubisi-idris-ayinde-05727b17a/"><strong>LinkedIn</strong></a> | <a target="_blank" href="https://github.com/Olanetsoft"><strong>GitHub</strong></a> | <a target="_blank" href="https://idrisolubisi.com/"><strong>Portfolio</strong></a></p>
<p>See you in my next article. Take care!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Switch Blockchains on MetaMask with JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ With over 10,000 blockchains currently operating, there are endless possibilities for deploying your smart contracts. For anybody to be able to use your Decentralized Application (DApp), they need to be connected to the blockchain where you've deploy... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-switch-blockchains-on-metamask-with-javascript/</link>
                <guid isPermaLink="false">66d45f653a8352b6c5a2aa9a</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Joshua Omobola ]]>
                </dc:creator>
                <pubDate>Thu, 26 Jan 2023 23:15:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/Custom-Network--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>With over 10,000 blockchains currently operating, there are endless possibilities for deploying your smart contracts.</p>
<p>For anybody to be able to use your Decentralized Application (DApp), they need to be connected to the blockchain where you've deployed your smart contract.</p>
<p>This article will show you how to prompt your users to switch to your preferred blockchain using JavaScript.</p>
<p>This guide requires that you have the MetaMask extension installed. Also, I assume you have a little bit of experience connecting with MetaMask—perhaps you've previously built a DApp. If you need a quick intro, <a target="_blank" href="https://docs.metamask.io/guide/create-dapp.html#basic-action-part-1">check out this brilliant piece by MetaMask to get started</a>.</p>
<p>Alright, Let’s dig in!</p>
<h2 id="heading-step-1-check-if-the-user-has-metamask-installed">Step 1 — Check if the User Has MetaMask Installed</h2>
<p>The first thing to do is to verify if the user has installed the MetaMask extension.</p>
<p>If they have another wallet installed besides MetaMask, switching networks using the method we are about to learn might not work. So it's a good idea to check first.</p>
<p>Let's check if the <code>ethereum</code> context has been injected into the browser. The code sample below shows how to do this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { ethereum } = <span class="hljs-built_in">window</span>;

<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> ethereum !== <span class="hljs-string">'undefined'</span> &amp;&amp; ethereum.isMetaMask) {  
 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"MetaMask is installed"</span>)
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"MetaMask is not installed"</span>)
}
</code></pre>
<p>Here's what we're doing:</p>
<p>At <code>const { ethereum } = window;</code> we destructure the <code>ethereum</code> property from the windows object and assign it to a variable of the same name.</p>
<p>If you are unfamiliar with this syntax, destructuring involves simply extracting the content of an object or array and assigning it to a variable. <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Read up on this piece to learn more about destructuring</a>.</p>
<p>Then we check if <code>ethereum</code> actually does exist using the if statement. Also, in the same condition we want to verify if the wallet installed is MetaMask.</p>
<p>Good! Let's see the next step.</p>
<h2 id="heading-step-2-how-to-switch-the-active-blockchain">Step 2 — How to Switch the Active Blockchain</h2>
<p>Once we have verified that the user has MetaMask installed, the next thing to do is trigger the RPC method for switching the MetaMask active blockchain. The code looks like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// MetaMask Docs</span>
<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">await</span> ethereum.request({
    <span class="hljs-attr">method</span>: <span class="hljs-string">'wallet_switchEthereumChain'</span>,
    <span class="hljs-attr">params</span>: [{ <span class="hljs-attr">chainId</span>: <span class="hljs-string">'0xf00'</span> }],
  });
} <span class="hljs-keyword">catch</span> (switchError) {
<span class="hljs-comment">// This error code indicates that the chain has not been added to MetaMask.</span>
  <span class="hljs-keyword">if</span> (switchError.code === <span class="hljs-number">4902</span>) {
      <span class="hljs-comment">// Do something</span>
  }
}
</code></pre>
<p>Here's what we are doing:</p>
<p>We invoke the <code>ethereum.request</code> method, passing it an object with two properties.</p>
<p>In the method property, we specify the <code>wallet_switchEthereumChain</code> RPC method, which allows Ethereum applications (DApps) to request that MetaMask switches its active Ethereum chain.</p>
<p>Then, the params property is an array that takes an object with the chain ID of the blockchain to switch to. <code>chainId</code> must be hexadecimal, hence the 0x in the sample code.</p>
<p>We wrap our request in a try/catch block to handle errors.</p>
<p><code>null</code> is returned if the active chain is switched.</p>
<p>If the requested chain does not exist in the user's wallet, the request throws an error code <code>error.code</code> of <code>4902</code>. If this happens, you can request to add the chain to the wallet.</p>
<p>You can follow this guide to see <a target="_blank" href="https://www.freecodecamp.org/news/how-to-add-custom-network-to-metamask/">how to add a new chain to MetaMask using JavaScript.</a></p>
<p>Great! That's all it takes to switch the active chain on MetaMask with Javascript.</p>
<p>Let's have a quick demo in the next section.</p>
<h2 id="heading-demo">Demo</h2>
<p>For this example, let's write a function that, when invoked, will prompt users to switch to the Polygon chain.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> SwitchChainToPolygon = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> { ethereum } = <span class="hljs-built_in">window</span>;
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> ethereum !== <span class="hljs-string">'undefined'</span> &amp;&amp; ethereum.isMetaMask) <span class="hljs-keyword">return</span>;

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> ethereum.request({
        <span class="hljs-attr">method</span>: <span class="hljs-string">'wallet_switchEthereumChain'</span>,
        <span class="hljs-attr">params</span>: [{ <span class="hljs-attr">chainId</span>: <span class="hljs-string">'0x89'</span> }],
      });
    } <span class="hljs-keyword">catch</span> (switchError) {
      <span class="hljs-keyword">if</span> (switchError.code === <span class="hljs-number">4902</span>) {
        <span class="hljs-comment">// You can make a request to add the chain to wallet here</span>
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Polygon Chain hasn'</span>t been added to the wallet!<span class="hljs-string">')
      }
    }
}</span>
</code></pre>
<p>In the function <code>SwitchChainToPolygon</code> above, we destructured <code>ethereum</code> from the windows object, as we learned in Step 1.</p>
<p>Next, we verified whether <code>ethereum</code> does exist or not. If the <code>ethereum</code> is unavailable, that is if MetaMask is not installed, the function will exit/break.</p>
<p>If <code>ethereum</code> exists, we call the <code>ethereum.request</code> method to make an RPC call. For the <code>method</code> property, we give it a value of <code>wallet_switchEthereumChain</code>. For the <code>params</code>, <code>chainId</code> will have the value of <code>0x89</code> ( <code>167</code> in decimal) which is the chainId for the polygon blockchain.</p>
<p>That's all folks!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you have learned how to switch blockchains on MetaMask with JavaScript. This will help you provide a frictionless user experience for your users.</p>
<p>Thank you for taking the time to read this. I hope you found it useful. Please feel free to connect and chat with me on <a target="_blank" href="https://twitter.com/kohawithstuff">Twitter</a> and <a target="_blank" href="https://youtube.com/@kohawithstuff">YouTube</a>. See you soon in my next article!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Solidity – A Handbook for Smart Contract Development ]]>
                </title>
                <description>
                    <![CDATA[ When I changed careers from lawyer to software engineer in 2018, I never imagined that I’d enjoy being a developer as much as I do. I also never thought I'd end up working for amazing organizations like Google and Chainlink labs. After 15 years in la... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-solidity-handbook/</link>
                <guid isPermaLink="false">66d461d437bd2215d1e24610</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Smart Contracts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Solidity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Wed, 14 Dec 2022 15:45:30 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738338914608/84596494-c070-4dd8-8c9a-399e69f2829a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When I changed careers from <a target="_blank" href="https://www.freecodecamp.org/news/from-lawyer-to-google-engineer/">lawyer to software engineer</a> in 2018, I never imagined that I’d enjoy being a developer as much as I do. I also never thought I'd end up working for amazing organizations <a target="_blank" href="https://www.freecodecamp.org/news/coding-interview-prep-for-big-tech/">like Google</a> and Chainlink labs.</p>
<p>After 15 years in law and other roles, I’d experienced a number of jobs, countries, companies, and career paths. None of them compared to the joy and thrill I get from coding.</p>
<p>The downside? Picking up new coding skills can be confusing, frustrating, and time consuming. And it’s easy to forget some of the minute but important details.</p>
<p>So I wrote this handbook. It's intended to get you started on coding Solidity ASAP. It follows the Pareto Principle (aka the 80/20 rule) by focusing on the 20% of the info that will cover 80% of your needs.</p>
<p>I started assembling these concepts when I was learning Solidity, as part of my role at <a target="_blank" href="http://chain.link">Chainlink Labs</a>. I applied many of the self-learning techniques that I learned when transitioning to coder at the age of 38.</p>
<p>This is the resource I wish I had. It is designed to give beginner and intermediate developers solid mental models to stack as you get deeper into the language (<a target="_blank" href="https://fs.blog/mental-models/#what_are_mental_models">mental models</a> massively accelerate effective learning).</p>
<p>I will keep this handbook updated, but I could really use your help! Just tweet me <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a> to let me know if I need to update this handbook.</p>
<p>I’d like to acknowledge my amazing colleagues <a target="_blank" href="https://twitter.com/@dalteco">Kevin Ryu</a>, <a target="_blank" href="https://twitter.com/@@andrej_dev">Andrej Rakic</a>, <a target="_blank" href="https://twitter.com/PatrickAlphaC">Patrick Collins</a>, and <a target="_blank" href="https://twitter.com/RGottleber">Richard Gottleber</a> for the invaluable guidance and input on this handbook.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-who-is-this-handbook-for">Who is this handbook for?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-essential-prior-knowledge">Essential prior knowledge</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-solidity">What is Solidity?</a></p>
</li>
<li><p><a class="post-section-overview" href="#what-is-a-basic-smart-contract">What is a smart contract?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-declare-variables-and-functions-in-solidity">How to declare variables and functions in Solidity?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-variable-scope-in-smart-contracts">Variable scope in Smart Contracts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-visibility-specifiers-work">How visibility specifiers work</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-constructors">What are constructors?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-interfaces-and-abstract-contracts">Interfaces and abstract contracts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-smart-contract-example-2">Smart contract example #2</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-contract-state">What is contract state?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-state-mutability-keywords-modifiers">State mutability keywords (modifiers)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-data-locations-storage-memory-and-stack">Data locations – storage, memory, and stack</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-typing-works">How typing works</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-solidity-data-types">Solidity data types</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-declare-and-initialize-arrays-in-solidity">How to declare and initialize arrays in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-function-modifiers">What are function modifiers?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-error-handling-in-solidity-require-assert-revert">Error handling in Solidity - require, assert, revert</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inheritance-in-solidity">Inheritance in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inheritance-with-constructor-parameters">Inheritance with constructor parameters</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-type-conversion-and-type-casting-in-solidity">Type conversion and type casting in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-work-with-floating-point-numbers-in-solidity">How to work with floating point numbers in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hashing-abi-encoding-and-decoding">Hashing, ABI encoding and decoding</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-call-contracts-and-use-the-fallback-function">How to call contracts and use the fallback function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-send-and-receive-ether">How to send and receive Ether</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-solidity-libraries">Solidity libraries</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-events-and-logs-in-solidity">Events and logs in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-time-logic-in-solidity">Time logic in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion-and-further-resources">Conclusion and further resources</a></p>
</li>
</ol>
<h2 id="heading-who-is-this-handbook-for">Who Is This Handbook For?</h2>
<p>This handbook is for people who are interested in exploring the <a target="_blank" href="https://chain.link/education/web3">vision behind “Web3”</a>, and who wish to acquire in-demand skills that are essential to realizing that vision.</p>
<p>Do not memorize it! Read it and then use it as a “desktop reference” companion. As you learn any new language, you will find that concepts, idioms, and usage can get a bit confusing or your memory fades with time. That’s ok! That’s what this handbook is designed to help you with.</p>
<p>Over time I may add some more advanced topics to this, or create a separate tutorial. But for now this handbook will get you most of the outcomes you require to build your first several Solidity dApps.</p>
<p>This handbook assumes you have at least a few months of experience with programming. By programming I mean at the very least you’ve written in JavaScript or Python or some compiled language (since HTML and CSS aren't actually "programming" languages, it won't be enough to know only them).</p>
<p>The only other requirements are that you are curious, committed, and not putting arbitrary deadlines on yourself.</p>
<p>As long as you have a laptop, and a browser with an internet connection, you’ll be able to run the Solidity code. You can use <a target="_blank" href="https://www.youtube.com/watch?v=JWJWT9cwFbo&amp;list=PLVP9aGDn-X0QwJVbQvuKr-zrh2_DV5M6J&amp;index=47">Remix</a> in your browser to write the code in this handbook. No other IDE required!</p>
<h2 id="heading-essential-prior-knowledge">Essential Prior Knowledge</h2>
<p>I have also assumed that you know the <a target="_blank" href="https://blog.chain.link/what-is-blockchain/">basics of blockchain technology</a>, and in particular you understand the <a target="_blank" href="https://www.youtube.com/watch?v=NsyFGzhktYA&amp;list=PLVP9aGDn-X0QwJVbQvuKr-zrh2_DV5M6J&amp;index=49">basics of Ethereum</a> and <a target="_blank" href="https://chain.link/education/smart-contracts">what smart contracts are</a> (hint: they’re programs that run on blockchains and hence provide special trust-minimized benefits!).</p>
<p>You are unlikely to need them to understand this handbook. But practically speaking, having a browser wallet like <a target="_blank" href="https://metamask.io/">Metamask</a> and understanding <a target="_blank" href="https://info.etherscan.com/understanding-ethereum-accounts/">the difference between Ethereum contract accounts and externally owned accounts</a> will help you get the most out of this handbook.</p>
<h2 id="heading-what-is-solidity">What is Solidity?</h2>
<p>Now, let’s start with understanding what Solidity is. Solidity is an <a target="_blank" href="https://www.freecodecamp.org/news/what-is-object-oriented-programming/">object-oriented programming language</a> influenced by C++, JavaScript and Python.</p>
<p>Solidity is designed to be compiled (converted from human readable to machine readable code) into bytecode that runs on the Ethereum Virtual Machine (EVM). This is the <a target="_blank" href="https://www.techopedia.com/definition/5466/runtime-environment-rte">runtime environment</a> for Solidity code, just like your browser is a runtime environment for JavaScript code.</p>
<p>So, you write Smart Contract code in Solidity, and the compiler converts it into bytecode. Then that bytecode gets deployed and stored on Ethereum (and other EVM-compatible blockchains).</p>
<p>You can get a basic introduction to the EVM and bytecode in <a target="_blank" href="https://www.youtube.com/watch?v=Z7UNjk_roXI&amp;t=1052s">this video I made</a>.</p>
<h2 id="heading-what-is-a-smart-contract">What is a Smart Contract?</h2>
<p>Here is a simple smart contract that works out of the box. It may not look useful, but you’re going to understand a lot of Solidity from just this!</p>
<p>Read it along with each comment to get a sense of what’s going on, and then move on to some key learnings.</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.8.0;<br><br>contract HotFudgeSauce {<br>&nbsp; &nbsp; uint public qtyCups;<br><br>&nbsp; &nbsp; // Get the current hot fudge quantity<br>&nbsp; &nbsp; function get() public view returns (uint) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return qtyCups;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; // Increment hot fudge quantity by 1<br>&nbsp; &nbsp; function increment() public {<br>&nbsp; &nbsp; &nbsp; &nbsp; qtyCups += 1; // same as&nbsp; qtyCups = qtyCups + 1;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; // Function to decrement count by 1<br>&nbsp; &nbsp; function decrement() public {<br>&nbsp; &nbsp; &nbsp; &nbsp; qtyCups -= 1; // same as&nbsp; qtyCups = qtyCups - 1;<br>&nbsp; &nbsp; &nbsp; &nbsp; // What happens if qtyCups = 0 when this func is called?<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>We will get to some of the details like what <code>public</code> and <code>view</code> mean shortly.</p>
<p>For now, take seven key learnings from the above example:</p>
<ol>
<li>The first comment is a machine readable line ( <code>// SPDX-License-Identifier: MIT</code>) that specifies the licensing that covers the code.</li>
</ol>
<p>SPDX license identifiers are strongly recommended, though your code will compile without it. Read more <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.6/layout-of-source-files.html#spdx-license-identifier">here</a>. Also, you can add a comment or “comment out” (suppress) any line by prefixing it with two forward slashes "<code>//</code> ".</p>
<ol start="2">
<li>The <code>pragma</code> directive must be the first line of code in any Solidity file. Pragma is a directive that tells the compiler which compiler version it should use to convert the human-readable Solidity code to machine readable bytecode.</li>
</ol>
<p>Solidity is a new language and is frequently updated, so different versions of the compiler produce different results when compiling code. Some older solidity files will throw errors or warnings when compiled with a newer compiler version.</p>
<p>In larger projects, when you use tools like Hardhat, you may need to specify multiple compiler versions because imported solidity files or libraries that you depend on were written for older versions of solidity. Read more on <a target="_blank" href="https://docs.soliditylang.org/en/develop/layout-of-source-files.html">Solidity’s pragma directive here</a>.</p>
<ol start="3">
<li><p>The <code>pragma</code> directive follows Semantic Versioning (SemVer) - a system where each of the numbers signifies the type and extent of changes contained in that version. If you want a hands-on explanation of SemVer is check out this tutorial - it is very useful to understand and it’s used widely in development (especially web dev) these days.</p>
</li>
<li><p>Semicolons are essential in Solidity. The compiler will fail if even a single one is missing. Remix will alert you!</p>
</li>
<li><p>The keyword <code>contract</code> tells the compiler that you’re declaring a Smart Contract. If you’re familiar with Object Oriented Programming, then you can think of Contracts as being like Classes.</p>
</li>
</ol>
<p>If you’re not familiar with OOP then think of contracts as being objects that hold data - both variables and functions. You can combine smart contracts to give your blockchain app the functionality it needs.</p>
<ol start="6">
<li>Functions are executable units of code that encapsulate single ideas, specific functionality, tasks, and so on. In general we want functions to do one thing at a time.</li>
</ol>
<p>Functions are most often seen inside smart contracts, though they can be declared in the file outside the smart contract’s block of code. Functions may take 0 or more arguments and they may return 0 or more values. Inputs and outputs are statically typed, which is a concept you will learn about later in this handbook.</p>
<ol start="7">
<li>In the above example the variable <code>qtyCups</code> is called a “state variable”. It holds the contract’s state - which is the technical term for data that the program needs to keep track of to operate.</li>
</ol>
<p>Unlike other programs, smart contract applications keep their state even when the program is not running. The data is stored in the blockchain, along with the application, which means that each node in the blockchain network maintains and synchronizes a local copy of the data and smart contracts on the blockchain.</p>
<p>State variables are like database “storage” in a traditional application, but since blockchains need to synchronize state across all nodes in the network, using storage can be quite expensive! More on that later.</p>
<h2 id="heading-how-to-declare-variables-and-functions-in-solidity">How to Declare Variables and Functions in Solidity</h2>
<p>Let’s break down that <code>HotFudgeSauce</code> Smart Contract so we understand more about each little piece.</p>
<p>The basic structure/syntax to defining things in Solidity is similar to other statically typed languages. We give functions and variables a name.</p>
<p>But in typed languages we also need to specify the <em>type</em> of the data that is created, passed as input or returned as output. You can jump down to the Typing Data section in this handbook if you need to understand what typed data is.</p>
<p>Below, we see what declaring a “State Variable” looks like. We also see what declaring a function looks like.</p>
<p><img src="https://lh5.googleusercontent.com/P0bkGvqTA70VN-VZlV13ICNL4sxhzHCIU_8GL0JF9iHZPn6ml4vA6grWy_dKbiMa-y_ALc8oHOyIDGLFZgIIi5pU2Ep5ENuFJd0dPRL8RCPx8bksESh44loRbFqAA9f7GZ9_e5thytMuOk3EeObhmQnG791pBviHuxrv3N3HAXcGAQL0q-4TwV2LQhoA-w" alt="(Alt: The structure variable declaration and function declaration) " width="600" height="400" loading="lazy"></p>
<p>The first snippet declares a State Variable (I’ll explain what this is soon, I promise) called <code>qtyCups</code>. This can only store values that are of type <code>uint</code> which means unsigned integers. “Integer” refers to all whole numbers below zero (negative) and above zero (positive).</p>
<p>Since these numbers have a + or - sign attached, they’re called <em>signed</em> integers. An unsigned integer is therefore always a positive integer (including zero).</p>
<p>In the second snippet, we see a familiar structure when we declare functions too. Most importantly, we see that the functions have to specify a data type for the value that the function returns.</p>
<p>In this example, since <code>get()</code> returns the value of the storage variable we just created, we can see that the returned value must be a <code>uint</code>.</p>
<p><code>public</code> is a visibility specifier. More on that later. <code>view</code> is a State-Mutability modifier. More on that below too!</p>
<p>It’s worth noting here that state variables can also be of other types - <code>constant</code> and <code>immutable</code>. They look like this:</p>
<table><tbody><tr><td><p>string constant TEXT = "abc";<br>address immutable owner = 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e;</p></td></tr></tbody></table>

<p>Constants and immutable variables have their values assigned once, and only once. They cannot be given another value after their first value is assigned.</p>
<p>So if we made the <code>qtyCups</code> state variable either constant or immutable, we would not be able to call the <code>increment()</code> or <code>decrement()</code> functions on it anymore (in fact, the code wouldn’t compile!).</p>
<p>Constants must have their values hardcoded in the code itself, whereas immutable variables can have their values set once, generally by assignment in the constructor function (we’ll talk about constructor functions very soon, I promise). You can read more in the <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.16/contracts.html#constant-and-immutable-state-variables">docs here</a>.</p>
<h2 id="heading-variable-scope-in-smart-contracts">Variable Scope in Smart Contracts</h2>
<p>There are three scopes of variables that Smart Contracts have access to:</p>
<ol>
<li><p>State Variables: store permanent data in the smart contract (referred to as persistent state) by recording the values on the blockchain.</p>
</li>
<li><p>Local Variables: these are “transient” pieces of data that hold information for short periods of time while running computations. These values are not stored permanently on the blockchain.</p>
</li>
<li><p><a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/units-and-global-variables.html#special-variables-and-functions">Global variables</a>: these variables and functions are “injected” into your code by Solidity, and made available without the need to specifically create or import them from anywhere. These provide information about the blockchain environment the code is running on and also include utility functions for general use in the program.</p>
</li>
</ol>
<p>You can tell the difference between the scopes as follows:</p>
<ol>
<li><p>state variables are generally found inside the smart contract but outside of a function.</p>
</li>
<li><p>local variables are found inside functions and cannot be accessed from outside that function’s scope.</p>
</li>
<li><p>Global variables aren’t declared by you - they are “magically” available for you to use.</p>
</li>
</ol>
<p>Here is our <code>HotFudgeSauce</code> example, slightly modified to show the different types of variables. We give <code>qtyCups</code> a starting value and we dispense cups of fudge sauce to everyone except me (because I’m on a diet).</p>
<p><img src="https://lh4.googleusercontent.com/Z9wk7BXxi-669WmSamT25cV88_RK-psGJvCA69vUxgpcs2_EzJFzLZJOitQlsuSl_AD-LdRylCaKh4Iumo_tVHmft2mtKofDu4qZfWQ8Z7BhdZ-6g4B6JAwLF57gMi-osCSDocgyE6kdqMCL4uxjBtpzjMf6rlLM0Ja6w4ndaIxEZhE3YsxmDY1BIWOwnA" alt="Annotated image showing state variables, local variables and global variables in a smart contract" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-visibility-specifiers-work">How Visibility Specifiers Work</h2>
<p>The use of the word “visibility” is a bit confusing because on a public blockchain, pretty much everything is “visible” because transparency is a key feature. But visibility, in this context, means the ability for one piece of code to be seen and accessed by another piece of code.</p>
<p>Visibility specifies the extent to which a variable, function, or contract can be accessed from outside the region of code where it was defined. The scope of visibility can be adjusted depending on which portions of the software system need to access it.</p>
<p>If you’re a JavaScript or NodeJS developer, you’re already familiar with visibility – any time you export an object you’re making it visible outside the file where it is declared.</p>
<h3 id="heading-types-of-visibility">Types of Visibility</h3>
<p>In Solidity there are <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.16/cheatsheet.html#function-visibility-specifiers">4 different types of visibility</a>: <code>public</code>, <code>external</code>, <code>internal</code> and <code>private</code>.</p>
<p><strong>Public</strong> functions and variables can be accessed inside the contract, outside it, from other smart contracts, and from external accounts (the kind that sit in your <a target="_blank" href="https://metamask.io/">Metamask</a> wallet) - pretty much from anywhere. It’s the broadest, most permissive visibility level.</p>
<p>When a storage variable is given <code>public</code> visibility, Solidity automatically creates an implicit getter function for that variable’s value.</p>
<p>So in our <code>HotFudgeSauce</code> smart contract, we don’t really need to have the <code>get()</code> method, because Solidity will implicitly provide us identical functionality, just by giving <code>qtyCups</code> a <code>public</code> visibility modifier.</p>
<p><strong>Private</strong> functions and variables are only accessible within the smart contract that declares them. But they cannot be accessed outside of the Smart Contract that encloses them. <code>private</code> is the most restrictive of the four visibility specifiers.</p>
<p><strong>Internal</strong> visibility is similar to <code>private</code> visibility, in that internal functions and variables can only be accessed from within the contract that declares them. But functions and variables marked internal can also be accessed from derived contracts (that is, child contracts that inherit from the declaring contract) but not from outside the contract. We will talk about inheritance (and derived/child contracts) later on.</p>
<p><code>internal</code> is the default visibility for storage variables.</p>
<p><img src="https://lh5.googleusercontent.com/gcNCm0-739P27Bqp_5zYT6kM_fmfW3tnrx-ZJ8iKH5Gnhpp9-JXo4NrSk7UaUPv9SF34ka7eNYtFK-FmnTGtHSupFUE6A6UvX1738cqDG0X9qhWCRdqI-jGf1BCpvK2Qi6MqMQWgN4H3VOpa5xh2zVkQrQlfGuBPRWIovNxfDH3zhFuxHKsUpXq9Oh_Saw" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The 4 Solidity Visibility specifiers and where they can be accessed from</em></p>
<p>The <strong>external</strong> visibility specifier does not apply to variables - only functions can be specified as external.</p>
<p>External functions cannot be called from inside the declaring contract or contracts that inherit from the declaring contract. Thus, they can only be called from outside the enclosing contract.</p>
<p>And that’s how they’re different from public functions – public functions can also be called from <em>inside</em> the contract that declare them, whereas an external function cannot.</p>
<h2 id="heading-what-are-constructors">What are Constructors?</h2>
<p>A constructor is a special type of function. In Solidity, it is optional and is executed once only on contract creation.</p>
<p>In the following example we have an explicit constructor and it accepts some data as a parameter. This constructor parameter must be injected by you into your smart contract at the time you create it.</p>
<p><img src="https://lh6.googleusercontent.com/51je7Hakb-_ARNnomBYpwoKpf2j86WvwRLDlaFzGLlGowJLt1T1MX2978gAGv8eZCoiZc-jZParqor28wBLx97WyrMrso-EwSRHnOBi3O956nIyHN4-cezZJk8avP7JBegFOq4DJ997t1YnC61bD4IUH08SPEbvw6HoZSbXqbOt_LwzfQAHXfeXiNC6xHw" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Solidity constructor function with input parameter</em></p>
<p>To understand when the constructor function gets called, it’s helpful to remember that a Smart Contract is created over a few phases:</p>
<ul>
<li><p>it is compiled down to bytecode (you can <a target="_blank" href="https://blog.chain.link/what-are-abi-and-bytecode-in-solidity/">read more about bytecode here</a>). This phase is called “compile time”.</p>
</li>
<li><p>it gets created (constructed) - this is when the constructor kicks into action. This can be referred to as “construction time”.</p>
</li>
<li><p>Bytecode then gets deployed to the blockchain. This is “deployment”.</p>
</li>
<li><p>The deployed smart contract bytecode gets run (executed) on the blockchain. This can be considered “runtime”.</p>
</li>
</ul>
<p>In Solidity, unlike other languages, the program (smart contract) is deployed only <em>after</em> the constructor has done its work of creating the smart contract.</p>
<p>Interestingly, in Solidity, the finally deployed bytecode does <em>not</em> include the constructor code. This is because in Solidity, the <a target="_blank" href="https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-ii-creation-vs-runtime-6b9d60ecb44c/">constructor code is part of the creation code</a> (construction time) and not part of the runtime code. It is used up when creating the smart contract, and since it’s only ever called once it is not needed past this phase, and is excluded in the finally deployed bytecode.</p>
<p>So in our example, the constructor creates (constructs) one instance of the <code>Person</code> smart contract. Our constructor expects us to pass a string value which is called <code>_name</code> to it.</p>
<p>When the smart contract is being constructed, that value of <code>_name</code> will get stored in the state variable called <code>name</code> (this is often how we pass configuration and other data into the smart contract). Then when the contract is actually deployed, the state variable <code>name</code> will hold whatever string value we passed into our constructor.</p>
<h3 id="heading-understanding-the-why">Understanding the Why</h3>
<p>You might wonder why we bother with injecting values into the constructor. Why not just write them into the contract?</p>
<p>This is because we want contracts to be configurable or “parameterized”. Rather than hard code values, we want the flexibility and reusability that comes with injecting data as and when we need.</p>
<p>In our example, let’s say that <code>_name</code> referred to the name of a given Ethereum network on which the contract is going to be deployed (like Rinkeby, Goerli, Kovan, Mainnet, and so on).</p>
<p>How could we give that information to our smart contract? Putting all those values in it would be wasteful. It would also mean we need to add extra code to work out which blockchain the contract is running on. Then we'd have to pick the right network name from a hard-coded list which we store in the contract, which takes up gas on deployment.</p>
<p>Instead, we can just inject it into the constructor, at the time we are deploying the smart contract to the relevant blockchain network. This is how we write one contract that can work with any number of parameter values.</p>
<p>Another common use case is when your smart contract inherits from another smart contract and you need to pass values to the parent smart contract when your contract is being created. But inheritance is something we will discuss later.</p>
<p>I mentioned that constructors are optional. In <code>HotFudgeSauce</code>, we didn’t write an explicit constructor function. But Solidity supports implicit constructor functions. So if we don’t include a constructor function in our smart contract, Solidity will <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.13/contracts.html#constructors">assume a default constructor</a> which looks like <code>constructor() {}</code>.</p>
<p>If you evaluate this in your head you’ll see it does nothing and that’s why it can be excluded (made implicit) and the compiler will use the default constructor.</p>
<h2 id="heading-interfaces-and-abstract-contracts">Interfaces and Abstract Contracts</h2>
<p>An <a target="_blank" href="https://docs.soliditylang.org/en/develop/contracts.html#interfaces">interface in solidity</a> is an essential concept to understand. Smart Contracts on Ethereum are publicly viewable and therefore you can interact with them via their functions (to the extent the Visibility Specifiers allow you to do so!).</p>
<p>This is what makes smart contracts “composable” and why so many Defi protocols are referred to as “money Legos” - you can write smart contracts that interact with other smart contracts that interact with other smart contracts and so on…you get the idea.</p>
<p>So when you want your smart contract A to interact with another smart contract B, you need B’s interface. An interface gives you an index or menu of the various functions available for you to call on a given Smart Contract.</p>
<p>An important feature of Interfaces is that they must not have any implementation (code logic) for any of the functions defined. Interfaces are just a collection of function names and their expected arguments and return types. They’re not unique to Solidity.</p>
<p>So an interface for our <code>HotFudgeSauce</code> Smart Contract would look like this (note that by convention, solidity interfaces are named by prefixing the smart contract’s name with an “I”:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br><br>pragma solidity ^0.8.7;<br><br>interface IHotFudgeSauce {<br>&nbsp; &nbsp; function get() public view returns (uint);<br>&nbsp; &nbsp; function increment() public;<br>&nbsp; &nbsp; function decrement() public;<br>}</p></td></tr></tbody></table>

<p>That’s it! Since <code>HotFudgeSauce</code> had only three functions, the interface shows only those.</p>
<p>But there is an important and subtle point here: an interface does not need to include all the functions available to call in a smart contract. An interface can be shortened to include the function definitions for the functions that you intend to call!</p>
<p>So if you only wanted to use the <code>decrement()</code> method on <code>HotFudgeSauce</code> then you could absolutely remove <code>get()</code> and <code>increment()</code> from your interface - but you would not be able to call those two functions from your contract.</p>
<p>So what’s actually going on? Well, interfaces just give your smart contract a way of knowing what functions can be called in your target smart contract, what parameters those functions accept (and their data type), and what type of return data you can expect. In Solidity, that’s all you need to interact with another smart contract.</p>
<p>In some situations, you can have an abstract contract which is similar to but different from an interface.</p>
<p>An <a target="_blank" href="https://docs.soliditylang.org/en/develop/contracts.html#abstract-contracts">abstract contract</a> is declared using the <code>abstract</code> keyword and is one where one or more of its functions are declared but not implemented. This is another way of saying that at least one function is declared but not implemented.</p>
<p>Flipping that around, an abstract contract can have implementations of its functions (unlike interfaces which can have zero implemented functions), but as long as at least one function is unimplemented, the contract must be marked as abstract:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.7;<br><br>abstract contract Feline {</p></td></tr></tbody></table>

<p>You may (legitimately) wonder what the point of this is. Well, abstract contracts cannot be instantiated (created) directly. They can only be used by other contracts that inherit from them.</p>
<p>So abstract contracts are often used as a template or a “base contract” from which other smart contracts can “inherit” so that the inheriting smart contracts are forced to implement certain functions declared by the abstract (parent) contract. This enforces a defined structure across related contracts which is often a useful design pattern.</p>
<p>This inheritance stuff will become a little clearer when we discuss Inheritance later. For now, just remember that you can declare an abstract smart contract that does not implement all its functions - but if you do, you cannot instantiate it, and future smart contracts that inherit it must do the work of implementing those unimplemented functions.</p>
<p>Some of the important differences between interfaces and abstract contracts are that:</p>
<ul>
<li><p>Interfaces can have zero implementations, whereas abstract contracts can have any number of implementations as long as at least one function is “abstract” (that is, not implemented).</p>
</li>
<li><p>All functions in an interface must be marked as “external” because they can only be called by other contracts that implement that interface.</p>
</li>
<li><p>Interfaces cannot have constructors, whereas abstract contracts may.</p>
</li>
<li><p>Interfaces cannot have state variables where abstract contracts may.</p>
</li>
</ul>
<h2 id="heading-smart-contract-example-2">Smart Contract Example #2</h2>
<p>For the next few Solidity concepts we’ll use the below smart contract. This is partly because this example contains a smart contract that is actually used in the real world. I've also chosen it because I have a clear bias to Chainlink Labs since I work there (😆) and it’s awesome. But it’s also where I learned a lot of Solidity, and it’s always better to learn with real-world examples.</p>
<p>So start by reading the code and the comments below. You’ve already learned 99% of what you need to understand the contract below, provided you read it carefully. Then move on to key learnings from this contract.</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.7;<br><br>import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";<br><br>contract PriceConsumerV3 {<br>&nbsp; &nbsp; AggregatorV3Interface internal priceFeed;<br><br>&nbsp; &nbsp; /<em>*<br>&nbsp; &nbsp; </em> Network: Goerli<br>&nbsp; &nbsp; <em> Aggregator: ETH/USD<br>&nbsp; &nbsp; </em> Address: 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e<br>&nbsp; &nbsp; */<br>&nbsp; &nbsp; constructor() {<br>&nbsp; &nbsp; &nbsp; &nbsp; priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e);<br>&nbsp; &nbsp; }<br>&nbsp;&nbsp;&nbsp;</p></td></tr></tbody></table>

<p>This smart contract <a target="_blank" href="https://docs.chain.link/docs/get-the-latest-price/">gets the latest USD price of 1 Eth</a>, from a live Chainlink price feed oracle (<a target="_blank" href="https://goerli.etherscan.io/address/0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e#code">see the oracle on etherscan</a>). The example uses the Goerli network so you don’t end up spending real money on the Ethereum mainnet.</p>
<p>Now to the 6 essential Solidity concepts you need to absorb:</p>
<ol>
<li>Right after the <code>pragma</code> statement we have an import statement. This imports existing code into our smart contract.</li>
</ol>
<p>This is super cool because this is how we reuse and benefit from code that others have written. You can check out the code that is imported on this <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol">GitHub link</a>.</p>
<p>In effect, when we compile our smart contract, this imported code gets pulled in and compiled into bytecode along with it. We will see why we need it in a second…</p>
<ol start="2">
<li><p>Previously you saw that single-line comments were marked with <code>//</code>. Now you're learning about multiline comments. They may span one or more lines and use <code>/*</code> and <code>*/</code> to start and end the comments.</p>
</li>
<li><p>We declare a variable called <code>priceFeed</code> and it has a type <code>AggregatorV3Interface</code>. But where does this strange type come from? From our imported code in the import statement - we get to use the <code>AggregatorV3Interface</code> type because Chainlink defined it.</p>
</li>
</ol>
<p>If you looked at that Github link, you’d see that the type defines an interface (we just finished talking about interfaces). So <code>priceFeed</code> is a <em>reference</em> to some object that is of type <code>AggregatorV3Interface</code>.</p>
<ol start="4">
<li>Take a look at the constructor function. This one doesn’t accept parameters, but we could have just as easily passed the ETH/USD Price Feed’s oracle smart contract’s address <code>0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e</code> to it as a parameter of type <code>address</code>. Instead, we are hard-coding the address inside the constructor.</li>
</ol>
<p>But we are also creating a reference to the Price Feed Aggregator smart contract (using the interface called <code>AggregatorV3Interface</code>).</p>
<p>Now we can call all the methods available on the <code>AggregatorV3Interface</code> because the <code>priceFeed</code> variable refers to that Smart Contract. In fact, we do that next… 5. Let's jump to the function <code>getLatestPrice()</code>. You’ll recognize its structure from our discussion in <code>HotFudgeSauce</code>, but it’s doing some interesting things.</p>
<p>Inside this <code>getLatestPrice()</code> function we call the <code>latestRoundData()</code> function which exists on the <code>AggregatorV3Interface</code> type. If you <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol#L22">look at the source code of this method</a> you’ll notice that this <code>latestRoundData()</code> function returns 5 different types of integers!</p>
<p><img src="https://lh5.googleusercontent.com/GMqCsBxRblJ2rMQDrMPTx1iDfj6Q3h0eiPqE-RE0-MaHwDDyr6JVna6-57e4jdQxp6VJ4FbMWUMKxFpM2ot4BzqsagLpmD2clz1xCjQhAfl4tn8HhCK4uSKj1hZkDGwXJj9DhuY7nmunj4j_aDx9APc8mqXUPoR9Tl20DdYvjIoUjotmQfJByXKbW2EY5g" alt="Calling methods on another smart contract from our smart contract" width="600" height="400" loading="lazy"></p>
<p><em>Calling methods on another smart contract from our smart contract</em></p>
<p>In our smart contract, we are commenting out all 4 values that we don’t need. So this means that Solidity functions can return multiple values (in this example we are returned 5 values), and we can pick and choose which ones we want.</p>
<p>Another way of consuming the results of calling <code>latestRoundData()</code> would be:<code>( ,int price, , ,) = priceFeed.latestRoundData()</code> where we ignore 4 out of 5 returned values by not giving them a variable name.</p>
<p>When we assign variable names to one or more values returned by a function, we call it “destructuring assignment” because we destructure the returned values (separate each one out) and assign them at the time of destructuring, like we do with <code>price</code> above.</p>
<p>Since you’ve learned about interfaces, I recommend you take a look at Chainlink Labs’ <a target="_blank" href="https://github.com/smartcontractkit/">GitHub repo</a> to examine the implemented <code>latestRoundData()</code> function in <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.6/AggregatorProxy.sol#L211">the <code>Aggregator</code> contract</a> and how the <code>AggregatorV3Interface</code> <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol#L22">provides the interface</a> to interact with the <code>Aggregator</code> contract.</p>
<h2 id="heading-what-is-contract-state">What is Contract State?</h2>
<p>Before we proceed any further, it’s important to make sure that the terminology that we’re going to see a lot is comprehensible to you.</p>
<p>“State” in computer science has a <a target="_blank" href="https://en.wikipedia.org/wiki/State_\(computer_science\)">well-defined meaning</a>. While it can get very confusing, the crux of state is that it refers to all the information that is “remembered” by a program as it runs. This information can change, update, be removed, created and so on. And if you were to take a snapshot of it at various times, the information will be in different “states”.</p>
<p>So the state is just the current snapshot of the program, at a point in time during its execution - what values do its variables hold, what are they doing, what objects have been created or removed, and so on.</p>
<p>We have previously examined the three types of variables - State Variables, Local Variables, and Global variables. State variables, along with Global variables give us the state of the smart contract at any given point in time. Thus, the state of a smart contract is a description of:</p>
<ol>
<li><p>what values its state variables hold,</p>
</li>
<li><p>what values the blockchain-related global variables have at that moment in time, and</p>
</li>
<li><p>the balance (if any) lying in the smart contract account.</p>
</li>
</ol>
<h2 id="heading-state-mutability-keywords-modifiers">State Mutability Keywords (Modifiers)</h2>
<p>Now that we have discussed state, state variables, and functions, let’s understand the Solidity keywords that specify what we are allowed to do with state.</p>
<p>These keywords are referred to as <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/cheatsheet.html#modifiers">modifiers</a>. But not all of them permit you to modify state. In fact many of them expressly <em>disallow</em> modifications.</p>
<p>Here are Solidity modifiers you will see any real-world smart contract:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Modifier Keyword</strong></td><td><strong>Applies to…</strong></td><td><strong>Purpose</strong></td></tr>
</thead>
<tbody>
<tr>
<td>constant</td><td>State variables</td><td>Declared and given a value once, at the same time. Hard coded into code. Its given value can never be changed.</td></tr>
<tr>
<td>immutable</td><td>State variables</td><td>These are declared at the top of smart contracts, but given their value (only once!) at construction time - i.e. via the constructor function.  Once they receive their value, they are (effectively) constants. And their values are actually stored in the code itself rather than in a storage slot (storage will be explained later).</td></tr>
<tr>
<td>view</td><td>functions</td><td>You’ll generally see this right after the visibility specifier.  A view modifier means that the function can only “view” (read from) contract state, but cannot change it (cannot “write” to contract state).  This is effectively a read-only modifier. If the function needs to use any value that is in the contract’s state, but not modify that value, it will be a view function.</td></tr>
<tr>
<td>pure</td><td>functions</td><td>Functions that are pure are not allowed to write to (modify) contract state, nor are they allowed to even read from it!  They do things that do not, in any way, interact with blockchain state.  Often these can be helper functions that do some calculation or convert an input of one data type into another data type etc.</td></tr>
<tr>
<td>payable</td><td>functions</td><td>This keyword enables a function to receive Eth. Without this keyword you cannot send Eth while calling a function.  </td></tr>
</tbody>
</table>
</div><p>Note that in Solidity version 0.8.17, there were <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/080-breaking-changes.html?highlight=payable%20address#new-restrictions">breaking changes</a> that enabled the use of payable as a data type.  Specifically we now allowed to convert the address data type to a payable address type by doing a type conversion that looks like payable(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF).<br>What this does is makes a given ethereum address payable, after which we can send Eth to that address.   </p>
<p>Note that this use of payable is a type conversion, and not the same as the function modifier, though the same keyword is used. We will cover the address type later, but you can read about this <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.16/types.html#address">here</a>. |
| virtual | functions | This is a slightly more advanced topic and is covered in detail in the section on Inheritance. This modifier allows the function to be “overridden” in a child contract that inherits from it.  In other words, a function with the keyword virtual can be “rewritten” with different internal logic in another contract that inherits from this one. |
| override | functions | This is the flip side to the virtual modifier.  When a child contract “rewrites” a function that was declared in a base contract (parent contract) from which it inherits, it marks that rewritten function with override to signal that its implementation overrides the one given in the parent contract. If a parent’s virtual function is not overridden by the child, the parent's implementation will apply to the child. |
| indexed | events | We will cover events later in this handbook.  They are small bundles of data “emitted” by a smart contract typically in response to noteworthy events happening.  The indexed keyword indicates that one of the pieces of data contained in an event should be stored in the blockchain for retrieval and filtering later. This will make more sense once we cover Events and Logging later in this handbook. |
| anonymous | events | The <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/cheatsheet.html#modifiers">docs</a> say “Does not store event signature as topic” which probably doesn’t mean a lot to you just yet.  But the keyword does indicate that it’s making some part of the event “anonymous”. So this will make sense once we understand events and topics later in this handbook. |</p>
<p>Note that variables that are not storage variables ( i.e. local variables declared and used inside the scope of a given function) do not need state modifiers. This is because they’re not actually part of the smart contract’s state. They’re just part of the local state inside that function. By definition then, they’re modifiable and don’t need controls on their modifiability.</p>
<h2 id="heading-data-locations-storage-memory-and-stack">Data Locations – Storage, Memory, and Stack</h2>
<p>On Ethereum and EVM-based chains, data inside the system can be placed and accessed in more than one “data location”.</p>
<p>Data locations are part of the fundamental design and architecture of the EVM. When you see the words “memory”, “storage” and “stack”, you should start thinking “data locations” - that is, where can data be stored (written) to and retrieved (read) from.</p>
<p>Data location has an impact on how the code executes at run time. But it also has very important impacts on how much <a target="_blank" href="https://ethereum.org/en/developers/docs/gas/">gas</a> gets used during deployment and running of the smart contract.</p>
<p>The use of gas requires a deeper understanding of the EVM and something called opcodes - we can park that discussion for now. While useful, it is not strictly necessary for you to understand data locations.</p>
<p>Though I’ve mentioned 3 data <em>locations</em> so far, there are 2 other ways in which data can be stored and accessed in Smart Contracts: “calldata”, and “code”. But these are not data locations in the EVM’s design. They’re just subsets of the 3 data locations.</p>
<p>Let’s start with storage. In the EVM’s design, data that needs to be stored permanently on the blockchain is placed in the relevant smart contract’s “storage” area. This includes any contract “state variables”.</p>
<p>Once a contract is deployed and has its specific address, it also gets its own storage area, which you can think of as a key-value store (like a hash table) where <strong>both</strong> the keys and the values are 256 bit (32 byte) data “words”. And “words” <a target="_blank" href="https://en.wikipedia.org/wiki/Word_\(computer_architecture\)">has a specific meaning</a> in computer architecture.</p>
<p>Because storage persists data on the blockchain permanently, all data needs to be synchronized across all the nodes in the network, which is why nodes have to achieve consensus on data state. This consensus makes storage expensive to use.</p>
<p>You’ve already seen examples of storage variables (aka contract state variables) but here is an example taken from the <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFConsumerBaseV2.sol">Chainlink Verifiable Random Number Consumer smart contract</a></p>
<p><img src="https://lh3.googleusercontent.com/oV_AXHhYqs7DIB_WQvzB7A97qlnVKAoQYAvLCr9euiwC-XlO8d23-HZuwGjkANpEBnMKQ8u1MrBupg8IWjdX9_YubpjQobML8AyKAQ9vnU_nBxgTAxlYHA-JJlc1xZ3wD14zzER6gAyKmkQ7yLQDCKOr2V5M48Xo5t2SfYVoPRJKI_lUJ5yJMh8YSNaT9w" alt="Storage data location. Putting data in the contract's storage layout." width="600" height="400" loading="lazy"></p>
<p><em>Storage data location. Putting data in the contract's storage layout.</em></p>
<p>When the above contract is created and deployed, whatever address that is passed into the contract’s constructor becomes permanently stored in the smart contract’s storage, and is accessible using the variable <code>vrfCoodinator</code>. Since this state variable is marked as <code>immutable</code>, it cannot be changed after this.</p>
<p>To refresh your memory from the previous section on keywords, where we last discussed <code>immutable</code> and <code>constant</code> variables, these values are not put in storage. They become part of the code itself when the contract is constructed, so these values don’t consume as much gas as storage variables.</p>
<p>Now let’s move to <code>memory</code>. This is temporary storage where you can read and write data needed during the running of the smart contract. This data is erased once the functions that use the data are done executing.</p>
<p>The <code>memory</code> location space is like a temporary notepad, and a new one is made available in the smart contract each time a function is triggered. That notepad is thrown away after the execution completes.</p>
<p>When understanding the difference between storage and memory, you can think of storage as a kind of hard disk in the traditional computing world, in the sense that it has “persistent” storage of data. But memory is closer to RAM in traditional computing.</p>
<p>The <code>stack</code> is the data area where most of the EVM’s computations are performed. The EVM follows a <a target="_blank" href="https://en.wikipedia.org/wiki/Stack_machine#Comparison_with_register_machines">stack based computation model</a> and not a register based computation model, which means each operation to be carried out needs to be stored and accessed using a <a target="_blank" href="https://en.wikipedia.org/wiki/Stack_\(abstract_data_type\)">stack data structure</a>.</p>
<p>The stack’s depth - that is the total number of items it can hold - is 1024, and each item in the stack can be 256 bits (32 bytes) long. This is the same as the size of each key and value in the storage data location.</p>
<p>You can read more about how the EVM controls access to the stack data storage area <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/introduction-to-smart-contracts.html#storage-memory-and-the-stack">here</a>.</p>
<p>Next, let's talk about <code>calldata</code>. I have assumed that you have a basic understanding about Ethereum smart contract <a target="_blank" href="https://ethereum.org/en/whitepaper/#messages">messages</a> and <a target="_blank" href="https://ethereum.org/en/developers/docs/transactions/#:~:text=An%20Ethereum%20transaction%20refers%20to,takes%20place%20within%20a%20transaction.">transactions</a>. If you don’t, you should first read those links.</p>
<p>Messages and transactions are how smart contract functions are invoked, and they contain a variety of data necessary for the execution of those functions. This message data is stored in a read-only section of the memory called <code>calldata</code>, which holds things like the function name and parameters.</p>
<p>This is relevant for externally callable functions, as internal and private functions don’t use calldata. Only “incoming” function execution data and function parameters are stored in this location.</p>
<p>Remember, <code>calldata</code> is memory except that <code>calldata</code> is read-only. You cannot write data to it.</p>
<p>And finally, <code>code</code> is not a data location but instead refers to the smart contract's compiled bytecode that is deployed and stored permanently on the blockchain. This bytecode is stored in an immutable ROM (Read Only Memory), that is loaded with the bytecode of the smart contract to be executed.</p>
<p>Remember how we discussed the difference between immutable and constant variables in Solidity? Immutable values get assigned their value once (usually in the constructor) and constant variables have their values hard-coded into the smart contract code. Because they’re hardcoded, constant values are compiled literally and embedded directly into the smart contract’s bytecode, and stored in this code / ROM data location.</p>
<p>Like <code>calldata</code>, <code>code</code> is also read-only - if you understood the previous paragraph you’ll understand why!</p>
<h2 id="heading-how-typing-works">How Typing Works</h2>
<p>Typing is a very important concept in programming because it is how we give structure to data. From that structure we can run operations on the data in a safe, consistent and predictable way.</p>
<p>When a language has strict typing, it means that the language strictly defines what each piece of data’s type is, and a variable that has a type cannot be given another type.</p>
<p>In other words, in strictly typed languages:</p>
<table><tbody><tr><td><p>int a =1&nbsp; // &nbsp; &nbsp; 1 here is of the integer type<br>string b= "1" //&nbsp; 1 here is of the string type</p></td></tr></tbody></table>

<p>But in JavaScript, which is not typed, <code>b=a</code> would totally work - this makes JavaScript “dynamically typed”.</p>
<p>Similarly, in statically typed languages you cannot pass an integer into a function that expects a string. But in JavaScript we can pass anything to a function and the program will still compile but it may throw an error when you execute the program.</p>
<p>For example take this function:</p>
<table><tbody><tr><td><p>function add(a,b){<br>&nbsp; &nbsp; return a + b<br>}<br><br>add(1, 2) // output is 3, of type integer<br><br>add(1, "2") // “2” is a string, not an integer, so the output becomes the string “12” (!?)</p></td></tr></tbody></table>

<p>As you can imagine, this can produce some pretty hard-to-find bugs. The code compiles and can even execute without failing, though it produces unexpected results.</p>
<p>But a strongly typed language would never let you pass the string “2” because the function would insist on the types that it accepts.</p>
<p>Let’s take a look at how this function would be written in a strongly typed language like Go.</p>
<p><img src="https://lh5.googleusercontent.com/KeWnVGJ3xZB9cJGLGVqM3XndabWGp5WeIbSGGn78QGzyTgZoRR6QWYJcyYw2jn150w9Y9qvZM62IW-Seeh_TjbyTmBYcnzZH5vBpCkUsBSVmgPuzFsa3q-UORkOEQZujoPa4EojQl5gWynWac5PVuNzOpS1OR6yGO_A31RsAFXIsRqJfJZ9HZRpdDW0oCQ" alt="How typing works in syntax, using Golang for illustration purposes" width="600" height="400" loading="lazy"></p>
<p><em>How typing works in syntax, using Golang for illustration purposes</em></p>
<p>Trying to pass a <code>string</code> (even if it represents a number) will prevent the program from even compiling (building). You will see an error like this:</p>
<pre><code class="lang-go">./prog.<span class="hljs-keyword">go</span>:<span class="hljs-number">13</span>:<span class="hljs-number">19</span>: cannot use <span class="hljs-string">"2"</span> (untyped <span class="hljs-keyword">string</span> constant) as <span class="hljs-keyword">int</span> value in argument to add

Go build failed.
</code></pre>
<p><a target="_blank" href="https://go.dev/play/p/SrE1CXVD_pj">Try it out for yourself</a>!</p>
<p>So types are important because data that seems the same to a human can be perceived very differently by a computer. This can cause some pretty weird bugs, errors, program crashes and even big security vulnerabilities.</p>
<p>Types also give developers the ability to create their own custom types, which can then be programmed with custom properties (attributes) and operations (behaviors).</p>
<p>Type systems exist so that humans can reason about the data by asking the question “what is this data’s type, and what should it be able to do?” and the machines can do exactly what is intended.</p>
<p>Here is another example of how data that looks the same to you and me may be interpreted in hugely different ways by a processor. Take the sequence of binary digits (that is the digits can only have a value of 0 or 1, which is the <a target="_blank" href="https://www.mathsisfun.com/binary-number-system.html">binary system</a> that processors work with) <code>1100001010100011</code>.</p>
<p>To a human, using the decimal system that looks like a very large number - perhaps 11 gazillion or something.</p>
<p>But to a computer that is binary, so it’s not 11 anything. The computer sees this as a sequence 16 bits (short for binary digits) and in binary this could mean the <em>positive number</em> (unsigned integer) 49,827 or the signed integer -15,709 or the UTF-8 representation of the British Pound symbol £ or something different!</p>
<p><img src="https://lh6.googleusercontent.com/zH0CD3sU2PRWVf0rdtAsvHgV7-7PiyOdKZbz6wOEkE2gax4KeMd7EswERIAR1iEbn_NhI-2P381GDujQ27-o-XiHIyB_lY7pjUKIK7XP-nqzLAlYNdNErYXRYuVPdKsiD4n0wSqtnxcwwP78OAYAUbZ4mFpe9hKSewPymjrSyjaUlIO2Ap28ftinejnLNw" alt="A sequence of bits can be interpreted by a computer to have very different meanings" width="600" height="400" loading="lazy"></p>
<p><em>A sequence of bits can be interpreted by a computer to have very different meanings (</em><a target="_blank" href="https://livebook.manning.com/book/programming-with-types/chapter-1/18"><em>source</em></a><em>)</em></p>
<p>So all this explanation is to say that types are important, and that types can be “inbuilt” into a language <strong>even if</strong> the language does not strictly enforce types, like JavaScript.</p>
<p>JavaScript already has <a target="_blank" href="https://www.w3schools.com/js/js_datatypes.asp">inbuilt types</a> like numbers, strings, booleans, objects, and arrays. But as we saw, JavaScript does not insist on types being stuck to the way a statically typed language like Go does.</p>
<p>Now back to Solidity. Solidity is very much a statically typed language. When you declare a variable you must also declare its type. Going further, Solidity will simply refuse to compile if you try to pass a string into a function that expects an integer.</p>
<p>In fact Solidity is very strict with types. For example, different types of integers may also fail compilation like the following example where the function <code>add()</code> expects an unsigned integer (positive) and will only add to that number thus always returning a positive integer. But the return type is specified as an <code>int</code> which means it could be positive or negative!</p>
<table><tbody><tr><td><p>function add(uint256 a) public pure returns (int256){<br>&nbsp; &nbsp; &nbsp; &nbsp; return a + 10;<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>So even though the input and output are 256-bit integers, the fact that the function only receives unsigned integers makes the compiler complain that the unsigned integer type is <em>not</em> implicitly convertible to the signed integer type.</p>
<p>That’s pretty strict! The developer can force the conversion (called type casting) by rewriting the return statement as <code>return int256(a + 10)</code>. But there are issues to consider with that sort of action, and that’s out of scope for what we’re talking about here.</p>
<p>For now, just remember that Solidity is statically typed, which means that the type of each variable must be expressly specified when declaring them in the code. You can combine types to form more complex, composite types. Next, we can discuss some of these inbuilt types.</p>
<h2 id="heading-solidity-data-types">Solidity Data Types</h2>
<p>Types that are built into the language and come with it “out of the box” are often referred to as “primitives”. They’re intrinsic to the language. You can combine primitive types to form more complex data structures that become “custom” data types.</p>
<p>In JavaScript, for example, <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">primitives</a> are data that is not a JS object <em>and</em> has no methods or properties. There are 7 primitive data types in JavaScript: <code>string</code>, <code>number</code>, <code>bigint</code>, <code>boolean</code>, <code>undefined</code>, <code>symbol</code>, and <code>null</code>.</p>
<p>Solidity also has its own primitive data types. Interestingly, Solidity does <em>not</em> have “undefined” or “null”. Instead, when you declare a variable and its type, but do not assign a value to it, Solidity will assign a <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/control-structures.html#default-value">Default Value</a> to that type. What exactly that default value is depends on the data type .</p>
<p>Many of Solidity’s primitive data types are variations of the same ‘base’ type. For example the <code>int</code> type itself has subtypes based on the number of binary digits that the <code>integer</code> type can hold.</p>
<p>If that confuses you a bit, don’t worry - it isn’t easy if you’re not familiar with bits and bytes, and I’ll cover integers a bit more shortly.</p>
<p>Before we explore Solidity types, there is another very important concept that you must understand - it is the source of many bugs, and “unexpected gotchas” in programming languages.</p>
<p>This is the difference between a value type and reference type, and the resulting distinction between data in programs being “passed by value” vs “passed by reference”. I’ll go into a quick summary below but you may also find it useful to watch <a target="_blank" href="https://www.youtube.com/watch?v=1HHjKG1372E">this short video</a> to strengthen your mental model before proceeding.</p>
<h3 id="heading-pass-by-reference-vs-pass-by-value">Pass by reference vs pass by value</h3>
<p>At an operating system level, when a program is running, all data used by the program during its execution is stored in locations in the computer’s RAM (memory). When you declare a variable, some memory space is allocated to hold data about that variable and the value that is, or eventually will be, assigned to that variable.</p>
<p>There is also a piece of data that is often called a “pointer”. This pointer points to the memory location (an “address” in the computer’s RAM) where that variable and its value can be found. So the pointer effectively contains a <em>reference</em> to where the data can be found in the computer’s memory.</p>
<p>So when you pass data around in a program (for example when you assign a value to a new variable name, or when you pass inputs (parameters) into a function or method, the language’s compiler can achieve this in two ways. It can pass a pointer to the data’s location in the computer’s memory, <strong>or</strong> it can make a copy of the data itself, and pass the actual value.</p>
<p>The first approach is “pass by reference”. The second approach is “pass by value”.</p>
<p>Solidity’s data type primitives fall into two buckets - they’re either value types, or they’re reference types.</p>
<p>In other words, in Solidity, when you pass data around, the type of the data will decide whether you’re passing copies of the value or a reference to the value’s location in the computer’s memory.</p>
<p><img src="https://lh6.googleusercontent.com/Nj0wt2rDWoanEGT3onBaNxJEnoBp-7NXBrXdL07SO1qbj6PYiE-fhz2zGId-AuGqLiMMHCJIwYbEMYp5oKebmhMudnOhhM_-ZRkLBiatMR6zgcpAPbMDl4hqlLr4UJYa061Plha044IqX_pqeWnx5V1P53dYxopqlddIFmj7qHnXAclPKdLy4XYuwkeGlA" alt="Value Types and Reference Types in Solidity" width="600" height="400" loading="lazy"></p>
<p><em>Value Types and Reference Types in Solidity</em></p>
<p>In Solidity’s “value types”, integers are of two categories - <code>uint</code> is unsigned (positive integers only, so they have no plus or minus signs) and <code>int</code> is signed (could be positive or negative, and if you wrote them down, they’d have a plus or minus sign).</p>
<p>Integer types can also specify how many bits long they are - or how many bits are used to represent the <code>integer</code>.</p>
<p>An <code>uint8</code> is an integer represented by 8 binary digits (bits) and can store up to 256 different values (2^8=256). Since <code>uint</code> is for unsigned (positive) integers, this means it can store values from 0 to 255 (not including 1 to 256).</p>
<p>However when you have signed integers, like an <code>int8</code>, then one of the bits is used up to represent whether it's a positive or negative number. That means we have only 7 bits left, and so we can only represent up to 2^7 (128) different values, including 0. So an <code>int8</code> can represent anything from -127 to +127.</p>
<p>By extension, an <code>int256</code> is 256 bits long and can store +/- (2^255) values.</p>
<p>The bit lengths are <a target="_blank" href="https://docs.soliditylang.org/fr/latest/types.html#integers">multiples of 8</a> (because 8 bits makes a byte) so you can have <code>int8</code>, <code>int16</code>, <code>int24</code> etc all the way to 256 (32 bytes).</p>
<p>Addresses refer to the Ethereum account types - either a smart contract account or an externally owned account (aka “EOA”. Your Metamask wallet represents an EOA). So an address is also a type in Solidity.</p>
<p>The default value of an address (that is the value it will have if you declare a variable of type address but don’t assign it any value) is <code>0x0000000000000000000000000000000000000000</code> which is also the result of this expression: <code>address(0)</code>.</p>
<p>Booleans represent either true or false values. Finally, we have <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/types.html#fixed-size-byte-arrays">fixed size byte arrays</a> like <code>bytes1</code>, <code>bytes2</code> … <code>bytes32</code>. These are arrays of fixed length that contain bytes. All these types of values are copied when they’re passed around in the code.</p>
<p>For “reference types”, we have arrays, which can have a fixed size specified when they’re declared, or dynamically sized arrays, which start off with a fixed size, but can be “resized” as the number of data elements in the array grows.</p>
<p>Bytes are a low-level data type that refer to the data that is encoded into binary format. All data is eventually reduced to binary form by the compiler so that the EVM (or, in traditional computing, the processor) can work with it.</p>
<p>Storing and working with bytes is often faster and more efficient compared to other data types that are more human readable.</p>
<p>You may be wondering why I’ve not referred to strings in either types of data in the picture above. That’s because in Solidity, strings are actually dynamically-sized arrays, and the arrays store a sequence of bytes (just binary numbers) that are encoded in the UTF-8 encoding format.</p>
<p>They’re not a primitive in Solidity. In JavaScript they’re referred to as primitives, but even in JavaScript strings are similar (but not the same as) to arrays and <a target="_blank" href="https://tc39.es/ecma262/#sec-ecmascript-language-types-string-type">are a sequence of integer values</a>, encoded in UTF-16.</p>
<p>It is often more efficient to store a <code>string</code> as a <code>bytes</code> type in a smart contract, as converting between <code>strings</code> and <code>bytes</code> is quite easy. It is therefore useful to store <code>strings</code> as <code>bytes</code> but return them in functions as strings. You can see an example below:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br><br>pragma solidity ^0.8.0;<br><br><br>contract StringyBytes {</p></td></tr></tbody></table>

<p>Other than Solidity strings, the <code>bytes</code> data type is a <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/types.html#dynamically-sized-byte-array">dynamically sized byte array</a>. Also, unlike its fixed-size byte array cousin, it's a reference type. The <code>bytes</code> type in Solidity is a shorthand for “array of bytes” and can be written in the program as <code>bytes</code> or <code>byte[]</code>.</p>
<p>If you’re confused by bytes and byte arrays…I sympathise.</p>
<p>The underlying gory details of strings and byte arrays are not too relevant for this handbook. The important point for now is that some data types are passed by reference and others are passed by copying their values.</p>
<p>Suffice it to say that Solidity strings and bytes without a size specified are reference types because they’re both dynamically sized arrays.</p>
<p>Finally, among Solidity’s primitives, we have <code>structs</code> and <code>mappings</code>. Sometimes these are referred to as “composite” data types because they’re composed from other primitives.</p>
<p>A <code>struct</code> will define a piece of data as having one or more properties or attributes, and specifying each property’s data type and name. Structs give you the ability to define your own custom type so that you can organize and collect pieces of data into one larger data type.</p>
<p>For example you could have struct that defines a <code>Person</code> as follows:</p>
<table><tbody><tr><td><p>struct Person {<br>&nbsp; &nbsp; string name;<br>&nbsp; &nbsp; uint age;</p></td></tr></tbody></table>

<p>You can instantiate or initialize a <code>Person</code> struct in the following ways:</p>
<table><tbody><tr><td><p>// dot notation updating. Job struct is uninitialized<br>// which means that its properties will have their respect default values<br>Person memory p;<br>P.name = "Zubin"<br>p.age = 41;<br>p.isSolidityDev = true;<br><br>// Or in a function-style call. Note I'm initializing a Job struct too!<br>Person p =&nbsp; Person("Zubin",&nbsp; "41", "true", Job("Chainlink Labs", "DevRel", true));<br><br>// Or in a key-value style<br>Job j = Job({ employer: "Chainlink Labs", "DevRel",&nbsp; true});<br>p.job = j // this is done in dot notation style.</p></td></tr></tbody></table>

<p>Mappings are similar to hashtables, dictionaries or JavaScript objects and maps, but with a little less functionality.</p>
<p>A <code>mapping</code> is also a key-value pair, and there are restrictions on the kinds of data types you can have as keys, which you can read about <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/types.html#mapping-types">here</a>. The data types associated with a mapping’s keys can be any of primitives, structs, and even other mappings.</p>
<p>Here is how mappings are declared, initialized, written to and read from - the below example is from the <a target="_blank" href="https://github.com/smartcontractkit/LinkToken/blob/f307ea6d4c02dd87ea4c1f1032e3e384ceac20c2/contracts/v0.4/token/linkStandardToken.sol">Chainlink Link Token Smart Contract source code</a>.</p>
<p><img src="https://lh5.googleusercontent.com/5x3v-NtBWU2gejrQDWU1m-D-9ZXzTi5JLDs2bMCq1d-TVoxCjFmTEEQg1af4pxEfRbrrpnQaPJLcVauLOZ-amT2hDuNhvXVuX9-cMdMWPiGiRblgcC-oX9dkt75uHzO1ieBVFl_MA6NtJMmWZQ39ypOhOE4qHQWEzk410vme9TR2_lvEzGI2O9_NPo2JGg" alt="Declaring and using the Mappings type in Solidity" width="600" height="400" loading="lazy"></p>
<p><em>Declaring and using the Mappings type in Solidity</em></p>
<p>If you try to access a value using a key that doesn’t exist in the mapping, it will return the <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/control-structures.html#default-value">default value</a> of the type that is stored in the mapping.</p>
<p>In the above example, the type of all values in the <code>balances</code> mapping is <code>uint256</code>, which has a default value of <code>0</code>. So if we called <code>balanceOf()</code> and passed in an address that does not have any LINK tokens issued to it, we’d get a value of <code>0</code> back.</p>
<p>This is reasonable in this example, but it can be a bit tricky when we want to find out whether or not a key exists in a mapping.</p>
<p>Currently there is no way to enumerate what keys exist in a mapping (that is, there is nothing equivalent to <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">JavaScript’s <code>Object.keys()</code></a> method). Retrieving using a key will only return the default value associated with the data type, which does not clearly tell us whether or not the key actually exists.</p>
<p>There is an interesting “gotcha” with mappings. Unlike other languages where you can pass key-value data structures as an argument to function, Solidity does not support passing mappings as arguments to functions except where the functions visibility is marked as <code>internal</code>. So you could not write an externally or publicly callable function that would accept key-value pairs as an argument.</p>
<h2 id="heading-how-to-declare-and-initialize-arrays-in-solidity">How to Declare and Initialize Arrays in Solidity</h2>
<p>Solidity comes with two flavors of arrays, so it is useful to understand the different ways in which they can be declared and initialized.</p>
<p>The two main types of arrays in Solidity are the fixed-size array and the dynamic-sized array.</p>
<p>To refresh your memory, fixed-size arrays are passed by value (copied when passed around in the code) and dynamic-sized arrays are passed by reference (a pointer to the memory address is passed around in the code).</p>
<p>They’re also different in their syntax and their capacity (size), which then dictates when we would use one versus the other.</p>
<p>Here’s what a fixed-size array looks like when declared and initialized. It has a fixed capacity of 6 elements, and this cannot be changed once declared. The memory space for an array of 6 elements is allocated and cannot change.</p>
<table><tbody><tr><td><p>string[6] fixedArray; // Max capacity is 6 elements.</p></td></tr></tbody></table>

<p>A fixed-size array can also be declared by just declaring a variable and the size of the array and the type of its elements with the following syntax:</p>
<table><tbody><tr><td><p>// datatype arrayName[arraySize];</p></td></tr></tbody></table>

<p>Contrast that with a dynamically-sized array that is declared and initialized as follows. Its capacity is unspecific and you can add elements using the push() method:</p>
<table><tbody><tr><td><p>uint[] dynamicArray;</p></td></tr></tbody></table>

<p>You can also declare and initialize the value of an array in the same line of code.</p>
<table><tbody><tr><td><p>string[3] fixedArray = ["a", "b", "c"]; // Fixed sized string array<br>fixedArray.push("abc"); // Won't work for fixed size arrays.<br><br>String[] dynamicArray =["chainlink", "oracles"]; /// Dynamic sized array<br>dynamicArray.push("rocks");&nbsp; // Works.</p></td></tr></tbody></table>

<p>These arrays are available in storage. But what if you needed only temporary in-memory arrays inside a function? In that case there are two rules: only fixed size arrays are allowed, and you must use the <code>new</code> keyword.</p>
<table><tbody><tr><td><p>function inMemArray(string memory firstName, string memory lastName)<br>&nbsp; &nbsp; &nbsp; &nbsp; public<br>&nbsp; &nbsp; &nbsp; &nbsp; pure<br>&nbsp; &nbsp; &nbsp; &nbsp; returns (string[] memory)<br>&nbsp; &nbsp; {</p></td></tr></tbody></table>

<p>Clearly, there are several ways to declare and initialize arrays. When you’re wanting to optimize for gas and computations you want to carefully consider which type of arrays are required, what their capacity is, and if they’re likely to grow without an upper bound.</p>
<p>This also influences and is influenced by the design of your code - whether you need arrays in storage or whether you need them only in memory.</p>
<h2 id="heading-what-are-function-modifiers">What are Function Modifiers?</h2>
<p>When writing functions, we often receive inputs that need some sort of validation, checking, or other logic run on those inputs before we go ahead with the rest of the “business” logic.</p>
<p>For example, if you’re writing in pure JavaScript, you may want to check that your function receives integers and not strings. If it’s on the backend you may want to check that the POST request contained the right authentication headers and secrets.</p>
<p>In Solidity, we can perform these sort of validation steps by declaring a function-like block of code called a modifier.</p>
<p>A modifier is a snippet of code that can run automatically before or after you run the main function (that is, the function that has the modifier applied to it).</p>
<p>Modifiers can be inherited from parent contracts too. It is generally used as a way to avoid repeating your code, by extracting common functionality and putting it in a modifier that can be reused throughout the codebase.</p>
<p>A <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/contracts.html#modifiers">modifier</a> looks a lot like a function. The key thing to observe about a modifier is where the <code>_</code> (underscore) shows up. That underscore is like a “placeholder” to indicate when the main function will run. It reads as if we inserted the main function where the underscore is currently.</p>
<p>So in the modifier snippet below, we run the conditional check to make sure that the message sender is the owner of the contract, and <em>then</em> we run the rest of the function that called this modifier. Note that a single modifier can be used by any number of functions.</p>
<p><img src="https://lh4.googleusercontent.com/Suv8g0wpHjPOgWCljmrlorL4CcqBrYS2JQWMjIpGMleXCSayt7P7dzobb_5G5sueR_v6LZu9R_RLPFWjBtgLAV9MlLIe-3zw5sG6FgfjdJUf3B994xhkZxTcTJsYx1RSIplKYZpeQhX85HG-Er6ZFu7hlBXOT9QGrmQzY7AoZFB6pzUm6s2peDf4OKkUcQ" alt="How function modifiers are written, and the role of the underscore symbol" width="600" height="400" loading="lazy"></p>
<p><em>How function modifiers are written, and the role of the underscore symbol</em></p>
<p>In this example, the <code>require()</code> statement runs before the underscore (<code>changeOwner()</code>) and that’s the correct way to ensure that only the current owner can change who owns the contract.</p>
<p>If you switched the modifier’s lines and the <code>require()</code> statement came second, then the code in <code>changeOwner()</code> would run first. Only after that would the <code>require()</code> statement run, and that would be a pretty unfortunate bug!</p>
<p>Modifiers can take inputs too - you’d just pass the type and name of the input into a modifier.</p>
<table><tbody><tr><td><p>modifier validAddress(address addr) {<br>&nbsp; &nbsp; // address should not be a zero-address.<br>&nbsp; &nbsp; require(addr != address(0), "Address invalid");<br>&nbsp;&nbsp;&nbsp;&nbsp;</p></td></tr></tbody></table>

<p>Modifiers are a great way to package up snippets of logic that can be reused in various smart contracts that together power your dApp. Reusing logic makes your code easier to read, maintain and reason about – hence the principle <a target="_blank" href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> (Don’t Repeat Yourself).</p>
<h2 id="heading-error-handling-in-solidity-require-assert-revert">Error Handling in Solidity - Require, Assert, Revert</h2>
<p>Error handling in Solidity can be achieved through a few different keywords and operations.</p>
<p>The EVM will revert all changes to the blockchain’s state when there is an error In other words, when an exception is thrown, and it’s not caught in a try-catch block, the exception will “bubble up” the stack of methods that were called, and be returned to the user. All changes made to the blockchain state in the current call (and its sub-calls) get reversed.</p>
<p>There are some exceptions, in low-level functions like <code>delegatecall</code>, <code>send</code>, <code>call</code>, and so on, where an error will return the boolean <code>false</code> back to the caller, rather than bubble up an error.</p>
<p>As a developer there are three approaches you can take to handle and throw errors. You can use <code>require()</code>, <code>assert()</code> or <code>revert()</code>.</p>
<p>A require statement evaluates a boolean condition you specify, and if false, it will throw an error with no data, or with a string that you provide:</p>
<table><tbody><tr><td><p>function requireExample() public pure {<br>&nbsp; &nbsp; require(msg.value &gt;= 1 ether, "you must pay me at least 1 ether!");<br>}</p></td></tr></tbody></table>

<p>We use <code>require()</code> to validate inputs, validate return values, and check other conditions before we proceed with our code logic.</p>
<p>In this example, if the function’s caller does not send at least 1 ether, the function will revert and throw an error with a string message: “<em>you must pay me at least 1 ether!</em>”.</p>
<p>The error string that you want returned is the second argument to the <code>require()</code> function, but it is optional. Without it, your code will throw an error with no data - which is not terribly helpful.</p>
<p>The good thing about a <code>require()</code> is that it will return gas that has not been used, but gas that was used before the <code>require()</code> statement will be lost. That’s why we use <code>require()</code> as early as possible.</p>
<p>An <code>assert()</code> function is quite similar to <code>require()</code> except that it <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/control-structures.html#panic-via-assert-and-error-via-require">throws an error with type <code>Panic(uint256)</code> rather than <code>Error(string)</code></a>.</p>
<table><tbody><tr><td><p>contract ThrowMe { &nbsp;<br>&nbsp; &nbsp; function assertExample() public pure {<br>&nbsp; &nbsp; &nbsp; &nbsp; assert(address(this).balance == 0);<br>&nbsp; // Do something.<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>An assert is also used in slightly different situations– where a different type of guarding is required.</p>
<p>Most often you use an assert to check an “invariant” piece of data. In software development, an invariant is one or more pieces of data whose value never changes while the program is executing.</p>
<p>In the above code example, the contract is a tiny contract, and is not designed to receive or store any ether. Its design is meant to ensure that it always has a contract balance of zero, which is the invariant we test for with an assert.</p>
<p><code>Assert()</code> calls are also used in internal functions. They test that local state does not hold unexpected or impossible values, but which may have changed due to the contract state becoming “dirty”.</p>
<p>Just as <code>require()</code> does, an <code>assert()</code> will also revert all changes. Prior to Solidity’s v0.8, <code>assert()</code> used to use up all remaining gas, which was different from <code>require()</code>.</p>
<p>In general, you’d likely use <code>require()</code> more than <code>assert()</code>.</p>
<p>A third approach is to use a <code>revert()</code> call. This is generally used in the same situation as a <code>require()</code> but where your conditional logic is much more complex.</p>
<p>In addition, you can throw custom-defined errors when using <code>revert()</code>. Using custom errors can often be cheaper in terms of gas used, and are generally more informative from a code and error readability point of view.</p>
<p>Note how I improve the readability and traceability of my error by prefixing my custom error’s name with the Contract name, so we know which contract threw the error.</p>
<table><tbody><tr><td><p>contract ThrowMe { &nbsp;<br>&nbsp; &nbsp; // custom error<br>&nbsp; &nbsp; error ThrowMe_BadInput(string errorMsg, uint inputNum);<br><br>&nbsp; &nbsp; function revertExample(uint input) public pure {<br>&nbsp; &nbsp; &nbsp; &nbsp; if (input &lt; 1000 ) {<br>&nbsp; &nbsp; revert ThrowMe_BadInput("Number must be an even number greater than 999",&nbsp; input);<br>&nbsp; &nbsp; &nbsp; }<br><br>&nbsp; &nbsp; &nbsp; if (input &lt; 0) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; revert("Negative numbers not allowed");<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>In the above example, we use revert once with a custom error that takes two specific arguments, and then we use revert another time with only a string error data. In either case, the blockchain state is reverted and unused gas will be returned to the caller.</p>
<h2 id="heading-inheritance-in-solidity">Inheritance in Solidity</h2>
<p><a target="_blank" href="https://www.freecodecamp.org/news/inheritance-in-java-explained/">Inheritance</a> is a powerful concept in Object Oriented Programming (OOP). We won't go into the details of what <a target="_blank" href="https://www.freecodecamp.org/news/object-oriented-concepts/">OOP</a> is here. But the best way to reason about inheritance in programming is to think of it as a way by which pieces of code “inherit” data and functions from other pieces of code by importing and embedding them.</p>
<p><a target="_blank" href="https://goo.gl/maps/YgMqAwFfHUP8EZmS9">Inheritance in Solidity</a> also allows a developer to access, use and modify the properties (data) and functions (behaviour) of contracts that are inherited from.</p>
<p>The contract that receives this inherited material is called the derived contract, child contract or the subclass. The contract whose material is made available to one or more derived contracts is called a parent contract.</p>
<p>Inheritance facilitates convenient and extensive code reuse – imagine a chain of application code that inherits from other code, and those in turn inherit from others and so on. Rather than typing out the entire hierarchy of inheritance, we can just use a a few key words to “extend” the functions and data captured by all the application code in the inheritance chain. That way child contract gets the benefit of all parent contracts in its hierarchy, like genes that get inherited down each generation.</p>
<p>Unlike some programming languages like Java, Solidity allows for multiple inheritance. Multiple inheritance refers to the ability of a derived contract to inherit data and methods from more than one parent contract. In other words, one child contract can have multiple parents.</p>
<p>You can spot a child contract and identify its parent contract by looking for the <code>is</code> keyword.</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; string public constant A_NAME = "A";<br><br>&nbsp; &nbsp; function getName() public pure returns (string memory) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return A_NAME;<br>&nbsp; &nbsp; }<br>}<br><br>contract B is A {<br>&nbsp; &nbsp; string public constant B_NAME = "B";<br>}</p></td></tr></tbody></table>

<p>If you were to deploy only Contract B using the in-browser <a target="_blank" href="http://remix.ethereum.org">Remix IDE</a> you’d note that Contract B has access to the <code>getName()</code> method even though it was not ever written as part of Contract B. When you call that function, it returns “A” , which is data that is implemented in Contract A, not contract B. Contract B has access to both storage variables <code>A_NAME</code> and <code>B_NAME</code>, and all functions in Contract A.</p>
<p>This is how inheritance works. This is how Contract B reuses code already written in Contract A, which could have been written by someone else.</p>
<p>Solidity lets developers change how a function in the parent contract is implemented in the derived contract. Modifying or replacing the functionality of inherited code is referred to as “overriding”. To understand it, let’s explore what happens when Contract B tries to implement its own <code>getName()</code> function.</p>
<p>Modify the code by adding a <code>getName()</code> to Contract B. Make sure the function name and signature is identical to what is in Contract A. A child contract’s implementation of logic in the <code>getName()</code> function can be totally different from how it’s done in the parent contract, as long as the function name and its signature are identical.</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; string public constant A_NAME = "A";<br><br>&nbsp; &nbsp; function getName() public returns (string memory) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return A_NAME;<br>&nbsp; &nbsp; }<br>}<br><br>contract B is A {<br>&nbsp; &nbsp; string public constant B_NAME = "B";<br><br>&nbsp; &nbsp; function getName() public returns (string memory) {</p></td></tr></tbody></table>

<p>The compiler will give you two errors:</p>
<ol>
<li><p>In Contract A, it will indicate that you are “<em>trying to override non-virtual function</em>” and prompt you by asking if you forgot to add the <code>virtual</code> keyword.</p>
</li>
<li><p>In Contract B, it will complain that the <code>getName()</code> function is missing the <code>override</code> specifier.</p>
</li>
</ol>
<p>This means that your new <code>getName</code> in Contract B is attempting to override a function by the same name in the parent contract, but the parent’s function is not marked as <code>virtual</code> – which means that it cannot be overridden.</p>
<p>You could change Contract A’s function and add <code>virtual</code> as follows:</p>
<table><tbody><tr><td><p>function getName() public virtual returns (string memory) {<br>&nbsp; &nbsp; return A_NAME;<br>}</p></td></tr></tbody></table>

<p>Adding the keyword <code>virtual</code> does not change how the function operates in Contract A. And it does not require that inheriting contracts <strong>must</strong> re-implement or override it. It simply means that this function <strong>may</strong> be overridden by any derived contracts if the developer chooses.</p>
<p>Adding <code>virtual</code> fixes the compiler’s complaint for Contract A, but not for Contract B. This is because <code>getName</code> in Contract B needs to also add the <code>override</code> keyword as follows:</p>
<table><tbody><tr><td><p>function getName() public pure override returns (string memory) {<br>&nbsp; &nbsp; return B_NAME;<br>}</p></td></tr></tbody></table>

<p>We also add the <code>pure</code> keyword for Contract B’s getName() as this function does not change the state of the blockchain, and reads from a constant (constants, you’ll remember, are hardcoded into the bytecode at compile time and are not in the storage data location).</p>
<p>Keep in mind that you only need to override a function if the name and the signature are identical.</p>
<p>But what happens with functions that have identical names but different arguments? When this happens it’s not an override, but an overload. And there is no conflict because the methods have different arguments, and so there is enough information in their signatures to show the compiler that they're different.</p>
<p>For example, in contract B we could have another <code>getName()</code> function that takes an argument, which effectively gives the function a different “signature” compared to the parent Contract A’s <code>getName()</code> implementation. Overloaded functions do not need any special keywords:</p>
<table><tbody><tr><td><p>// getName() now accepts a string argument.&nbsp;</p></td></tr></tbody></table>

<p>Don’t worry about the <code>abi.encodepacked()</code> method call. I’ll explain that later when we talk about encoding and decoding. For now just understand that <code>encodepacked()</code> encodes the strings into bytes and then concatenates them, and returns a bytes array.</p>
<p>We discussed the relationship between Solidity strings and bytes in a previous section of this handbook (under Typing).</p>
<p>Also, since you’ve already learned about function modifiers, this is a good place to add that modifiers are also inheritable. Here’s how you’d do it:</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; modifier X virtual {<br>&nbsp; &nbsp; &nbsp; &nbsp;// … some logic</p></td></tr></tbody></table>

<p>You might wonder which version of a function will be called if a function by the same name and signature exists in a chain of inheritance.</p>
<p>For example, let's say there is a chain of inherited contracts like A → B → C → D → E and all of them have a <code>getName()</code> that overrides a <code>getName()</code> in the previous parent contract.</p>
<p>Which <code>getName()</code> gets called? The answer is the last one – the “most derived” implementation in the contract hierarchy.</p>
<p>State variables in child contracts cannot have the same name and type as their parent contracts.</p>
<p>For example, Contract B below will not compile because its state variable “shadows” that of the parent Contract A. But note how Contract C correctly handles this:</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; string public author = "Zubin";<br><br>&nbsp; &nbsp; function getAuthor() public virtual returns (string memory) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return author;<br>&nbsp; &nbsp; }<br>}<br><br></p></td></tr></tbody></table>

<p>It’s important to note that by passing a new value to the variable <code>author</code> in Contract C’s constructor, we are effectively overriding the value in Contract A. And then calling the inherited method <code>C.getAuthor()</code> will return ‘Hemingway’ and not ‘Zubin’!</p>
<p>It is also worth noting that when a contract inherits from one or more parent contract, only one single (combined) contract is created on the blockchain. The compiler effectively compiles all the other contracts and their parent contracts and so on up the entire hierarchy all into a single compiled contract (which is referred to as a “flattened” contract).</p>
<h2 id="heading-inheritance-with-constructor-parameters">Inheritance with Constructor Parameters</h2>
<p>Some constructors specify input parameters and so they need you to pass arguments to them when instantiating the smart contract.</p>
<p>If that smart contract is a parent contract, then its derived contracts must also pass arguments to instantiate the parent contracts.</p>
<p>There are two ways to pass arguments to parent contracts - either in the statement that lists the parent contracts, or directly in the constructor functions for each parent contract. You can see both approaches below:</p>
<p><img src="https://lh5.googleusercontent.com/8MV8HOaET3aVL30ygclKgPhUKIiMK8feTpNNN20W4qFQ880SPBFNeRb2BsS7fLR7b8iUJpRPdG1osMGT451FKOZGpuiihn8h00hTHipxe-MPh9QQ1t2bm2r-qhe4xj7vFFewg64ve9NPjlMlN3BHaX7hWG2ZJvMC8-tsHS2vV74ZluERre2fcH_52CFO9Q" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In Method 2 in the <code>ChildTwo</code> contract, you’ll note that the arguments passed to the parent contracts are first supplied to the child contract and then just passed up the inheritance chain.</p>
<p>This is not necessary, but is a very common pattern. The key point is that where parent contract constructor functions expect data to be passed to them, we need to provide them when we instantiate the child contract.</p>
<h2 id="heading-type-conversion-and-type-casting-in-solidity">Type Conversion and Type Casting in Solidity</h2>
<p>Sometimes we need to convert one data type to another. When we do so we need to be very careful when converting data and how the converted data is understood by the computer.</p>
<p>As we saw in our discussion on typed data, JavaScript can sometimes do strange things to data because it is dynamically typed. But that’s also why it’s useful to introduce the concept of type casting and type conversions generally.</p>
<p>Take the following JavaScript code:</p>
<table><tbody><tr><td><p>var a = "1"<br>var b = a +&nbsp; 9 // we get the string '19'!!<br>typeof a // string<br>typeof b // string&nbsp;</p></td></tr></tbody></table>

<p>There are two ways of converting the variable <code>a</code> into an integer. The first, called type casting, is done explicitly by the programmer and usually involves a constructor-like operator that uses <code>()</code>.</p>
<table><tbody><tr><td><p>a = Number(a) // Type casting the string to number is explicit.<br>typeof a // number</p></td></tr></tbody></table>

<table><tbody><tr><td><p>var b = a +&nbsp; 9 // 10. A number. More intuitive!</p></td></tr></tbody></table>

<p>Now let's reset <code>a</code> to a string and do an implicit conversion, also known as a type conversion. This is implicitly done by the compiler when the program is executed.</p>
<table><tbody><tr><td><p><em>a = '1'</em><br><em>var b = a * 9 // Unlike addition, this doesn't concatenate but implicitly converts 'a' to a number!&nbsp;</em></p></td></tr></tbody></table>

<p>In Solidity, type casting (explicit conversion) is permissible between some types, and would look like this:</p>
<table><tbody><tr><td><p>uint256 a = 2022;<br>bytes32 b = bytes32(a);</p></td></tr></tbody></table>

<p>In this example we converted an integer with a size of 256 bits (since 8 bits makes 1 byte, this is 32 bytes) into a bytes array of size 32.</p>
<p>Since both the integer value of 2022 and the bytes value are of length 32 bytes, there was no “loss” of information in the conversion.</p>
<p>But what would happen if you tried to convert 256 bits into 8 bits (1 byte)? Try running the following in your browser-based Remix IDE:</p>
<table><tbody><tr><td><p>contract Conversions {<br>&nbsp; function explicit256To8() public pure returns (uint8) {<br>&nbsp; &nbsp; &nbsp; uint256 a = 2022;<br>&nbsp; &nbsp; &nbsp; uint8 b = uint8(a);<br>&nbsp; &nbsp; &nbsp; return b;<em> // 230.</em>&nbsp;&nbsp;&nbsp;</p></td></tr></tbody></table>

<p>Why does the integer 2022 get converted to 230? That’s clearly an undesirable and unexpected change in the value. A bug, right?</p>
<p>The reason is that an unsigned integer of size 256 bits will hold 256 binary digits (either 0 or 1). So <code>a</code> holds the integer value ‘2022’ and that value, in bits, will have 256 digits, of which most will be 0, except for the last 11 digits which will be... (see for yourself by converting 2022 from decimal system to binary <a target="_blank" href="https://decimaltobinary.com/256-in-binary">here</a>).</p>
<p>The value of <code>b</code> on the other hand will have only 8 bits or digits, being 11100110. This binary number, when converted to decimal (you can use the same converter - just fill in the other box!) is 230. Not 2022.</p>
<p>Oopsie.</p>
<p>So what happened? When we dropped the integer’s size from 256 bits to 8 bits we ended up shaving the first three digits of data (11111100110) which totally changed the value in binary!</p>
<p>This, folks, is information loss.</p>
<p>So when you’re explicitly casting, the compiler will let you do it in some cases. But you could lose data, and the compiler will assume you know what you’re doing because you’re explicitly asking to do it. This can be the source of many bugs, so make sure you test your code properly for expected results and be careful when explicitly casting data to smaller sizes.</p>
<p>Casting up to larger sizes does not result in data lost. Since 2022 needs only 11 bits to be represented, you could declare the variable <code>a</code> as type <code>uint16</code> and then up-cast it to a variable <code>b</code> of type <code>uint256</code> without data loss.</p>
<p>The other kind of casting that is problematic is when you’re casting from unsigned integers to signed integers. Play around with the following example:</p>
<table><tbody><tr><td><p>contract Conversions {<br>&nbsp; function unsignedToSigned() public pure returns (int16, uint16) {<br>&nbsp; &nbsp; &nbsp; int16 a = -2022;<br>&nbsp; &nbsp; &nbsp; uint16 b = uint16(a);<br>&nbsp; &nbsp; &nbsp; // uint256 c = uint256(a); // Compiler will complain<br>&nbsp; &nbsp; &nbsp; return (a, b); // b is 63514<br>&nbsp; }<br>}</p></td></tr></tbody></table>

<p>Note that <code>a</code> , being a signed integer of size 16 bits holds -2022 as a (negative integer) value. If we explicitly type cast it to an <em>unsigned</em> integer (only positive) values, the compiler will let us do it.</p>
<p>But if you run the code, you’ll see that <code>b</code> is not -2022 but 63,514! Because <code>uint</code> cannot hold information regarding the minus sign, it has lost that data, and the resulting binary gets converted to a massive decimal (base 10) number - clearly undesirable, and a bug.</p>
<p>If you go further, and un-comment the line that assigns the value of <code>c</code>, you’ll see the compiler complain with '<em>Explicit type conversion not allowed from "int16" to "uint256"</em>'. Even though we are up-casting to a larger number of bits in <code>uint256</code>, because <code>c</code> is an unsigned integer, it cannot hold minus sign information.</p>
<p>So when explicitly casting, be sure to think through what the value will evaluate to after you’ve forced the compiler to change the type of the data. It is the source of many bugs and code errors.</p>
<p>There is more to Solidity type conversions and type casting and you can go deep into some of the nitty gritty in <a target="_blank" href="https://betterprogramming.pub/solidity-tutorial-all-about-conversion-661130eb8bec">this article</a>.</p>
<h2 id="heading-how-to-work-with-floating-point-numbers-in-solidity">How to Work with Floating Point Numbers in Solidity</h2>
<p>Solidity doesn’t handle decimal points. That may change in the future, but currently you cannot really work with fixed (floating) point numbers like 93.6. In fact typing <code>int256 floating = 93.6;</code> in your Remix IDE will throw an error like : <em>Error: Type rational_const 468 / 5 is not implicitly convertible to expected type int256.</em></p>
<p>What’s going on here? 468 divided by 5 is 93.6, which seems a weird error, but that’s basically the compiler saying it cannot handle floating point numbers.</p>
<p>Follow the suggestions of the error, and declare the variable’s type to be <code>fixed</code> or <code>ufixed16x1</code>.</p>
<table><tbody><tr><td><p>fixed floating = 93.6;</p></td></tr></tbody></table>

<p>You’ll get an “<em>UnimplementedFeatureError: Not yet implemented - FixedPointType</em>” error.</p>
<p>So in Solidity, we get around this by converting the floating point number to a whole number (no decimal points) by multiplying by 10 raised to the exponent of the number of decimal places to the right of the decimal point.</p>
<p>In this case we multiply 93.6 by 10 to get 936 and we have to keep track of our factor (10) in a variable somewhere. If the number was 93.2355 we would multiply it by 10 to the power 4 as we need to shift the decimal 4 places to the right to make the number whole.</p>
<p>When working with ERC tokens we will note that the decimal places are often 10, 12, or 18.</p>
<p>For example, 1 Ether is 1*(10^18) wei, which is 1 followed by 18 zeros. If we wanted that expressed with a floating point, we would need to divide 1000000000000000000 by 10^18 (which will give us 1), but if it was 1500000000000000000 wei, then dividing by 10^18 will throw a compiler error in Solidity, because it cannot handle the return value of 1.5.</p>
<p>In scientific notation, 10^18 is also expressed as 1e18, where 1e represents 10 and the number after that represents the exponent that 1e is raised to.</p>
<p>So the following code will produce a compiler error: “<em>Return argument type rational_const 3 / 2 is not implicitly convertible to expected type…int256</em>”:</p>
<table><tbody><tr><td><p>function divideBy1e18()public pure returns (int) {<br>&nbsp; &nbsp; return 1500000000000000000/(1e18); // 1.5 → Solidity can’t handle this.</p></td></tr></tbody></table>

<p>The result of the above division operation is 1.5, but that has a decimal point which Solidity does not currently support. Thus Solidity smart contracts return very big numbers, often up to 18 decimal places, which is more than JavaScript can handle. So you'll need to handle that appropriately in your front end using JavaScript libraries like <a target="_blank" href="https://docs.ethers.io">Ethersjs</a> that implement helper functions for the <a target="_blank" href="https://docs.ethers.io/v5/api/utils/bignumber/">BigNumber</a> type.</p>
<h2 id="heading-hashing-abi-encoding-and-decoding">Hashing, ABI Encoding and Decoding</h2>
<p>As you work more with Solidity, you’ll see some strange-sounding terms like hashing, ABI encoding, and ABI decoding.</p>
<p>While these can take some effort to wrap your head around, they’re quite fundamental to working with cryptographic technology, and Ethereum in particular. They’re not complex in principle, but can be a bit hard to grasp at first.</p>
<p>Let’s start with hashing. Using cryptographic math, you can convert <strong>any</strong> data into a (very large) unique integer. This operation is called hashing. There are some key properties to hashing algorithms:</p>
<ol>
<li><p>They’re deterministic - identical inputs will <strong>always</strong> produce an identical output, each time and every time. But the chance of producing the same output using different inputs is extremely unlikely.</p>
</li>
<li><p>It is not possible (or computationally infeasible) to reverse engineer the input if you only have the output. It is a one-way process.</p>
</li>
<li><p>The output’s size (length) is fixed - the algorithm will produce fixed-size outputs for all inputs, regardless of the input size. In other words the outputs of a hashing algorithm will always have a fixed number of bits, depending on the algorithm.</p>
</li>
</ol>
<p>There are many algorithms that are industry-standard for hashing but you’ll likely see SHA256 and Keccak256 most commonly. These are very similar. And the 256 refers to the size - the number of bits in the hash that is produced.</p>
<p>For example, go to <a target="_blank" href="https://emn178.github.io/online-tools/keccak_256.html">this site</a> and copy and paste “FreeCodeCamp” into the text input. Using the Keccak256 algorithm, the output will (always) be <code>796457686bfec5f60e84447d256aba53edb09fb2015bea86eb27f76e9102b67a</code>.</p>
<p>This is a 64 character hexadecimal string, and since each character in a hex string represents 4 bits, this hexadecimal string is 256 bits (32 bytes long).</p>
<p>Now, delete everything in the text input box except the “F”. The result is a totally different hex string, but it still has 64 characters. This is the “fixed-size” nature of the Keccak265 hashing algorithm.</p>
<p>Now paste back the “FreeCodeCamp” and change any character at all. You could make the “F” lowercase. Or add a space. For each individual change you make, the hash hex string output changes a lot, but the size is constant.</p>
<p>This is an important benefit from hashing algorithms. The slightest change changes the hash substantially. Which means you can always test whether two things are identical (or have not been tampered with at all) by comparing their hashes.</p>
<p>In Solidity, comparing hashes is much more efficient than comparing the primitive data types.</p>
<p>For example, comparing two strings is often done by comparing the hashes of their ABI-encoded (bytes) form. A common helper function to compare two strings in Solidity would look like this:</p>
<table><tbody><tr><td><p>function compareStrings(string memory str1, string memory str2)<br>&nbsp; &nbsp; &nbsp; &nbsp; public<br>&nbsp; &nbsp; &nbsp; &nbsp; pure<br>&nbsp; &nbsp; &nbsp; &nbsp; returns (bool)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; return (keccak256(abi.encodePacked((str1))) ==<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keccak256(abi.encodePacked((str2))));<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>We’ll address what ABI encoding is in a moment, but note how the result of <code>encodePacked()</code> is a <code>bytes</code> array which is then hashed using the keccak256 algorithm (this is the native hashing algorithm used by Solidity). The hashed outputs (256 bit integers) are compared for equality.</p>
<p>Now let's turn to ABI encoding. First, we recall that ABI (Application Binary Interface) is the interface that specifies how to interact with a deployed smart contract. ABI-encoding is the process of converting a given element from the ABI into bytes so that the EVM can process it.</p>
<p>The EVM runs computation on bits and bytes. So encoding is the process of <a target="_blank" href="https://stackoverflow.com/questions/14822323/why-is-encoding-and-decoding-needed-for-any-programming-language-database">converting structured input data into bytes</a> so that a computer can operate on it. Decoding is the reverse process of converting bytes back into structured data. Sometimes, encoding is also referred to as “serializing”.</p>
<p>You can read more about the solidity built-in methods provided with the global variable <code>abi</code> that do different types of encoding and decoding <a target="_blank" href="https://docs.soliditylang.org/en/latest/cheatsheet.html#global-variables">here</a>. Methods that encode data convert them to byte arrays (<code>bytes</code> data type). In reverse, methods that decode their inputs expect the bytes data type as input and then convert that into the data types that were encoded.</p>
<p>You can observe this in the following snippet:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.13;<br><br>contract EncodeDecode {<br><br></p></td></tr></tbody></table>

<p>I ran the above in Remix, and used the following inputs for <code>encode()</code>: 1981, 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC, [1,2,3,4].</p>
<p>And the bytes I got returned were represented in hexadecimal form as the following:</p>
<pre><code class="lang-plaintext">0x00000000000000000000000000000000000000000000000000000000000007bd0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
</code></pre>
<p>I fed this as my input into the <code>decode()</code> function and got my original three arguments back.</p>
<p>Thus, the purpose of encoding is to convert data into the bytes data type that the EVM needs to process data. And decoding brings it back into the human readable structured data that we developers can work with.</p>
<h2 id="heading-how-to-call-contracts-and-use-the-fallback-function">How to Call Contracts and Use the Fallback Function</h2>
<p>Depending on the design of the smart contract and the visibility specifiers present in it, the contract can be interacted with by other smart contracts or by externally owned accounts.</p>
<p>Calling from your wallet via Remix is an example of the latter, as is using Metamask. You can also interact with smart contracts programmatically via libraries like EthersJS and Web3JS, the Hardhat and Truffle toolchains, and so on.</p>
<p>For the purposes of this Solidity handbook, we will use Solidity to interact with another contract.</p>
<p>There are two ways for a smart contract to call other smart contracts. The first way calls the target contract directly, by using interfaces (which we discussed previously). Or, if the Target contract is imported into the scope of the calling contract, it directly calls it.</p>
<p>This approach is illustrated below:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement() public {<br>&nbsp; &nbsp; &nbsp; &nbsp; count--;<br>&nbsp; &nbsp; }<br>}<br><br>interface ITarget {<br>&nbsp; &nbsp; function decrement() external;<br>}<br><br>contract TargetCaller {<br>&nbsp; &nbsp; function callDecrementInterface(address _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; ITarget target = ITarget(_target);<br>&nbsp; &nbsp; &nbsp; &nbsp; target.decrement();<br><br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; function callDecrementDirect(Target _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; _target.decrement();<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>In Remix you can deploy <code>Target</code> first, and call <code>count()</code> to see that the default value for the count variable is <code>0</code>, as expected. This value will be decremented by 1 if you call the <code>decrement()</code> method.</p>
<p>Then you can deploy <code>TargetCaller</code> and there are two methods you can call, both of which will decrement the value of <code>count</code> in <code>Target</code>.</p>
<p>Note that each of these two methods access the <code>Target</code> contract using a slightly different syntax. When interacting by using the <code>ITarget</code> interface, the first method takes in <code>Target</code>’s address whereas the second method treats <code>Target</code> as a custom type.</p>
<p>This second approach is only possible when the <code>Target</code> contract is declared in, or imported into, the same file as the <code>TargetCaller</code>. Most often, you will interact with smart contracts deployed by third parties, for which they publish ABI interfaces.</p>
<p>Each time you call these methods, the value of <code>count</code> in <code>Target</code> will decrease by <code>1</code>. This is a very common way to interact with other smart contracts.</p>
<p>The second way to do it is by using the “low level” call syntax that Solidity provides. You use this when you also want to send some ether (value) to the target contract. Will talk about sending value in the next section, but for now just replace the code in Remix with the following:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement(int num) public payable {<br>&nbsp; &nbsp; &nbsp; &nbsp; count = count - num;<br>&nbsp; &nbsp; }<br>}<br><br>interface ITarget {<br>&nbsp; &nbsp; function decrement(int num) external payable;<br>}<br><br>contract TargetCaller {<br>&nbsp; &nbsp; function callDecrementLowLevel(address _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; ITarget target = ITarget(_target);<br>&nbsp; &nbsp; &nbsp; &nbsp; target.decrement{value:0}(5);<br><br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; // other decrementing functions….<br>}</p></td></tr></tbody></table>

<p>You’ll note that <code>decrement()</code> now takes an argument, and the interface and the <code>Target</code> contract are updated with this new input data.</p>
<p>Next note that <code>TargetCaller</code> implements a new function that calls <code>decrement()</code> with a new syntax, explained below.</p>
<p><img src="https://lh4.googleusercontent.com/xwOSOgsIrqRNzz2PFYziACphMXlVp1QWDItbAAaxAHGYChhIq7eyntuP6FQOrYdWL37dvD4qyUrp2SAOgwk8BC9nnm27k_0jCOCbTvEBbTPvGvd2xMoCfIjV75s6l9O7a-nEPJbpFVzKDnOdP-2S6Ot-8vtV6iD-SRYNp1pCRe8mfQDij7_c8Ek2LDux6Q" alt="Calling a contract's function and sending it value in Wei." width="600" height="400" loading="lazy"></p>
<p>In the next section we will see examples of these low level ways of calling a target smart contract to send Ether to it.</p>
<p>But what happens when you call a contract and it doesn’t actually have the function you tried to call?</p>
<p>This can happen maliciously to exploit how Solidity works on the EVM. Or, more commonly, it can happen accidentally. This occurs when, for example, there is an error in the Interface and the compiler cannot match the function and parameters you sent with any that are actually contained in the contract. What happens then?</p>
<p>For these situations, many contracts employ a special function called the fallback function. The function looks like a normal function but it doesn’t need the <code>function</code> keyword. If you want it to also handle situations where your contract is sent some ether, you must also mark it <code>payable</code>. But this is not the recommended way to enable your contract to receive payments.</p>
<p>Let’s take a look by repurposing our previous <code>Target</code>, <code>ITarget</code> and <code>TargetCaller</code> and adding a fallback function as follows:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement(int num) public payable {<br>&nbsp; &nbsp; &nbsp; &nbsp; count = count - num;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; fallback() external payable&nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; count++;<br>&nbsp; &nbsp; }<br>}<br><br>interface ITarget {<br>&nbsp; &nbsp; function decrement(int num) external payable;<br>&nbsp; &nbsp; function nonExistentFunction() external;<br>}<br><br>contract TargetCaller {<br>&nbsp; &nbsp; function callFallback(address _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; ITarget target = ITarget(_target);<br>&nbsp; &nbsp; &nbsp; &nbsp; target.nonExistentFunction();<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>Once we deploy a fresh instance of <code>Target</code>, we can call <code>count()</code> and see that it is set to the default value of zero.</p>
<p>Next we can deploy <code>TargetCaller</code> and call the <code>callFallback()</code> method which internally calls <code>nonExistentFunction()</code>.</p>
<p>It’s worth noting that the interface says that <code>nonExistentFunction()</code> is available but the actual <code>Target</code> contract does not have any such function. This is why the <code>Target</code> fallback function gets triggered and the value of count is now incremented by <code>1</code>.</p>
<p>The purpose of the fallback function is to handle calls to the contract where no other function is available to handle it. And if the fallback is marked <code>payable</code>, the fallback function will also enable the smart contract to receive Ether (though that is not the recommended use for fallback). We will cover this in the next section.</p>
<h2 id="heading-how-to-send-and-receive-ether">How to Send and Receive Ether</h2>
<p>To send Ether to a target contract from your smart contract, you need to call the target contract using one of the following three in-built Solidity methods: <code>transfer</code>, <code>send</code> or <code>call</code>.</p>
<p><code>transfer</code> will throw an exception when it fails, and <code>send</code> and <code>call</code> will return a boolean that you must check before proceeding. Of these three, <code>transfer</code> and <code>send</code> are no longer recommended for security reasons, though you can still use them and they'll work.</p>
<p>Smart Contracts cannot receive Ether except in the following scenarios:</p>
<ul>
<li><p>They implement a <code>payable</code> fallback or <code>payable</code> receive special function, or</p>
</li>
<li><p>Forcibly when the calling contract calls <code>selfdestruct</code> and forces a target contract to accept all its remaining ether. The calling contract is then deleted from the blockchain. This is a separate topic and is often used maliciously by exploiters.</p>
</li>
</ul>
<p>It is generally recommended that you use a <code>receive()</code> function if you want your smart contract to receive Ether. You can get away by just making your fallback function <code>payable</code>, but recommended practice is to use a <code>receive()</code> function instead.</p>
<p>If you rely only on the fallback function, your compiler will grumble at you with the following message: “<em>Warning: This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.”</em></p>
<p>If you have both <code>receive</code> and <code>fallback</code>, you may legitimately wonder how Solidity decides which function to receive Ether with. This design decision also tells you what these functions are designed to do.</p>
<p>Receive is meant to receive ether. And fallback is meant to handle situations where the contract has been called but, as we discussed in the previous section, there is no matching method in the contract that can handle the call.</p>
<p>Solidity matches the method that was intended to be called by checking the <code>msg.data</code> field in the transaction sent by the caller. If that field is a non-empty value, and that value does not match any other function declared in the called contract, then the fallback method is triggered.</p>
<p>If <code>msg.data</code> is empty, then it will check if there is a receive function that has been implemented. If so, it will use that to accept the Ether. If no receive exists, it will default to the fallback function. The fallback is therefore the...fallback (default) method when nothing else makes sense.</p>
<p>The <code>receive</code> function is the better way to enable your contract to receive Ether. You can use the fallback function for any scenario where your smart contract is called but there is nothing to “handle” that call.</p>
<p>Here is a super handy logic tree that shows what receive and fallback are intended to handle.</p>
<table><tbody><tr><td><p>Which function is called, fallback() or receive()?<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; send Ether<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; msg.data is empty?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / \<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yes&nbsp; no<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; &nbsp; \<br>receive() exists?&nbsp; fallback()<br>&nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; \<br>&nbsp; &nbsp; &nbsp; &nbsp; yes &nbsp; no<br>&nbsp; &nbsp; &nbsp; &nbsp; /&nbsp; &nbsp; &nbsp; \<br>&nbsp; &nbsp; receive() &nbsp; fallback()</p></td></tr></tbody></table>

<p>(credit: <a target="_blank" href="https://solidity-by-example.org/sending-ether/">Solidity By Example</a>)</p>
<p>Going back to our example where we explored the fallback function, we can add a <code>receive</code> function to <code>Target</code> as follows:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement() public payable {<br>&nbsp; &nbsp; &nbsp; &nbsp; count = count - num;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; fallback() external payable&nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; count++;<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>We already saw how <code>callFallback</code> will change the count value in <code>Target</code>. But if we deploy a fresh instance of <code>Target</code>, we can now send it 10 wei, as shown below, because it now has a <code>payable</code> <code>receive</code> function. Prior to sending 10 wei (or any other amount) <code>Target</code> has a balance of zero, as shown below.</p>
<p><img src="https://lh5.googleusercontent.com/yCKofUjShb7KqezaShYgDsPMbx9EBX1aetb9AbzJJawPz-ehvzhsHkkW_Uyd4Ah95Wmrm6nbkKCCDKAkoFU7_obDJ6zeQIB1nU9Q9laJo3o58Lg1_A_tRj-zQyEj7_DOaIeKoc1fV8wAcUbfUY2vYhVljTrewhT1PyeWZbWyAv5KYdKySqtWu3P6D_3_bQ" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Hitting the Transact button with empty calldata (<code>msg.data</code>) will change the balance as shown in the image below. We can check <code>count</code> to see that it is incremented by 5, which is the logic in the <code>receive</code> function.</p>
<p><img src="https://lh5.googleusercontent.com/dMbTEYYraIK2EwGRYdkKxBFQ6rS1inTuyvVeNwJbObQoxAyJaZ957HHDm4buyKl5le1iP_f41hOB-4ACVm8Oz0wVK1LjPfylhEfpwP9oBo5RlWcN27XemNWWwrt0S2Vng5TaQlZyfnIhqPrV8xUaR2ZVS-Oj7F0XQUALn2AxENG_1PiK_uGT3mJLw-Iklw" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Sending Wei to the Target Contract and observing the updated balance</em></p>
<p>If we call <code>callFallback</code> and give it the address of the new <code>Target</code> instance, we will note that it increments only by <code>1</code>. If we include some wei, that will increase the balance of <code>Target</code> as well.</p>
<p>So any transfer of Ether to a smart contract would require the receiving smart contract to have <code>payable</code> functions that can receive it. At the very minimum, the receiving smart contract would need a <code>payable</code> fallback function, though a <code>payable</code> <code>receive</code> function is the better approach for receiving Ether payments.</p>
<h2 id="heading-solidity-libraries">Solidity Libraries</h2>
<p>In any programming language, a library refers to a collection of helper and utility functions that are designed to be reusable across multiple code bases. These functions solve specific, recurring programming problems.</p>
<p>In Solidity, libraries serve the same purpose, but have some special attributes.</p>
<p>First, they are stateless - that is, they don't store data (other than constants because these do not change the blockchain’s state). They also can't receive value (which means they cannot have <code>payable receive</code> or <code>fallback</code> functions).</p>
<p>They also cannot inherit from other contracts or libraries, nor can libraries have child (derived) contracts.</p>
<p>All functions declared in a library must not be abstract - that is, they must all have concrete implementations.</p>
<p>Since Solidity libraries are stateless, none of the methods in them can modify the blockchain’s state. This means all methods inside libraries are <code>pure</code> or <code>view</code> functions.</p>
<p>Another interesting attribute of Solidity libraries is that they don't need to be imported into your smart contract. They can be deployed as standalone contracts and then called via their interface in all consuming smart contracts - just as you would an API service in the traditional engineering world.</p>
<p>However, this is true only where the library contains public or external methods. Then that library can be deployed as a standalone contract with its own Ethereum address, and becomes callable to all consuming smart contracts.</p>
<p>If the libraries contain only internal methods, then the EVM simply “embeds” the library code into the smart contract that uses the library (because internal functions cannot be accessed from other smart contracts).</p>
<p>Libraries in Solidity have advantages that go beyond code reuse. Deploying a library one time on the blockchain can save on future gas costs by avoiding repeated deployment or importing of the library's code.</p>
<p>Let's look at a simple library and then dissect the code to understand how to use the library’s code.</p>
<table><tbody><tr><td><p>library WeirdMath {<br>&nbsp; &nbsp; int private constant factor = 100;<br><br>&nbsp; &nbsp; function applyFactor(int self) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return self * factor;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; function add(int self, int numberToAdd) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return self + numberToAdd;<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>This library has two methods that operate on the <code>int</code> data type. The first argument is called <code>self</code> for reasons that will become clear shortly. One method takes a number and then multiplies it by a constant value that is stored in the library’s code. The second method takes in two numbers and adds them.</p>
<p>Now let’s see how we can use this in a consuming smart contract.</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br><br>pragma solidity &gt;=0.5.22 &lt;=0.8.17;<br><br>contract StrangeMath {<br>&nbsp; &nbsp; // Method 1 - using Library name with dot notation<br>&nbsp; &nbsp; function multiplyWithFactor(int num) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return WeirdMath.applyFactor(num);<br>&nbsp; &nbsp; }<br><br><br>&nbsp; &nbsp; // Method 2 - the 'using' keyword and dot notation.<br>&nbsp; &nbsp; // Syntax: using &lt;&lt;Library Name&gt;&gt; for data type of the first argument in the method to be called.<br>&nbsp; &nbsp; using WeirdMath for int;<br>&nbsp; &nbsp; function addTwoNums(int num1, int num2) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return num1.add(num2);<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>The first thing to note is that there are two ways of using the <code>WeirdMath</code> library.</p>
<p>You can use it by either:</p>
<ol>
<li><p>Invoking the library’s name followed by the function you want to call, or</p>
</li>
<li><p>calling the function directly on the data type you want the function to operate on. This data type must be identical to the type of the <code>self</code> parameter in the library’s function.</p>
</li>
</ol>
<p>The first approach is demonstrated by method 1 in the code snippet where we invoke the library with <code>WeirdMath.add(num1, num2);</code>.</p>
<p>The second approach uses the Solidity <code>using</code> keyword. The expression <code>return num1.add(num2);</code> applies the <code>WeirdMath</code> library’s add function to the <code>num1</code> variable. This is the same as passing it in as <code>self</code>, which is the first argument to the add function.</p>
<h2 id="heading-events-and-logs-in-solidity">Events and Logs in Solidity</h2>
<p>Smart Contracts can emit events. The events contain pieces of data that you the developer specify.</p>
<p>Events cannot be consumed by other smart contracts. Instead, they are stored on the blockchain as logs, and can be retrieved via the APIs that read from the blockchain.</p>
<p>This means that your application (most commonly your front end application) can “read” logs that contain the event’s data from the blockchain. In this way your user interface can respond to events on the blockchain.</p>
<p>This is how application user interfaces are updated to respond to on-chain events. Since these logs on the blockchain can be queried, logs are a cheap form of storage, as discussed previously in the discussion on storage areas.</p>
<p>Events emitted by a Smart Contract can be inspected using the relevant blockchain explorer, because everything on a public blockchain is publicly viewable. But if the smart contract’s bytecode has not been verified, the event data may not be human readable (it will be encoded). The events of verified smart contracts will be human readable.</p>
<p>Nodes and other blockchain clients can listen for (subscribe to) specific events. At the heart of it, this is how <a target="_blank" href="http://docs.chain.link">Chainlink Oracles</a> work - decentralized oracle nodes listen to events from smart contracts, and then respond accordingly. They can even pull data off from events, run complex and resource-intensive computations off-chain, and then submit cryptographically verifiable computation results back onto the blockchain.</p>
<p>Other network APIs and indexing services <a target="_blank" href="https://thegraph.com/en/">like subgraphs</a> are made possible because of the ability to query blockchain data via the events emitted by smart contracts.</p>
<p>Here is what an Event looks like in Solidity:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.7;<br><br>contract SimpleStorage {<br>&nbsp; &nbsp; uint256 favoriteNumber;<br><br>&nbsp; &nbsp; event storedNumber(<br>&nbsp; &nbsp; &nbsp; &nbsp; uint256 indexed oldNumber, // up to 3 indexed params allowed<br>&nbsp; &nbsp; &nbsp; &nbsp; uint256 indexed newNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; uint256 addedNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; address sender<br>&nbsp; &nbsp; );<br><br>&nbsp; &nbsp; function store(uint256 newNumber) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; emit storedNumber(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; favoriteNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newNumber + favoriteNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.sender<br>&nbsp; &nbsp; &nbsp; &nbsp; );<br>&nbsp; &nbsp; &nbsp; &nbsp; favoriteNumber = newNumber;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; function retrieve() public view returns (uint256) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return favoriteNumber;<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>An event is first declared, and its arguments and their data types are specified. Any piece of data that has the <code>indexed</code> keyword is indexed by the EVM so that queries on blockchain logs can use the indexed param as a filter. This makes retrieving logs faster.</p>
<p>An event can store up to 4 indexed parameters - depending on whether it is anonymous or non-anonymous. Indexed event parameters are also referred to as “Topics” in the Solidity world.</p>
<p>Most events are non-anonymous, meaning that they include data on the name and arguments of the Event.</p>
<p>Non-anonymous events allow the developer to specify only 3 topics because the first topic is reserved to specify the Event signature in ABI-encoded hexadecimal form. You can read more about anonymous and non-anonymous topics <a target="_blank" href="https://docs.ethers.io/v5/concepts/events/#events-solidity">here</a>.</p>
<p>You can also explore Events on the relevant blockchain explorer (like <a target="_blank" href="http://etherscan.io">etherscan.io</a>).</p>
<p>You can approach this from one of two entry points. You can look at the contract’s address directly and then go to the Events Tab (which will show you events emitted by that contract only). Or you can go to a transaction hash and examine all the events emitted by all contracts that were touched by that transaction.</p>
<p>For example, below is a screenshot of the <a target="_blank" href="https://docs.chain.link/vrf/v2/subscription/supported-networks#ethereum-mainnet">Chainlink VRF Coordinator smart contract’s</a> events on Ethereum mainnet.</p>
<p><img src="https://lh3.googleusercontent.com/P-Ue4bGSB4swKcUxv6DJpuZxADBw6ZKPKeo_H7_x5lZBcJGuHxYUjcYm9rRCi80TFJSkKVpXJ_2zS7Pm9s0ASs9SrmIXc9uGTeTn_9e2FBwgTlRYSKQkB4cfIWRA3K8S8RWx6-5dEb048MtvlUkvPH17So9nPyo9R36L5Zwi8aoe4BdWfw4MIOH0M3NRjw" alt="Inspecting the Chainlink VRF Coordinator Contract's events on etherscan" width="600" height="400" loading="lazy"></p>
<p><em>Inspecting the Chainlink VRF Coordinator Contract's events on etherscan</em></p>
<p>The contract tab has a green tick mark which means the contract is verified, and so the Event name and arguments are human readable. Take a moment to study this image as it contains a lot of information! If you’d like to study it directly on etherscan, <a target="_blank" href="https://etherscan.io/address/0x271682DEB8C4E0901D1a1550aD2e64D568E69909#events">click here</a>.</p>
<p>This Chainlink VRF Coordinator contract responds to requests for cryptographically verifiable random numbers, and supplies the asking smart contract with random numbers (referred to as “random words”).</p>
<p>If you want to learn what the computer science meaning of “word” is, check out my colleague and I addressing this question in this <a target="_blank" href="https://youtu.be/lu3yDJQqqY0?t=2627">Chainlink 2022 Hackathon video</a>).</p>
<p>When the VRF Coordinator contract fulfills the request for random numbers, it emits a <code>RandomWordsFulfilled</code> event. That event contains 4 pieces of data, of which the first one, <code>requestID</code>, is indexed.</p>
<p>Solidity events contain three categories of data:</p>
<ol>
<li><p>The address of the contract that emitted the event.</p>
</li>
<li><p>The topics (indexed event parameters used for filtering queries of the logs).</p>
</li>
<li><p>Non-indexed parameters, referred to as “data”, and they are ABI-encoded and represented in hexadecimal. This data needs to be ABI-decoded, in the way described in the section on ABI encoding and decoding.</p>
</li>
</ol>
<p>When working in Remix you can also inspect the Events in the console as shown below:</p>
<p><img src="https://lh4.googleusercontent.com/YyXlklkork7-lcLKXdQqWYYGZeIX8IWaqRUgjKNGG9cG4AiyAG-9MGyjWwP8hXFT9tkSWu5Q6X8qVUHWwgczo-H4W07qAsmAPny4y8FWNz5jBQ1YynBIeor7mtpbZLshRRN4hYrehAj3lhXbzxEYYguNDqeJxjowshHeVLltuzrHXM8RMnS2-82bvGOcjg" alt="Inspecting Event data in the Remix Browser IDE" width="600" height="400" loading="lazy"></p>
<p><em>Inspecting Event data in the Remix Browser IDE</em></p>
<p>You can also programmatically access the events <a target="_blank" href="https://stackoverflow.com/questions/73230175/does-etherjs-transactionreceipt-have-an-events-object">using the contract receipts object</a> in EthersJS. Using the code snippet we used above in the SimpleStorage contract, we can access the events using EthersJS and Hardhat using the following JavaScript:</p>
<table><tbody><tr><td><p>const transactionResponse = await simpleStorage.store(1981)<br>const receipt = await transactionResponse.wait()<br><br>console.log(receipt.events[0].args.newNumber.toString()) // 1981</p></td></tr></tbody></table>

<p>You can also use libraries such as the EtherJs library in your front end application to <a target="_blank" href="https://docs.ethers.io/v5/getting-started/#getting-started--events">listen to events</a> and <a target="_blank" href="https://docs.ethers.io/v5/getting-started/#getting-started--history">filter historical events</a>. Both of these are useful when your application needs to respond to events on the blockchain.</p>
<h2 id="heading-time-logic-in-solidity">Time Logic in Solidity</h2>
<p>Time in Solidity is specified in relation to each block that gets added to the blockchain.</p>
<p>The global variable <code>block.timestamp</code> refers to the time, in milliseconds, when the block was generated and added to the blockchain. The milliseconds count refers to the number of milliseconds that have passed since the beginning of the Unix Epoch (in computing, this is 1 January 1970).</p>
<p>Unlike Web2 references to timestamps in milliseconds, the value may not increment with every millisecond.</p>
<p>A block often contains several transactions, and since <code>block.timestamp</code> refers to the time at which the block was mined, all transactions in a mined block will have the same timestamp value. So the timestamp really refers to the block’s time, and not so much as to when the caller may have initiated the transaction.</p>
<p>Solidity supports directly referring to the following units of time: seconds, minutes, hours, days, and weeks.</p>
<p>So we could do something like <code>uint lastWeek = block.timestamp - 1 weeks;</code> to calculate the timestamp of exactly 1 week before this current block was mined, down to milliseconds. That value would be the same as <code>block.timestamp - 7 days;</code>.</p>
<p>You can also use this to calculate future expiry dates, where, for example, you may want an operation to be possible between now and next week. You could do this with <code>uint registrationDeadline = block.timestamp + 1 weeks;</code> and then we could use the <code>registrationDeadline</code> as a validation or guard in a function as follows:</p>
<table><tbody><tr><td><p>function registerVoter(address voter) public view {<br>&nbsp; &nbsp; &nbsp; &nbsp; require(block.timestamp &lt;= registrationDeadline, “registration deadline has passed.”);<br>&nbsp; &nbsp; &nbsp; &nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; // Register the Voter....<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>In this function we register the voter only if the current block’s timestamp is not past the registration deadline.</p>
<p>This logic is used extensively when we want to make sure certain operations are performed at the right time, or within an interval.</p>
<p>This is also one of the ways in which <a target="_blank" href="https://docs.chain.link/chainlink-automation/introduction/">Chainlink Automation</a>, a decentralized way to automate the execution of your smart contract, can be configured. The Chainlink decentralized oracle network can be configured to automatically trigger your smart contracts, and you can run a wide variety of automations by checking conditions, including time related conditions. These are used extensively for airdrops, promotions, special rewards, earn-outs and so on.</p>
<h2 id="heading-conclusion-and-further-resources">Conclusion and Further Resources</h2>
<p>Congrats! You made it through this epic journey. If you’ve invested the time digesting this handbook, and run some of the code in the Remix IDE, you are now trained in Solidity.</p>
<p>From here on, it’s a question of practice, repetition and experience. As you go about building your next awesome decentralized application, remember to revisit the basics and focus on security. Security is especially important in the Web3 space.</p>
<p>You can get good information on best practices from <a target="_blank" href="https://blog.openzeppelin.com/">OpenZeppelin’s blogs</a> and the <a target="_blank" href="https://www.trailofbits.com/resources">Trail of Bits</a> resources, amongst others.</p>
<p>You can also get more practical hands on experience by doing the full <a target="_blank" href="https://www.youtube.com/watch?v=gyMwXuJrbJQ&amp;t=59657s">end-to-end full-stack blockchain developer course</a> that my colleague Patrick Collins published on freeCodeCamp (it’s free!).</p>
<p>There are other resources like blockchain.education and freeCodeCamp’s own upcoming Web3 curriculum that can consolidate your learnings.</p>
<p>In any event, this handbook can be your “desktop companion” for that quick refresh on basic concepts, regardless of what level of experience you’re at.</p>
<p>The important thing to remember is that Web3 technology is always evolving. There is a crying need for developers willing to tackle complex challenges, learn new skills, and solve important problems that come with decentralized architecture.</p>
<p>That could (and should) be you! So just follow your curiosity and don’t be afraid to struggle along the way.</p>
<p>And once again, I intend to keep this handbook updated. So if you see anything that’s not quite right, is outdated, or unclear, just mention it in a tweet and <a target="_blank" href="https://twitter.com/zubinpratap">tag me</a> and freeCodeCamp - a big shout out to you all for being part of keeping this handbook fresh.</p>
<p>Now…go be awesome!</p>
<h3 id="heading-post-script"><strong>Post Script</strong></h3>
<p>If you are serious about a career change to code, you can learn more about my journey from lawyer to software engineer. Check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a> and also <a target="_blank" href="https://lessonsfromaquitter.com/episode207/">Episode 207</a> of "Lessons from a Quitter". These provide the blueprint for my career change.</p>
<p>If you are interested in changing your career and becoming a professional coder, please reach out <a target="_blank" href="http://linktree.com/zubinpratap">here</a>. You can also check out my <a target="_blank" href="http://futurecoderstraining.com/">free webinar</a> on <a target="_blank" href="http://futurecoderstraining.com/">Career Change to Code</a> if that is what you're dreaming of.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Blockchain for Beginners Tutorial – Learn to Code Smart Contracts with JavaScript and Solidity ]]>
                </title>
                <description>
                    <![CDATA[ By Njoku Samson Ebere The first time I tried to learn blockchain development, I felt overwhelmed.  This tutorial you're reading is what I wish I could send back in time to myself.  This will give you a strong foundation in blockchain development, and... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/introduction-to-blockchain/</link>
                <guid isPermaLink="false">66d84fb1c15439a8d5631e6f</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Smart Contracts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Solidity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 17 Nov 2022 21:42:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/pexels-archie-binamira-705075.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Njoku Samson Ebere</p>
<p>The first time I tried to learn blockchain development, I felt overwhelmed. </p>
<p>This tutorial you're reading is what I wish I could send back in time to myself. </p>
<p>This will give you a strong foundation in blockchain development, and set you up for success in coding your own smart contracts.</p>
<p>In in addition to my explanation and code examples, I've included lots of videos you can use to supplement your learning.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>This tutorial assumes that you understand some foundational coding concepts. One of these that will be particularly helpful is the concept of object-oriented programming (OOP).</p>
<h2 id="heading-what-is-blockchain">What is Blockchain?</h2>
<p>The Blockchain is a network of transactions or assets called blocks where every block is connected to the others. Everyone here has equal access to the data circulating within the network.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GvmRSS0vKxE" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>You can see blockchain as a document that holds the details of transactions made by a group of people where everyone has a copy. Everyone must agree upon any updates before they are accepted. </p>
<p>Anyone who tries to mutilate their document without the others' consent is seen as fraudulent and will suffer predefined consequences.</p>
<p>For example, imagine that a group of friends (Njoku, Samson, and Ebere) decides to start a peer-to-peer savings account that must run for a certain period before a withdrawal is possible. The three agree that no one will be the boss, and each person will have equal access to the account to ensure trust. So they open an account. </p>
<p>Each time one of them deposits money, everyone gets a new account history document emailed to them. Whenever they decide to add a new member, the person becomes part of the signatories and gets a copy of the account history. </p>
<p>Everyone must consent before a withdrawal happens outside the proposed date. Not following these terms will incur consequences such as losing all of a person’s savings or leaving the association after paying a fine.</p>
<p>Blockchain is known as a decentralized technology since data and authority are shared equally among everybody in the network. It differs from centralized applications where the company owns the data, and the consumers just hope their data isn’t misused. </p>
<p>Examples of decentralized applications include Bitcoin and Ethereum, while centralized applications include Facebook and Google.</p>
<p>Blockchain technology falls under the category of <strong>Web 3</strong> simply because it is the third phase of the internet in which users can <strong>read, write, and own data</strong>. Web 1 was the stage where users could only <strong>read data</strong>. <strong>Web 2</strong> emerged sometime around the early 2000s and is the phase in which users can <strong>read and write data</strong>.</p>
<h2 id="heading-how-blockchain-works">How Blockchain Works</h2>
<p>In this section, I will explain what happens in a blockchain application behind the scenes. </p>
<p>We will begin by looking at how it works in theory and then how we can replicate it using a programming language that many devs already know – JavaScript.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/jWXH-49BAPU" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h3 id="heading-theory-behind-the-blockchain">Theory Behind the Blockchain</h3>
<p>A blockchain is a connection of many blocks. So it begins with one block called the <strong>genesis block</strong>. Among other things, a block contains a hash, the previous block hash, and at least one transaction.</p>
<p>Every block in the blockchain keeps a record of its hash and the previous block’s hash to keep the network safe from hackers. </p>
<p>This implies that for a hacker to gain access and break the network, they need to generate the hashes and match them to the right block without breaking other blocks. Now that sounds really stressful and almost impossible. That is how secure blockchains are.</p>
<p>Next, any user on the network can perform at least one transaction. If the user has completed a set of transactions they need at a time, they can use those transactions to create a block. The block may now be added to the others. </p>
<p>The whole process of adding a new block is known as <strong>mining</strong>. The process secures and verifies the transactions contained in a block.</p>
<p>The hash of a block gets generated when mining. The process of calculating the hash is known as <strong>proof of work</strong>.</p>
<h3 id="heading-blockchain-in-practice">Blockchain in Practice</h3>
<p>Let's use some JavaScript object-oriented programming to demonstrate how blockchain works. We are using the OOP method because blockchain programming uses the same pattern. </p>
<p>But before we start building, let's learn how to generate the hash for every block in a blockchain.</p>
<h4 id="heading-how-to-generate-a-blocks-hash">How to generate a block's hash</h4>
<p>There are a lot of libraries for generating a block's hash. But we will use the <a target="_blank" href="https://www.npmjs.com/package/sha256">SHA256</a> library for this tutorial. SHA256 is the most popular and is used by many renowned companies.</p>
<p>The SHA256 library takes any data given to it and returns a 64-character long string. Every string passed to the SHA256 library will always return the same 64-character long string every time. </p>
<p>You can check out <a target="_blank" href="https://emn178.github.io/online-tools/sha256.html">https://emn178.github.io/online-tools/sha256.html</a> and play around with the UI to see how it works.</p>
<p>Blockchains do not use just any hash generated because of security reasons. It specifies what the first few characters must look like for the hash to be accepted. This means that the hash will have to be generated several times, and a record of what changes on each iteration will be kept for reference purposes.</p>
<p>For example, a blockchain may specify that the only acceptable hash must contain three zeros at the beginning. </p>
<p>To calculate the hash, we need to add a number known as a <code>nonce</code> to the string being hashed. The <code>nonce</code> usually starts from zero and is incremented every time the hash is generated until a hash beginning with three zeros is found. Then the hash and the <code>nonce</code> will be stored for reference purposes.</p>
<p>The code below will calculate the hash for "man":</p>
<pre><code class="lang-javascript">SHA256(<span class="hljs-string">"man"</span>).toString()
</code></pre>
<p>However, we may run the function several times to get a string with three zeros at the beginning. Since the function will always return the same result, we need to add a number to the string and increment it until we get the hash we want.</p>
<p>The code we'd use for that will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> hash = <span class="hljs-string">""</span>;
<span class="hljs-keyword">let</span> nonce = <span class="hljs-number">0</span>;

<span class="hljs-keyword">while</span> (hash.substring(<span class="hljs-number">0</span>, <span class="hljs-number">3</span>) !== <span class="hljs-string">"000"</span>) {
  nonce++;
  hash = SHA256(<span class="hljs-string">"man"</span> + nonce).toString();
}

<span class="hljs-built_in">console</span>.log(nonce);
<span class="hljs-built_in">console</span>.log(hash);
</code></pre>
<p>This code will produce <code>000d6575d4670dae39df9944e54c27dc4837beab1db23e2de264a7c1a3f38b1a</code> after <code>5707</code> times instead of <code>48b676e2b107da679512b793d5fd4cc4329f0c7c17a97cf6e0e3d1005b600b03</code>.</p>
<p>This level of security measures taken to build blockchain applications makes them very reliable and acceptable.</p>
<p>Now that we understand how a hash is generated in blockchain, let's get back to demonstrating how blockchain works.</p>
<h3 id="heading-how-blockchain-works-using-javascript">How Blockchain Works Using JavaScript</h3>
<p>First, create a directory called <strong>intro_to_blockchain</strong>. Then open the directory in a terminal.</p>
<p>Run the following command and hit enter for all the prompts to initialize the project:</p>
<pre><code>npm init
</code></pre><p>Create 2 files: <code>blockchain.js</code> and <code>test.js</code>:</p>
<pre><code>touch blockchain.js test.js
</code></pre><p>We will use the <code>blockchain.js</code> file to write the code that emulates how blockchain works and use <code>test.js</code> to test the code and see the result.</p>
<p>In the <code>blockchain.js</code>, enter the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Blockchain</span> </span>{
    <span class="hljs-keyword">constructor</span> () {
        <span class="hljs-built_in">this</span>.chain = [<span class="hljs-built_in">this</span>.createGenesisBlock()];
        <span class="hljs-built_in">this</span>.pendingTransactions = [];    
    }
}
</code></pre>
<p>The code above declares a class named <code>Blockchain</code>. The <code>constructor</code> function is used to initialize the <code>chain</code> and <code>pendingTransactions</code> array. </p>
<p>The <code>chain</code> array will contain every block or group of transactions added to the network. The <code>pendingTransactions</code> array will hold all transactions that have not been added to a block.</p>
<p>Remember that a blockchain starts with a genesis block. That is why the <code>chain</code> array is initialized with an array containing a function that creates the genesis block. You may hardcode the genesis block into the chain array, too.</p>
<p>We now need to build the <code>createGenesisBlock</code> function. Use the code below:</p>
<pre><code class="lang-javascript">  createGenesisBlock() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">index</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">timestamp</span>: <span class="hljs-built_in">Date</span>.now(),
      <span class="hljs-attr">transactions</span>: [],
      <span class="hljs-attr">nonce</span>: <span class="hljs-number">0</span>,
      <span class="hljs-attr">hash</span>: <span class="hljs-string">"hash"</span>,
      <span class="hljs-attr">previousBlockHash</span>: <span class="hljs-string">"previousBlockHash"</span>,
    };
  }
</code></pre>
<p>The function will only execute once because the <code>constructor</code> function runs only once – at the beginning of the program. </p>
<p>It is also the only time a random uncalculated hash or previousBlockHash is used because it is the first block in the chain and does not carry any transactions.</p>
<p>The next thing to do is to make a function to get the last block. Use the code below:</p>
<pre><code class="lang-javascript">  getLastBlock() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.chain[<span class="hljs-built_in">this</span>.chain.length - <span class="hljs-number">1</span>];
  };
</code></pre>
<p>This code will enable us to access the details of the most recent block added. Remember that we need to keep track of the previous block's hash.</p>
<p>Let's now add the code to calculate the hash of a block.</p>
<pre><code class="lang-javascript">
generateHash(previousBlockHash, timestamp, pendingTransactions) {
    <span class="hljs-keyword">let</span> hash = <span class="hljs-string">""</span>;
    <span class="hljs-keyword">let</span> nonce = <span class="hljs-number">0</span>;

    <span class="hljs-keyword">while</span> (hash.substring(<span class="hljs-number">0</span>, <span class="hljs-number">3</span>) !== <span class="hljs-string">"000"</span>) {
      nonce++;
      hash = SHA256(
        previousBlockHash +
          timestamp +
          <span class="hljs-built_in">JSON</span>.stringify(pendingTransactions) +
          nonce
      ).toString();
    }

    <span class="hljs-keyword">return</span> { hash, nonce };
  }
</code></pre>
<p>To ensure that this works, install the <code>SHA256</code> library using the following command:</p>
<pre><code>npm i sha256
</code></pre><p>Import it at the top of your <code>blockchain.js</code> file like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> SHA256 = <span class="hljs-built_in">require</span>(<span class="hljs-string">"sha256"</span>);
</code></pre>
<p>We will now add a function that creates our transactions and adds them to the list of pending transactions. Enter the following code:</p>
<pre><code class="lang-javascript">  createNewTransaction(amount, sender, recipient) {
    <span class="hljs-keyword">const</span> newTransaction = {
      amount,
      sender,
      recipient,
    };

    <span class="hljs-built_in">this</span>.pendingTransactions.push(newTransaction);
  }
</code></pre>
<p>The time has now arrived for us to build the last function – <code>createNewBlock</code>. It will enable us to add the pending transactions to a block, calculate the hash, and add the block to the <code>chain</code>. Type the code below:</p>
<pre><code class="lang-javascript">  createNewBlock() {
    <span class="hljs-keyword">const</span> timestamp = <span class="hljs-built_in">Date</span>.now();
    <span class="hljs-keyword">const</span> transactions = <span class="hljs-built_in">this</span>.pendingTransactions;
    <span class="hljs-keyword">const</span> previousBlockHash = <span class="hljs-built_in">this</span>.getLastBlock().hash;
    <span class="hljs-keyword">const</span> generateHash = <span class="hljs-built_in">this</span>.generateHash(
      previousBlockHash,
      timestamp,
      transactions
    );

    <span class="hljs-keyword">const</span> newBlock = {
      <span class="hljs-attr">index</span>: <span class="hljs-built_in">this</span>.chain.length + <span class="hljs-number">1</span>,
      timestamp,
      transactions,
      <span class="hljs-attr">nonce</span>: generateHash.nonce,
      <span class="hljs-attr">hash</span>: generateHash.hash,
      previousBlockHash,
    };

    <span class="hljs-built_in">this</span>.pendingTransactions = [];
    <span class="hljs-built_in">this</span>.chain.push(newBlock);

    <span class="hljs-keyword">return</span> newBlock;
  }
</code></pre>
<p>The code above uses the <code>getLastBlock</code> function to access the previous block's hash. It calculates the hash of the current block, adds all the detail of the new block in an object, clears the <code>pendingTransactions</code> array, and pushes the new block into the <code>chain</code>.</p>
<p>Let's export the <code>Blockchain</code> class to be able to access it outside the file:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = Blockchain;
</code></pre>
<h4 id="heading-how-to-test-the-code">How to Test the Code</h4>
<p>We want to test the code we have written so far and see if it works as expected. We will navigate to the <code>test.js</code> file and begin by importing the <code>Blockchain</code> class that we exported a moment ago like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Blockchain = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./blockchain"</span>);
</code></pre>
<p>Now that we have the class here, we can make an instance of it and name it <code>bitcoin</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> bitcoin = <span class="hljs-keyword">new</span> Blockchain();
</code></pre>
<p>You may call it whatever you see fit, but I will use <code>bitcoin</code> because it is popular.</p>
<p>Let's now see what we have in <code>bitcoin</code> by default. To do that, we will log it to the console like this:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(bitcoin);
</code></pre>
<p>We will now open the project in a terminal and run the following command:</p>
<pre><code>node test
</code></pre><p>It should output the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-12.21.35.png" alt="Image" width="600" height="400" loading="lazy">
<em>Default Output</em></p>
<p>In the output above, we have the <code>chain</code> array containing the genesis block and the <code>pendingTransactions</code> array containing nothing. </p>
<p>You will recall that the <code>constructor</code> function contains all those data and it runs once at the beginning of the program.</p>
<p>To add a new transaction, use the code below:</p>
<pre><code class="lang-javascript">bitcoin.createNewTransaction(
  <span class="hljs-string">"100"</span>,
  <span class="hljs-string">"0xBcd4042DE499D14e55001CcbB24a551F3b954096"</span>,
  <span class="hljs-string">"0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"</span>
);
</code></pre>
<p>The first parameter is the <code>amount</code>, the second is the <code>sender</code>, and the third is the <code>recipient</code> just as we specified while creating the function.</p>
<p>If you run <code>node test</code> again, you should have one item in the <code>pendingTransactions</code> array like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-12.31.46.png" alt="Image" width="600" height="400" loading="lazy">
<em>One pending transaction added</em></p>
<p>To create or mine a block, enter the following code:</p>
<pre><code class="lang-javascript">bitcoin.createNewBlock();
</code></pre>
<p>You should get the output below this time:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-12.38.30.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You will notice that there are now two (2) blocks in the chain and no more transactions in the <code>pendingTransactions</code> array.</p>
<p>Some things to note in the second block are the <code>nonce</code> and the <code>hash</code>. The <code>nonce</code> is <code>1404</code>. That means it took 1404 iterations to get the correct <code>hash</code> for this block.</p>
<p>To see the transactions in the second block, we use the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\n"</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Second Block Transactions"</span>, bitcoin.chain[<span class="hljs-number">1</span>].transactions);
</code></pre>
<p>Now we have the result below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-12.49.08.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>That looks good! It shows that all our functions work as intended. And that is what goes on behind the scenes of many blockchain applications.</p>
<p>You've just learned how blockchain works. But you shouldn’t build a blockchain application solely on this program idea. There is much more to learn to enable you to build real-world DApp. Still, what we have done so far will help you dive more into learning web3.</p>
<p>One of the things you need to learn is a blockchain programming language such as Solidity and other blockchain frontend libraries such as Web3js and Etherjs.</p>
<p>I'll now introduce you to smart contracts using Solidity.</p>
<h2 id="heading-how-to-write-a-smart-contract">How to Write a Smart Contract</h2>
<p>In this section, we will cover all you need to know about smart contracts and the Solidity programming language.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/5P-ntj1MVDY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h3 id="heading-what-is-a-smart-contract">What is a Smart Contract?</h3>
<p>A smart contract is a program stored on the blockchain. It holds certain conditions that must be met before it executes. </p>
<p>Smart contracts take after traditional contracts. But they're different because they are run by a computer automatically when the predefined terms are met. </p>
<h3 id="heading-what-is-solidity">What is Solidity?</h3>
<p>Solidity is the main programming language used to build most smart contracts because it is specifically designed for that purpose. It follows the OOP pattern that we demonstrated using JavaScript and borrows the typed nature of TypeScript. So while some syntax might differ from what you already know, it is not too far-fetched to grasp.</p>
<p>We will be learning the basics of Solidity by using it to build a smart contract that enables users to send funds to each other. </p>
<p>Don't worry, you will not have to set up another project. We will use the <a target="_blank" href="https://remix.ethereum.org/">remix playground</a> to do everything – write the code, compile, debug, and test.</p>
<p>Let's now head over to <a target="_blank" href="https://remix.ethereum.org/">https://remix.ethereum.org/</a>. You should have the following screen stare at you for a while:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-21.54.11-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Remix welcome page</em></p>
<p>Remix is getting everything ready for you. Just be patient 😊</p>
<p>When it's done, you should have the following screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-21.59.30.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This playground provides us with all we need to write our first smart contract.</p>
<p>Let's start by deleting the file created for us by default. To do that, click on the first icon below the remix logo.</p>
<p>Right-click on the file name in the explorer section and select <code>delete</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-22.08.37.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click <code>OK</code> in the pop-up menu.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-22.10.36.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We will now create a new file named <code>Blockchain.sol</code> by clicking the document icon marked red in the image below and type the name of the file in the space provided:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-10-at-22.15.47.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>.sol</code> is the extension used for solidity files. The blank space is where we will type our code.</p>
<p>Solidity code always begins with the line below:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
</code></pre>
<p>Without this code, you will get an error. It is just like saying that you accept the terms and conditions of writing Solidity.</p>
<p>The next thing to do is to state the Solidity version you want to use. I will use the following code:</p>
<pre><code class="lang-javascript">pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;
</code></pre>
<p>The caret (^) sign indicates that the program will be compatible with higher versions of solidity. We can now start the program.</p>
<p>The first thing to do is to define a <code>Class</code> named <code>Blockchain</code>. However, the keyword for <code>Class</code> in solidity is <code>contract</code>. So we have:</p>
<pre><code class="lang-javascript">contract Blockchain {

}
</code></pre>
<p>Inside the contract above, we will create a data-type called <code>BlockStruck</code> with the code below:</p>
<pre><code class="lang-javascript">struct BlockStruck {
    uint256 index;
    uint256 timestamp;
    uint256 amount;
    address sender;
    address recipient;
}
</code></pre>
<p>Solidity allows us to create any data-type that we see fit using the <code>struct</code> keyword, which is short for <strong>structure.</strong> </p>
<p>We define all the keys we expect a value for in the struct. Since solidity is a strongly typed language, we specified a data-type before each key. The <code>struct</code> is similar to <code>Object</code> in JavaScript.</p>
<p><code>uint</code> indicates that a variable is an integer. Adding a number after it (such as <code>uint256</code> or <code>uint18</code>) specifies the maximum size it should take, but <code>uint</code> assumes <code>uint256</code> by default. </p>
<p><code>address</code>, on the other hand, indicates that a variable is a wallet address. There is also the <code>string</code> data-type.</p>
<p>The next thing that we want to define is an <code>event</code>. An <code>event</code> is usually triggered at the end of a function's execution to send data to the frontend. You can see it like <code>console.log</code>. Some people also use it as a cheap way of storage.</p>
<p>We want to define a <code>BlockEvent</code> that we will trigger after adding a block to the chain. Enter the following code below the <code>BlockStruct</code>:</p>
<pre><code class="lang-javascript">
event BlockEvent(uint256 amount, address sender, address recipient);
</code></pre>
<p>Unlike <code>struct</code>, circular braces are used for an <code>event</code>, and their keys are separated by commas (,). Also, notice that <code>struct</code> does not end with a semicolon, but <code>event</code> does.</p>
<p>Now that we have defined the structure of blocks, let's use it to setup an array of blocks called <code>chain</code> like this:</p>
<pre><code class="lang-javascvript">BlockStruck[] chain;
</code></pre>
<p>The code above defines the <code>chain</code> to be an array of <code>BlockStruct</code>. As always, we specify the data-type before the variable name.</p>
<p>Next, define a variable to keep track of how many blocks are in the <code>chain</code>:</p>
<pre><code class="lang-javascript">uint256 chainCount;
</code></pre>
<p>You may choose to assign it a value on the same line (<code>uint256 chainCount = 0;</code>) or do it in the <code>constructor</code> function like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">constructor</span>() {
    chainCount = <span class="hljs-number">0</span>;
}
</code></pre>
<p>We will now define three (3) functions: <code>addBlockToChain</code> (to add blocks to the chain), <code>getChain</code> (to return all the blocks added to the chain), and <code>getChainCount</code> (to get the number of blocks added to the chain).</p>
<h4 id="heading-addblocktochain-function">addBlockToChain function</h4>
<p>The code below begins the function:</p>
<pre><code class="lang-javascript">
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addBlockToChain</span>(<span class="hljs-params">uint256 amount, address payable recipient</span>) <span class="hljs-title">public</span> </span>{

}
</code></pre>
<p>Like the functions you already know, it begins with the <code>function</code> keyword followed by the name of the <code>function</code>, and the argument it expects in braces. </p>
<p>One of the arguments (<code>recipient</code>) has a flag called <code>payable</code>, indicating that the wallet address is eligible to receive funds. Next to it is the function's visibility flag (<code>public</code>). </p>
<p>Visibility defines who can call a function or variable. It can be <code>public</code>, <code>private</code>, <code>internal</code>, or <code>external</code>. </p>
<ol>
<li>A <code>public</code> function can be called by any contract.</li>
<li><code>private</code> functions can only be called inside the contract where they are defined.</li>
<li>Only contracts that inherit <code>internal</code> functions can call them.</li>
<li><code>external</code> functions are only accessible by other contracts.</li>
</ol>
<p>In the <code>addBlockToChain</code>, we start by incrementing the <code>chainCount</code> by one like this:</p>
<pre><code class="lang-javascript">chainCount += <span class="hljs-number">1</span>;
</code></pre>
<p>Next, add the block of a transaction to the chain like this:</p>
<pre><code class="lang-javascript">        chain.push(
            BlockStruck(
                chainCount,
                block.timestamp,
                amount,
                msg.sender,
                recipient
            )
        );
</code></pre>
<p>The <code>BlockStruct</code> takes values corresponding to the keys set when defining the <code>struct</code>. It is then added to the <code>chain</code> array using the <code>.push</code> method. Now we have a new block in the <code>chain</code>.</p>
<p>Finally, we trigger the <code>BlockEvent</code> we created a while ago:</p>
<pre><code class="lang-javascript">emit BlockEvent(amount, msg.sender, recipient);
</code></pre>
<p><code>emit</code> is the keyword used to call an event. As with the <code>BlockStruct</code>, the <code>BlockEvent</code> takes the values as they correspond to the keys set when defining the it.</p>
<p>The <code>addBlockToChain</code> function now looks like this:</p>
<pre><code class="lang-javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addBlockToChain</span>(<span class="hljs-params">uint256 amount, address payable recipient</span>) <span class="hljs-title">public</span> </span>{
        chainCount += <span class="hljs-number">1</span>;

        chain.push(
            BlockStruck(
                chainCount,
                block.timestamp,
                amount,
                msg.sender,
                recipient
            )
        );

        emit BlockEvent(amount, msg.sender, recipient);
    }
</code></pre>
<h4 id="heading-getchain-function">getChain function</h4>
<p>This function takes no argument but returns a <code>BlockStruct</code>. We will use the following code:</p>
<pre><code class="lang-javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getChain</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">BlockStruck[] memory</span>) </span>{
        <span class="hljs-keyword">return</span> chain;
    }
</code></pre>
<p>The program returns the <code>chain</code>, an array of all blocks.</p>
<p>Something to note in the function above is that we used <code>view</code> to show that this function returns a value. We also indicated the kind of data type we expect to be returned (<code>returns (BlockStruck[] memory)</code>) and the storage type to be used (<code>memory</code>).</p>
<p>There are two main storage types in solidity: <code>Storage</code> and <code>Memory</code>. <code>Storage</code> is the default type of storage used to hold data permanently for a program while <code>Memory</code> is temporary and is less expensive in terms of gas.</p>
<p>Gas is a fee paid to execute smart contracts. Don't worry about that. We have some dummy gas that will enable us to test our program.</p>
<h4 id="heading-getchaincount-function">getChainCount function</h4>
<p>Like the <code>getChain</code>, this function also takes no argument. It returns the number of blocks added to the <code>chain</code> so far. See the code below:</p>
<pre><code class="lang-javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getChainCount</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint256</span>) </span>{
        <span class="hljs-keyword">return</span> chainCount;
    }
</code></pre>
<p>That completes the smart contract that we intended to create. Now the code looks like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.7</span>;

contract Blockchain {
    struct BlockStruck {
        uint256 index;
        uint256 timestamp;
        uint256 amount;
        address sender;
        address recipient;
    }

    event BlockEvent(uint256 amount, address sender, address recipient);

    BlockStruck[] chain;
    uint256 chainCount;

    <span class="hljs-keyword">constructor</span>() {
        chainCount = <span class="hljs-number">0</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addBlockToChain</span>(<span class="hljs-params">uint256 amount, address payable recipient</span>) <span class="hljs-title">public</span> </span>{
        chainCount += <span class="hljs-number">1</span>;

        chain.push(
            BlockStruck(
                chainCount,
                block.timestamp,
                amount,
                msg.sender,
                recipient
            )
        );

        emit BlockEvent(amount, msg.sender, recipient);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getChain</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">BlockStruck[] memory</span>) </span>{
        <span class="hljs-keyword">return</span> chain;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getChainCount</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint256</span>) </span>{
        <span class="hljs-keyword">return</span> chainCount;
    }
}
</code></pre>
<h3 id="heading-how-to-compile-the-smart-contract">How to Compile the Smart Contract</h3>
<p>We need to compile the code to check if there are errors that we need to fix. The steps below will help us do just that.</p>
<p>Click on the third icon on the left side menu of the remix IDE:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-11.07.34.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Ensure that the solidity version selected matches the one you specified at the beginning of the smart contract. Then click the <code>Compile</code> button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-11.18.36.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The compilation was successful since we have no errors. Beautiful 🥰.</p>
<h3 id="heading-how-to-deploy-the-smart-contract">How to Deploy the Smart Contract</h3>
<p>Now that compilation is successful, let's deploy the contract.</p>
<p>Click on the fourth icon in the side menu:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-11.27.27-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Select <code>Remix VM (London)</code> for the <code>ENVIRONMENT</code>. It has ten (10) accounts with 100 dummy ethers each that you may use for test purposes. Then click the <code>Deploy</code> button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-11.33.30.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now when you scroll to the bottom, you will find the <code>Blockchain</code> contract under <strong>Deployed Contracts.</strong> Click the arrow by the deployed contract name to see the functions of the contract that you can interact with.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-11.46.28.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>There are three (3) functions in the image above that match the three (3) functions we defined in our smart contract. Remix automatically creates a UI for you to test your contracts as soon as you deploy them</p>
<h3 id="heading-how-to-test-the-smart-contract">How to Test the Smart Contract</h3>
<p>We will now test the functions we created to see how they respond.</p>
<h4 id="heading-how-to-test-the-addblocktochain-function">How to test the addBlockToChain function</h4>
<p>To test the <code>addBlockToChain</code> function, click the caret (^) icon by the side of the function button and input box. That drops down a form. Fill in <code>10</code> for the <code>amount</code>, and fill in one of the ten 10 account addresses for the <code>recipient</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-11.56.31.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click the <code>transact</code> button.</p>
<p>Note that you cannot send funds to the same address you used to deploy the contract. You must choose a different account.</p>
<h4 id="heading-how-to-test-the-getchain-function">How to test the getChain function</h4>
<p>Click the <code>getChain</code> button to reveal the blocks in the chain so far:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-12.02.10.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>It returns a <code>tuple</code>, which is a kind of <code>array</code>. Recall that <code>chain</code> is supposed to be an <code>array</code> containing a list of blocks.</p>
<h4 id="heading-how-to-test-the-getchaincount-function">How to test the getChainCount function</h4>
<p>To get the number of blocks added, click the <code>getChainCount</code> button:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot-2022-11-11-at-12.08.25.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And just as we defined it, it returns a <code>uint</code>. There is just one item in the <code>chain</code> for now, but as you keep adding more blocks, the number will increase.</p>
<p>Walah! Did we come this far? 😳 How Awesome 😍.</p>
<p>Congratulations on sticking to the end of this tutorial!</p>
<p>You are now ready to explore all that you can do with blockchain.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Blockchain is redefining the internet and has come to stay. The difficulty I encountered trying to learn the ropes of this new technology moved me to document this beginner-friendly guide. I hope that it helps everyone still struggling out there.</p>
<p>In this tutorial, you learned what blockchain is, how it works and what goes on behind the scenes. We demonstrated how it works using the OOP pattern of JavaScript and then concluded with a brief introduction to how to build smart contracts using the solidity programming language and remix IDE.</p>
<p>I recommend that you keep learning and getting better at building blockchain applications by creating the following projects in the order they are listed (by increasing difficulty):</p>
<pre><code class="lang-javascript">Hello World
Simple Storage
Voting Smart Contract
Ether Wallets
Multi Send
Time Lock Smart Contract
ERC20 Token
Token Wallet
Air Drop
ICO
</code></pre>
<p>These projects will challenge you to do research and sharpen your blockchain skill.</p>
<p>Happy Chaining!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Architect a Blockchain on Kubernetes – K8S Microservice Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I will describe how to use microservices architecture and Kubernetes to build a blockchain.  The technologies usually used for blockchains are purpose-driven, and you can use them for other projects as well. The examples in this arti... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-architect-a-blockchain-on-kubernetes-k8s-microservice-tutorial/</link>
                <guid isPermaLink="false">66b9ef5d148b506e83d90ab8</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kubernetes ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Microservices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kayode Adeniyi ]]>
                </dc:creator>
                <pubDate>Mon, 17 Oct 2022 16:02:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/Screenshot-2022-10-01-at-07.39.09.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I will describe how to use microservices architecture and Kubernetes to build a blockchain. </p>
<p>The technologies usually used for blockchains are purpose-driven, and you can use them for other projects as well.</p>
<p>The examples in this article can readily handle heavy loads and remain responsive and quick to execute user requests. </p>
<p>Because the cryptocurrency industry is growing fast, a lot of countries are setting rules around how everything should be managed. As a result, I will adhere to certain regulations and take into account certain details, such as the characteristics of the blockchain technology.</p>
<p>For instance, you can have overloads and performance problems with blockchain technology. And as the market for cryptocurrencies and blockchain technology expands, new products are more likely to appeal to a wide range of active blockchain technology users. </p>
<p>Because of this, I had to find a way to prevent the program from becoming overloaded in the event of a significant increase in users.</p>
<h1 id="heading-tutorial-prerequisites">Tutorial Prerequisites</h1>
<p>For this walkthrough, these are the following technologies we will be using. You should be familiar with them:</p>
<ul>
<li><strong>Node.js</strong> (specifically, the NestJS framework) for backend development. Nest.js forces you to use a modular structure where each feature can be isolated and easily connected/disconnected to/from other modules. Nest supports TypeScript out-of-the-box.</li>
<li><strong>PostgreSQL</strong> is the database we'll use to collect data.</li>
<li><strong>Kafka JS</strong> serves incoming loads and establishes communication between microservices.</li>
<li><strong>Helm charts and Kubernetes (k8s)</strong> for deployment. These tools will enable easy deployment of scalable microservices infrastructure on any cloud platform (we will use AWS EKS)</li>
</ul>
<p>Also, this article assumes you have a decent level of knowledge about Kubernetes, Helm, and Node. Let's dive in.</p>
<h1 id="heading-development-method">Development Method</h1>
<p>Our primary goal for the first phase is to divide our application into microservices.</p>
<p>In addition to helping with service communication, load balancing with Kafka enables the one-by-one processing of input data. When we have many customers, processing times may increase, but at least the service will continue and be preserved.</p>
<p>Additionally, if the cluster has enough resources, we can spawn extra consumers for the group that manages particular events. This reduces delays and accelerates task processing.</p>
<p>In this situation, we will develop six different microservices:</p>
<ol>
<li><strong>Admin Microservice</strong> – We'll use the admin microservice for all administrative panel logic, which should be isolated from user-facing functionality.</li>
<li><strong>Core Microservice</strong> – Logic pertaining to users and their accounts is contained in the core microservice. Identification, gifts, charts, profiles, and so on. However, this microservice does not carry out the duties of a financial service, such as processing payments and exchanging currency.</li>
<li><strong>Payment Microservice</strong> – A financial service called a "payment microservice" includes logic for trade, exchange, and withdrawal transactions. There will be integrations with CEX and DeFi solutions.</li>
<li><strong>Email and notification service</strong> – This microservice is in charge of informing the user of emails, push notifications, and other types of alerts. It contains a separate Kafka queue for requests from other microservices to send users emails or notifications.</li>
<li><strong>Cron Tasks</strong> – A microservice called Cron Tasks Service transmits predetermined events for task processing. Microservices don't carry out tasks on their own. Holding such a microservice helps prevent skipping cron job iterations when, for instance, the processing service is down due to deployment or a breakdown. The event will remain in a queue as it waits to be executed.</li>
<li><strong>Webhooks Microservice</strong> – The goal of the webhooks microservice is to prevent any events from external APIs that may be very significant and contain transaction statuses or other vital data from being missed. Such events are processed after being queued up (based on the sender API).</li>
</ol>
<p>Now let's see how to make these microservices using Nest.js.</p>
<p>For the Kafka messages broker, you'll need to create configuration options. In order to store the shared modules and configurations of all microservices, we will establish a shared resources folder.</p>
<h2 id="heading-microservices-configuration-options">Microservices Configuration Options</h2>
<p>Production apps must have configuration. The configuration is crucial for understanding what your production application consumes as you build out a microservice application. It is usually recommended practice to keep configuration settings distinct from your code when developing microservices.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { ClientProviderOptions, Transport } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/microservices'</span>;

<span class="hljs-keyword">import</span> CONFIG <span class="hljs-keyword">from</span> <span class="hljs-string">'@application-config'</span>;

<span class="hljs-keyword">import</span> { ConsumerGroups, ProjectMicroservices } <span class="hljs-keyword">from</span> <span class="hljs-string">'./microservices.enum'</span>;

<span class="hljs-keyword">const</span> { BROKER_HOST, BROKER_PORT } = CONFIG.KAFKA;




<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> PRODUCER_CONFIG = (name: ProjectMicroservices): <span class="hljs-function"><span class="hljs-params">ClientProviderOptions</span> =&gt;</span> ({

 name,

 <span class="hljs-attr">transport</span>: Transport.KAFKA,

 <span class="hljs-attr">options</span>: {

   <span class="hljs-attr">client</span>: {

     <span class="hljs-attr">brokers</span>: [${BROKER_HOST}:${BROKER_PORT}],

   },

 }

});



<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> CONSUMER_CONFIG = <span class="hljs-function">(<span class="hljs-params">groupId: ConsumerGroups</span>) =&gt;</span> ({

 <span class="hljs-attr">transport</span>: Transport.KAFKA,

 <span class="hljs-attr">options</span>: {

   <span class="hljs-attr">client</span>: {

     <span class="hljs-attr">brokers</span>: [${BROKER_HOST}:${BROKER_PORT}],

   },

   <span class="hljs-attr">consumer</span>: {

     groupId

   }

 }

});
</code></pre>
<p>Let's link our microservice for the admin panel to Kafka in consumer mode. We can detect and manage events from topics thanks to it.</p>
<p>Make the app operate in microservice mode so that events can be consumed like this:</p>
<pre><code class="lang-js">app.connectMicroservice(CONSUMER_CONFIG(ConsumerGroups.ADMIN));

 <span class="hljs-keyword">await</span> app.startAllMicroservices();
</code></pre>
<p>We can see that groupId is included in the consumer configuration. It's a crucial choice that will enable customers from the same group to get events from topics and share them with one another to process them more quickly.</p>
<p>For instance, we can use autoscaling to launch more pods to divide loading between them and speed up the process double if our microservice receives events more quickly than it can process them.</p>
<p>Consumers must be included in the group for this to work, and after scaling, spawned pods will also be included. They won't have to handle the same subject events from several Kafka partitions because they can share loading.</p>
<p>Let's look at an illustration of how we can use Nest to capture and handle Kafka events.</p>
<h2 id="heading-consumer-controller">Consumer Controller</h2>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Controller } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

<span class="hljs-keyword">import</span> { Ctx, KafkaContext, MessagePattern, EventPattern, Payload } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/microservices'</span>;




@Controller(<span class="hljs-string">'consumer'</span>)

<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsumerController</span> </span>{

 @MessagePattern(<span class="hljs-string">'hero'</span>)

 readMessage(@Payload() message: any, @Ctx() context: KafkaContext) {

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

 }




 @EventPattern(<span class="hljs-string">'event-hero'</span>)

 sendNotif(data) {

   <span class="hljs-built_in">console</span>.log(data);

 }

}
</code></pre>
<p>Customers can operate in two modes. It accepts events, processes them without delivering a response (EventPattern decorator), or, after processing an event, returns the response to the producer (MessagePattern decorator). </p>
<p>Since it doesn't contain any additional source code layers to enable request/response functionality, EventPattern is preferable and you should choose it wherever possible.</p>
<h2 id="heading-who-are-the-producers">Who Are the Producers?</h2>
<p>We must supply producer configuration for a module that will be in charge of transmitting events in order to link producers.</p>
<h3 id="heading-producer-connection">Producer Connection</h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

<span class="hljs-keyword">import</span> DatabaseModule <span class="hljs-keyword">from</span> <span class="hljs-string">'@shared/database/database.module'</span>;

<span class="hljs-keyword">import</span> { ClientsModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/microservices'</span>;

<span class="hljs-keyword">import</span> { ProducerController } <span class="hljs-keyword">from</span> <span class="hljs-string">'./producer.controller'</span>;

<span class="hljs-keyword">import</span> { PRODUCER_CONFIG } <span class="hljs-keyword">from</span> <span class="hljs-string">'@shared/microservices/microservices.config'</span>;

<span class="hljs-keyword">import</span> { ProjectMicroservices } <span class="hljs-keyword">from</span> <span class="hljs-string">'@shared/microservices/microservices.enum'</span>;




@Module({

 <span class="hljs-attr">imports</span>: [

   DatabaseModule,

   ClientsModule.register([PRODUCER_CONFIG(ProjectMicroservices.ADMIN)]),

 ],

 <span class="hljs-attr">controllers</span>: [ProducerController],

 <span class="hljs-attr">providers</span>: [],

})

<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProducerModule</span> </span>{}
</code></pre>
<h3 id="heading-event-based-producer">Event-based producer</h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Controller, Get, Inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

<span class="hljs-keyword">import</span> { ClientKafka } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/microservices'</span>;

<span class="hljs-keyword">import</span> { ProjectMicroservices } <span class="hljs-keyword">from</span> <span class="hljs-string">'@shared/microservices/microservices.enum'</span>;




@Controller(<span class="hljs-string">'producer'</span>)

<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProducerController</span> </span>{

 <span class="hljs-keyword">constructor</span>(

   @Inject(ProjectMicroservices.ADMIN)

   private readonly client: ClientKafka,

 ) {}




 @Get()

 <span class="hljs-keyword">async</span> getHello() {

   <span class="hljs-built_in">this</span>.client.emit(<span class="hljs-string">'event-hero'</span>, { <span class="hljs-attr">msg</span>: <span class="hljs-string">'Event Based'</span>});

 }

}
</code></pre>
<h3 id="heading-requestresponse-based-producer">Request/response-based producer</h3>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Controller, Get, Inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

<span class="hljs-keyword">import</span> { ClientKafka } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/microservices'</span>;

<span class="hljs-keyword">import</span> { ProjectMicroservices } <span class="hljs-keyword">from</span> <span class="hljs-string">'@shared/microservices/microservices.enum'</span>;




@Controller(<span class="hljs-string">'producer'</span>)

<span class="hljs-keyword">export</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProducerController</span> </span>{

 <span class="hljs-keyword">constructor</span>(

   @Inject(ProjectMicroservices.ADMIN)

   private readonly client: ClientKafka,

 ) {}




 <span class="hljs-keyword">async</span> onModuleInit() {

   <span class="hljs-comment">// Need to subscribe to a topic</span>

   <span class="hljs-comment">// to make the response receiving from Kafka microservice possible</span>

   <span class="hljs-built_in">this</span>.client.subscribeToResponseOf(<span class="hljs-string">'hero'</span>);

   <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.client.connect();

 }




 @Get()

 <span class="hljs-keyword">async</span> getHello() {

   <span class="hljs-keyword">const</span> responseBased = <span class="hljs-built_in">this</span>.client.send(<span class="hljs-string">'hero'</span>, { <span class="hljs-attr">msg</span>: <span class="hljs-string">'Response Based'</span> });

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

 }

}
</code></pre>
<p>Each microservice has the option of operating in one of the two modes—producer or consumer—or in both modes simultaneously (mixed). </p>
<p>Microservices typically employ mixed mode for load balancing, producing events to the subject, and consuming them while equally splitting the load.</p>
<p>For each microservice, we'll use a Kubernetes setup based on Helm chart templates.</p>
<p><img src="https://lh5.googleusercontent.com/t7eB19l8xOFm4Fsm-cJ1HMAkBhIOBiHHs-psH_6NXPIqbOPFWI1uMlbOYeD0mCaD3BLNjR070IktMx1V-cTfThBZ3GzgKo2aNnLtObBJvzq09YZNhL5nuOOY9FUE2HBx_FF0L3VqCuFZBSWV6532GmXu7OFUiOtAjTufDfJEEhI-wPtfn-EazwRCIA" alt="Image" width="498" height="700" loading="lazy"></p>
<p>There are several configuration files in the template:</p>
<ul>
<li>Hpa (horizontal pod autoscaler)</li>
<li>Ingress controller</li>
<li>Service</li>
<li>Deployment</li>
</ul>
<p>We'll examine each configuration file separately (without Helm templating).</p>
<h3 id="heading-how-to-deploy-the-admin-api">How to deploy the admin-API</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api</span>

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">replicas:</span> <span class="hljs-number">1</span>

 <span class="hljs-attr">selector:</span>

   <span class="hljs-attr">matchLabels:</span>

     <span class="hljs-attr">app:</span> <span class="hljs-string">admin-api</span>

 <span class="hljs-attr">template:</span>

   <span class="hljs-attr">metadata:</span>

     <span class="hljs-attr">labels:</span>

       <span class="hljs-attr">app:</span> <span class="hljs-string">admin-api</span>

   <span class="hljs-attr">spec:</span>

     <span class="hljs-attr">containers:</span>

     <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api</span>

       <span class="hljs-attr">Image:</span> <span class="hljs-string">xxx208926xxx.dkr.ecr.us-east-1.amazonaws.com/project-name/stage/admin-api</span>

       <span class="hljs-attr">resources:</span>

         <span class="hljs-attr">requests:</span>

           <span class="hljs-attr">cpu:</span> <span class="hljs-string">250m</span>

           <span class="hljs-attr">memory:</span> <span class="hljs-string">512Mi</span>

         <span class="hljs-attr">limits:</span>

           <span class="hljs-attr">cpu:</span> <span class="hljs-string">250m</span>

           <span class="hljs-attr">memory:</span> <span class="hljs-string">512Mi</span>

       <span class="hljs-attr">ports:</span>

         <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">80</span>

       <span class="hljs-attr">env:</span>

         <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">NODE_ENV</span>

           <span class="hljs-attr">value:</span> <span class="hljs-string">production</span>




         <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">APP_PORT</span>

           <span class="hljs-attr">value:</span> <span class="hljs-string">"80"</span>
</code></pre>
<p>You can include more minimal configurations, such as resource limitations, health check configurations, update strategies, and so on in a deployment. </p>
<h3 id="heading-admin-api-service">Admin-API service</h3>
<pre><code class="lang-yaml"><span class="hljs-meta">---</span>

<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api</span>

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">selector:</span>

   <span class="hljs-attr">app:</span> <span class="hljs-string">admin-api</span>

 <span class="hljs-attr">ports:</span>

   <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api-port</span>

     <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>

     <span class="hljs-attr">targetPort:</span> <span class="hljs-number">80</span>

     <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>

 <span class="hljs-attr">type:</span> <span class="hljs-string">NodePort</span>
</code></pre>
<p>To use this service, we must make it available to the public. Let's utilise SSL setup to leverage a secure HTTPS connection and expose our app via a load balancer.</p>
<p>On our cluster, we must deploy a load balancer controller. The most widely used answer is as follows: Load Balancer Controller for AWS.</p>
<p>Next, we must set up ingress with the following settings:</p>
<h3 id="heading-admin-api-ingress-controller">Admin-API ingress controller</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.k8s.io/v1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">Ingress</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">namespace:</span> <span class="hljs-string">default</span>

 <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api-ingress</span>

 <span class="hljs-attr">annotations:</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/load-balancer-name:</span> <span class="hljs-string">admin-api-alb</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/ip-address-type:</span> <span class="hljs-string">ipv4</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/tags:</span> <span class="hljs-string">Environment=production,Kind=application</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/scheme:</span> <span class="hljs-string">internet-facing</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/certificate-arn:</span> <span class="hljs-string">arn:aws:acm:us-east-2:xxxxxxxx:certificate/xxxxxxxxxx</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/listen-ports:</span> <span class="hljs-string">'[{"HTTP": 80}, {"HTTPS":443}]'</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/healthcheck-protocol:</span> <span class="hljs-string">HTTPS</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/healthcheck-path:</span> <span class="hljs-string">/healthcheck</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/healthcheck-interval-seconds:</span> <span class="hljs-string">'15'</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/ssl-redirect:</span> <span class="hljs-string">'443'</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/group.name:</span> <span class="hljs-string">admin-api</span>

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">ingressClassName:</span> <span class="hljs-string">alb</span>

 <span class="hljs-attr">rules:</span>

   <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> <span class="hljs-string">example.com</span>

     <span class="hljs-attr">http:</span>

       <span class="hljs-attr">paths:</span>

         <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">/*</span>

           <span class="hljs-attr">pathType:</span> <span class="hljs-string">ImplementationSpecific</span>

           <span class="hljs-attr">backend:</span>

             <span class="hljs-attr">service:</span>

               <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api</span>

               <span class="hljs-attr">port:</span>

                 <span class="hljs-attr">number:</span> <span class="hljs-number">80</span>
</code></pre>
<p>Once this configuration has been applied, a new alb load balancer will be formed. We must construct a domain with the name we specified in the 'host' option and direct traffic to our load balancer from this host.</p>
<h3 id="heading-admin-api-autoscaling-configuration">Admin-API autoscaling configuration</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">autoscaling/v2beta1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">HorizontalPodAutoscaler</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api-hpa</span>

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">scaleTargetRef:</span>

   <span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>

   <span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>

   <span class="hljs-attr">name:</span> <span class="hljs-string">admin-api</span>

 <span class="hljs-attr">minReplicas:</span> <span class="hljs-number">1</span>

 <span class="hljs-attr">maxReplicas:</span> <span class="hljs-number">2</span>

 <span class="hljs-attr">metrics:</span>

   <span class="hljs-bullet">-</span> <span class="hljs-attr">type:</span> <span class="hljs-string">Resource</span>

     <span class="hljs-attr">resource:</span>

       <span class="hljs-attr">name:</span> <span class="hljs-string">cpu</span>

       <span class="hljs-attr">targetAverageUtilization:</span> <span class="hljs-number">90</span>
</code></pre>
<h2 id="heading-how-does-helm-come-into-the-picture">How Does Helm Come into the Picture?</h2>
<p>When we want to make our k8s infrastructure less complex, Helm is quite helpful. Without this tool, running it on a cluster requires writing numerous YML files.</p>
<p>Additionally, we must consider the relationships among applications, labels, names, and so on. Helm, on the other hand, can simplify things. It functions similarly to a package manager, allowing us to make an app template, prepare it using short commands, and then launch it.</p>
<p>Let's create our templates using Helm.</p>
<h3 id="heading-admin-api-deployment-helm-chart">Admin-API deployment (Helm chart)</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">name:</span> {{ <span class="hljs-string">.Values.appName</span> }}

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">replicas:</span> {{ <span class="hljs-string">.Values.replicas</span> }}

 <span class="hljs-attr">selector:</span>

   <span class="hljs-attr">matchLabels:</span>

     <span class="hljs-attr">app:</span> {{ <span class="hljs-string">.Values.appName</span> }}

 <span class="hljs-attr">template:</span>

   <span class="hljs-attr">metadata:</span>

     <span class="hljs-attr">labels:</span>

       <span class="hljs-attr">app:</span> {{ <span class="hljs-string">.Values.appName</span> }}

   <span class="hljs-attr">spec:</span>

     <span class="hljs-attr">containers:</span>

     <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> {{ <span class="hljs-string">.Values.appName</span> }}

       <span class="hljs-attr">image:</span> {{ <span class="hljs-string">.Values.image.repository</span> }}<span class="hljs-string">:{{</span> <span class="hljs-string">.Values.image.tag</span> <span class="hljs-string">}}"</span>

       <span class="hljs-attr">imagePullPolicy:</span> {{ <span class="hljs-string">.Values.image.pullPolicy</span> }}

       <span class="hljs-attr">ports:</span>

       <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> {{ <span class="hljs-string">.Values.internalPort</span> }}

       {{<span class="hljs-bullet">-</span> <span class="hljs-string">with</span> <span class="hljs-string">.Values.env</span> }}

       <span class="hljs-attr">env:</span> {{ <span class="hljs-string">tpl</span> <span class="hljs-string">(.</span> <span class="hljs-string">|</span> <span class="hljs-string">toYaml)</span> <span class="hljs-string">$</span> <span class="hljs-string">|</span> <span class="hljs-string">nindent</span> <span class="hljs-number">12</span> }}

       {{<span class="hljs-bullet">-</span> <span class="hljs-string">end</span> }}
</code></pre>
<h3 id="heading-admin-api-service-helm-chart">Admin-API service (Helm chart)</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">name:</span> {{ <span class="hljs-string">.Values.global.appName</span> }}

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">selector:</span>

   <span class="hljs-attr">app:</span> {{ <span class="hljs-string">.Values.global.appName</span> }}

 <span class="hljs-attr">ports:</span>

   <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> {{ <span class="hljs-string">.Values.global.appName</span> }}<span class="hljs-string">-port</span>

     <span class="hljs-attr">port:</span> {{ <span class="hljs-string">.Values.externalPort</span> }}

     <span class="hljs-attr">targetPort:</span> {{ <span class="hljs-string">.Values.internalPort</span> }}

     <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>

 <span class="hljs-attr">type:</span> <span class="hljs-string">NodePort</span>
</code></pre>
<h3 id="heading-admin-api-ingress-helm-chart">Admin-API ingress (Helm chart)</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.k8s.io/v1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">Ingress</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">namespace:</span> <span class="hljs-string">default</span>

 <span class="hljs-attr">name:</span> <span class="hljs-string">ingress</span>

 <span class="hljs-attr">annotations:</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/load-balancer-name:</span> {{ <span class="hljs-string">.Values.ingress.loadBalancerName</span> }}

   <span class="hljs-attr">alb.ingress.kubernetes.io/ip-address-type:</span> <span class="hljs-string">ipv4</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/tags:</span> {{ <span class="hljs-string">.Values.ingress.tags</span> }}

   <span class="hljs-attr">alb.ingress.kubernetes.io/scheme:</span> <span class="hljs-string">internet-facing</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/certificate-arn:</span> {{ <span class="hljs-string">.Values.ingress.certificateArn</span> }}

   <span class="hljs-attr">alb.ingress.kubernetes.io/listen-ports:</span> <span class="hljs-string">'[{"HTTP": 80}, {"HTTPS":443}]'</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/healthcheck-protocol:</span> <span class="hljs-string">HTTPS</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/healthcheck-path:</span> {{ <span class="hljs-string">.Values.ingress.healthcheckPath</span> }}

   <span class="hljs-attr">alb.ingress.kubernetes.io/healthcheck-interval-seconds:</span> {{ <span class="hljs-string">.Values.ingress.healthcheckIntervalSeconds</span> }}

   <span class="hljs-attr">alb.ingress.kubernetes.io/ssl-redirect:</span> <span class="hljs-string">'443'</span>

   <span class="hljs-attr">alb.ingress.kubernetes.io/group.name:</span> {{ <span class="hljs-string">.Values.ingress.loadBalancerGroup</span> }}

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">ingressClassName:</span> <span class="hljs-string">alb</span>

 <span class="hljs-attr">rules:</span>

   <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> {{ <span class="hljs-string">.Values.adminApi.domain</span> }}

     <span class="hljs-attr">http:</span>

       <span class="hljs-attr">paths:</span>

         <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> {{ <span class="hljs-string">.Values.adminApi.path</span> }}

           <span class="hljs-attr">pathType:</span> <span class="hljs-string">ImplementationSpecific</span>

           <span class="hljs-attr">backend:</span>

             <span class="hljs-attr">service:</span>

               <span class="hljs-attr">name:</span> {{ <span class="hljs-string">.Values.adminApi.appName</span> }}

               <span class="hljs-attr">port:</span>

                 <span class="hljs-attr">number:</span> {{ <span class="hljs-string">.Values.adminApi.externalPort</span> }}
</code></pre>
<h3 id="heading-admin-api-autoscaling-configuration-helm-chart">Admin-API autoscaling configuration (Helm chart)</h3>
<pre><code class="lang-yaml">{{<span class="hljs-bullet">-</span> <span class="hljs-string">if</span> <span class="hljs-string">.Values.autoscaling.enabled</span> }}

<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">autoscaling/v2beta1</span>

<span class="hljs-attr">kind:</span> <span class="hljs-string">HorizontalPodAutoscaler</span>

<span class="hljs-attr">metadata:</span>

 <span class="hljs-attr">name:</span> {{ <span class="hljs-string">include</span> <span class="hljs-string">"ks.fullname"</span> <span class="hljs-string">.</span> }}

 <span class="hljs-attr">labels:</span>

   {{<span class="hljs-bullet">-</span> <span class="hljs-string">include</span> <span class="hljs-string">"ks.labels"</span> <span class="hljs-string">.</span> <span class="hljs-string">|</span> <span class="hljs-string">nindent</span> <span class="hljs-number">4</span> }}

<span class="hljs-attr">spec:</span>

 <span class="hljs-attr">scaleTargetRef:</span>

   <span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>

   <span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>

   <span class="hljs-attr">name:</span> {{ <span class="hljs-string">include</span> <span class="hljs-string">"ks.fullname"</span> <span class="hljs-string">.</span> }}

 <span class="hljs-attr">minReplicas:</span> {{ <span class="hljs-string">.Values.autoscaling.minReplicas</span> }}

 <span class="hljs-attr">maxReplicas:</span> {{ <span class="hljs-string">.Values.autoscaling.maxReplicas</span> }}

 <span class="hljs-attr">metrics:</span>

 {{<span class="hljs-bullet">-</span> <span class="hljs-string">if</span> <span class="hljs-string">.Values.autoscaling.targetCPUUtilizationPercentage</span> }}

   <span class="hljs-bullet">-</span> <span class="hljs-attr">type:</span> <span class="hljs-string">Resource</span>

     <span class="hljs-attr">resource:</span>

       <span class="hljs-attr">name:</span> <span class="hljs-string">cpu</span>

       <span class="hljs-attr">targetAverageUtilization:</span> {{ <span class="hljs-string">.Values.autoscaling.targetCPUUtilizationPercentage</span> }}

 {{<span class="hljs-bullet">-</span> <span class="hljs-string">end</span> }}

 {{<span class="hljs-bullet">-</span> <span class="hljs-string">if</span> <span class="hljs-string">.Values.autoscaling.targetMemoryUtilizationPercentage</span> }}

   <span class="hljs-bullet">-</span> <span class="hljs-attr">type:</span> <span class="hljs-string">Resource</span>

     <span class="hljs-attr">resource:</span>

       <span class="hljs-attr">name:</span> <span class="hljs-string">memory</span>

       <span class="hljs-attr">targetAverageUtilization:</span> {{ <span class="hljs-string">.Values.autoscaling.targetMemoryUtilizationPercentage</span> }}

 {{<span class="hljs-bullet">-</span> <span class="hljs-string">end</span> }}

{{<span class="hljs-bullet">-</span> <span class="hljs-string">end</span> }}
</code></pre>
<p>The "values.yml," "values-dev.yml," and "values-stage.yml" files contain the values for the templates. The environment will determine which of them is used. </p>
<p>Let's look at few samples of dev env values.</p>
<h3 id="heading-admin-api-helm-values-stageyml-file">Admin-API Helm values-stage.yml file</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">env:</span> <span class="hljs-string">stage</span>

<span class="hljs-attr">appName:</span> <span class="hljs-string">admin-api</span>

<span class="hljs-attr">domain:</span> <span class="hljs-string">admin-api.xxxx.com</span>

<span class="hljs-attr">path:</span> <span class="hljs-string">/*</span>

<span class="hljs-attr">internalPort:</span> <span class="hljs-string">'80'</span>

<span class="hljs-attr">externalPort:</span> <span class="hljs-string">'80'</span>




<span class="hljs-attr">replicas:</span> <span class="hljs-number">1</span>

<span class="hljs-attr">image:</span>

 <span class="hljs-attr">repository:</span> <span class="hljs-string">xxxxxxxxx.dkr.ecr.us-east-2.amazonaws.com/admin-api</span>

 <span class="hljs-attr">pullPolicy:</span> <span class="hljs-string">Always</span>

 <span class="hljs-attr">tag:</span> <span class="hljs-string">latest</span>




<span class="hljs-attr">ingress:</span>

 <span class="hljs-attr">loadBalancerName:</span> <span class="hljs-string">project-microservices-alb</span>

 <span class="hljs-attr">tags:</span> <span class="hljs-string">Environment=stage,Kind=application</span>

 <span class="hljs-attr">certificateArn:</span> <span class="hljs-string">arn:aws:acm:us-east-2:xxxxxxxxx:certificate/xxxxxx</span>

 <span class="hljs-attr">healthcheckPath:</span> <span class="hljs-string">/healthcheck</span>

 <span class="hljs-attr">healthcheckIntervalSeconds:</span> <span class="hljs-string">'15'</span>

 <span class="hljs-attr">loadBalancerGroup:</span> <span class="hljs-string">project-microservices</span>




<span class="hljs-attr">autoscaling:</span>

 <span class="hljs-attr">enabled:</span> <span class="hljs-literal">false</span>

 <span class="hljs-attr">minReplicas:</span> <span class="hljs-number">1</span>

 <span class="hljs-attr">maxReplicas:</span> <span class="hljs-number">100</span>

 <span class="hljs-attr">targetCPUUtilizationPercentage:</span> <span class="hljs-number">80</span>




<span class="hljs-attr">env:</span>

 <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">NODE_ENV</span>

   <span class="hljs-attr">value:</span> <span class="hljs-string">stage</span>




 <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">ADMIN_PORT</span>

   <span class="hljs-attr">value:</span> <span class="hljs-string">"80</span>
</code></pre>
<p>We must upgrade the chart and restart our deployment in order for the configuration to take effect on the cluster.</p>
<p>Let's investigate the GitHub Actions steps in question.</p>
<h3 id="heading-how-to-apply-helm-configuration-in-github-actions">How to apply Helm configuration in GitHub Actions</h3>
<p>GitHub actions are CI/CD services from GitHub. They provide straightforward work processes arranged as Yaml files which run configurable blocks of code based on GitHub events. Since they are integrated into GitHub, they reduce significantly the overhead in getting a CI/CD pipeline setup.</p>
<pre><code class="lang-yaml"> <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Admin</span> <span class="hljs-string">image</span> <span class="hljs-string">build</span> <span class="hljs-string">and</span> <span class="hljs-string">push</span>

       <span class="hljs-attr">run:</span> <span class="hljs-string">|</span>

         <span class="hljs-string">docker</span> <span class="hljs-string">build</span> <span class="hljs-string">-t</span> <span class="hljs-string">project-admin-api</span> <span class="hljs-string">-f</span> <span class="hljs-string">Dockerfile.admin</span> <span class="hljs-string">.</span>

         <span class="hljs-string">docker</span> <span class="hljs-string">tag</span> <span class="hljs-string">project-admin-api</span> <span class="hljs-string">${{</span> <span class="hljs-string">env.AWS_ECR_REGISTRY</span> <span class="hljs-string">}}/project/${{</span> <span class="hljs-string">env.ENV</span> <span class="hljs-string">}}/admin-api:latest</span>

         <span class="hljs-string">docker</span> <span class="hljs-string">push</span> <span class="hljs-string">${{</span> <span class="hljs-string">env.AWS_ECR_REGISTRY</span> <span class="hljs-string">}}/project/${{</span> <span class="hljs-string">env.ENV</span> <span class="hljs-string">}}/admin-api:latest</span>




     <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Helm</span> <span class="hljs-string">upgrade</span> <span class="hljs-string">admin-api</span>

       <span class="hljs-attr">uses:</span> <span class="hljs-string">koslib/helm-eks-action@master</span>

       <span class="hljs-attr">env:</span>

         <span class="hljs-attr">KUBE_CONFIG_DATA:</span> <span class="hljs-string">${{</span> <span class="hljs-string">env.KUBE_CONFIG_DATA</span> <span class="hljs-string">}}</span>

       <span class="hljs-attr">with:</span>

         <span class="hljs-attr">command:</span> <span class="hljs-string">helm</span> <span class="hljs-string">upgrade</span> <span class="hljs-string">--install</span> <span class="hljs-string">admin-api</span> <span class="hljs-string">-n</span> <span class="hljs-string">project-${{</span> <span class="hljs-string">env.ENV</span> <span class="hljs-string">}}</span> <span class="hljs-string">charts/admin-api/</span> <span class="hljs-string">-f</span> <span class="hljs-string">charts/admin-api/values-${{</span> <span class="hljs-string">env.ENV</span> <span class="hljs-string">}}.yaml</span>




     <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">admin-api</span> <span class="hljs-string">image</span>

       <span class="hljs-attr">uses:</span> <span class="hljs-string">kodermax/kubectl-aws-eks@master</span>

       <span class="hljs-attr">env:</span>

         <span class="hljs-attr">KUBE_CONFIG_DATA:</span> <span class="hljs-string">${{</span> <span class="hljs-string">env.KUBE_CONFIG_DATA</span> <span class="hljs-string">}}</span>

       <span class="hljs-attr">with:</span>

         <span class="hljs-attr">args:</span> <span class="hljs-string">rollout</span> <span class="hljs-string">restart</span> <span class="hljs-string">deployment/admin-api-project-admin-api</span> <span class="hljs-string">--namespace=project-${{</span> <span class="hljs-string">env.ENV</span> <span class="hljs-string">}}</span>
</code></pre>
<h1 id="heading-summary">Summary</h1>
<p>In this article, we looked at infrastructure-building and Kubernetes cluster deployment steps for microservices. By using straightforward examples and avoiding further complexity with full configurations, I hope it was relatively easy to grasp. </p>
<p>Connect with me on <a target="_blank" href="https://www.linkedin.com/in/kadeniyi/">LinkedIn</a> and <a target="_blank" href="https://twitter.com/mkbadeniyi">Twitter</a></p>
<p>Hasta la vista!</p>
 ]]>
                </content:encoded>
            </item>
        
            <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>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp is Building a NEAR Curriculum ]]>
                </title>
                <description>
                    <![CDATA[ Update December 2022: The first group of projects is fully released. The newly available projects are "Learn NEAR Smart Contracts by Building a Word Guessing Game" and "Build a Sentence Making Smart Contract". The "When Will it be Available?" section... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/near-curriculum/</link>
                <guid isPermaLink="false">66b0aa487cd8dca6718a22ae</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ NEAR ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tom Mondloch ]]>
                </dc:creator>
                <pubDate>Wed, 21 Sep 2022 15:10:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/joshua-newton-IRXYNAMlUtw-unsplash-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><em>Update December 2022: The first group of projects is fully released. The newly available projects are "Learn NEAR Smart Contracts by Building a Word Guessing Game" and "Build a Sentence Making Smart Contract". The <a class="post-section-overview" href="#heading-when-will-it-be-available">"When Will it be Available?"</a> section has been updated to include the new projects.</em></p>
<p>Over the past 9 months, several of our instructors have been hard at work on a comprehensive NEAR curriculum. This will focus on NEAR's blockchain protocol and the NEAR tool ecosystem.</p>
<p>This curriculum is made possible by NEAR Foundation, who gave our charity a grant to 100% fund development of this curriculum.</p>
<h2 id="heading-what-will-it-contain">What will it contain?</h2>
<p>The curriculum will contain at least ten interactive practice projects that will guide you through learning the NEAR protocol and their tools. </p>
<p>You'll learn how to build and deploy your own smart contracts, dApps, work with NEAR command line tools, and much more. There will also be five challenging integrated projects to test your knowledge.</p>
<h2 id="heading-how-will-it-work">How will it work?</h2>
<p>These courses will run in a docker container using VS Code and the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=freeCodeCamp.freecodecamp-courses">freeCodeCamp Courses extension.</a></p>
<h3 id="heading-heres-a-sample-of-the-first-project">Here's a Sample of the first Project</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/gV4aL0LY2LA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-when-will-it-be-available">When Will it be Available?</h2>
<p>The courses will be released in batches. As we finish creating a group of projects, typically consisting of two interactive practice projects and one integrated project, they will be released for you to complete. The first group is available now! and consists of these projects:</p>
<ul>
<li>Learn How to Set Up NEAR by Building a Hello World Smart Contract</li>
<li>Learn NEAR Smart Contracts by Building a Word Guessing Game</li>
<li>Build a Sentence Making Smart Contract</li>
</ul>
<h2 id="heading-how-to-run-the-courses">How to Run the Courses</h2>
<p>Follow the steps below to run the courses</p>
<h3 id="heading-developer-environment-prerequisites">Developer Environment Prerequisites</h3>
<p>Before you get started, make sure you have these installed on your computer:</p>
<ol>
<li><a target="_blank" href="https://docs.docker.com/engine/">Docker Engine</a></li>
<li><a target="_blank" href="https://code.visualstudio.com/download">VS Code</a> and the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers">Dev Containers</a> extension</li>
<li>Git</li>
</ol>
<h3 id="heading-how-to-run-the-curriculum-in-docker">How to Run the Curriculum in Docker</h3>
<p>Follow these instructions to clone the repo and run the courses:</p>
<ol>
<li>Open a terminal and clone the <a target="_blank" href="https://github.com/freeCodeCamp/near-curriculum">near-curriculum</a> repo with:<pre><code class="lang-console">git clone https://github.com/freeCodeCamp/near-curriculum.git
</code></pre>
</li>
<li><p>Navigate to the <code>near-curriculum</code> directory, and open it in a VSCode workspace with:</p>
<pre><code class="lang-console">code .
</code></pre>
</li>
<li><p>Press <code>Ctrl / Cmd + Shift + P</code> to open the command palette, and run <code>Dev Containers: Rebuild Container and Reopen in Container</code>. VS Code will build the container to run the projects in, it will take a few minutes the first time.</p>
</li>
<li>Once it's finished, press <code>Ctrl / Cmd + Shift + P</code> again and run <code>freeCodeCamp: Run Course</code> to start the courses. This will also take a moment.</li>
<li>The simple browser will open when it's done. If it's a blank white page, use the refresh button to update it and see the courses home page.</li>
<li>Click on one of the available projects to start a project.</li>
<li>Follow the instructions to complete the project.</li>
<li>Have fun!</li>
</ol>
<p>If you want to switch projects, click the freeCodeCamp logo at the top to get back to the home page.</p>
<h2 id="heading-sign-up-for-updates">Sign up for updates</h2>
<p>Fill out <a target="_blank" href="https://docs.google.com/forms/d/e/1FAIpQLSf2-_-TNKOd_q-uOHkuZfpogZe0GLZkrCwvG2ZvAJXFnfA_Ag/viewform?usp=sf_link">this google form</a> to sign up to receive updates when new courses are released.</p>
<h2 id="heading-while-youre-waiting">While You're Waiting</h2>
<p>While you are waiting for these courses, you can <a target="_blank" href="https://www.freecodecamp.org/news/web3-curriculum-open-beta">try the Web3 curriculum</a> (also under development). It will teach you many Web3 and blockchain concepts you will want to know for the NEAR curriculum.</p>
<h2 id="heading-learn-more-about-near-foundation">Learn more about NEAR Foundation</h2>
<p>You can learn more about <a target="_blank" href="https://near.foundation/">NEAR Foundation</a> by visiting their website.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp's Web3 Curriculum Open Beta – And How to Run it ]]>
                </title>
                <description>
                    <![CDATA[ Update January 2023: The first group of projects is now fully available. The "Available interactive projects" section has been added to list the completed practice projects. The newly available projects are "Learn Digital Ledgers by Building a Blockc... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/web3-curriculum-open-beta/</link>
                <guid isPermaLink="false">66b0aa4f2cf7184612a5a9c1</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tom Mondloch ]]>
                </dc:creator>
                <pubDate>Wed, 21 Sep 2022 14:45:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/09/thomas-habr-wprOCzLIEYI-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><em>Update January 2023: The first group of projects is now fully available. The <a class="post-section-overview" href="#heading-available-interactive-projects">"Available interactive projects"</a> section has been added to list the completed practice projects. The newly available projects are "Learn Digital Ledgers by Building a Blockchain", "Learn Proof of Work Consensus by Building a Block Mining Algorithm", and "Learn Digital Signatures by Building a Wallet".</em></p>
<p>Over the past 11 months, we've made considerable progress on our Web3 curriculum. Today I'm thrilled to say that parts of this curriculum are now in open beta. You can try them today.</p>
<p>Before we get into the details, I want to thank the KaijuKingz community, who made a donation to freeCodeCamp that made development of these courses possible. You can <a target="_blank" href="https://www.freecodecamp.org/news/carbon-neutral-web3-curriculum-plans/">read more about their gift to the freeCodeCamp community here</a>.</p>
<h2 id="heading-how-to-approach-these-web3-courses">How to Approach These Web3 Courses</h2>
<p>As a prerequisite for this course, we recommend first learning full stack web development. You can do this by working through the first 7 <a target="_blank" href="https://www.freecodecamp.org/learn/">freeCodeCamp certifications</a> and building their projects:</p>
<ol>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/2022/responsive-web-design/">Responsive Web Design</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/">JavaScript Algorithms and Data Structures</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/front-end-development-libraries/">Front End Development Libraries</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/data-visualization/">Data Visualization</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/relational-database/">Relational Database</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/back-end-development-and-apis/">Back End Development and APIs</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/quality-assurance/">Quality Assurance</a></li>
</ol>
<p>We also recommend you know some knowledge of basic blockchain development concepts. freeCodeCamp has <a target="_blank" href="https://www.freecodecamp.org/news/learn-blockchain-solidity-full-stack-javascript-development/">an in-depth 32-hour course that covers this</a>, taught by developer and instructor Patrick Collins.</p>
<p>We also recommend learning some Rust, which you can learn interactively using <a target="_blank" href="https://www.freecodecamp.org/news/rust-in-replit/">freeCodeCamp's Rust course</a>.</p>
<p>Again, these prerequisites are just our recommendations. Feel free to just dive in and return to those resources as you see fit.</p>
<p>Right now, we have designed five integrated Web3 projects for you to complete:</p>
<ol>
<li>Build a Video Game Marketplace Blockchain</li>
<li>Build a Fundraising Smart Contract</li>
<li>Build a Peer-to-Peer Network</li>
<li>Build a Web3 Client-Side Package for your dApp</li>
<li>Build a Smart Contract in Rust</li>
</ol>
<p>Each of these projects has its own set of instructions with tasks for you to fulfill, and tests to ensure you've implemented your project correctly. Complete all the tasks and get all the tests to pass to finish each project.</p>
<h2 id="heading-these-5-projects-are-just-the-beginning">These 5 projects are just the beginning</h2>
<p>We are also developing 10 interactive Web3 practice projects.</p>
<p>These will walk you through all the Web3 concepts you need to know to build these 5 integrated projects we're releasing today. </p>
<p>Why are we releasing the hard part (the 5 integrated projects) first? For the die-hard Web3 enthusiasts who don't mind using watching <a target="_blank" href="https://www.freecodecamp.org/news/learn-blockchain-solidity-full-stack-javascript-development/">Patrick's course</a>, reading official documentation, and referencing the many other free Web3 tutorials out there.</p>
<p>Soon it will be a smoother ride for anyone to learn these tools and concepts. But we wanted to first get something out there for the hardcore crowd.</p>
<h2 id="heading-available-interactive-projects">Available interactive projects</h2>
<p>As of January 2023, the first group of interactive practice projects is now fully available. They will teach you the concepts you need to know to complete the first integrated project. The new courses are:</p>
<ol>
<li>Learn Digital Ledgers by Building a Blockchain</li>
<li>Learn Proof of Work Consensus by Building a Block Mining Algorithm</li>
<li>Learn Digital Signatures by Building a Wallet</li>
</ol>
<h2 id="heading-the-web3-curriculum-is-in-open-beta-we-welcome-your-feedback-and-bug-reports">The Web3 Curriculum is in open beta. We welcome your feedback and bug reports.</h2>
<p>Note that these are in open beta – meaning that we will continue to refine them with your feedback.</p>
<p>You can help by joining our new <a target="_blank" href="https://discord.gg/9KngwWzvd4">Web3 Curriculum Discord server</a>, introducing yourself, and helping other people who get stuck trying to build these 5 integrated projects.</p>
<p>You can also sign up for updates These will make it a lot easier to build these 5 integrated projects So in a way, you actually doing the hardest, most ambiguos  part <a class="post-section-overview" href="#heading-sign-up-for-updates">Sign up for updates below</a> for when new courses are released.</p>
<h2 id="heading-how-will-it-work">How will it work?</h2>
<p>The courses will run in a docker container using VS Code and the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=freeCodeCamp.freecodecamp-courses">freeCodeCamp Courses extension.</a></p>
<h3 id="heading-heres-a-sample">Here's a sample</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/EAidlZ6FZwE" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-how-to-run-the-courses">How to Run the Courses</h2>
<p>Follow the steps below to run the courses</p>
<h3 id="heading-developer-environment-prerequisites">Developer Environment Prerequisites</h3>
<p>Before you get started, make sure you have these installed on your computer:</p>
<ol>
<li><a target="_blank" href="https://docs.docker.com/engine/">Docker Engine</a></li>
<li><a target="_blank" href="https://code.visualstudio.com/download">VS Code</a> and the <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers">Dev Containers</a> extension</li>
<li>Git</li>
</ol>
<h3 id="heading-how-to-run-the-curriculum-in-docker">How to Run the Curriculum in Docker</h3>
<p>Follow these instructions to clone the repo and run the courses:</p>
<ol>
<li>Open a terminal and clone the <a target="_blank" href="https://github.com/freeCodeCamp/web3-curriculum">web3-curriculum</a> repo with:<pre><code class="lang-console">git clone https://github.com/freeCodeCamp/web3-curriculum.git
</code></pre>
</li>
<li><p>Navigate to the <code>web3-curriculum</code> directory, and open it in a VSCode workspace with:</p>
<pre><code class="lang-console">code .
</code></pre>
</li>
<li><p>Press <code>Ctrl / Cmd + Shift + P</code> to open the command palette, and run <code>Dev Containers: Rebuild Container and Reopen in Container</code>. VS Code will build the container to run the projects in, it will take a few minutes the first time.</p>
</li>
<li>Once it's finished, press <code>Ctrl / Cmd + Shift + P</code> again and run <code>freeCodeCamp: Run Course</code> to start the courses. This will also take a moment.</li>
<li>The simple browser will open when it's done. If it's a blank white page, use the refresh button to update it and see the courses home page.</li>
<li>Click on one of the available projects to start a project.</li>
<li>Follow the instructions to complete the project.</li>
<li>Have fun!</li>
</ol>
<p>If you want to switch projects, click the freeCodeCamp logo at the top to get back to the home page.</p>
<h2 id="sign-up">Sign up for updates</h2>

<p>Fill out <a target="_blank" href="https://docs.google.com/forms/d/e/1FAIpQLSdaKRd34e36eGVA7ne1g1x3kLPjTbLF0YoNqLWH6L7P2AmpxA/viewform?usp=sf_link">this google form</a> to receive updates when new courses are released.</p>
<h2 id="heading-other-courses">Other Courses</h2>
<p>We are also creating courses around the Solana and NEAR protocols.</p>
<p>View the <a target="_blank" href="https://www.freecodecamp.org/news/solana-curriculum/">Solana announcement article.</a>
View the <a target="_blank" href="https://www.freecodecamp.org/news/near-curriculum/">NEAR announcement article.</a></p>
<p>Or, check out the <a target="_blank" href="https://web3.freecodecamp.org/">web3.freecodecamp.org</a> domain where we showcase all the courses.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Truffle and Ganache – How to Create and Deploy a Smart Contract ]]>
                </title>
                <description>
                    <![CDATA[ By Jagruti Tiwari Learning a new technology often means learning a new framework, programming language, IDE, or deployment method. And the blockchain is no different.  In this tutorial, I am going to show you how to get started with Truffle, a Node.j... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/getting-started-with-truffle/</link>
                <guid isPermaLink="false">66d45f333a8352b6c5a2aa5f</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Smart Contracts ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 20 Jul 2022 16:08:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/ff-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jagruti Tiwari</p>
<p>Learning a new technology often means learning a new framework, programming language, IDE, or deployment method. And the blockchain is no different. </p>
<p>In this tutorial, I am going to show you how to get started with <a target="_blank" href="https://trufflesuite.com/docs/vscode-ext/installation-guide/">Truffle</a>, a Node.js blockchain framework, in Visual Studio Code.</p>
<h1 id="heading-how-to-install-truffle">How to Install Truffle</h1>
<p>To install Truffle you need to have <a target="_blank" href="https://nodejs.org/en/download/">Node and NPM</a> along with <a target="_blank" href="https://www.python.org/downloads/">Python</a> setup on your machine. </p>
<p>If you do not have them already, you can install them from their official websites (<a target="_blank" href="https://nodejs.org/en/">Node</a> and <a target="_blank" href="https://www.python.org/">Python</a>). Once you're done with that, you are all set to install Truffle.</p>
<p>We will use npm to install Truffle. Enter the following command in your command prompt:</p>
<p><code>npm install -g truffle</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-190328.png" alt="Screenshot-2022-07-16-190328" width="600" height="400" loading="lazy"></p>
<p>While the installation runs, if you come across the following error, I have got you covered:</p>
<p><code>gyp ERR! stack Error: Could not find any Visual Studio installation to use</code></p>
<p>Google shows a bunch of solutions for the above error. What actually worked for me was installing <a target="_blank" href="https://visualstudio.microsoft.com/downloads/">Visual Studio</a> along with 'Desktop Development with C++'.</p>
<p>After you download Visual Studio and run the installer you will see the following screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-190639.png" alt="Screenshot-2022-07-16-190639" width="600" height="400" loading="lazy"></p>
<p>Under the 'Desktop and mobile' section, check 'Desktop Developement with C++' and continue with the installation process.</p>
<p>Once this is done you can run the Truffle installation command again.</p>
<p>To verify if Truffle is installed successfully, run:</p>
<p><code>truffle version</code> </p>
<p>in your command prompt. You should see an output like the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-17-201823.png" alt="Screenshot-2022-07-17-201823" width="600" height="400" loading="lazy"></p>
<p>Congratulations! You have installed Truffle.</p>
<h1 id="heading-how-to-use-truffle-in-visual-studio-code">How to Use Truffle in Visual Studio Code</h1>
<p>Visual Studio Code comes with it's own extension for Truffle. We will install it to make our work easier. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-191633.png" alt="Screenshot-2022-07-16-191633" width="600" height="400" loading="lazy"></p>
<p>In the marketplace search bar, type "Truffle for VS Code" and click on install (similar to the image below).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-191836.png" alt="Screenshot-2022-07-16-191836" width="600" height="400" loading="lazy"></p>
<p>VS Code requires you to have other extensions for it to work, so just check the ones you don't have installed and continue the setup:
<img src="https://www.freecodecamp.org/news/content/images/2022/07/Untitled.png" alt="Untitled" width="600" height="400" loading="lazy"></p>
<p>If you do not see the Truffle logo in the left bar you might have to restart VS Code.</p>
<h1 id="heading-how-to-set-up-ganache-in-vs-code">How to Set Up Ganache in VS Code</h1>
<p>Ganache comes with the Truffle suite to deploy DApps. </p>
<p>Click on the 'Networks' &gt; 'Create a new network' in Truffle explorer.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-195911.png" alt="Screenshot-2022-07-16-195911" width="600" height="400" loading="lazy"></p>
<p>From the dropdown box select 'Ganache service'. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-195943.png" alt="Screenshot-2022-07-16-195943" width="600" height="400" loading="lazy"></p>
<p>Select type 'local' or 'fork'. Since this a local setup I will select 'local'.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-200019.png" alt="Screenshot-2022-07-16-200019" width="600" height="400" loading="lazy"></p>
<p>Next, you will be asked to enter your 'local project's name'. Enter any name of your choice and hit enter. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-200046.png" alt="Screenshot-2022-07-16-200046" width="600" height="400" loading="lazy"></p>
<p>Your network setup is complete. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-200242.png" alt="Screenshot-2022-07-16-200242" width="600" height="400" loading="lazy"></p>
<p>To start the network, right click on the network name and click on 'Start Ganache'.</p>
<p>When you start the Ganache service, you will see a command line output as follows:
<img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-200504.png" alt="Screenshot-2022-07-16-200504" width="600" height="400" loading="lazy"></p>
<p>The output displays a set of things to speed up. We do not need to worry about them just yet. </p>
<h1 id="heading-how-to-start-a-tuffle-project">How to Start a Tuffle Project</h1>
<p>To start a project in Truffle, go into a directory and type the init command.</p>
<p><code>truffle init</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-193451.png" alt="Screenshot-2022-07-16-193451" width="600" height="400" loading="lazy"></p>
<p>This will create a new Truffle project.</p>
<h1 id="heading-how-to-create-a-contract-in-truffle">How to Create a Contract in Truffle</h1>
<p>The following commands creates a contract in Truffle:</p>
<p><code>truffle create contract &lt;contract name&gt;</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-16-202855.png" alt="Screenshot-2022-07-16-202855" width="600" height="400" loading="lazy"></p>
<p>Here we created a contract named 'SimpleStorage'.</p>
<h1 id="heading-how-to-run-tests-in-truffle">How to Run Tests in Truffle</h1>
<p>To run test in Truffle, just enter this command:</p>
<p><code>truffle test</code> </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-17-171254.png" alt="Screenshot-2022-07-17-171254" width="600" height="400" loading="lazy"></p>
<p>All the tests will be run one by one.</p>
<h1 id="heading-how-to-deploy-in-truffle">How to Deploy in Truffle</h1>
<p>We will use Ganache to deploy in Truffle. </p>
<p><code>truffle develop</code> </p>
<p>You use the above command to start the deployment process.</p>
<p>Ganache has some accounts and private key ready for this purpose.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-17-171755.png" alt="Screenshot-2022-07-17-171755" width="600" height="400" loading="lazy"></p>
<p>In the above image at the bottom you will see <code>truffle (develop)&gt;</code> console.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-17-172106.png" alt="Screenshot-2022-07-17-172106" width="600" height="400" loading="lazy"></p>
<p>Type <code>migrate --reset</code> in the console.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Screenshot-2022-07-17-172204.png" alt="Screenshot-2022-07-17-172204" width="600" height="400" loading="lazy"></p>
<p>You will see that the initial migrations are made and the deployment process starts. In the end you will get a summary (the cost and number of deployments) of the deployment.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>We progress more quickly when we can learn from each other's mistake. I have just started learning Blockchain, and it took me a while to get the setup running. So here I am sharing my findings. Happy learning!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Blockchain, Solidity, and Full Stack JavaScript Development ]]>
                </title>
                <description>
                    <![CDATA[ There are thousands of open jobs related to blockchain development companies like IBM, VMware, and Deloitte. We just published a 30-hour course on the freeCodeCamp.org YouTube channel that will help you learn skills related to blockchain, Solidity, a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-blockchain-solidity-full-stack-javascript-development/</link>
                <guid isPermaLink="false">66b20406712508eb16067874</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 26 May 2022 19:00:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/blockchain1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>There are thousands of open jobs related to blockchain development companies like IBM, VMware, and Deloitte.</p>
<p>We just published a 30-hour course on the freeCodeCamp.org YouTube channel that will help you learn skills related to blockchain, Solidity, and Web3 development.</p>
<p>If you are interested in learning about blockchain development, this is the course for you. You will learn how to implement the concepts and technologies using JavaScript.</p>
<p>Patrick Collins developed this course. He is a veteran software engineer and finance industry developer. He also previously created one of the most popular blockchain courses on the Internet.</p>
<p>This course will give you a full introduction into all of the core concepts related to blockchain, smart contracts, Solidity, full-stack Web3 dapps, decentralized finance (DeFi), Chainlink, and more.</p>
<p>This is one of the most cutting-edge and in-depth Web3 / smart contract tutorials out there.</p>
<p>Here are the sections in this course:</p>
<ul>
<li>Blockchain Basics</li>
<li>Remix and Simple Storage</li>
<li>Remix Storage Factory</li>
<li>Ethers.js Simple Storage</li>
<li>Hardhat Simple Storage</li>
<li>HTML / Javascript (Full Stack / Front End)</li>
<li>Hardhat Smart Contract Lottery</li>
<li>NextJS Smart Contract Lottery (Full Stack / Front End)</li>
<li>Hardhat Starter Kit</li>
<li>Hardhat ERC20s</li>
<li>Hardhat DeFi &amp; Aave</li>
<li>Hardhat NFTs </li>
<li>NextJS NFT Marketplace (Full Stack / Front End)</li>
<li>Hardhat Upgrades</li>
<li>Hardhat DAOs</li>
<li>Security &amp; Auditing </li>
</ul>
<p>Watch the full course below or <a target="_blank" href="https://youtu.be/gyMwXuJrbJQ">on the freeCodeCamp.org YouTube channel</a> (32-watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/gyMwXuJrbJQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
