<?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[ Web3 - 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[ Web3 - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 15:48:49 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/web3/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build and Deploy a Smart Contract With Rust and the Gear Protocol ]]>
                </title>
                <description>
                    <![CDATA[ Smart contracts are like digital agreements that run on blockchain technology, making transactions automatic and secure. While many people use Ethereum and Solidity to create these contracts, there are other options that can be just as powerful.  One... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-and-deploy-smart-contract-rust-gear-protocol/</link>
                <guid isPermaLink="false">66bb89c32108ff2ab9af1673</guid>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rust ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rocky Essel ]]>
                </dc:creator>
                <pubDate>Tue, 04 Jun 2024 10:36:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/06/How-to-Build-and-Deploy-a-Smart-Contract-With-Rust-and-the-Gear-Protocol-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Smart contracts are like digital agreements that run on blockchain technology, making transactions automatic and secure. While many people use Ethereum and Solidity to create these contracts, there are other options that can be just as powerful. </p>
<p>One great combination is using Rust with the Gear Protocol. In this guide, I'll show you how to build and deploy a smart contract using Rust and the Gear Protocol. Whether you're new to this or have some experience, this article will help you get started with clear and easy-to-follow steps.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ol>
<li>Have basic Rust knowledge.</li>
<li>Having a basic understanding of decentralization. </li>
</ol>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><a class="post-section-overview" href="#heading-introduction-to-vara-network-amp-gear-protocol">Introduction to Vara Network &amp; Gear Protocol.</a></li>
<li><a class="post-section-overview" href="#heading-why-use-the-web2-analogy">Why Use the Web2 Analogy</a>? </li>
<li><a class="post-section-overview" href="#heading-message-based-communication">Message-based Communication</a>.</li>
<li><a class="post-section-overview" href="#heading-illustration">Illustration</a></li>
<li><a class="post-section-overview" href="#heading-vara-networks-role">Vara Network's Role</a>.</li>
<li><a class="post-section-overview" href="#heading-first-project-reading-a-joke">First Project – Reading a Joke</a></li>
<li><a class="post-section-overview" href="#heading-next-project-input-msg">Next Project – <code>input-msg</code></a></li>
<li><a class="post-section-overview" href="#heading-metadata-amp-state">Metadata &amp; State</a></li>
<li><a class="post-section-overview" href="#heading-third-project-building-messages">Third Project – Building Messages</a></li>
<li><a class="post-section-overview" href="#heading-final-project">Final Project – Battle Showdown</a></li>
<li><a class="post-section-overview" href="#conclusion-1">Conclusion.</a></li>
</ol>
<h2 id="heading-introduction-to-vara-network-amp-gear-protocol">Introduction to Vara Network &amp; Gear Protocol.</h2>
<h3 id="heading-vara-network">Vara Network</h3>
<p>Think of Vara as the sturdy foundation of blockchain technology. It's a layer-1 blockchain, meaning that it's at the core of transactions, ensuring that they are secure and decentralized. Vara uses Nominated Proof-of-Stake (NPoS) for agreement, making it reliable and efficient.</p>
<p>Furthermore, Vara Network distinguishes itself through its novel Actor Model, an architecture characterized by isolation and asynchronous messaging. This paradigm shift in smart contract execution imbues Vara Network with unparalleled security and scalability, setting it apart from conventional blockchain platforms.</p>
<h3 id="heading-gear-protocol">Gear Protocol</h3>
<p>Gear Protocol is like a toolbox for developers. It's a smart contract engine that makes building decentralized apps (dApps) faster, safer, and cheaper. By using substrate technology and WebAssembly (Wasm), Gear makes it easy for developers to create dApps that run smoothly and securely.</p>
<p>Gear's utilization of the Wasm virtual machine serves as a cornerstone of its efficiency. By harnessing the power of Wasm, developers can transcend language barriers, seamlessly integrating existing codebases and accelerating the development lifecycle. This fusion of familiarity and performance paves the way for a new era of dApp creation, where speed, security, and scalability converge harmoniously.</p>
<p>In simpler terms, Vara Network and Gear Protocol work together to make blockchain technology more user-friendly and secure for building and using decentralized apps.</p>
<h2 id="heading-why-use-the-web2-analogy">Why Use the Web2 Analogy?</h2>
<p>Understanding message-based communication, particularly within the context of Gear Protocol, can be quite challenging. To gain a clearer understanding, I delved into the documentation and conducted additional research. Eventually, I stumbled upon an analogy that made it all click: the analogy of web HTTP requests, specifically the POST method.</p>
<p>Let's dissect this analogy step by step. Consider the familiar scenario of a user visiting a website like google.com and interacting with the search bar. When the user enters a search query and hits enter, what's happening behind the scenes is akin to a POST HTTP request being sent.</p>
<h3 id="heading-heres-how-it-unfolds">Here's how it unfolds:</h3>
<ol>
<li><strong>User Interaction:</strong> The user initiates the action by typing a search query into the search bar and hitting enter. This action triggers a request for information.</li>
<li><strong>Client Acknowledgment:</strong> Google's website, acting as the client-side user interface (UI), acknowledges the user's input and prepares to send a request to the server for processing.</li>
<li><strong>Request Sent:</strong> Just like when you hit enter after typing a query, Google's website sends a POST request to its server, conveying the user's search query.</li>
<li><strong>Server Processing:</strong> Upon receiving the POST request, Google's server processes the query, searching its vast index for relevant information.</li>
<li><strong>Response Generation:</strong> After processing the query, Google's server generates a response containing the search results.</li>
<li><strong>Response Sent:</strong> Finally, Google's server sends the response back to the client (the user's web browser), completing the communication cycle.</li>
</ol>
<p>In this analogy, the user represents the initiator of the communication, the client (UI) serves as the intermediary between the user and the server, and the server acts as the responder, processing requests and generating responses.</p>
<p>By drawing parallels between message-based communication in Gear Protocol and the familiar concept of web HTTP requests, we can better grasp the dynamics at play. Just as understanding how web requests facilitate communication between users and servers is essential for navigating the internet, comprehending message-based communication in Gear Protocol is crucial for building and interacting with decentralized applications effectively.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-114.png" alt="Image" width="600" height="400" loading="lazy">
<em>how the POST method works</em></p>
<h2 id="heading-message-based-communication">Message-based Communication</h2>
<p>Similarly, the Gear Protocol operates based on user or program interactions.<br><strong>Note</strong>: Programs on Gear can also interact with each other.<br>So here is a detailed explanation to the whole communication flow in Gear.</p>
<h3 id="heading-user-interaction-and-gear-jsapi">User Interaction and @gear-js/api</h3>
<p>When a user (actor) interacts with the dApp's UI elements (like buttons or forms), <code>_@gear-js/api_</code> (which is integrated into the UI) captures these interactions. Based on the interactions, it extracts information and potentially pre-defined message formats, and then contracts a message object containing the user's intent or request.</p>
<h3 id="heading-how-to-send-messages">How to Send Messages</h3>
<p>The constructed message object encapsulates the user's input and becomes the data <code>@gear-js/api</code> transmits across the Vara Network to the Gear crate within the program.</p>
<h3 id="heading-how-the-program-receives-and-processes-messages">How the Program Receives and Processes Messages</h3>
<p>Gear (<code>crate</code>) delivers the message object to the appropriate program deployed on the Vara Network based on the location the user initiated the action. The Gear crate within the program utilizes functions like <code>msg::load()</code> and access the delivered message object, which the program extracts information (such as <code>payload</code>, <code>source</code>, <code>messsageId</code>) from, and process it according to how it's designed by the developer.</p>
<h3 id="heading-how-to-generate-a-reply">How to Generate a Reply</h3>
<p>Based on the processed input, the program creates a new message object containing a reply (<code>response</code> in <code>web2</code>) to the user's action or interaction (called <code>reply</code>) to or for the user. </p>
<p>Note, the program typically doesn't send the original message object back, it generates a new one based message received, which a reply is sent back to be received by <code>@gear-js/api</code> using the <code>gstd</code> crate from the program utilizing functions like the <code>msg::reply</code> or <code>msg::reply_bytes</code>.</p>
<h3 id="heading-ui-update">UI Update</h3>
<p><code>@gear-js/api</code>, within the dApp, receives the reply message object delivered by the <code>gstd</code> crate from the program across the Vara Network and extracts the response data from the reply object, and finally updates the UI reflecting the program's response to the user's interaction.  </p>
<p>And that's pretty much the communication between the Users, Client(dApp), Gear Protocol(<code>gstd</code>), and finally Vara Network.</p>
<h2 id="heading-illustration">Illustration</h2>
<p>Let's discuss more about the diagrams below, and how they each interact with each other.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/image-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>UI Update</em></p>
<p>This illustration above is just a bird's eye view of how communication flows from the user to the program<strong>.</strong> I'll provide a complete illustration for more clarity. But before that, let's break the overview illustration into three stages.</p>
<h3 id="heading-initial-interaction-stage">Initial Interaction Stage</h3>
<p>As said earlier, this is when the user interacts with the program, both <code>@gear-js/api</code> and <code>gstd</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-124.png" alt="Image" width="600" height="400" loading="lazy">
<em>Initial Interaction Stage</em></p>
<h3 id="heading-businessprogram-logic">Business/Program Logic</h3>
<p>This section depicts the communication between the program and Gear within Vara Network. The <code>gstd</code> is used by the program to access the transmitted message (<code>msg::load()</code>) from the initial stage to perform business logic.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-126.png" alt="Image" width="600" height="400" loading="lazy">
<em>Business/Program Logic</em></p>
<h3 id="heading-reply-response">Reply (Response)</h3>
<p>This final stage shows how user feedback is delivered to the user or program. <code>@gear-js/api</code> translates it if necessary, and then updates the dApp's UI with the results. This allows the user to see the outcome of their action within the dApp.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-127.png" alt="Image" width="600" height="400" loading="lazy">
<em>Reply(Response)</em></p>
<p>That's great, right? This should help you understand how messages are passed from the client to the program. But what does Vara Network role mean here? Earlier I said that, the message object get transmitted across the Vara Network, but I didn't say how. Let's explain that.</p>
<h2 id="heading-vara-networks-role">Vara Network's Role</h2>
<p>In Vara, all participants, including user interfaces (through <code>@gear-js/api</code>) and smart contracts (programs &amp; <code>gstd</code>), are considered as actors. Another point to know is that, actors don't directly call functions within other actors (as in, programs interacting with other programs or even users). </p>
<p>Instead, they send messages containing data or instructions. So in our explanation of the message-based communication, Vara serves as the underlying decentralized network infrastructure for communication of our system (dApps). It provides a secure and reliable platform for message transmission across distributed network of nodes. And since Vara utilize a consensus mechanism NPoS (Nominated Proof-of-Stake), it ensures network security and transaction validation.</p>
<h2 id="heading-getting-our-hands-dirty">Getting Our Hands Dirty</h2>
<p>In order to build upon the above information I provided, you and I need to get our hands dirty by building and deploying programs with additional explanation for a clearer understanding. </p>
<p>Let's get started.</p>
<h3 id="heading-first-project-reading-a-joke">First Project - Reading a Joke</h3>
<p>In this project, you're going to interact with and deploy your smart contract on Vara Network, and receive a reply message back.</p>
<p>This is just a simple project, and nothing too complex. I chose this example project because it aligns with the analogy I gave earlier.</p>
<p>Currently, this project should be fine when running it on your Windows system. In case you get an error, scroll to the part of this article with a guide for setting up a Windows Subsystem for Linux (WSL), since it would allow you to run a Linux environment, including command-line tools and applications, directly on Windows, without the overhead of a traditional virtual machine or dual boot setup.</p>
<p>To get started, create a directory named <code>freecodecamp-gear-protocol</code>. Since you'll be building about fours projects, and I think it is important on how you can setup your projects for Gear Protocol.</p>
<p>So in your <code>freecodecamp-gear-protocol</code> directory, create a <code>Cargo.toml</code> file with the following code:</p>
<pre><code class="lang-toml"><span class="hljs-section">[workspace]</span>
<span class="hljs-attr">resolver</span> = <span class="hljs-string">"2"</span>
<span class="hljs-attr">members</span> = []


<span class="hljs-section">[workspace.package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"freecodecamp-gear-protocol"</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">"0.1.0"</span>
<span class="hljs-attr">edition</span> = <span class="hljs-string">"2021"</span>
<span class="hljs-attr">authors</span> = [<span class="hljs-string">"Rocky Essel"</span>]
<span class="hljs-attr">license</span> = <span class="hljs-string">"MIT"</span>
<span class="hljs-attr">publish</span> = <span class="hljs-literal">false</span>

<span class="hljs-section">[workspace.dependencies]</span>
<span class="hljs-comment"># Internal Crates</span>
<span class="hljs-comment"># External Crates</span>
</code></pre>
<p>For someone new to Rust or used to creating single projects, I'll guide you through understanding and setting up a workspace in Rust, making it easy to grasp.</p>
<h3 id="heading-understanding-your-workspace">Understanding Your Workspace</h3>
<p>A workspace in Rust is a set of packages (crates) that are managed together. Let's break down the key sections: <code>[workspace]</code>, <code>members</code>, <code>[workspace.package]</code>, and <code>[workspace.dependencies]</code>. So think of this like a cabin for your shoes, where each pair of shoes is a crate (package) that you want to keep organized.</p>
<h4 id="heading-workspace-section"><code>[workspace]</code> Section</h4>
<p>The <code>[workspace]</code> section defines the overall workspace. It typically contains multiple members.</p>
<p><strong><code>resolver = "2"</code></strong>: Specifies the version of Cargo's feature resolver to use, improving how dependencies are managed across the workspace.</p>
<p><strong><code>members</code></strong>: Lists the crates that are part of the workspace. When you add a project with <code>cargo new --lib sneakers</code> or <code>boots</code>, the <code>members</code> section of the <code>Cargo.toml</code> is populated with the name of the project you created.</p>
<blockquote>
<p>If not added automatically, you can add them yourself.</p>
</blockquote>
<p>  For example:</p>
<pre><code class="lang-toml"><span class="hljs-attr">members</span> = [<span class="hljs-string">"sneakers"</span>, <span class="hljs-string">"boots"</span>]
</code></pre>
<h4 id="heading-workspacepackage-section"><code>[workspace.package]</code> Section</h4>
<p>This section provides metadata for the entire workspace as if it were a single package.</p>
<ul>
<li><strong><code>name</code></strong>: The name of the workspace package.</li>
<li><strong><code>version</code></strong>: The version of the workspace package.</li>
<li><strong><code>edition</code></strong>: The Rust edition being used (e.g., "2021").</li>
<li><strong><code>authors</code></strong>: List of authors.</li>
<li><strong><code>license</code></strong>: The license for the workspace package.</li>
<li><strong><code>publish</code></strong>: Indicates whether the workspace package should be published to crates.io.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-toml"><span class="hljs-section">[workspace.package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"my-shoe-collection"</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">"0.1.0"</span>
<span class="hljs-attr">edition</span> = <span class="hljs-string">"2021"</span>
<span class="hljs-attr">authors</span> = [<span class="hljs-string">"Your Name"</span>]
<span class="hljs-attr">license</span> = <span class="hljs-string">"MIT"</span>
<span class="hljs-attr">publish</span> = <span class="hljs-literal">false</span>
</code></pre>
<h4 id="heading-workspacedependencies-section"><code>[workspace.dependencies]</code> Section</h4>
<p>Lists dependencies that apply to the entire workspace. Meaning that every crate whether external or internal added to the <code>[workspace.dependencies]</code> is accessible to every project you create under project workspace. So below is how both external and internal crate are made accessible to other project.</p>
<p><strong>Note</strong>: For internal crate, you need to add them yourself.</p>
<p><strong><code>Internal Crates</code></strong>: Add internal crates like this:</p>
<pre><code class="lang-toml"><span class="hljs-attr">sneakers</span> = { path = <span class="hljs-string">"sneakers"</span> }
<span class="hljs-attr">boots</span> = { path = <span class="hljs-string">"boots"</span> }
</code></pre>
<p><strong><code>External Crates</code></strong>: Add external crates like this:</p>
<pre><code class="lang-toml"><span class="hljs-attr">polish</span> = <span class="hljs-string">"1.0"</span>
</code></pre>
<h3 id="heading-example-cargotoml">Example <code>Cargo.toml</code></h3>
<p>Here's an example combining these sections:</p>
<pre><code class="lang-toml"><span class="hljs-section">[workspace]</span>
<span class="hljs-attr">resolver</span> = <span class="hljs-string">"2"</span>
<span class="hljs-attr">members</span> = [<span class="hljs-string">"sneakers"</span>, <span class="hljs-string">"boots"</span>]

<span class="hljs-section">[workspace.package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"my-shoe-collection"</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">"0.1.0"</span>
<span class="hljs-attr">edition</span> = <span class="hljs-string">"2021"</span>
<span class="hljs-attr">authors</span> = [<span class="hljs-string">"Your Name"</span>]
<span class="hljs-attr">license</span> = <span class="hljs-string">"MIT"</span>
<span class="hljs-attr">publish</span> = <span class="hljs-literal">false</span>

<span class="hljs-section">[workspace.dependencies]</span>
<span class="hljs-comment"># Internal crate</span>
<span class="hljs-attr">sneakers</span> = { path = <span class="hljs-string">"sneakers"</span> } 
<span class="hljs-attr">boots</span> = { path = <span class="hljs-string">"boots"</span> } 

<span class="hljs-comment"># External crate</span>
<span class="hljs-attr">polish</span> = <span class="hljs-string">"1.0"</span>
</code></pre>
<p>So, here's how you set up a workspace for your project to manage multiple crates (sub-projects) and share dependencies and configuration settings across them. I spent quite some time understanding this, so I thought I'd share it with you all to make it easier.</p>
<p>To build your first smart contract, run the command below in your parent directory (<code>freecodecamp-gear-protocol</code>) on your terminal.</p>
<pre><code class="lang-bash">cargo new --lib receive-joke
</code></pre>
<pre><code class="lang-bash">.freecodecamp-gear-protocol
├── Cargo.toml
└── receive-joke
    ├── Cargo.toml
    └── src
        └── lib.rs

2 directories, 3 files
</code></pre>
<p>Head over to your <code>freecodecamp-gear-protocol/receive-joke/Cargo.toml</code>, and this is how you access crates, and configuration from the workspace directory(main) using <code>.workspace=true</code>, like below;</p>
<pre><code class="lang-toml"><span class="hljs-section">[package]</span>
<span class="hljs-attr">name</span> =<span class="hljs-string">"receive-joke"</span>
<span class="hljs-attr">version.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">edition.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">authors.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">license.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">publish.workspace</span> = <span class="hljs-literal">true</span>

<span class="hljs-comment"># See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html</span>

<span class="hljs-section">[dependencies]</span>
</code></pre>
<p>Next, create a <code>build</code> file in your <code>receive-joke</code> directory with path like<code>receive-joke/build.rs</code>, and paste the code below. Now, the <code>build.rs</code> helps you to build your project into <code>.wasm</code> file, that is used to deploy your smart contract.</p>
<p><strong>build.rs:</strong></p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    gear_wasm_builder::build();
}
</code></pre>
<p>Currently, you have't install the nesscessary crate to help create your smart contract. Therefore, add the following crate to your workspace dependency.</p>
<p><strong>Cargo.toml:</strong></p>
<pre><code class="lang-toml"><span class="hljs-section">[workspace]</span>
<span class="hljs-attr">resolver</span> = <span class="hljs-string">"2"</span>
<span class="hljs-attr">members</span> = [<span class="hljs-string">"receive-joke"</span>]


<span class="hljs-section">[workspace.package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"freecodecamp-gear-protocol"</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">"0.1.0"</span>
<span class="hljs-attr">edition</span> = <span class="hljs-string">"2021"</span>
<span class="hljs-attr">authors</span> = [<span class="hljs-string">"Rocky Essel"</span>]
<span class="hljs-attr">license</span> = <span class="hljs-string">"MIT"</span>
<span class="hljs-attr">publish</span> = <span class="hljs-literal">false</span>

<span class="hljs-section">[workspace.dependencies]</span>
<span class="hljs-comment"># Internal Crates</span>

<span class="hljs-comment"># External Crates</span>
<span class="hljs-attr">gstd</span> = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">gmeta</span> = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">gtest</span>  = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">gear-wasm-builder</span> = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">parity-scale-codec</span> = { version = <span class="hljs-string">"3.6.12"</span>, default-features = <span class="hljs-literal">false</span> }
<span class="hljs-attr">scale-info</span> = { version = <span class="hljs-string">"2.11.3"</span>, default-features = <span class="hljs-literal">false</span> }
</code></pre>
<p>For your first project, only <code>gstd</code> would be used, so like add that external crate to your <code>receive-joke</code>'s <code>Cargo.toml</code>. Like below:</p>
<pre><code class="lang-toml"><span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">gstd.workspace</span> = <span class="hljs-literal">true</span>


<span class="hljs-section">[build-dependencies]</span>
<span class="hljs-attr">gear-wasm-builder.workspace</span> = <span class="hljs-literal">true</span>
</code></pre>
<p>If you reached here without any errors, well done my friend. Next, is to clear any code in <code>freecodecamp-gear-protocol/receive-joke/src/lib.rs</code>. Let's move on to the next step.</p>
<p>In Gear Protocol, there are entry points. An entry point serves as a gateway or door to your code. Gear has a few entry points, namely:</p>
<pre><code class="lang-rust">state(),
handle(),
handle_reply(),
init(),
handle_signal(),
</code></pre>
<p>Each entry point plays a significant role. For example, <code>init()</code> is called when the smart contract(<code>.wasm</code>) is deployed, allowing you to set certain conditions or variables or even other functions  that need to be executed for smooth sailing of your smart contract or program.</p>
<p>However, it's optional, meaning that you can choose to include or exclude it depending on your project, but it still gets executed, and it is the first message you'll see once you deploy your smart contract.</p>
<p>The <code>handle()</code> method is crucial as it contains most of the business logic. It's mandatory to include your program. More light will be shared on the entry points as you move forward.</p>
<p>Now, paste the following code into your <code>receive-joke/src/lib.rs</code>:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gstd::msg;

<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">handle</span></span>() {
    <span class="hljs-comment">// Send a reply(in HTTP GET Request, you'd use "response").</span>
    msg::reply_bytes(
        <span class="hljs-string">"What did the dirt say to the rain? If you keep this up, my name will be mud!"</span>,
        <span class="hljs-number">0</span>,
    )
    .expect(<span class="hljs-string">"Unable to reply"</span>);
}
</code></pre>
<p>The code above defines a function <code>handle</code> that, when called, sends a message you've defined as a response using the <code>gstd::msg</code> functionality. This <code>gstd</code> is a crate provided by Gear Protocol<strong>,</strong> to send and receive messages, and this is crucial for programs running on Vara Network to communicate with each other and external systems. And the <code>reply_bytes</code> send a new message as a reply to the message that is currently being processed.</p>
<p>Time to deploy and send your first message and recieve your joke reply. In your terminal, run the following command to build your program into <strong><code>.wasm</code></strong>.</p>
<p>Usually, I use <code>cargo check</code> for check for errors first, before using the <code>build</code> command below, either way is fine.</p>
<pre><code class="lang-bash">cargo build --release
</code></pre>
<p>After the build is completed, follow the structure below to locate your <strong><code>.wasm</code></strong> file in the path below:</p>
<pre><code class="lang-bash">.freecodecamp-gear-protocol
├── Cargo.lock
├── Cargo.toml
├── receive-joke
│   └── ...
└── target
    ├── ...
    └── wasm32-unknown-unknown
        ├── ...
        └── release
            ├── receive_joke.opt.wasm &lt;--- Optimized <span class="hljs-keyword">for</span> deployment.
            └── receive_joke.wasm
</code></pre>
<h3 id="heading-how-to-deploy-your-smart-contract">How to Deploy Your Smart Contract</h3>
<p>Just like in other blockchain tools, that help you deploy your smart contract from the terminal, IDEA is where you deploy your smart contract and interact with it. We'll be exploring the interface in a bit. So finally, head over to <a target="_blank" href="https://idea.gear-tech.io/">IDEA</a> so start familiarizing yourself with your deployment environment. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-30-135927.png" alt="Image" width="600" height="400" loading="lazy">
<em>Smart Contract Deplyment Web App- IDEA</em></p>
<ol>
<li>Step one, click on <strong>Upload program</strong>, then select or drag your <strong><code>.opt.wasm</code></strong> inside the modal. This takes you to the upload page, where you can change names, enter values for the payload, or change the payload type. For now, let's leave everything as it is, and click on the <strong>Calculate,</strong> which will enter a <code>0.00015</code> gas fee value for uploading your program.</li>
</ol>
<p><strong>Note</strong>: You can either set the gas limit yourself, or click on <strong>Calculate</strong> to allow the program to generate one for you.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-30-144729.png" alt="Image" width="600" height="400" loading="lazy">
<em>Upload Page Details</em></p>
<p>At this point, click on the <strong>Upload Program</strong>, and click on the <strong>Submit</strong> button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-30-144825.png" alt="Image" width="600" height="400" loading="lazy">
<em>Transaction Details- PopUp</em></p>
<p>When you submit, you'll be prompted you sign into a your wallet, and approve.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-128.png" alt="Image" width="600" height="400" loading="lazy">
<em>Wallet - SubWallet</em></p>
<p>After the approval, a toast message should be displayed at the right-hand corner your computer/laptop screen for you to see the status of your program, whether it failed or succeeded.</p>
<p>Assuming it's a success, click on the <strong>Programs</strong> on the sidebar, then BOOM!, there's your program. Click on it, and let's explore.</p>
<p>Upon deploying, the first thing you see is the program ID, but after a few seconds, the name of your program would be shown.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-30-150230.png" alt="Image" width="600" height="400" loading="lazy">
<em>Smart Contract Block - Page</em></p>
<p>Earlier, I said that when you deploy a program, the <code>init()</code> function is executed regardless of whether you defined it in your project or not, and that's what you see in the <strong>Messages</strong> section. Below is a simple illustration for you to familiarize and understand the information about your program.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-129.png" alt="Image" width="600" height="400" loading="lazy">
<em>Page Illustration</em></p>
<p>Now, it's time to send a message to your program and receive a reply back, which is our joke. Remember, you're not inputting any values, you're just performing a simple action to receive a reply from the program. So click on <strong>Calculate</strong> and press the <strong>Send Message</strong> (that's the action or interaction) button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-30-152529.png" alt="Image" width="600" height="400" loading="lazy">
<em>Performing an action - Initial Stage</em></p>
<p>After the message has been sent, a <code>success</code> toast will popup. Then head back to your program by clicking on the <strong>Cancel</strong> button, and you'll see two additional messages. </p>
<p>Remember, the blue color with the arrow represent the message you sent, and the green represents the reply you've received. So click on the replied message to see the joke, which says: <code>What did the dirt say to the rain? If you keep this up, my name will be mud!</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-130.png" alt="Image" width="600" height="400" loading="lazy">
<em>Receiving Reply &amp; More Illustration</em></p>
<p>Now, you're finally done with this project. In the next project, you'll be sending data or information to your program, and having it return a reply with your entered value attached to it. <a target="_blank" href="https://idea.gear-tech.io/programs/0x79e6c86aa1ab2026ef3bbc0ccbe801ce085ca2614b36f9e5be04d2354ad56396">Here is the program deployed on the <strong>Vara Network</strong></a>.</p>
<h3 id="heading-important-information">Important Information</h3>
<p>Though I've provided some context to the picture above, I want to expand on it. Both the <code>Source</code> and <code>Destination</code> takes an address that can be either a user (actor) and a program (actor), or even a message object.</p>
<h2 id="heading-next-project-input-msg">Next Project – <code>input-msg</code></h2>
<p>Just like the illustration earlier, you're going to interact with your program by sending an input value to your smart contract deployed on <strong><code>[IDEA](https://idea.gear-tech.io/programs?node=wss%3A%2F%2Ftestnet.vara.network)</code></strong>. <a target="_blank" href="https://idea.gear-tech.io/programs?node=wss%3A%2F%2Ftestnet.vara.network"><strong>IDEA</strong> </a> is your deployment environment where you deploy your smart contract on the Vara Network.<br> The point here is for you to load input values from your user, and process it by concatenating a string to the user's input value: "We've received your query. {user's-input}".</p>
<p>This is the reply you'll send back to the user that sends a message (input value).</p>
<p>So in your <code>freecodecamp-gear-protocol</code> directory, run the command below to add another member to your <code>freecodecamp-gear-protocol/Cargo.toml</code>.</p>
<pre><code class="lang-bash">cargo new --lib input-msg
</code></pre>
<p>After adding another member or project in the <code>freecodecamp-gear-protocol</code>, your path should be <code>freecodecamp-gear-protocol/input-msg</code>.</p>
<p>Earlier, I made mention of how to access input values into the smart contract or program by using <code>gstd</code>, which has a function or method called <code>load()</code>. For the next step, clear your <code>freecodecamp-gear-protocol/input-msg/src/lib.rs</code>, and paste the following code and run <code>cargo check</code>.</p>
<pre><code class="lang-bash"><span class="hljs-comment">#![no_std]</span>

use gstd::{msg, prelude::*};

<span class="hljs-comment">#[no_mangle]</span>
extern <span class="hljs-string">"C"</span> fn <span class="hljs-function"><span class="hljs-title">handle</span></span>() {
    <span class="hljs-built_in">let</span> new_msg = msg::load().expect(<span class="hljs-string">"Unable to create string"</span>);
    <span class="hljs-built_in">let</span> reply_msg = format!(<span class="hljs-string">"We've received your query {}"</span>, new_msg);
    msg::reply_bytes(reply_msg, 0).expect(<span class="hljs-string">"Unable to reply."</span>);
}
</code></pre>
<p>The check fails, but why? Well, the <code>load()</code> function has a type of <code>unknown</code>. And since Rust is a strongly typed language, it has to always know the type before hand, which wasn't the case, so it failed to build the project.</p>
<p>This should tell you that the <code>load()</code> doesn't have a type, and it is up to you to set the right data type, and failure to do so would result in some frustrating errors like below.</p>
<h3 id="heading-debugging">Debugging</h3>
<p>Now if you were to use a single project and not a workspace, then debugging the error might have easy like below.</p>
<pre><code class="lang-bash">
  error[E0282]: <span class="hljs-built_in">type</span> annotations needed
   --&gt; C:\Users\user\Desktop\2024\web3\re-gear\input-msg\src\lib.rs:7:9
    |
  7 |     <span class="hljs-built_in">let</span> new_msg = msg::load().expect(<span class="hljs-string">"Unable to create string"</span>);
    |         ^^^^^^^
    |
  <span class="hljs-built_in">help</span>: consider giving `new_msg` an explicit <span class="hljs-built_in">type</span>
    |
  7 |     <span class="hljs-built_in">let</span> new_msg: /* Type */ = msg::load().expect(<span class="hljs-string">"Unable to create string"</span>);
    |                ++++++++++++
</code></pre>
<p>But since you and I are using a workspace, it makes debugging a little difficult. This is my error message i got, when dubgging this error.</p>
<pre><code class="lang-bash">  error[E0275]: overflow evaluating the requirement `gstd::parity_scale_codec::Compact&lt;_&gt;: gstd::Decode`
    |
    = <span class="hljs-built_in">help</span>: consider increasing the recursion <span class="hljs-built_in">limit</span> by adding a `<span class="hljs-comment">#![recursion_limit = "256"]` attribute to your crate (`input_msg`)</span>
    = note: required <span class="hljs-keyword">for</span> `gstd::parity_scale_codec::Compact&lt;_&gt;` to implement `gstd::Decode`
    = note: 125 redundant requirements hidden
    = note: required <span class="hljs-keyword">for</span> `gstd::parity_scale_codec::Compact&lt;&lt;_ as CompactAs&gt;::As&gt;` to implement `gstd::Decode`

  For more information about this error, try `rustc --explain E0275`.
  error: could not compile `input-msg` (lib) due to 1 previous error
  warning: build failed, waiting <span class="hljs-keyword">for</span> other <span class="hljs-built_in">jobs</span> to finish...
  error: cargo <span class="hljs-built_in">command</span> run failed: <span class="hljs-built_in">exit</span> status: 101
warning: build failed, waiting <span class="hljs-keyword">for</span> other <span class="hljs-built_in">jobs</span> to finish...
</code></pre>
<p>And  if you look closely, you can tell that the <code>input-msg</code> is what creating the error. In this case, run <code>rustc --explain E0275</code>, which output an suggestion like this</p>
<pre><code class="lang-bash">An evaluation of a trait requirement overflowed.

Erroneous code example:

trait Foo {}

struct Bar&lt;T&gt;(T);

impl&lt;T&gt; Foo <span class="hljs-keyword">for</span> T <span class="hljs-built_in">where</span> Bar&lt;T&gt;: Foo {}

This error occurs when there was a recursive trait requirement that overflowed before it could be
evaluated. This often means that there is an unbounded recursion <span class="hljs-keyword">in</span> resolving some <span class="hljs-built_in">type</span> bounds.

To determine <span class="hljs-keyword">if</span> a T is Foo, we need to check <span class="hljs-keyword">if</span> Bar&lt;T&gt; is Foo. However, to <span class="hljs-keyword">do</span> this check, we need to
determine that Bar&lt;Bar&lt;T&gt;&gt; is Foo. To determine this, we check <span class="hljs-keyword">if</span> Bar&lt;Bar&lt;Bar&lt;T&gt;&gt;&gt; is Foo, and so on. This
is clearly a recursive requirement that can<span class="hljs-string">'t be resolved directly.

Consider changing your trait bounds so that they'</span>re less self-referential.
</code></pre>
<p>Now, though, compared to the first error message, this message doesn't provide a direct solution, it does tells you that, there's a type error in your code. And the reason is that, the <code>load()</code> can load any data type, so you should always defined a type for it.</p>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gstd::{msg, prelude::*};

<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">handle</span></span>() {
    <span class="hljs-keyword">let</span> new_msg: <span class="hljs-built_in">String</span> = msg::load().expect(<span class="hljs-string">"Unable to create string"</span>);
    <span class="hljs-keyword">let</span> reply_msg = <span class="hljs-built_in">format!</span>(<span class="hljs-string">"We've received your query {}"</span>, new_msg);
    msg::reply_bytes(reply_msg, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Unable to reply."</span>);
}
</code></pre>
<p>In the above code, you've added a type <code>String</code> to the <code>new_msg</code> because that's the <code>type</code> you're expecting. Now run the build command, and deploy the file <strong><code>.opt.wasm</code></strong> to <code>IDEA</code>. </p>
<pre><code class="lang-bash">.freecodecamp-gear-protocol
├── receive-joke
├── Cargo.toml
├── input-msg
│   └── ...
└── target
    ├── ...
    └── wasm32-unknown-unknown
        ├── ...
        └── release
            ├── input_msg.opt.wasm &lt;--- Optimized <span class="hljs-keyword">for</span> deployment.         
            ├── input_msg.wasm
            ├── receive_joke.opt.wasm
            └── receive_joke.wasm
</code></pre>
<p>When you're done, go to your program and click on the <strong>Send Messages</strong>. Type any value into the <code>payload</code> field, and it should be a <code>type</code> of <code>String</code>. </p>
<p>Submit and approve and head back to your program, then select your <code>reply_message</code> box and you should see your <code>reply message</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot-2024-04-06-080437.png" alt="Image" width="600" height="400" loading="lazy">
<em>Smart Contract - Reply Message</em></p>
<p><a target="_blank" href="https://idea.gear-tech.io/programs/0x25629eaa3c7a51ec407f89bbaae7ccb4f58c6026283758d0fccb50e3bb042bdd">You can find the program here on the Vara Network</a>.</p>
<h2 id="heading-metadata-amp-state">Metadata &amp; State</h2>
<p>Metadata and state goes hand in hand with each other. In order for your client application to allow users to interact or request data(state) from your smart contract, you need to define both the metadata and state, and even if the state is defined, and the metadata was not provided, you cannot access the any data.</p>
<p>So let's take each step by step.</p>
<h3 id="heading-metadata">Metadata</h3>
<p>In the Gear Protocol world, metadata is like a blueprint for defining how different parts of a decentralized app (dApp) talk to each other. It's similar to how interfaces or types work in TypeScript. These blueprints describe how things like initial data type to expect, handling messages, and swapping data happen in the dApp, whether <code>In</code>, <code>Out</code>, and <code>InOut</code>.</p>
<p>When we make clear blueprints, it helps developers make sure that all the different parts of the dApp understand each other's data formats. This makes it easy for the smart contract (program-actor) and the client side app to share data smoothly.</p>
<p>To create these blueprints for your program, we use the <code>gmeta</code> tool. It helps us define these blueprints by outlining how different interactions work and what kinds of data they involve.</p>
<p>So, think of metadata in your program as similar to how interfaces/types work in TypeScript. They help organize how the different parts of your dApp communicate and understand each other's data.</p>
<h3 id="heading-example-of-a-metadata">Example Of A Metadata</h3>
<pre><code class="lang-bash">use gmeta::{InOut, Metadata, Out};

pub struct ProgramMetadata;

// Be sure to describe all the types.
// But <span class="hljs-keyword">if</span> any of the endpoints is missing <span class="hljs-keyword">in</span> your program, you can use ();
// as indicated <span class="hljs-keyword">in</span> the <span class="hljs-keyword">case</span> of `<span class="hljs-built_in">type</span> Signal`.

impl Metadata <span class="hljs-keyword">for</span> ProgramMetadata {
    <span class="hljs-built_in">type</span> Init = InOut&lt;MessageInitIn, MessageInitOut&gt;;
    <span class="hljs-built_in">type</span> Handle = InOut&lt;MessageIn, MessageOut&gt;;
    <span class="hljs-built_in">type</span> Others = InOut&lt;MessageAsyncIn, Option&lt;u8&gt;&gt;;
    <span class="hljs-built_in">type</span> Reply = String;
    <span class="hljs-built_in">type</span> Signal = ();
    <span class="hljs-built_in">type</span> State = Out&lt;Vec&lt;Wallet&gt;&gt;;
}
</code></pre>
<p>The above is an example of how it is defined. Don't worry if you don't understand it now, I'll cover more into details later. Now let's talk about the state.</p>
<h3 id="heading-state">State</h3>
<p>In Gear Protocol, the <code>state</code> function serves as a dedicated storage space within a program. This storage allows us to store and retrieve data as needed. Since this data is stored in persistent memory, it remains accessible even after the contract stops running. What's fascinating is that anyone with access to the blockchain can view this stored data. The <code>state</code> function doesn't alter or modify the blockchain itself. Instead, it simply provides a way to access stored data within the program.</p>
<p>Here is an example of a <code>state</code> function:</p>
<pre><code class="lang-bash">// Describe state structure
<span class="hljs-comment">#[derive(TypeInfo, Decode, Encode, Clone)]</span>
pub struct Messages {
    pub id: ActorId,
    pub content: String,
}

// Declare and initialize the state
static mut MESSAGES: Vec&lt;Messages&gt; = Vec::new();

<span class="hljs-comment">#[no_mangle]</span>
extern <span class="hljs-string">"C"</span> fn <span class="hljs-function"><span class="hljs-title">state</span></span>() {
    msg::reply(unsafe { MESSAGES.clone() }, 0).expect(<span class="hljs-string">"Failed to share state"</span>);
}
</code></pre>
<p>When the <code>state</code> function is called, it returns a list of <code>wallets</code> data stored within the program. This means that once a program is deployed on the blockchain, anyone can read its state.</p>
<p>Additionally, developers have the flexibility to create custom programs that can read the state. This empowers you and I to tailor our data access methods according to the specific needs for our dApp, even if the primary program undergoes changes.</p>
<p>The key takeaway is that, the <code>state</code> function facilitates access to data stored in smart contracts. It's worth noting that both users and other programs can access the state of a program, providing a versatile means of interacting with stored data.</p>
<h2 id="heading-third-project-building-messages">Third Project - Building Messages</h2>
<p>In our last project <code>input-msg</code>, we didn't keep track of the messages that got sent. So in this project, we'll cover the metadata and state.</p>
<p>Run the command below to create your project in <strong>/freecodecamp-gear-protocol/</strong>:</p>
<pre><code class="lang-bash">cargo new --lib messages
</code></pre>
<p>Next, add your <strong>build.rs</strong> file, and make the workspace dependencies available to the <code>/freecodecamp-gear-protocol/messages</code>.</p>
<h3 id="heading-adding-metadata-to-messages">Adding Metadata to Messages</h3>
<p>To setup a metadata for your project, you need to create an additional crate to manage that, so <code>cd</code> into <strong>messages</strong>, and run the command below.</p>
<pre><code class="lang-bash">cargo new --lib io
</code></pre>
<p>In your <strong>freecodecamp-gear-protocol/messages/io/Cargo.toml</strong>, copy and paste the following code:</p>
<pre><code class="lang-toml"><span class="hljs-section">[package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"messages-io"</span>
<span class="hljs-attr">version.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">edition.workspace</span> = <span class="hljs-literal">true</span>


<span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">gstd.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">gmeta.workspace</span> = <span class="hljs-literal">true</span>
</code></pre>
<p>Here, I changed the name from <code>io</code> to <code>messages-io</code>, and the reason is for me to identify, and separate it for other <code>io</code>'s in the workspace. And add the dependencies.</p>
<p>In order to use the <code>io</code> in your workspace, you need to go the <strong>freecodecamp-gear-protocol/Cargo.toml</strong>, and add a path from your <code>io</code> to your workspace, which you can then use in any of the projects that need <code>struct</code>, <code>enum</code>, and <code>method</code>.</p>
<p>In <strong>freecodecamp-gear-protocol/Cargo.toml</strong>:</p>
<pre><code class="lang-bash">[workspace]
resolver = <span class="hljs-string">"2"</span>
members = [<span class="hljs-string">"receive-joke"</span>,<span class="hljs-string">"input-msg"</span>]


[workspace.package]
name = <span class="hljs-string">"freecodecamp-gear-protocol"</span>
version = <span class="hljs-string">"0.1.0"</span>
edition = <span class="hljs-string">"2021"</span>
authors = [<span class="hljs-string">"Rocky Essel"</span>]
license = <span class="hljs-string">"MIT"</span>
publish = <span class="hljs-literal">false</span>

[workspace.dependencies]
<span class="hljs-comment"># Internal Crates</span>
messages-io={path = <span class="hljs-string">"messages/io"</span>} &lt; ---- Here

<span class="hljs-comment"># External Crates</span>
gstd = <span class="hljs-string">"1.4.1"</span>
gmeta = <span class="hljs-string">"1.4.1"</span>
gtest  = <span class="hljs-string">"1.4.1"</span>
gear-wasm-builder = <span class="hljs-string">"1.4.1"</span>
parity-scale-codec = { version = <span class="hljs-string">"3.6.12"</span>, default-features = <span class="hljs-literal">false</span> }
scale-info = { version = <span class="hljs-string">"2.11.3"</span>, default-features = <span class="hljs-literal">false</span> }
</code></pre>
<p>And that's the <code>Internal Crate</code> I talked about earlier. Next, you need to include the <code>messages-io</code> in your <code>messages</code> project, like below:</p>
<pre><code class="lang-toml"><span class="hljs-section">[package]</span>
<span class="hljs-attr">name</span>=<span class="hljs-string">"messages"</span>
<span class="hljs-attr">version.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">edition.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">authors.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">license.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">publish.workspace</span> = <span class="hljs-literal">true</span>


<span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">gstd.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">messages-io.workspace</span> = <span class="hljs-literal">true</span> &lt;---

<span class="hljs-section">[build-dependencies]</span>
<span class="hljs-attr">gear-wasm-builder.workspace</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">messages-io.workspace</span> = <span class="hljs-literal">true</span> &lt; ---
</code></pre>
<p>The reason for adding <code>messages-io.workspace</code> to both the <code>[dependencies]</code> and <code>[build-dependencies]</code> is to make the <code>struct</code>, <code>enums</code>, <code>pub variables</code> and <code>methods</code> accessible to <code>messages/src/lib.rs</code>, and <code>messages/build.rs</code> using <code>messages-io.workspace</code>.</p>
<h3 id="heading-metadata-in-iosrclibrs">Metadata in <code>io/src/lib.rs</code></h3>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gmeta::{InOut, Metadata, Out};
<span class="hljs-keyword">use</span> gstd::{prelude::*, ActorId, <span class="hljs-built_in">Vec</span>};

<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">MessageMetadata</span></span>;

<span class="hljs-keyword">pub</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">mut</span> MESSAGES: <span class="hljs-built_in">Vec</span>&lt;User&gt; = <span class="hljs-built_in">Vec</span>::new();

<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Message</span></span> {
    <span class="hljs-keyword">pub</span> id: ActorId,
    <span class="hljs-keyword">pub</span> content: <span class="hljs-built_in">String</span>,
}

<span class="hljs-keyword">impl</span> Metadata <span class="hljs-keyword">for</span> MessageMetadata {
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Init</span></span> = InOut&lt;Message, <span class="hljs-built_in">String</span>&gt;;
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Handle</span></span> = InOut&lt;Message, <span class="hljs-built_in">String</span>&gt;;
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">State</span></span> = Out&lt;<span class="hljs-built_in">Vec</span>&lt;Message&gt;&gt;;
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Reply</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Others</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Signal</span></span> = ();
}
</code></pre>
<p>To implement the logic of the message-handling system for your program or smart contract, understanding how to set the metadata of your program is crucial.<br>Therefore, much attention is needed here.</p>
<p>The <code>MessageMetadata</code> struct you've defined implements the <code>Metadata</code> trait, which then structures the message metadata for the program. Also, a mutable static variable <code>MESSAGES</code> is declared to store all the messages you and your users send to the program. And since it’s a mutable static variable, unsafe code will be required to modify it due to Rust's safety guarantees around mutable static variables.</p>
<p>The <code>Message</code> struct is defined with two fields: <code>id</code> (sender's identifier) and <code>content</code> (the message text).</p>
<p>The <code>Metadata</code> trait is implemented for <code>MessageMetadata</code>, defining several associated types. The <code>Init</code> type is set to <code>InOut&lt;MessageInit, String&gt;</code>, specifying the input-output types for the initialization phase. \</p>
<p>This means that when the contract is initialized, it will accept a <code>MessageInit</code> type and return a <code>String</code>. The <code>Handle</code> type is set to <code>InOut&lt;Message, String&gt;</code>, specifying the input-output types for handling messages. It accepts a <code>Message</code> type as input and returns a <code>String</code>. </p>
<p>The <code>State</code> type is set to <code>Out&lt;Vec&lt;Message&gt;&gt;</code>, defining the state output type, meaning that the state of the contract will be a vector of <code>Message</code> objects, and it doesn’t accept any input to retrieve this state. The <code>Reply</code>, <code>Others</code>, and <code>Signal</code> types are all set to <code>()</code>, indicating no additional reply, other types, or signals are used in this case.</p>
<h3 id="heading-further-context-of-its-usage">Further Context of its usage.</h3>
<p>In this system, the metadata definition specifies how the smart contract should handle initialization and message handling. During the initialization phase (<code>Init</code>), when the contract is deployed on the Vara Network, it uses the <code>Init</code> type to set up the initial state. The input is expected to be of type <code>MessageInit</code>, and the output will be a <code>String</code>. During deployment, you provide your ID and message content, which the contract processes using the <code>init()</code> method.</p>
<p>After deployment, the contract can handle new messages using the <code>Handle</code> type, which expects a <code>Message</code> type as input and returns a <code>String</code> as a response. This functionality is useful for adding new messages to the <code>MESSAGES</code> vector. For state management (<code>State</code>), the contract’s state is a list of messages (<code>Vec&lt;Message&gt;</code>), and it doesn’t accept any input to retrieve the state but outputs the current state when queried.</p>
<p>So to summarize, the code in <strong>freecodecamp-gear-protocol/messages/io/src/lib.rs</strong> defines the structure and behavior of a message-handling smart contract, specifying how it initializes, handles messages, and manages state.</p>
<h3 id="heading-building-the-metadata">Building the Metadata</h3>
<p>In order to build your project with the metadata, you need to modify the <strong>build.rs</strong>, which initially looks like below:</p>
<pre><code class="lang-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    gear_wasm_builder::build();
}
</code></pre>
<p>There's nothing wrong with using the above code, but if you plan to build your program and deploy on the blockchain to use it on the client or anywhere else, it would be impossible to interact with your smart contract if the metadata is not defined. Think of it like <code>ABI</code> in other blockchain environment.</p>
<p>So replace the code with:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> messages_io::MessageMetadata;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    gear_wasm_builder::build_with_metadata::&lt;MessageMetadata&gt;();
}
</code></pre>
<p>Finally, you would be handling the logic for your smart contract in the <code>messages/src/lib.rs</code> using the <code>handle()</code> function.</p>
<p>Here is the code for the <code>lib.rs</code>:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gstd::{exec, msg, prelude::*, ActorId};

<span class="hljs-keyword">use</span> messages_io::*;

<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">init</span></span>() {
    <span class="hljs-keyword">let</span> init: Message = msg::load().expect(<span class="hljs-string">"Unable to decode Message"</span>);
    <span class="hljs-keyword">let</span> init_message = Message {
        id: init.id,
        content: init.content,
    };

    <span class="hljs-keyword">unsafe</span> { MESSAGES.push(init_message) };    
    msg::reply_bytes(<span class="hljs-string">"Successfully initialized"</span>, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to initialize successfully."</span>);
}


<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">handle</span></span>() {

    <span class="hljs-keyword">let</span> message_handler: Message = msg::load().expect(<span class="hljs-string">"Unable to decode Message"</span>);
    <span class="hljs-keyword">let</span> message = Message {
        id: message_handler.id,
        content: message_handler.content,
    };
    <span class="hljs-keyword">unsafe</span> { MESSAGES.push(message) };
    msg::reply_bytes(<span class="hljs-string">"Message sent successfully."</span>, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to send  reply message."</span>);
}


<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">state</span></span>() {
    msg::reply(<span class="hljs-keyword">unsafe</span> { MESSAGES.clone() }, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to share state"</span>);
}
</code></pre>
<h3 id="heading-initialization-function-init">Initialization Function (<code>init</code>)</h3>
<pre><code class="lang-rust"><span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">init</span></span>() {
    <span class="hljs-keyword">let</span> init: Message = msg::load().expect(<span class="hljs-string">"Unable to decode Message"</span>);
    <span class="hljs-keyword">let</span> init_message = Message {
        id: init.id,
        content: init.content,
    };

    <span class="hljs-keyword">unsafe</span> { MESSAGES.push(init_message) };
    msg::reply_bytes(<span class="hljs-string">"Successfully initialized"</span>, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to initialize successfully."</span>);
}
</code></pre>
<p>The <code>init</code> function is the entry point for initializing the smart contract. It is marked with <code>#[no_mangle]</code> to prevent Rust from applying name mangling, making the function accessible from the smart contract runtime. </p>
<p>The function begins by loading the initial message from the input payload using <code>msg::load()</code>. This message is expected to be of type <code>Message</code>, and if decoding fails, the function will panic with an error message. Next, a new <code>Message</code> instance is created from the loaded data. This new message is then added to the global <code>MESSAGES</code> vector, which is a mutable static variable marked as unsafe due to potential data races. Finally, the function sends a reply indicating successful initialization using <code>msg::reply_bytes</code>. If this reply fails, the function will panic.</p>
<h3 id="heading-message-handling-function-handle">Message Handling Function (<code>handle</code>)</h3>
<pre><code class="lang-rust"><span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">handle</span></span>() {
    <span class="hljs-keyword">let</span> message_handler: Message = msg::load().expect(<span class="hljs-string">"Unable to decode Message"</span>);
    <span class="hljs-keyword">let</span> message = Message {
        id: message_handler.id,
        content: message_handler.content,
    };
    <span class="hljs-keyword">unsafe</span> { MESSAGES.push(message) };
    msg::reply_bytes(<span class="hljs-string">"Message sent successfully."</span>, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to send  reply message."</span>);
}
</code></pre>
<p>The <code>handle</code> function is designed to handle incoming messages after the contract is deployed. Like the <code>init</code> function, it is marked with <code>#[no_mangle]</code> to ensure it can be called from the smart contract runtime. The function begins by loading the incoming message from the input payload. This message is decoded into a <code>Message</code> struct, and if decoding fails, the function will panic. </p>
<p>A new <code>Message</code> instance is then created from the decoded data and added to the global <code>MESSAGES</code> vector using an unsafe block. The function then sends a reply indicating that the message was sent successfully. If the reply fails, the function will panic.</p>
<h3 id="heading-state-query-function-state">State Query Function (<code>state</code>)</h3>
<pre><code class="lang-rust"><span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">state</span></span>() {
    msg::reply(<span class="hljs-keyword">unsafe</span> { MESSAGES.clone() }, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to share state"</span>);
}
</code></pre>
<p>The <code>state</code> function allows querying the current state of the smart contract. It is also marked with <code>#[no_mangle]</code> for the same reasons as the previous functions. The function replies with a cloned version of the global <code>MESSAGES</code> vector, containing all the messages that have been added so far. This is done within an unsafe block due to the mutable static variable. If the function fails to send the state, it will panic.</p>
<p>So this code simply defines a smart contract with three main functions: <code>init</code> for initialization, <code>handle</code> for processing incoming messages, and <code>state</code> for querying the current state of the contract. Where each function carefully manages the global <code>MESSAGES</code> vector.</p>
<h3 id="heading-deployment-on-the-vara-network">Deployment on the Vara Network</h3>
<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/e967ebf211f54f2c9c85fedc593e427e?sid=3ef6709a-8b5a-412b-b80c-93f721ba135b">https://www.loom.com/share/e967ebf211f54f2c9c85fedc593e427e?sid=3ef6709a-8b5a-412b-b80c-93f721ba135b</a></div>
<p>Now you're done with this project, and hope you learned and have understood most of what I've written. In our next project, you'll be building something a bit more complex than this. So let's begin.</p>
<p><a target="_blank" href="https://idea.gear-tech.io/programs/0x58acd467aa011554b0dc167f741e745b336a03943df6f1eba635e9c28ca9824e">Here is the program deployed on Vara Network</a>, and this is the <a target="_blank" href="https://github.com/rockyessel/freecodecamp-gear-protocol">entire repository for the 3 projects</a> we've built so far. The next project is going to be stand-alone project so you won't use the workspace.</p>
<h2 id="heading-final-project">Final Project</h2>
<p>In this final project, you'll build a very simple game: where you (<code>player</code>) fights with the <code>boss</code>. So here is a simple layman's explanation of the game mechanics.</p>
<h3 id="heading-game-description">Game Description</h3>
<p>This game is a one-on-one battle between a player and a boss. To begin, the player selects their character from three options: Warrior, Mage, or Archer. Once the player's character data is stored in the program, the game begins.</p>
<p>In the game, the player immediately faces the boss, who starts with 10 lives (represented as an integer), while the player begins with 10 lives by default. The objective is to defeat the boss using a specific rule: the boss has weaknesses represented by letters (X, Y, Z), each associated with a random number.</p>
<p>During gameplay, if the player enters one of these letters, for example, 'Y' with a value of 4, and the boss starts with 0 lives, the program subtracts 4 lives from the boss, leaving 6. Similarly, when the player makes a move with a letter, the boss also makes a move with the a random letter with an associated value added to it.</p>
<p>The player progresses to the next level upon defeating the boss, continuing the battle with new challenges. I call this game Battle Showdown <strong>🤣😁😂.</strong></p>
<h3 id="heading-battle-showdown-mechanics-summary"><strong>Battle Showdown</strong> Mechanics Summary</h3>
<h4 id="heading-player-and-boss-lives">Player and Boss Lives</h4>
<ul>
<li>Player starts with 10 lives.</li>
<li>Boss starts with 10 lives.</li>
</ul>
<h4 id="heading-weaknesses-and-values">Weaknesses and Values</h4>
<ul>
<li>Boss and the player has weaknesses represented by letters ( <code>X</code>, <code>Y</code>, <code>Z</code>), each associated with a random number.</li>
</ul>
<h4 id="heading-gameplay">Gameplay</h4>
<ul>
<li>Player inputs a letter (for example, <code>'Y'</code>) and the associated value (for example, <code>4</code>) is subtracted from the boss's lives.</li>
<li>Boss retaliates with a letter and the same value is subtracted from the player's lives.</li>
<li>The objective is for the player to reduce the boss's lives to 0 to progress to the next level.</li>
</ul>
<h3 id="heading-match-equation">Match Equation</h3>
<p>Let's define the key variables:</p>
<ul>
<li>(<code>Lp</code>) = Player's current lives.</li>
<li>(<code>Lb</code>) = Boss's current lives.</li>
<li>(<code>V</code>) = Value associated with the letter representing the attack.</li>
</ul>
<p><strong>Initial conditions:</strong></p>
<ul>
<li>( <code>Lp</code> = 10 )</li>
<li>( <code>Lb</code> = 10 )</li>
</ul>
<p><strong>Player's turn:</strong></p>
<ul>
<li>Player selects a letter with an associated value (<code>V</code>).</li>
<li>Boss's lives are reduced: (<code>Lb</code> = <code>Lb</code> - <code>V</code>).</li>
</ul>
<p><strong>Boss's retaliation:</strong></p>
<ul>
<li>Boss selects a letter (same value (<code>V</code>)).</li>
<li>Player's lives are reduced: (<code>Lp</code> = <code>Lp</code> - <code>V</code>).</li>
</ul>
<p>This continues until either ( <code>Lb</code> ) (boss's lives) or ( <code>Lp</code> ) (player's lives) reaches 0.</p>
<h3 id="heading-equations">Equations</h3>
<p>After the player's attack and the Boss's retaliation:<br>[<code>Lb</code> = <code>Lb</code> - <code>V</code>]<br>[<code>Lp</code> = <code>Lp</code> - <code>V</code>]</p>
<p>The game loop continues with the player and boss exchanging moves. Repeat until <code>Lb</code> <code>&lt;= 0</code> or <code>Lp</code> <code>&lt;= 0</code></p>
<h3 id="heading-example">Example</h3>
<p>If the player inputs <code>'Y'</code> with a value of <code>4</code>:</p>
<ul>
<li>Initial: ( <code>Lp</code> = 10 ), ( <code>Lb</code> = 10 )</li>
<li>Player's attack: ( <code>Lb</code> = 10 - 4 = 6 )</li>
<li>Boss's retaliation: ( <code>Lp</code> = 10 - 4 = 6 )</li>
</ul>
<p>Next move:</p>
<ul>
<li>If the player inputs another value, let's say: <code>'X'</code> with a value of <code>5</code>:</li>
<li>Player's attack: ( <code>Lb</code> = 6 - 5 = 1 )</li>
<li>Boss's retaliation: ( <code>Lp</code> = 6 - 5 = 1 )</li>
</ul>
<p>The player wins as the Boss's lives ( <code>Lb</code> ) have reached 0.</p>
<p>The match equation for each round of the game can be summarized as:<br>[<code>Lb</code> = <code>Lb</code> - <code>V</code>]<br>[<code>Lp</code> = <code>Lp</code> - <code>V</code>]<br>This process is repeated until either the player's lives (( <code>Lp</code> )) or the Boss's lives (( <code>Lb</code> )) reach 0, determining the winner of the battle.</p>
<h3 id="heading-windows-error">Windows Error</h3>
<p>If you use Windows, you may encounter an error with the <strong>link.exe</strong>. Honestly, I cannot explain the reason behind the error, but in the Gear docs, it was made clear that Windows users might experience some problems when building their project.</p>
<p>But rest assured, there's a solution, and I'm going to guide you through it. So please follow these steps carefully so you don't have to deal with bugs along the way.</p>
<h3 id="heading-step-1-install-wsl-via-command-prompt">Step 1 - Install WSL via Command Prompt</h3>
<p>Open your CLI with administrative privileges, and run the command below:</p>
<pre><code class="lang-bash">wsl --install
</code></pre>
<p>After excutting the command, run the command below to list other Linux releases. </p>
<pre><code class="lang-bash">wsl -l -o
</code></pre>
<p>This command shows a list of other Linux distros, and you can select anyone you've used before. If you're new to Linux distros, I recommend selecting the <code>Ubuntu-22.04</code>.</p>
<p>These are just lists and are read-only. In order to select your system, run the command below.</p>
<pre><code class="lang-bash">wsl --install -d {Distribtion Name here(Ubuntu-22.04)}
</code></pre>
<p>After you're done with the installation, restart your PC. Wait a little while for the terminal to popup and prompt you for your details such as your username and password. If the terminal doesn't open, go to your start menu, and you will find something similar to this in your <code>Start</code> menu.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/image-6.png" alt="Image" width="600" height="400" loading="lazy">
<em>Ubuntu in start menu</em></p>
<p>After that, the next thing to do is to install Rust on your WSL. </p>
<h3 id="heading-how-to-install-rust-on-your-wsl">How to Install Rust On Your WSL</h3>
<p>To install Rust on your machine, I recommend that whenever you want to install any package, it is best practice to install updates and upgrades to the system before continuing with the installation.</p>
<pre><code class="lang-bash">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
<p>When you run <code>sudo apt update &amp;&amp; sudo apt upgrade -y</code>, you first update the package lists to get the latest information about available software packages. Then, if the update is successful, it proceeds to upgrade the installed packages to their latest versions, automatically confirming the upgrades to avoid manual intervention. This is a common and recommended practice to keep your Linux system up-to-date and secure.</p>
<h3 id="heading-essential-dependencies">Essential Dependencies.</h3>
<p>The command below installs essential development tools (<code>build-essential</code>, <code>gcc</code>, and <code>make</code>) and the <code>curl</code> utility for making HTTP requests and downloading files. These packages are commonly required for software development, compilation, and system administration tasks.</p>
<pre><code class="lang-bash"> sudo apt install curl build-essential gcc make -y
</code></pre>
<p>After that, run the command in the terminal  </p>
<pre><code class="lang-bash"> curl --proto <span class="hljs-string">'=https'</span> --tlsv1.2 -sSf https://sh.rustup.rs | sh
</code></pre>
<p>In the installation process, you'll be prompted a question: go with the <code>default</code> when it happens.</p>
<pre><code class="lang-bash">1. Proceed with installation (default) --&gt; Enter
2. Customize installation
3. Cancel installation.
</code></pre>
<p>After this prompt, you have successfully installed Rust on the Ubuntu System. Now the next step is to restart your terminal, simply close the current terminal. Open a new one, and run the command below.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> <span class="hljs-string">"<span class="hljs-variable">$HOME</span>/.cargo/env"</span>
</code></pre>
<p>What this command source <code>"$HOME/.cargo/env"</code> does is to activate the Rust environment. The reason is that the Rust environment comprises essential variables and configurations required for effective Rust usage. Now, once run, there's no output, so you can verify the installation by running the command below.</p>
<pre><code class="lang-bash"> rustc -V
</code></pre>
<p>Expected output:</p>
<pre><code class="lang-bash">rockyessel@UBUNTU-ROCKY:~$ rustc -V rustc 1.73.0 (cc66ad468 2024-02-07)
</code></pre>
<p>When you're done, there're also additional dependencies we have to install. So here, install them.</p>
<pre><code class="lang-bash">// Install the following.

 --&gt; rustup toolchain add nightly-2023-09-18
 --&gt; rustup target add wasm32-unknown-unknown --toolchain nightly-2023-09-18
</code></pre>
<p>After successfully installing them, head to the next section, which is building a game project.</p>
<p>In your WSL terminal, create your project name <code>battle-showdown</code>, and adding all the necessary <strong>toml</strong> files, and dependences. After that, <code>cd</code> into your project <code>battle-showdown</code> and added another program called <strong>io</strong>, this is where you write your metadate and other complex or simple data-type for your dApp.</p>
<pre><code class="lang-bash">battle-showdown
.
├── Cargo.toml
├── io
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
└── src
    └── lib.rs
</code></pre>
<p>So head-over to to your <strong>./io/src/lib.rs</strong> and paste the follow code:</p>
<pre><code class="lang-bash"><span class="hljs-comment">#![no_std]</span>

use gmeta::Metadata;

pub struct BattleShowdown;

impl Metadata <span class="hljs-keyword">for</span> BattleShowdown {
    <span class="hljs-built_in">type</span> Init = ();
    <span class="hljs-built_in">type</span> Handle = ();
    <span class="hljs-built_in">type</span> State = ();
    <span class="hljs-built_in">type</span> Reply = ();
    <span class="hljs-built_in">type</span> Others = ();
    <span class="hljs-built_in">type</span> Signal = ();
}
</code></pre>
<p>Here, you have defined a new public struct named <code>BattleShowdown</code>. Structs are used to create custom data types by grouping fields of various types together. But in this case, you're providing an implementation for the required types of the <code>Metadata</code> trait for the <code>BattleShowdown</code> struct: <code>impl Metadata for BattleShowdown</code>.</p>
<p><code>type Init = ()</code>, <code>type Handle = ()</code>, <code>type State = ()</code>, <code>type Reply = ()</code>, <code>type Others = ()</code>, and <code>type Signal = ()</code> specifies that the handlers or functions data type for <code>BattleShowdown</code> is of type <code>()</code>, which in Rust's unit type, equivalent to <code>void</code> in other language such as <code>TypeScript</code>.</p>
<p>So for now, we're saying that these handlers do not send or receive data as such. Hence, the code just specifies how <code>BattlwShowdown</code> interacts with the system. However, it is worth mentioning that, the <code>BattleShowdown</code> struct itself doesn't have any specific initialization data, state, handling behavior, replies, signals, or other associated types defined.</p>
<h3 id="heading-building-our-game">Building Our Game</h3>
<p>First off, let's make register the <strong>io</strong> in your parent directory <strong>cargo.toml</strong>. So head over to <code>./cargo.toml</code> and paste the code below:</p>
<pre><code class="lang-toml"><span class="hljs-attr">workspace</span> = { members = [<span class="hljs-string">"io"</span>] }
<span class="hljs-section">[package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"battle-showdown"</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">"0.1.0"</span>
<span class="hljs-attr">edition</span> = <span class="hljs-string">"2021"</span>

<span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">gstd</span> = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">battle-showdown-io</span>={path = <span class="hljs-string">"io"</span>}



<span class="hljs-section">[build-dependencies]</span>
<span class="hljs-attr">gear-wasm-builder</span> = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">battle-showdown-io</span>={path = <span class="hljs-string">"io"</span>}
</code></pre>
<p>I've ensured that the "battle-showdown-io" path is included in both the dependencies and build-dependencies sections. This decision was intentional because when it's added solely to build-dependencies, only the structs, enums, and other data types or functions within the build.rs file gain access to them, not the dependencies in your <strong><code>./src/lib.rs</code></strong>. This is important because I'll be utilizing <code>battle-showdown-io</code> in both build-dependencies (<code>build.rs</code>) and dependencies (<code>./src/lib.rs</code>).</p>
<p>This step is crucial because overlooking it can lead to frustrating import errors.</p>
<p>Next, is the file <strong><code>./io/cargo.toml</code></strong>, paste the following code below.</p>
<pre><code class="lang-toml"><span class="hljs-section">[package]</span>
<span class="hljs-attr">name</span> = <span class="hljs-string">"battle-showdown-io"</span>
<span class="hljs-attr">version</span> = <span class="hljs-string">"0.1.0"</span>
<span class="hljs-attr">edition</span> = <span class="hljs-string">"2021"</span>

<span class="hljs-comment"># See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html</span>

<span class="hljs-section">[dependencies]</span>
<span class="hljs-attr">gstd</span> = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">gmeta</span> = <span class="hljs-string">"1.4.1"</span>
<span class="hljs-attr">parity-scale-codec</span> = { version = <span class="hljs-string">"3.6.12"</span>, default-features = <span class="hljs-literal">false</span> }
<span class="hljs-attr">scale-info</span> = { version = <span class="hljs-string">"2.11.3"</span>, default-features = <span class="hljs-literal">false</span> }
</code></pre>
<h3 id="heading-explaining-metadata-for-battleshown">Explaining Metadata For BattleShown</h3>
<p>It's crucial to pay closer attention to this section, as I'll shed more light on explaining the metadata types for <code>BattleShown</code> and deploying it on the Vara Network.</p>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gmeta::Metadata;

<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BattleShowdown</span></span>;

<span class="hljs-keyword">impl</span> Metadata <span class="hljs-keyword">for</span> BattleShowdown {
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Init</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Handle</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">State</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Reply</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Others</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Signal</span></span> = ();
}
</code></pre>
<h3 id="heading-defining-initialization-init">Defining Initialization – <code>Init</code></h3>
<p>To define the types for this purpose, consider whether your program or smart contract needs to store data or perform actions before the user can interact with it. In the case of this game, the answer is yes. </p>
<p>The game assumes that only one person is playing and does not allow users to create their characters or players. This means that you need to store data before proceeding to use this program, and in this scenario, we need information about the person/developer/actor/user deploying the contract or program, which is you.</p>
<p>Here is the information you'll want to store:</p>
<ul>
<li><strong>playerId - Type: ActorId</strong><br>The playerId is actually the address associated with your account, which has the type of <code>ActorId</code>.</li>
<li><strong>playerName - Type: String</strong><br>This has a type of string, pretty much straightforward.</li>
<li><strong>playerCharacterType - Type: Enum</strong><br>The <code>playerCharacterType</code> is an enum that gives the actor an option to select which type they want to be, with options including Mage, Warrior, and Archer.</li>
</ul>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gmeta::Metadata;

<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BattleShowdown</span></span>;

<span class="hljs-keyword">impl</span> Metadata <span class="hljs-keyword">for</span> BattleShowdown {
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Init</span></span> = InOut&lt;InitBattleShowdown, <span class="hljs-built_in">String</span>&gt;;
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Handle</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">State</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Reply</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Others</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Signal</span></span> = ();
}

<span class="hljs-meta">#[derive(Debug, Clone, Copy, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">CharacterType</span></span> {
    Warrior,
    Mage,
    Archer,
}


<span class="hljs-meta">#[derive(Default, Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">InitBattleShowdown</span></span> {
    <span class="hljs-keyword">pub</span> player_id: ActorId,
    <span class="hljs-keyword">pub</span> player_character_type: CharacterType,
    <span class="hljs-keyword">pub</span> player_name: <span class="hljs-built_in">String</span>,
}
</code></pre>
<p>Although I've previously discussed metadata, you might be curious about what <code>type Init = InOut&lt;InitBattleShowdown, String&gt;;</code> means. Well, it's nothing complex. Here, we're simply stating that the <code>init</code> handle will accept a data type of <code>InitBattleShowdown</code> and will respond with a data type of <code>String</code>.</p>
<p>Before you continue, one more step remains: implementing a <code>default trait</code> for the enum <code>CharacterType</code>. This ensures that if the <code>CharacterType</code> is not explicitly defined, it defaults to <code>Warrior</code>. Simply add the following code to the existing code above:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">impl</span> <span class="hljs-built_in">Default</span> <span class="hljs-keyword">for</span> CharacterType {
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">default</span></span>() -&gt; <span class="hljs-keyword">Self</span> {
        CharacterType::Warrior
    }
}
</code></pre>
<h3 id="heading-defining-the-handle">Defining the <code>Handle</code></h3>
<p>Defining a type for the <code>handle</code> function mirrors the process for the <code>init</code> function, but the actual implementation is left to the developer, which in this case, is you. After reviewing code and experimenting with different approaches, I discovered a method used by Gear Protocol (which shares similarities with some of their projects) that made more sense.</p>
<h3 id="heading-action-amp-event">Action &amp; Event</h3>
<p>In their implementation, they utilized Actions and Events. Actions represent a set of operations that the program can perform, while Events are the outcomes of these Actions.</p>
<p>For example, in the context of this game, you could have an action named <code>Attack</code> with a corresponding Event named <code>Attacked</code>. These could potentially accept parameters and return results.</p>
<p>Therefore, to define the handle type, include the following code in your existing codebase:</p>
<pre><code class="lang-rust">
<span class="hljs-meta">#[derive(Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">BattleShowdownAction</span></span> {
    Attack {
        character_hit_power_value: PlayerHitPowerValue,
    },
}
</code></pre>
<p>Previously, when describing the game mechanics, I introduced a mechanic involving a letter with a randomly assigned number to inject an element of randomness. In this context, these letters correspond to an <code>ENUM</code> state of <code>X</code>, <code>Z</code>, and <code>Y</code>.</p>
<p>Therefore, to implement this mechanic, add the following code:</p>
<pre><code class="lang-rust">...

<span class="hljs-meta">#[derive(Debug, Clone, Copy, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">PlayerHitPowerValue</span></span> {
    X,
    Y,
    Z,
}
</code></pre>
<p>When an actor or user decides to attack the boss, they can select from the options provided above, each with a random value. Consequently, each attack on the boss will yield different outcomes due to the variability in these values. Similar to how you implemented a default trait for the <code>CharacterType</code>, you should follow suit here.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">impl</span> <span class="hljs-built_in">Default</span> <span class="hljs-keyword">for</span> PlayerHitPowerValue {
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">default</span></span>() -&gt; <span class="hljs-keyword">Self</span> {
        PlayerHitPowerValue::X
    }
}
</code></pre>
<h3 id="heading-event">Event</h3>
<p>As mentioned earlier, events are the outcomes of actions. Unlike the <code>BattleShowdownAction</code>, which only had one action, the <code>BattleShowdownEvent</code> will encompass more than two actions. Why? Because the game's logic dictates that when the user attacks, the boss also counterattacks. This results in three possible outcomes: either the user loses, the boss is defeated, or the battle continues. </p>
<p>However, the third outcome is contingent upon the first two outcomes.<br>Therefore, for the <code>BattleShowdownEvent</code>, you will need to define:</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">BattleShowdownEvent</span></span> {
    Attacked {
        id: ActorId,
        character_type: CharacterType,
        name: <span class="hljs-built_in">String</span>,
        player_lives: <span class="hljs-built_in">u32</span>,
        boss_livesL: <span class="hljs-built_in">u32</span>,
    },

    PlayerLost {
        id: ActorId,
        character_type: CharacterType,
        boss_livesL: <span class="hljs-built_in">u32</span>,
        player_lives: <span class="hljs-built_in">u32</span>,
        message: <span class="hljs-built_in">String</span>,
    },

    BossLost {
        character_type: CharacterType,
        player_lives: <span class="hljs-built_in">u32</span>,
        boss_livesL: <span class="hljs-built_in">u32</span>,
        message: <span class="hljs-built_in">String</span>,
    },
}
</code></pre>
<p>You have one action, but there are three possible events, correct? When the user/actor attacks the boss and the boss counterattacks, if either of them is defeated, the "Attacked" event is returned. However, if the player successfully defeats the boss, the "BossLost" event is returned.<br>Now that you have a solid understanding, let's incorporate both the input and output types for the Handle function: <code>type Handle = InOut&lt;BattleShowdownAction, BattleShowdownEvent&gt;;</code>.</p>
<h3 id="heading-defining-state">Defining <code>State</code></h3>
<p>As previously mentioned, the state stores information within your program. For <code>BattleShowdown</code>, the state you'd want to store includes information about the player, the boss, and the current level.</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(Default, Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BattleShowdownState</span></span> {
    <span class="hljs-keyword">pub</span> player_id: ActorId,
    <span class="hljs-keyword">pub</span> player_character_type: CharacterType,
    <span class="hljs-keyword">pub</span> current_level: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_name: <span class="hljs-built_in">String</span>,
    <span class="hljs-keyword">pub</span> boss_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_hit_power: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> boss_hit_power: <span class="hljs-built_in">u32</span>,
}
</code></pre>
<p>Therefore, whenever you call the state function, you should expect to see the result in this format. Now, add the <code>BattleShowdownState</code> to the state in the metadata, like so: <code>type State = Out&lt;BattleShowdownState&gt;;</code>.</p>
<p>With that, the setup is complete. Here is the entire code for the <strong>./io/src/lib.rs</strong> file.</p>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gmeta::{In, InOut, Metadata, Out};
<span class="hljs-keyword">use</span> gstd::{prelude::*, ActorId};

<span class="hljs-comment">// Define the main struct for the BattleShowdown</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BattleShowdown</span></span>;

<span class="hljs-comment">// Implementing Metadata for BattleShowdown</span>
<span class="hljs-keyword">impl</span> Metadata <span class="hljs-keyword">for</span> BattleShowdown {
    <span class="hljs-comment">// Define the type for initialization messages</span>
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Init</span></span> = InOut&lt;InitBattleShowdown, <span class="hljs-built_in">String</span>&gt;;
    <span class="hljs-comment">// Define the type for handle messages</span>
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Handle</span></span> = InOut&lt;BattleShowdownAction, BattleShowdownEvent&gt;;
    <span class="hljs-comment">// Define the type for state messages</span>
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">State</span></span> = Out&lt;BattleShowdownState&gt;;
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Reply</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Others</span></span> = ();
    <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">Signal</span></span> = ();
}

<span class="hljs-comment">// Struct for initializing the BattleShowdown</span>
<span class="hljs-meta">#[derive(Default, Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">InitBattleShowdown</span></span> {
    <span class="hljs-keyword">pub</span> player_id: ActorId,
    <span class="hljs-keyword">pub</span> player_character_type: CharacterType,
    <span class="hljs-keyword">pub</span> player_name: <span class="hljs-built_in">String</span>,
}

<span class="hljs-comment">// Struct representing the state of the BattleShowdown</span>
<span class="hljs-meta">#[derive(Default, Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BattleShowdownState</span></span> {
    <span class="hljs-keyword">pub</span> player_id: ActorId,
    <span class="hljs-keyword">pub</span> player_character_type: CharacterType,
    <span class="hljs-keyword">pub</span> current_level: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_name: <span class="hljs-built_in">String</span>,
    <span class="hljs-keyword">pub</span> boss_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_hit_power: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> boss_hit_power: <span class="hljs-built_in">u32</span>,
}

<span class="hljs-comment">// Enum representing different character types</span>
<span class="hljs-meta">#[derive(Debug, Clone, Copy, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">CharacterType</span></span> {
    Warrior,
    Mage,
    Archer,
}

<span class="hljs-comment">// Enum representing different values for player hit power</span>
<span class="hljs-meta">#[derive(Debug, Clone, Copy, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">PlayerHitPowerValue</span></span> {
    X,
    Y,
    Z,
}

<span class="hljs-comment">// Implementing Default for PlayerHitPowerValue</span>
<span class="hljs-keyword">impl</span> <span class="hljs-built_in">Default</span> <span class="hljs-keyword">for</span> PlayerHitPowerValue {
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">default</span></span>() -&gt; <span class="hljs-keyword">Self</span> {
        PlayerHitPowerValue::X
    }
}

<span class="hljs-comment">// Implementing Default for CharacterType</span>
<span class="hljs-keyword">impl</span> <span class="hljs-built_in">Default</span> <span class="hljs-keyword">for</span> CharacterType {
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">default</span></span>() -&gt; <span class="hljs-keyword">Self</span> {
        CharacterType::Warrior
    }
}

<span class="hljs-comment">// Enum representing different actions in the BattleShowdown</span>
<span class="hljs-meta">#[derive(Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">BattleShowdownAction</span></span> {
    Attack {
        character_hit_power_value: PlayerHitPowerValue,
    },
}

<span class="hljs-comment">// Enum representing different events in the BattleShowdown</span>
<span class="hljs-meta">#[derive(Debug, Encode, Decode, TypeInfo)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">BattleShowdownEvent</span></span> {
    Attacked {
        id: ActorId,
        character_type: CharacterType,
        name: <span class="hljs-built_in">String</span>,
        player_lives: <span class="hljs-built_in">u32</span>,
        boss_lives: <span class="hljs-built_in">u32</span>,
    },
    PlayerLost {
        id: ActorId,
        character_type: CharacterType,
        boss_lives: <span class="hljs-built_in">u32</span>,
        player_lives: <span class="hljs-built_in">u32</span>,
        message: <span class="hljs-built_in">String</span>,
    },
    BossLost {
        character_type: CharacterType,
        player_lives: <span class="hljs-built_in">u32</span>,
        boss_lives: <span class="hljs-built_in">u32</span>,
        message: <span class="hljs-built_in">String</span>,
    },
}
</code></pre>
<h3 id="heading-buildrs"><code>Build.rs</code></h3>
<p>Import <code>BattleShowdown</code> to the <strong>build.rs</strong> from your parent directory at <strong>./src/build.rs</strong>. If you encounter an import error, make sure that in your <strong>./cargo.toml</strong>, you're registering <code>battle-showdown-io={path = "io"}</code> there.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> battle_showdown_io::BattleShowdown;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
    gear_wasm_builder::build_with_metadata::&lt;BattleShowdown&gt;();
}
</code></pre>
<p>That's it for the <strong>build.rs</strong>, and what it does is to build your project into <code>wasm</code> and then build the <code>metadata</code> for <code>BattleShown</code> for you.</p>
<h3 id="heading-game-logic-implementation-srclibrs">Game Logic Implementation - <code>./src/lib.rs</code></h3>
<p>For this section, I'll write the code below, then I'll explain this as we go. There's going to be a problem I'd want you to solve, which will be about the state.</p>
<pre><code class="lang-rust"><span class="hljs-meta">#![no_std]</span>

<span class="hljs-keyword">use</span> gstd::{exec, msg, prelude::*, ActorId};

<span class="hljs-keyword">use</span> battle_showdown_io::*;

<span class="hljs-comment">// Function to generate random number between 1 and 3</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">get_random_u32</span></span>() -&gt; <span class="hljs-built_in">u32</span> {
    <span class="hljs-keyword">let</span> salt = msg::id();
    <span class="hljs-keyword">let</span> (hash, _num) = exec::random(salt.into()).expect(<span class="hljs-string">"get_random_u32(): random call failed"</span>);
    (<span class="hljs-built_in">u32</span>::from_le_bytes([hash[<span class="hljs-number">0</span>], hash[<span class="hljs-number">1</span>], hash[<span class="hljs-number">2</span>], hash[<span class="hljs-number">3</span>]]) % <span class="hljs-number">3</span>) + <span class="hljs-number">1</span> <span class="hljs-comment">// Generate random number between 1 and 3</span>
}

<span class="hljs-meta">#[derive(Debug, Default)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BattleShowdown</span></span> {
    <span class="hljs-keyword">pub</span> player_id: ActorId,
    <span class="hljs-keyword">pub</span> player_character_type: CharacterType,
    <span class="hljs-keyword">pub</span> current_level: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_name: <span class="hljs-built_in">String</span>,
    <span class="hljs-keyword">pub</span> boss_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> character_hit_power_value: PlayerHitPowerValue,
    <span class="hljs-keyword">pub</span> player_hit_power: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> boss_hit_power: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> game_state: <span class="hljs-built_in">String</span>,
}

<span class="hljs-keyword">static</span> <span class="hljs-keyword">mut</span> BATTLESHOWNDOWN: <span class="hljs-built_in">Option</span>&lt;BattleShowdown&gt; = <span class="hljs-literal">None</span>;

<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">unsafe</span> <span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">init</span></span>() {
    <span class="hljs-keyword">let</span> init: InitBattleShowdown = msg::load().expect(<span class="hljs-string">"Unable to decode InitBattleShowdown"</span>);

    <span class="hljs-keyword">let</span> battle_showdown = BattleShowdown {
        player_id: msg::source(),
        player_character_type: init.player_character_type,
        player_name: init.player_name,
        boss_lives: <span class="hljs-number">10</span>,
        player_lives: <span class="hljs-number">10</span>,
        ..<span class="hljs-built_in">Default</span>::default()
    };

    BATTLESHOWNDOWN = <span class="hljs-literal">Some</span>(battle_showdown);

    msg::reply_bytes(<span class="hljs-string">"Successfully initialized"</span>, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to initialize successfully."</span>);
}

<span class="hljs-keyword">impl</span> Encode <span class="hljs-keyword">for</span> BattleShowdown {
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">encode</span></span>(&amp;<span class="hljs-keyword">self</span>) -&gt; <span class="hljs-built_in">Vec</span>&lt;<span class="hljs-built_in">u8</span>&gt; {
        <span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> encoded = <span class="hljs-built_in">Vec</span>::new();

        <span class="hljs-comment">// Encode each field of BattleShowdown struct</span>
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.player_id.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.player_character_type.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.current_level.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.player_lives.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.player_name.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.boss_lives.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.character_hit_power_value.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.player_hit_power.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.boss_hit_power.encode());
        encoded.extend_from_slice(&amp;<span class="hljs-keyword">self</span>.game_state.encode());

        encoded
    }
}

<span class="hljs-keyword">impl</span> BattleShowdown {
    <span class="hljs-comment">// Placeholder for the `attack` method</span>
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">attack</span></span>(&amp;<span class="hljs-keyword">mut</span> <span class="hljs-keyword">self</span>, _character_hit_power_value: PlayerHitPowerValue) -&gt; BattleShowdownEvent {
        <span class="hljs-comment">// Implement this method according to your game logic</span>
        <span class="hljs-comment">// For now, just returning an empty event</span>

        <span class="hljs-comment">// Calculate total hit power for player based on character type and random values</span>
        <span class="hljs-keyword">let</span> character_hit_power = <span class="hljs-keyword">match</span> &amp;<span class="hljs-keyword">self</span>.player_character_type {
            CharacterType::Warrior =&gt; <span class="hljs-number">4</span>,
            CharacterType::Mage =&gt; <span class="hljs-number">3</span>,
            CharacterType::Archer =&gt; <span class="hljs-number">2</span>,
        };

        <span class="hljs-keyword">let</span> player_hit_power = <span class="hljs-keyword">match</span> &amp;<span class="hljs-keyword">self</span>.character_hit_power_value {
            PlayerHitPowerValue::X =&gt; character_hit_power + get_random_u32(),
            PlayerHitPowerValue::Y =&gt; character_hit_power + get_random_u32(),
            PlayerHitPowerValue::Z =&gt; character_hit_power + get_random_u32(),
        };

        <span class="hljs-comment">// Placeholder for boss attack logic</span>
        <span class="hljs-comment">// Update boss hit power to a random value for each attack</span>
        <span class="hljs-keyword">self</span>.boss_hit_power = get_random_u32();

        <span class="hljs-keyword">self</span>.player_hit_power = player_hit_power;

        <span class="hljs-comment">// Reduce boss's lives based on player's hit power</span>
        <span class="hljs-keyword">self</span>.boss_lives = <span class="hljs-keyword">self</span>.boss_lives.saturating_sub(<span class="hljs-keyword">self</span>.player_hit_power);
        <span class="hljs-comment">// Reduce player's lives based on boss's hit power</span>
        <span class="hljs-keyword">self</span>.player_lives = <span class="hljs-keyword">self</span>.player_lives.saturating_sub(<span class="hljs-keyword">self</span>.boss_hit_power);

        <span class="hljs-comment">// Check if player or boss has lost</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.player_lives == <span class="hljs-number">0</span> {
            <span class="hljs-comment">// Player lost</span>
            <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"Player lost."</span>.to_string();
            <span class="hljs-keyword">return</span> BattleShowdownEvent::PlayerLost {
                id: <span class="hljs-keyword">self</span>.player_id,
                boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
                character_type: <span class="hljs-keyword">self</span>.player_character_type,
                message: <span class="hljs-string">""</span>.to_string(),
                player_lives: <span class="hljs-keyword">self</span>.player_lives,
            };
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.boss_lives == <span class="hljs-number">0</span> {
            <span class="hljs-comment">// Boss lost</span>
            <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"Boss lost."</span>.to_string();
            <span class="hljs-keyword">return</span> BattleShowdownEvent::BossLost {
                boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
                character_type: <span class="hljs-keyword">self</span>.player_character_type,
                player_lives: <span class="hljs-keyword">self</span>.player_lives,
                message: <span class="hljs-string">"You've defeated the boos"</span>.to_string(),
            };
        }

        <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"The games continues."</span>.to_string();
        BattleShowdownEvent::Attacked {
            boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
            character_type: <span class="hljs-keyword">self</span>.player_character_type,
            id: <span class="hljs-keyword">self</span>.player_id,
            name: <span class="hljs-keyword">self</span>.player_name.clone(),
            player_lives: <span class="hljs-keyword">self</span>.player_lives,
        }
    }
}

<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">handle</span></span>() {
    <span class="hljs-keyword">let</span> battle_showdown_action: BattleShowdownAction =
        msg::load().expect(<span class="hljs-string">"Could not load BattleShowdownAction"</span>);
    <span class="hljs-keyword">let</span> battle_showdown = <span class="hljs-keyword">unsafe</span> {
        BATTLESHOWNDOWN
            .as_mut()
            .expect(<span class="hljs-string">"`BattleShowdown` is not initialized."</span>)
    };
    <span class="hljs-keyword">let</span> result: BattleShowdownEvent = <span class="hljs-keyword">match</span> battle_showdown_action {
        BattleShowdownAction::Attack {
            character_hit_power_value,
        } =&gt; battle_showdown.attack(character_hit_power_value),
    };
    msg::reply_bytes(result.encode(), <span class="hljs-number">0</span>)
        .expect(<span class="hljs-string">"Failed to encode or reply with `BattleShowdownEvent`."</span>);
}

<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">state</span></span>() {
    <span class="hljs-keyword">let</span> battle_showdown = <span class="hljs-keyword">unsafe</span> {
        BATTLESHOWNDOWN
            .take()
            .expect(<span class="hljs-string">"Unexpected error in taking state"</span>)
    };

    msg::reply(battle_showdown, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Unable to share the state"</span>);
}
</code></pre>
<p>At first glance this might seem a lot, but it isn't, so don't get too intimidated. Before you start, make sure you understand the whole logic of the game description I gave earlier since you'll be implementing it here.</p>
<p>Above, we have some important functions, <code>struct</code>, and <code>impl</code>, and here is an overview of what they do.</p>
<ol>
<li>With the <code>get_random_u32</code> function, we generated a random number between 1 and 3.</li>
<li>The <code>BattleShowdown</code> struct in the <code>/src/lib.rs</code> represents the main state of the game. It holds information such as player and boss stats, current game level, and game state. The <code>static mut BATTLESHOWNDOWN: Option&lt;BattleShowdown&gt; = None;</code> is a static mutable variable that holds the current state of the game. It's wrapped in an <code>Option</code> to indicate whether the game has been initialized yet or not, which you'll use later in your implementation.</li>
<li><code>unsafe extern "C" fn init()</code> is responsible for initializing the game state when called after the contract has been uploaded. It loads an initialization message, constructs a <code>BattleShowdown</code> instance based on that message, and sets <code>BATTLESHOWNDOWN</code> to <code>Some</code> with the constructed instance.</li>
<li><code>impl Encode for BattleShowdown</code>: this trait is implemented for <code>BattleShowdown</code>, enabling it to be encoded into a byte representation. This is useful for serialization and sending the game state over the network. And there's a way to also implement the trait without creating an <code>impl</code> for <code>BattleShowdown</code>.</li>
<li><code>impl BattleShowdown</code>: this <code>impl</code> for <code>BattleShowdown</code> is where the entire logic happens, and for now, we've only added an <code>attack</code> method for it. It worth noting that we'll be adding more as we continue this project.</li>
<li>So what does the <code>attack</code> method do? Well, The <code>attack</code> method simulates a combat encounter between the player and the boss character in our game. It calculates the hit power for both entities based on character type and randomness, manages their health points accordingly, and generates game events to reflect the outcome of the encounter.</li>
<li><code>extern "C" fn handle()</code>: In our case, the <code>handle</code> function is used to process incoming messages, specifically <code>BattleShowdownAction</code>. So depending on the action perform by the actor, it dispatches a result of the action to the appropriate methods of <code>BattleShowdown</code>, such as <code>attack</code>, and sends back the resulting game events to the actor. Like disccued in the illustration.</li>
<li>And lastly, <code>extern "C" fn state()</code> simply retrieves the current game state represented by <code>BattleShowdown</code> and sends it as a reply.</li>
</ol>
<p>This is the overall explanation to the code in the file. But leaving with this isn't enough for even me. Let's disccus more below.</p>
<h3 id="heading-understanding-theinit">Understanding the<code>init()</code></h3>
<pre><code class="lang-rust"><span class="hljs-meta">#[derive(Debug, Default)]</span>
<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">BattleShowdown</span></span> {
    <span class="hljs-keyword">pub</span> player_id: ActorId,
    <span class="hljs-keyword">pub</span> player_character_type: CharacterType,
    <span class="hljs-keyword">pub</span> current_level: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> player_name: <span class="hljs-built_in">String</span>,
    <span class="hljs-keyword">pub</span> boss_lives: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> character_hit_power_value: PlayerHitPowerValue,
    <span class="hljs-keyword">pub</span> player_hit_power: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> boss_hit_power: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> game_state: <span class="hljs-built_in">String</span>,
}

<span class="hljs-keyword">static</span> <span class="hljs-keyword">mut</span> BATTLESHOWNDOWN: <span class="hljs-built_in">Option</span>&lt;BattleShowdown&gt; = <span class="hljs-literal">None</span>;

<span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">unsafe</span> <span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">init</span></span>() {
    <span class="hljs-comment">// Load initialization data</span>
    <span class="hljs-keyword">let</span> init: InitBattleShowdown = msg::load().expect(<span class="hljs-string">"Unable to decode InitBattleShowdown"</span>);

    <span class="hljs-comment">// Create a BattleShowdown instance with initial values</span>
    <span class="hljs-keyword">let</span> battle_showdown = BattleShowdown {
        player_id: msg::source(),
        player_character_type: init.player_character_type,
        player_name: init.player_name,
        boss_lives: <span class="hljs-number">10</span>,
        player_lives: <span class="hljs-number">10</span>,
        ..<span class="hljs-built_in">Default</span>::default()
    };

    <span class="hljs-comment">// Store the BattleShowdown instance</span>
    BATTLESHOWNDOWN = <span class="hljs-literal">Some</span>(battle_showdown);

    <span class="hljs-comment">// Reply to signal successful initialization</span>
    msg::reply_bytes(<span class="hljs-string">"Successfully initialized"</span>, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Failed to initialize successfully."</span>);
}
</code></pre>
<p>The function loads data from an initialization message (<code>InitBattleShowdown</code>) sent by the developer or player. This data includes the player's chosen <code>character type</code> and <code>name</code>. Based on the initialization data, a <code>BattleShowdown</code> instance is created with initial values, which is stored in <code>battle_showdown</code>. </p>
<p>This instance represents the state of the game, including player and boss stats, current level, and game state. The created <code>BattleShowdown</code> instance is stored in the <code>BATTLESHOWNDOWN</code> static variable, allowing the game logic to access and manipulate the game state throughout the gameplay. Finally, a reply message is sent back to the developer or player to indicate successful initialization of the game contract. </p>
<p>This function sets up the initial state of the game, paving the way for further interactions and gameplay logic.</p>
<h3 id="heading-understanding-the-handle">Understanding the <code>handle()</code></h3>
<pre><code class="lang-rust"><span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">handle</span></span>() {
    <span class="hljs-comment">// Load the action from the message</span>
    <span class="hljs-keyword">let</span> battle_showdown_action: BattleShowdownAction =
        msg::load().expect(<span class="hljs-string">"Could not load BattleShowdownAction"</span>);

    <span class="hljs-comment">// Retrieve the current game state</span>
    <span class="hljs-keyword">let</span> battle_showdown = <span class="hljs-keyword">unsafe</span> {
        BATTLESHOWNDOWN
            .as_mut()
            .expect(<span class="hljs-string">"`BattleShowdown` is not initialized."</span>)
    };

    <span class="hljs-comment">// Execute the appropriate action on the game state and get the result</span>
    <span class="hljs-keyword">let</span> result: BattleShowdownEvent = <span class="hljs-keyword">match</span> battle_showdown_action {
        BattleShowdownAction::Attack {
            character_hit_power_value,
        } =&gt; battle_showdown.attack(character_hit_power_value),
    };

    <span class="hljs-comment">// Send back the result as a reply message</span>
    msg::reply_bytes(result.encode(), <span class="hljs-number">0</span>)
        .expect(<span class="hljs-string">"Failed to encode or reply with `BattleShowdownEvent`."</span>);
}
</code></pre>
<p>The <code>handle()</code> function plays a crucial role in processing incoming messages and orchestrating the game's actions. It serves as the bridge between player interactions and the game's internal logic. When invoked, <code>handle()</code> begins by loading the <code>action</code> sent by the player from the message. </p>
<p>This <code>action</code>, encapsulated as <code>BattleShowdownAction</code>, dictates the player's intended move, such as attacking the boss. Next, the function retrieves the current game state from the <code>BATTLESHOWNDOWN</code> variable. This state holds essential information about the player, the boss, and the overall game environment. </p>
<p>With both the action and the game state at hand, <code>handle()</code> proceeds to execute the appropriate action. For instance, if the player's action is an <code>attack</code>, the function triggers the <code>attack()</code> method on the <code>battle_showdown</code> instance. This method calculates the outcome of the player's attack, considering factors like the player's hit power and the boss's remaining health points.</p>
<p>Crucially, the <code>attack()</code> method requires a parameter: <code>character_hit_power_value</code>. This parameter corresponds to the player's choice between three options: <code>X</code>, <code>Y</code>, and <code>Z</code>, each associated with different hit power values as disccused in earlier sections. </p>
<p>Once the <code>action</code> is executed, <code>handle()</code> generates an event, encapsulated as <code>BattleShowdownEvent</code>, reflecting the outcome of the player's move. This event encapsulates important details, such as changes in player and boss health points. Finally, <code>handle()</code> responds to the player by replying with the result of the action as a byte-encoded message. This message contains the updated game state, allowing the player to understand their current situation, including their health status and that of the boss.</p>
<h3 id="heading-understanding-the-impl-battleshowdown-for-attack">Understanding the <code>impl BattleShowdown for attack</code></h3>
<pre><code class="lang-rust"><span class="hljs-keyword">impl</span> BattleShowdown {
    <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">attack</span></span>(&amp;<span class="hljs-keyword">mut</span> <span class="hljs-keyword">self</span>, _character_hit_power_value: PlayerHitPowerValue) -&gt; BattleShowdownEvent {
        <span class="hljs-comment">// Calculate total hit power for player based on character type and random values</span>
        <span class="hljs-keyword">let</span> character_hit_power = <span class="hljs-keyword">match</span> &amp;<span class="hljs-keyword">self</span>.player_character_type {
            CharacterType::Warrior =&gt; <span class="hljs-number">4</span>,
            CharacterType::Mage =&gt; <span class="hljs-number">3</span>,
            CharacterType::Archer =&gt; <span class="hljs-number">2</span>,
        };

        <span class="hljs-keyword">let</span> player_hit_power = <span class="hljs-keyword">match</span> &amp;<span class="hljs-keyword">self</span>.character_hit_power_value {
            PlayerHitPowerValue::X =&gt; character_hit_power + get_random_u32(),
            PlayerHitPowerValue::Y =&gt; character_hit_power + get_random_u32(),
            PlayerHitPowerValue::Z =&gt; character_hit_power + get_random_u32(),
        };

        <span class="hljs-comment">// Placeholder for boss attack logic</span>
        <span class="hljs-comment">// Update boss hit power to a random value for each attack</span>
        <span class="hljs-keyword">self</span>.boss_hit_power = get_random_u32();

        <span class="hljs-keyword">self</span>.player_hit_power = player_hit_power;

        <span class="hljs-comment">// Reduce boss's lives based on player's hit power</span>
        <span class="hljs-keyword">self</span>.boss_lives = <span class="hljs-keyword">self</span>.boss_lives.saturating_sub(<span class="hljs-keyword">self</span>.player_hit_power);
        <span class="hljs-comment">// Reduce player's lives based on boss's hit power</span>
        <span class="hljs-keyword">self</span>.player_lives = <span class="hljs-keyword">self</span>.player_lives.saturating_sub(<span class="hljs-keyword">self</span>.boss_hit_power);

        <span class="hljs-comment">// Check if player or boss has lost</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.player_lives == <span class="hljs-number">0</span> {
            <span class="hljs-comment">// Player lost</span>
            <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"Player lost."</span>.to_string();
            <span class="hljs-keyword">return</span> BattleShowdownEvent::PlayerLost {
                id: <span class="hljs-keyword">self</span>.player_id,
                boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
                character_type: <span class="hljs-keyword">self</span>.player_character_type,
                message: <span class="hljs-string">""</span>.to_string(),
                player_lives: <span class="hljs-keyword">self</span>.player_lives,
            };
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.boss_lives == <span class="hljs-number">0</span> {
            <span class="hljs-comment">// Boss lost</span>
            <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"Boss lost."</span>.to_string();
            <span class="hljs-keyword">return</span> BattleShowdownEvent::BossLost {
                boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
                character_type: <span class="hljs-keyword">self</span>.player_character_type,
                player_lives: <span class="hljs-keyword">self</span>.player_lives,
                message: <span class="hljs-string">"You've defeated the boss"</span>.to_string(),
            };
        }

        <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"The game continues."</span>.to_string();
        <span class="hljs-comment">// Return event indicating attack occurred</span>
        BattleShowdownEvent::Attacked {
            boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
            character_type: <span class="hljs-keyword">self</span>.player_character_type,
            id: <span class="hljs-keyword">self</span>.player_id,
            name: <span class="hljs-keyword">self</span>.player_name.clone(),
            player_lives: <span class="hljs-keyword">self</span>.player_lives,
        }
    }
}
</code></pre>
<p>The <code>attack</code> method within the <code>BattleShowdown</code> implementation simulates a pivotal moment in the game: a combat encounter between the player and the boss character. </p>
<p>Here's how it works:</p>
<p>Firstly, the method calculates the total hit power for the player based on their character type (<code>character_hit_power</code>) and randomness (<code>player_hit_power</code>). Different character types (<code>Warrior</code>, <code>Mage</code>, or <code>Archer</code>) have different base hit powers. </p>
<p>Next, a random hit power value is added to the character's base hit power. This adds an element of unpredictability to each attack. The method then updates the boss's hit power (<code>self.boss_hit_power = get_random_u32();</code>) to a random value, representing the boss's retaliatory strike against the player.</p>
<p>After calculating the hit powers, the method reduces the boss's lives based on the player's hit power and vice versa, updating their respective health points accordingly.</p>
<pre><code class="lang-rust">        <span class="hljs-comment">// Reduce boss's lives based on player's hit power</span>
        <span class="hljs-keyword">self</span>.boss_lives = <span class="hljs-keyword">self</span>.boss_lives.saturating_sub(<span class="hljs-keyword">self</span>.player_hit_power);
        <span class="hljs-comment">// Reduce player's lives based on boss's hit power</span>
        <span class="hljs-keyword">self</span>.player_lives = <span class="hljs-keyword">self</span>.player_lives.saturating_sub(<span class="hljs-keyword">self</span>.boss_hit_power);
</code></pre>
<p>The game state is then checked to determine if either the player or the boss has lost the battle. If the player's health points reaches zero, the game state is updated to indicate that the player has lost. Conversely, if the boss's health points reach zero, the game state reflects the boss's defeat.</p>
<pre><code class="lang-rust">        <span class="hljs-comment">// Check if player or boss has lost</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.player_lives == <span class="hljs-number">0</span> {
            <span class="hljs-comment">// Player lost</span>
            <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"Player lost."</span>.to_string();
            <span class="hljs-keyword">return</span> BattleShowdownEvent::PlayerLost {
                id: <span class="hljs-keyword">self</span>.player_id,
                boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
                character_type: <span class="hljs-keyword">self</span>.player_character_type,
                message: <span class="hljs-string">""</span>.to_string(),
                player_lives: <span class="hljs-keyword">self</span>.player_lives,
            };
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.boss_lives == <span class="hljs-number">0</span> {
            <span class="hljs-comment">// Boss lost</span>
            <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"Boss lost."</span>.to_string();
            <span class="hljs-keyword">return</span> BattleShowdownEvent::BossLost {
                boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
                character_type: <span class="hljs-keyword">self</span>.player_character_type,
                player_lives: <span class="hljs-keyword">self</span>.player_lives,
                message: <span class="hljs-string">"You've defeated the boss"</span>.to_string(),
            };
        }

        <span class="hljs-keyword">self</span>.game_state = <span class="hljs-string">"The game continues."</span>.to_string();
        <span class="hljs-comment">// Return event indicating attack occurred</span>
        BattleShowdownEvent::Attacked {
            boss_lives: <span class="hljs-keyword">self</span>.boss_lives,
            character_type: <span class="hljs-keyword">self</span>.player_character_type,
            id: <span class="hljs-keyword">self</span>.player_id,
            name: <span class="hljs-keyword">self</span>.player_name.clone(),
            player_lives: <span class="hljs-keyword">self</span>.player_lives,
        }
</code></pre>
<p>Finally, if neither the player nor the boss has lost, the game state is updated to indicate that the battle continues.</p>
<h3 id="heading-understanding-the-state">Understanding the <code>State()</code></h3>
<pre><code class="lang-rust"><span class="hljs-meta">#[no_mangle]</span>
<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">state</span></span>() {
    <span class="hljs-keyword">let</span> battle_showdown = <span class="hljs-keyword">unsafe</span> {
        BATTLESHOWNDOWN
            .take()
            .expect(<span class="hljs-string">"Unexpected error in taking state"</span>)
    };

    msg::reply(battle_showdown, <span class="hljs-number">0</span>).expect(<span class="hljs-string">"Unable to share the state"</span>);
}
</code></pre>
<p>For this instance there's nothing more to share, it retrieves the current state of the game, represented by the <code>BattleShowdown</code> struct, from a static mutable variable <code>BATTLESHOWNDOWN</code>, and sends a reply message containing the game state back to the player. If there is an error sending the reply message, it will panic with an error message indicating the inability to share the state.</p>
<p>And that's that for this project. There are some exciting features you can consider if you want to extend this project. Imagine the possibility of resetting the game state, accommodating multiple players, or even resetting the game for a single player. And for the ambitious, you could even tackle the challenge of resetting the state for the entire game. These additions can offer new dimensions to the project and provide excellent opportunities for you to challenge yourself.</p>
<h3 id="heading-short-recording-of-what-weve-built-demo">Short Recording of what we've built - Demo</h3>
<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/590d685f311f46c386943c41816dbf83?sid=e99d4948-f0ab-486d-a5fa-98fbcdfe3fe3">https://www.loom.com/share/590d685f311f46c386943c41816dbf83?sid=e99d4948-f0ab-486d-a5fa-98fbcdfe3fe3</a></div>
<p>In the video you could see I added another method for resetting everything back to it inital state. Though I didn't guide you through the process of doing that, you should know it is easy to implement, and I've added <a target="_blank" href="https://github.com/rockyessel/battle-showdown">a GitHub repository</a> for the entire code.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>As demonstrated, developing a smart contract with Gear Protocol becomes straightforward once you grasp the communication message concepts. By following the steps outlined, you can start building your own projects with confidence.</p>
<p>While this article didn't delve into handling transactions such as token transfers, minting, or NFTs, I will cover these topics in a future article.</p>
<p>For now, you can explore the repository of the project we built together: <a target="_blank" href="https://github.com/rockyessel/battle-showdown">Battle-Showdown</a>, and if you have any question to ask, feel free to reach @rockyessel on X.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tezos Blockchain Development Course ]]>
                </title>
                <description>
                    <![CDATA[ Tezos is a blockchain network that distinguishes itself through a unique self-amending ledger, allowing it to upgrade without the need for hard forks—an approach that promotes continuity and reduces division within the community. Tezos aims to addres... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/tezos-blockchain-development-course/</link>
                <guid isPermaLink="false">663cde3fffe9aa4f76665d0c</guid>
                
                    <category>
                        <![CDATA[ Blockchain development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 09 May 2024 14:31:27 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1715265004149/cfbd8cf4-3748-4291-a058-053aa88df5e6.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Tezos is a blockchain network that distinguishes itself through a unique self-amending ledger, allowing it to upgrade without the need for hard forks—an approach that promotes continuity and reduces division within the community. Tezos aims to address some of the fundamental hurdles encountered by earlier blockchain systems, such as scalability, governance, and upgradeability. The platform operates on a Proof of Stake consensus mechanism, which not only enhances energy efficiency but also enables stakeholders to participate actively in the governance process through "baking," where they validate transactions and add them to the blockchain.</p>
<p>We just posted a comprehensive 12-hour course on the freeCodeCamp.org YouTube channel that is designed to provide an introduction to blockchain technology with a focus on the Tezos ecosystem. It covers everything from the basics of blockchain technology to more advanced topics such as smart contract development and dApp deployment. The only perquisites are a basic understanding of Python. This course was made possible by a grant from Tezos Foundation back in 2022.</p>
<h3 id="heading-what-makes-tezos-unique">What Makes Tezos Unique?</h3>
<p>Tezos supports smart contracts and provides a robust platform for developing decentralized applications (dApps), making it a strong competitor in a landscape dominated by other players like Ethereum. One of the key features of Tezos is its on-chain governance process, where proposed amendments to the protocol can be submitted by developers and voted on by token holders. This democratic approach ensures that the future direction of the network reflects the preferences of its community, helping to prevent contentious forks and ensuring a stable and predictable evolution of the platform.</p>
<h3 id="heading-course-overview">Course Overview</h3>
<p>Here are some of the key sections included in this massive course:</p>
<ul>
<li><p><strong>Introduction to Blockchain and Tezos</strong>: Understand the fundamental concepts of blockchain technology and how Tezos differentiates itself from other blockchain platforms.</p>
</li>
<li><p><strong>Setting Up a Tezos Wallet</strong>: Learn about the different types of wallets available for Tezos, how to set them up, and how to secure your assets.</p>
</li>
<li><p><strong>Smart Contracts on Tezos</strong>: Dive deep into writing and deploying smart contracts. Explore the Tezos-specific languages like Michelson and SmartPy, and learn how to use them to create functional and secure contracts.</p>
</li>
<li><p><strong>Developing Decentralized Applications</strong>: Gain hands-on experience developing dApps on Tezos, understanding the architecture, and connecting the frontend with the Tezos blockchain backend.</p>
</li>
<li><p><strong>Governance and Upgrades</strong>: Learn about the governance process that allows Tezos to evolve smoothly over time, and how you can participate in this process as a developer or a stakeholder.</p>
</li>
</ul>
<p>This course will help you deepen your understanding of blockchain technology and develop the skills necessary to build innovative solutions on Tezos. With its hands-on approach, the course not only teaches theoretical knowledge but also provides practical skills and real-world applications. By the end of this course, you will be proficient in navigating the Tezos ecosystem, developing your own smart contracts, and contributing to the platform’s evolution.</p>
<p>Watch the full course on <a target="_blank" href="https://www.youtube.com/watch?v=pHQfw1W7V8s">the freeCodeCamp.org YouTube channel</a> (12-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/pHQfw1W7V8s" 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[ 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[ 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[ 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[ How to Add a MetaMask Login to Your Laravel Web Application ]]>
                </title>
                <description>
                    <![CDATA[ By Darren Chowles Logging into a website via third parties is ubiquitous online. Almost every other member-based website allows you to log in with accounts like Facebook, Twitter, and Google. If you’ve ever visited NFT marketplaces like OpenSea or Ra... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/add-a-metamask-login-to-your-laravel-app/</link>
                <guid isPermaLink="false">66d45e0055db48792eed3f57</guid>
                
                    <category>
                        <![CDATA[ Laravel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Metamask ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 23 Mar 2022 18:38:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/photo.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Darren Chowles</p>
<p>Logging into a website via third parties is ubiquitous online. Almost every other member-based website allows you to log in with accounts like Facebook, Twitter, and Google.</p>
<p>If you’ve ever visited NFT marketplaces like OpenSea or Rarible, you would have noticed they allow you to sign in with a crypto wallet like MetaMask. </p>
<p>This login process affirms you’re the owner of the Ethereum address in question and allows the system to authenticate your access. Very similar to how a username and password would allow you access to a gated part of a website.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before starting this tutorial, I’ll assume you have a basic understanding of Laravel, and that you can initialise a new project in your environment. Even though this tutorial is Laravel-focused, with some tweaking you can apply this to any other PHP project. The concepts remain the same.</p>
<p>I’ve tried to keep this as generic as possible. I only focus on the MetaMask signing and validation, without restricting you to using it with specific front-end technologies (like React or Vue) or authentication scaffolding (like Breeze or Jetstream). This gives you the freedom to implement it with minimal effort into an existing project.</p>
<p>We’ll need the following before we start:</p>
<ul>
<li>A new or existing Laravel project.</li>
<li><a target="_blank" href="https://metamask.io/">MetaMask</a> installed in your browser.</li>
</ul>
<h2 id="heading-boilerplate">Boilerplate</h2>
<p>We’ll start out with some boilerplate code by importing <a target="_blank" href="https://getbootstrap.com/">Bootstrap 5</a> and creating a simple “Log in with MetaMask” button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-1-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</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">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</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">title</span>&gt;</span>MetaMask Login<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.ethers.io/lib/ethers-5.2.umd.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</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">body</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-12 text-center"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary mt-5"</span>&gt;</span>Log in with MetaMask<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">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">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Easy enough. 😀</p>
<p>We’re also importing the <a target="_blank" href="https://docs.ethers.io/">ethers.js library</a> that will allow us to interact with the Ethereum blockchain via MetaMask, which in this case acts as the interface to the provider (<a target="_blank" href="https://infura.io/">Infura</a> by default).</p>
<h3 id="heading-quick-tip">Quick tip:</h3>
<p>Providers allow us to interact with the Ethereum blockchain. To connect to the network, you need access to a node. Depending on the type of node, it could require a large amount of disk space and bandwidth. Running a node can also be a complex process, especially if you want to focus on development rather than maintaining and operating a node. </p>
<p>Enter, the provider! Companies like Infura provide these nodes as a service, so you don’t need to worry about running your own. Instead, you can access this functionality via their APIs.</p>
<p>You may run into older tutorials that state MetaMask injects web3.js (a library providing similar functionality to ethers.js) into the page by default. This is <a target="_blank" href="https://docs.metamask.io/guide/provider-migration.html#summary-of-breaking-changes">no longer the case</a>.</p>
<h2 id="heading-detect-the-provider">Detect the Provider</h2>
<p>We’ll start off our new <code>web3Login()</code> function by checking that the browser has a provider available. This would be the case if you have MetaMask installed. You can also test this code where MetaMask is not installed (for example, an incognito window) to confirm the detection works.</p>
<p>Add the click event to the button:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary mt-5"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"web3Login();"</span>&gt;</span>Log in with MetaMask<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>And start off the function with our detection snippet in our <code>&lt;head&gt;</code> below the ethers.js import:</p>
<pre><code class="lang-js">&lt;script&gt;
    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">web3Login</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">window</span>.ethereum) {
            alert(<span class="hljs-string">'MetaMask not detected. Please install MetaMask first.'</span>);
            <span class="hljs-keyword">return</span>;
        }
    }
&lt;/script&gt;
</code></pre>
<p>Go ahead and test this in a browser with no MetaMask installed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-2-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-install-laravel-dependencies">Install Laravel Dependencies</h2>
<p>Before we continue with the front-end login process, we need to put some endpoints in place. Our login script will need these so the user can sign a message with their wallet, and our system can then verify their signature.</p>
<p>We need to install two dependencies via Composer to help us perform hashing and use elliptic curve cryptography:</p>
<pre><code class="lang-bash">composer require kornrunner/keccak
composer require simplito/elliptic-php
</code></pre>
<h2 id="heading-add-laravel-routes">Add Laravel Routes</h2>
<p>Open your <strong>routes/web.php</strong> file and add the following routes:</p>
<pre><code class="lang-php">Route::get(<span class="hljs-string">'/web3-login-message'</span>, <span class="hljs-string">'Web3LoginController@message'</span>);
Route::post(<span class="hljs-string">'/web3-login-verify'</span>, <span class="hljs-string">'Web3LoginController@verify'</span>);
</code></pre>
<p>The first route will return the message that needs to be signed, and the second route will verify the signed message.</p>
<h2 id="heading-create-the-login-controller">Create the Login Controller</h2>
<p>Now it’s time to create the controller that will generate the message and perform the verification.</p>
<p>Create a new file called <strong>Web3LoginController.php</strong> in <strong>app/Http/Controllers</strong> and add the following code to it:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Elliptic</span>\<span class="hljs-title">EC</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Str</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">kornrunner</span>\<span class="hljs-title">Keccak</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Web3LoginController</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">message</span>(<span class="hljs-params"></span>): <span class="hljs-title">string</span>
    </span>{
        $nonce = Str::random();
        $message = <span class="hljs-string">"Sign this message to confirm you own this wallet address. This action will not cost any gas fees.\n\nNonce: "</span> . $nonce;

        session()-&gt;put(<span class="hljs-string">'sign_message'</span>, $message);

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

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">verify</span>(<span class="hljs-params">Request $request</span>): <span class="hljs-title">string</span>
    </span>{
        $result = <span class="hljs-keyword">$this</span>-&gt;verifySignature(session()-&gt;pull(<span class="hljs-string">'sign_message'</span>), $request-&gt;input(<span class="hljs-string">'signature'</span>), $request-&gt;input(<span class="hljs-string">'address'</span>));
        <span class="hljs-comment">// If $result is true, perform additional logic like logging the user in, or by creating an account if one doesn't exist based on the Ethereum address</span>
        <span class="hljs-keyword">return</span> ($result ? <span class="hljs-string">'OK'</span> : <span class="hljs-string">'ERROR'</span>);
    }

    <span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">verifySignature</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> $message, <span class="hljs-keyword">string</span> $signature, <span class="hljs-keyword">string</span> $address</span>): <span class="hljs-title">bool</span>
    </span>{
        $hash = Keccak::hash(sprintf(<span class="hljs-string">"\x19Ethereum Signed Message:\n%s%s"</span>, strlen($message), $message), <span class="hljs-number">256</span>);
        $sign = [
            <span class="hljs-string">'r'</span> =&gt; substr($signature, <span class="hljs-number">2</span>, <span class="hljs-number">64</span>),
            <span class="hljs-string">'s'</span> =&gt; substr($signature, <span class="hljs-number">66</span>, <span class="hljs-number">64</span>),
        ];
        $recid = ord(hex2bin(substr($signature, <span class="hljs-number">130</span>, <span class="hljs-number">2</span>))) - <span class="hljs-number">27</span>;

        <span class="hljs-keyword">if</span> ($recid != ($recid &amp; <span class="hljs-number">1</span>)) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }

        $pubkey = (<span class="hljs-keyword">new</span> EC(<span class="hljs-string">'secp256k1'</span>))-&gt;recoverPubKey($hash, $sign, $recid);
        $derived_address = <span class="hljs-string">'0x'</span> . substr(Keccak::hash(substr(hex2bin($pubkey-&gt;encode(<span class="hljs-string">'hex'</span>)), <span class="hljs-number">1</span>), <span class="hljs-number">256</span>), <span class="hljs-number">24</span>);

        <span class="hljs-keyword">return</span> (Str::lower($address) === $derived_address);
    }
}
</code></pre>
<p>There’s a lot going on in there, so let’s break it down:</p>
<h3 id="heading-create-the-message">Create the message</h3>
<p>The <code>message()</code> method creates the message we’ll supply to the front end. It also includes a random token to ensure the message to sign will be different each time.</p>
<p>This token is usually referred to as a nonce, or number used once. In this case, however, it’s a simple random string. </p>
<p>The purpose of this is to prevent <a target="_blank" href="https://en.wikipedia.org/wiki/Replay_attack">replay attacks</a> where, if a malicious user obtained your signature, they could use that to authenticate as you on the website.</p>
<p>The message is then saved to the session and returned to the front end.</p>
<h3 id="heading-verify-the-message">Verify the message</h3>
<p>Once you have signed the message with your private key via MetaMask, your Ethereum address as well as the signature is sent to the back end for verification.</p>
<p>If it passes the verification, we determine the Ethereum address that signed the message and ensure it matches the Ethereum address sent from the front end during the signing process.</p>
<p>If that passes, we send an <strong>OK</strong> or <strong>ERROR</strong> back to the front end.</p>
<p>It’s also at this point where you can add additional logic like logging the member in or creating a new member record if one doesn’t exist for the Ethereum address in question.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/Laravel-Metamask.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-finalise-the-front-end">Finalise the Front End</h2>
<p>Now that the backend is ready, we can complete the rest of the front end. This will involve launching MetaMask, asking the user to sign the message, and then verifying the signature by using our back-end route.</p>
<p>Below is the full <code>web3Login()</code> function:</p>
<pre><code class="lang-js">&lt;script&gt;
    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">web3Login</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">window</span>.ethereum) {
            alert(<span class="hljs-string">'MetaMask not detected. Please install MetaMask first.'</span>);
            <span class="hljs-keyword">return</span>;
        }

        <span class="hljs-keyword">const</span> provider = <span class="hljs-keyword">new</span> ethers.providers.Web3Provider(<span class="hljs-built_in">window</span>.ethereum);

        <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'/web3-login-message'</span>);
        <span class="hljs-keyword">const</span> message = <span class="hljs-keyword">await</span> response.text();

        <span class="hljs-keyword">await</span> provider.send(<span class="hljs-string">"eth_requestAccounts"</span>, []);
        <span class="hljs-keyword">const</span> address = <span class="hljs-keyword">await</span> provider.getSigner().getAddress();
        <span class="hljs-keyword">const</span> signature = <span class="hljs-keyword">await</span> provider.getSigner().signMessage(message);

        response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'/web3-login-verify'</span>, {
            <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
            <span class="hljs-attr">headers</span>: {
                <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
            },
            <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
                <span class="hljs-string">'address'</span>: address,
                <span class="hljs-string">'signature'</span>: signature,
                <span class="hljs-string">'_token'</span>: <span class="hljs-string">'{{ csrf_token() }}'</span>
            })
        });
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.text();

        <span class="hljs-built_in">console</span>.log(data);
    }
&lt;/script&gt;
</code></pre>
<p>Let’s break it down:</p>
<ul>
<li>We first set the provider to the MetaMask provided <code>window.ethereum</code>.</li>
<li>Next, we grab the message returned from our back end (refresh the page a few times to try this out, you will notice the random token changes every time).</li>
<li>Once we have the message, we obtain the user’s Ethereum address and ask them to sign the message.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/image-3-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li>We then POST the address and signature to the back end (along with our Laravel CRSF token) for verification.</li>
<li>The result is either an <strong>OK</strong> or <strong>ERROR</strong> string which we output in the console.</li>
<li>At this point you may elect to show an error message (if applicable) or redirect the user if they were registered or logged in during the back-end verification.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial we covered the basics of adding a MetaMask login to your website. I hope this has proven useful! <a target="_blank" href="https://webdev.chowles.com/">Sign up to my newsletter</a> or <a target="_blank" href="https://www.chowles.com/">visit my blog</a> where I’ll share insightful web development articles to supercharge your skills.</p>
<p>Here are some ideas to take your integration one step further:</p>
<ul>
<li>Integrate a library like <a target="_blank" href="https://github.com/web3modal/web3modal">Web3Modal</a> to provide users with various wallet options instead of only MetaMask.</li>
<li>With the user’s Ethereum address validated, provide them with functions like displaying their ETH balance.</li>
</ul>
<h3 id="heading-resources">Resources</h3>
<ul>
<li>Download <a target="_blank" href="https://metamask.io/">MetaMask</a>.</li>
<li>View the <a target="_blank" href="https://docs.ethers.io/">ethers.js documentation</a>.</li>
<li>Latest <a target="_blank" href="https://laravel.com/docs">Laravel documentation</a>.</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp Just Got a Million Dollar Donation from an Alum to Build a Carbon-Neutral Web3 Curriculum ]]>
                </title>
                <description>
                    <![CDATA[ A freeCodeCamp alum who founded his own successful Web3 company has donated $1M to freeCodeCamp He asked that we use some of these funds to develop a carbon-neutral Web3 curriculum We are building an interactive Web3 curriculum where you can learn by... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/carbon-neutral-web3-curriculum-plans/</link>
                <guid isPermaLink="false">66b8d2640c9c1d363b7c420d</guid>
                
                    <category>
                        <![CDATA[ freeCodeCamp Curriculum ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Quincy Larson ]]>
                </dc:creator>
                <pubDate>Wed, 19 Jan 2022 21:23:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/christian-wiediger-WkfDrhxDMC8-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <ul>
<li>A freeCodeCamp alum who founded his own successful Web3 company has donated $1M to freeCodeCamp</li>
<li>He asked that we use some of these funds to develop a carbon-neutral Web3 curriculum</li>
<li>We are building an interactive Web3 curriculum where you can learn by building more than a dozen projects. This free curriculum will teach the fundamentals of smart contracts and distributed application development.</li>
<li>This will be a stand-alone curriculum that you can choose to tackle whenever you feel ready. The prerequisites will involve learning full stack web development through the first 7 freeCodeCamp certifications. (Though as with all aspects of freeCodeCamp, you're welcome to skip around.)</li>
<li>Our goal is to help people learn these skills so they can get one of the thousands of open jobs that require these technologies, or start entrepreneurial projects of their own.</li>
</ul>
<h2 id="heading-nathans-story">Nathan's Story</h2>
<p>Nathan Flickinger was a college dropout. After a period of homelessness, he vowed to get his life together. It started with using his CompTIA certification he had earned in high school to get a minimum wage job in tech support.</p>
<p>From there, Nathan decided to teach himself to code. After several months of study on freeCodeCamp, he was able to land his first software engineering job.</p>
<p>He became obsessed with Web3 development, and eventually took the plunge and created his own startup. He helped write smart contract code for several Web3 projects. Most notably, KaijuKingz, a monster-inspired collection of cute lizards, each with quirky features. Instead of coffee, they drink radioactive sludge.</p>
<p>People from the KaijuKingz community buy and trade these artistic works through a system called Non-fungible Tokens – essentially, deeds of ownership.</p>
<p>Instead of being stored in a centralized database, these deeds are backed up in computers around the world through a distributed database.</p>
<p>Early on, Nathan decided that if his project was successful, he wanted to donate a large amount of money to freeCodeCamp to help other people to learn how to harness technology to realize their career potential.</p>
<p>And today, he and KaijuKingz have done that. They have donated a million dollars to our nonprofit, for us to use toward our mission of creating free learning resources for people around the world.</p>
<p>I am extremely grateful for Nathan and his colleagues at KaijuKingz, and their willingness to support free, open source education. You can <a target="_blank" href="https://www.freecodecamp.org/news/donating-a-million-dollars-to-freecodecamp-a-web3-curriculum">read more about Nathan and his coding journey here</a>.</p>
<h2 id="heading-the-web3-curriculum">The Web3 Curriculum</h2>
<p>This free curriculum will teach the fundamentals of smart contracts and distributed application development.</p>
<p>It will be a stand-alone curriculum that you can choose to tackle whenever you feel ready. The prerequisites will involve learning full stack web development through the first 7 freeCodeCamp certifications.</p>
<p>We will build this curriculum using the same tools we used to build freeCodeCamp's <a target="_blank" href="https://www.freecodecamp.org/news/how-to-run-freecodecamps-relational-databases-curriculum-using-docker-vscode-and-coderoad/">Relational Database Curriculum</a>. It will teach you Web3 development through building more than a dozen projects.</p>
<h2 id="heading-frequently-asked-questions">Frequently Asked Questions</h2>
<h3 id="heading-how-will-this-be-carbon-neutral">How will this be carbon neutral?</h3>
<p>Since all of the development will take place on your own computer and use local blockchains, there will be no carbon emissions. All of freeCodeCamp's cloud servers are already carbon-neutral.</p>
<h3 id="heading-will-all-of-this-be-free-including-the-blockchain-transactions">Will all of this be free? Including the blockchain transactions?</h3>
<p>Yes. Again, this curriculum will use local blockchains. You will never have to buy any coins or tokens.</p>
<h3 id="heading-will-this-curriculum-discuss-aspects-of-speculation">Will this curriculum discuss aspects of speculation?</h3>
<p>No. This curriculum will be 100% focused on software engineering.</p>
<h3 id="heading-when-will-this-curriculum-go-live">When will this curriculum go live?</h3>
<p>We hope to have parts of this curriculum live as early as Summer 2022. In the meantime, we recommend learning web development using the existing freeCodeCamp curriculum.</p>
<p>One way to think about Web3 development is that it's mostly traditional web development with a lot of additional tools for using distributed networks. So everything you learn for traditional web development will also be applicable here.</p>
<h3 id="heading-what-about-the-data-science-curriculum">What about the Data Science curriculum?</h3>
<p>The Data Science curriculum is coming along great, and we hope to publish parts of it in the next few months. The Web3 curriculum shouldn't affect the development of the Data Science curriculum – they are being built by separate teams of teachers and developers.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Donating a Million Dollars to freeCodeCamp to Develop a Free, Carbon-Neutral Web3 Curriculum ]]>
                </title>
                <description>
                    <![CDATA[ By Nathan Flickinger I am a freeCodeCamp alumnus. I learned to code on freeCodeCamp. I used these skills to build a profitable company. Today, this company – KaijuKingz – is donating $1 million to freeCodeCamp to help them create even more free learn... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/donating-a-million-dollars-to-freecodecamp-a-web3-curriculum/</link>
                <guid isPermaLink="false">66d46040677cb8c6c15f3165</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ community ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 19 Jan 2022 21:23:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/kaijuxcode.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nathan Flickinger</p>
<p>I am a freeCodeCamp alumnus. I learned to code on freeCodeCamp. I used these skills to build a profitable company.</p>
<p>Today, this company – KaijuKingz – is donating $1 million to freeCodeCamp to help them create even more free learning resources.</p>
<p>The freeCodeCamp community has helped me and thousands of other people learn to code by building projects. To set the scene for our donation, I would like to give you some context into my own developer journey – from stumbling upon freeCodeCamp to breaking into Web3.</p>
<p>This is my story.</p>
<h2 id="heading-from-tinkerer-to-drop-out"><strong>From Tinkerer to Drop-Out</strong></h2>
<p>I was interested in programming from an early age. I would make simple IF-ELSE text-based adventure games for my girlfriend in high school. I guess in my mind, I was some sort of leet developer.</p>
<p>Unfortunately, my school didn't offer any paths to explore programming at the time. Despite this, I did my best to build my skills. I got heavily involved in a computer systems course that allowed students to get certifications like CompTIA, A+, and Net+.</p>
<p>When I was able to go to college, I decided to pursue a CS degree, but I quickly fell behind. Textbooks were expensive. I faced an overall lack of resources. I ended up dropping out.</p>
<p>After struggling with motivation and being homeless for a while, I resolved to get my life back in order.</p>
<h2 id="heading-clawing-my-way-back"><strong>Clawing My Way Back</strong></h2>
<p>I was able to leverage my CompTIA certification to land my first job as a minimum wage computer tech at a large retailer. I dove deeper and deeper into the field, and worked my way up with consistent effort.</p>
<p>I worked my way up to a level-two-support role in the IT department of a large health center. This is where I rediscovered my love for programming and began simple automation tasks. I started writing scripts in Visual Basic. PowerShell became my tool of choice for automating tasks. Little by little I grew into the field.</p>
<p>This is when I first considered learning to become a full-stack developer. I would research tools and dream of the day I could attend a coding bootcamp and become some super awesome full stack developer.</p>
<p>This is when I first discovered free resources like freeCodeCamp and the many YouTube channels that were teaching development. (Shout out to Sentdex &lt;3).</p>
<p>In 2019, I completed the freeCodeCamp Responsive Web Design certification course. I would always check back on freeCodeCamp to read new tutorials and watch some of the new video courses the community created each day. It was fun, I was learning a ton, and it didn't cost me a single penny.</p>
<h2 id="heading-from-my-first-software-engineer-job-to-starting-my-first-company"><strong>From My First Software Engineer Job to Starting My First Company</strong></h2>
<p>In 2020, I landed my first software engineering job working on an eCommerce platform. I continued to sharpen my skills.</p>
<p>Fast Forward to six months ago – I decided to dedicate all my time toward learning the Web3 space, with a focus on decentralization and community building. The result: KaijuKingz.</p>
<p><img src="https://lh4.googleusercontent.com/HksSNM6Vm1K635EdBVlDwlMCHhRG3FamNt9lgWyfydvjHsW7xiZPlQcKgF-HSDsucgxqon49qRxXVmaFKdK_icSidKIWA5wsh6LKeNr_w4S0T-a9xQdjanAPMpHbWJb4SWB_CL-q" alt="Image" width="1052" height="334" loading="lazy">
<em>The KaijuKingz logo, inspired by traditional Japanese brush stroke technique</em></p>
<p>When creating KaijuKingz, my team decided to set aside some funds for other aspiring developers and creators to learn Web3. We planned on raising enough money to maybe send 3-4 people to a coding boot camp, hopefully change someone's life, and call it a day.</p>
<p>After our success, we realized we had the opportunity to impact more people's lives than we had initially planned. So we reached out to Quincy to discuss how we could leverage our funds and build a Web3 program for aspiring developers. We wanted to help people who were passionate about decentralization and community-owned technology.</p>
<p>We decided to go all-in with his team and their track record for developing effective courses and certifications accessible by anyone in the world.</p>
<h2 id="heading-plans-for-the-upcoming-freecodecamp-web3-curriculum"><strong>Plans for the Upcoming freeCodeCamp Web3 Curriculum</strong></h2>
<p>Our million-dollar donation will go toward building an entire curriculum on Web3 development. It will cover everything from the basics of programming with Rust and Solidity, to using JavaScript libraries like web3.js.</p>
<p>This curriculum will ultimately provide around 300 hours of free learning to help people go from zero to hero with Web3. The only thing learners will need is access to a computer, and the discipline to complete the curriculum. freeCodeCamp's existing Web2 development curriculum will teach you all of the necessary prerequisite tools.</p>
<p>Quincy and I both feel strongly about the environment. And this curriculum will be carbon-neutral.</p>
<p>I have fundamentally changed my life by learning programming through free resources. Giving back to one of the most comprehensive and effective resources for learning programming (while helping upgrade their curriculum for the future) has given me a purpose. Instead of changing one person's life with this, we hope to change thousands of people's lives, and to bring new developers to the Web3 ecosystem.</p>
<p>Thank you to freeCodeCamp, to the KaijuKingz community who have supported us, and to everyone who's helping build the decentralized future.</p>
<p>Cheers,<br>Nathan</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Web3? The Decentralized Internet of the Future Explained ]]>
                </title>
                <description>
                    <![CDATA[ By Nader Dabit If you’re reading this then you are a participant in the modern web. The web we are experiencing today is much different than what it was just 10 years ago. How has the web evolved, and more importantly – where is it going next? Also, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-web3/</link>
                <guid isPermaLink="false">66d4604be39d8b5612bc0dd0</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ decentralization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ decentralized apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 08 Sep 2021 21:09:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/web3-future-of-web.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nader Dabit</p>
<p>If you’re reading this then you are a participant in the modern web. The web we are experiencing today is much different than what it was just 10 years ago. How has the web evolved, and more importantly – where is it going next? Also, why do any of these things matter?</p>
<p>If history has taught us anything, these changes will matter a lot. </p>
<p>In this article, I will lay out how the web has evolved, where's it going next, and why this matters.</p>
<p>Think about how the internet affects your life on a daily basis. Consider how society has changed as a result of the internet. Social media platforms. Mobile apps. And now the internet is going through another paradigm shift as we speak.</p>
<h2 id="heading-the-evolution-of-the-web"><strong>The Evolution of the Web</strong></h2>
<p>The web has evolved a lot over the years, and the applications of it today are almost unrecognizable from its most <a target="_blank" href="https://en.wikipedia.org/wiki/History_of_the_Internet">early days</a>. The evolution of the web is often partitioned into three separate stages: Web 1.0, Web 2.0, and Web 3.0.</p>
<h3 id="heading-what-is-web-10"><strong>What is Web 1.0?</strong></h3>
<p>Web 1.0 was the first iteration of the web. Most participants were consumers of content, and the creators were typically developers who build websites that contained information served up mainly in text or image format. Web 1.0 lasted approximately from 1991 to 2004.</p>
<p>Web 1.0 consisted of sites serving static content instead of dynamic HTML. Data and content were served from a static file system rather than a database, and sites didn't have much interactivity at all.</p>
<p>You can think of Web 1.0 as the read-only web.</p>
<h3 id="heading-what-is-web-20"><strong>What is Web 2.0?</strong></h3>
<p>Most of us have primarily experienced the web in its current form, commonly referred to as <a target="_blank" href="https://en.wikipedia.org/wiki/Web_2.0#top">web2</a>. You can think of web2 as the interactive and social web.</p>
<p>In the web2 world, you don’t have to be a developer to participate in the creation process. Many apps are built in a way that easily allows anyone to be a creator.</p>
<p>If you want to craft a thought and share it with the world, you can. If you want to upload a video and allow millions of people to see it, interact with it, and comment on it, you can do that too.</p>
<p>Web2 is simple, really, and because of its simplicity more and more people around the world are becoming creators.</p>
<p>The web in its current form is really great in many ways, but there are some areas where we can do a lot better.</p>
<h3 id="heading-web-20-monetization-and-security"><strong>Web 2.0 Monetization and Security</strong></h3>
<p>In the web2 world, many popular apps are following a common pattern in their life cycles. Think of some of the apps that you use on a daily basis, and how the following examples might apply to them.</p>
<h4 id="heading-monetization-of-apps"><strong>Monetization of Apps</strong></h4>
<p>Imagine the early days of popular applications like Instagram, Twitter, LinkedIn, or YouTube and how different they are today. The process usually goes something like this:</p>
<ol>
<li>Company launches an app</li>
<li>It onboards as many users as possible</li>
<li>Then it monetizes its user base</li>
</ol>
<p>When a developer or company launches a popular app, the user experience is often very slick as the app continues rising in popularity. This is the reason they are able to gain traction quickly in the first place.</p>
<p>At first, many software companies do not worry about monetization. They strictly focus on growth and on locking in new users – but eventually they have to start turning a profit.</p>
<p>They also need to consider the role of outside investors. Often the constraints of taking on things like venture capital negatively affect the life cycle, and eventually the user experience, of many applications that we use today.</p>
<p>If a company building an application takes in venture capital, its investors often expect a return on investment in the order of magnitude of tens or hundreds of what they paid in.</p>
<p>This means that, instead of going for some sustainable model of growth that they can sustain in a somewhat organic manner, the company is often pushed towards two paths: advertisements or selling personal data.</p>
<p>For many web2 companies like Google, Facebook, Twitter, and others, more data leads to more personalized ads. This leads to more clicks and ultimately more ad revenue. The exploitation and centralization of user data is core to how the web as we know and use it today is engineered to function.</p>
<h4 id="heading-security-and-privacy"><strong>Security and privacy</strong></h4>
<p>Web2 applications repeatedly experience <a target="_blank" href="https://en.wikipedia.org/wiki/List_of_data_breaches">data breaches</a>. There are even <a target="_blank" href="https://haveibeenpwned.com/">websites</a> dedicated to keeping up with these breaches and telling you when your data has been compromised.</p>
<p>In web2, you don’t have any control over your data or how it is stored. In fact, companies often track and save user data without their users' consent. All of this data is then owned and controlled by the companies in charge of these platforms.</p>
<p>Users who live in countries where they have to worry about the negative consequences of free speech are also at risk.</p>
<p>Governments will often shut down servers or seize bank accounts if they believe a person is voicing an opinion that goes against their propaganda. With centralized servers, it is easy for governments to intervene, control, or shut down applications as they see fit.</p>
<p>Because banks are also digital and under centralized control, governments often intervene there as well. They can shut down access to bank accounts or limit access to funds during times of volatility, extreme inflation, or other political unrest.</p>
<p>Web3 aims to solve many of these shortcomings by fundamentally rethinking how we architect and interact with applications from the ground up.</p>
<h2 id="heading-what-is-web-30"><strong>What is Web 3.0?</strong></h2>
<p>There are a few fundamental differences between web2 and web3, but decentralization is at its core.</p>
<p>Web3 enhances the internet as we know it today with a few other added characteristics. web3 is:</p>
<ul>
<li>Verifiable</li>
<li>Trustless</li>
<li>Self-governing</li>
<li>Permissionless</li>
<li>Distributed and robust</li>
<li>Stateful</li>
<li>Native built-in payments</li>
</ul>
<p>In web3, developers don't usually build and deploy applications that run on a single server or that store their data in a single database (usually hosted on and managed by a single cloud provider).</p>
<p>Instead, web3 applications either run on blockchains, decentralized networks of many peer to peer nodes (servers), or a combination of the two that forms a <a target="_blank" href="https://thegraph.com/blog/modeling-cryptoeconomic-protocols-as-complex-systems-part-1">cryptoeconomic protocol</a>. These apps are often referred to as dapps (decentralized apps), and you will see that term used often in the web3 space.</p>
<p>To achieve a stable and secure decentralized network, network participants (developers) are incentivized and compete to provide the highest quality services to anyone using the service.</p>
<p>When you hear about web3, you'll notice that cryptocurrency is often part of the conversation. This is because cryptocurrency plays a big role in many of these protocols. It provides a financial incentive (tokens) for anyone who wants to participate in creating, governing, contributing to, or improving one of the projects themselves.</p>
<p>These protocols may often offer a variety of different services like compute, storage, bandwidth, identity, hosting, and other web services commonly provided by cloud providers in the past.</p>
<p>People can make a living by participating in the protocol in various ways, in both technical and non-technical levels.</p>
<p>Consumers of the service usually pay to use the protocol, similarly to how they would pay a cloud provider like AWS today. Except in web3, the money goes directly to the network participants.</p>
<p>In this, like in many forms of decentralization, you'll see that unnecessary and often inefficient intermediaries are cut out.</p>
<p>Many web infrastructure protocols like <a target="_blank" href="https://filecoin.io/blog/filecoin-circulating-supply/">Filecoin</a>, <a target="_blank" href="https://livepeer.com/">Livepeer</a>, <a target="_blank" href="https://www.arweave.org/">Arweave</a>, and <a target="_blank" href="https://thegraph.com/blog/the-graph-grt-token-economics">The Graph</a> (which is what I work with at Edge &amp; Node) have issued utility tokens that govern how the protocol functions. These tokens also reward participants at many levels of the network. Even native blockchain protocols like <a target="_blank" href="https://ethereum.org/en/">Ethereum</a> operate in this manner.</p>
<h3 id="heading-native-payments"><strong>Native payments</strong></h3>
<p>Tokens also introduce a native payment layer that is completely borderless and frictionless. Companies like Stripe and Paypal have created billions of dollars of value in enabling electronic payments.</p>
<p>These systems are overly complex and still do not enable true international interoperability between participants. They also require you to hand over your sensitive information and personal data in order to use them.</p>
<p>Crypto <a target="_blank" href="https://everest.link/category/0xc00f480db7754ce2e0f992a1080598e53fc511a0/">wallets</a> like <a target="_blank" href="https://metamask.io/">MetaMask</a> and <a target="_blank" href="https://toruswallet.io/">Torus</a> enable you to integrate easy, anonymous, and secure international payments and transactions into web3 applications.</p>
<p>Networks like Solana offer several hundred digit millisecond latency and transaction costs of a small fraction of a penny. Unlike the current financial system, users do not have to go through the traditional numerous, friction-filled steps to interact with and participate in the network. All they need to do is download or install a wallet, and they can start sending and receiving payments without any gatekeeping.</p>
<h3 id="heading-a-new-way-of-building-companies"><strong>A new way of building companies</strong></h3>
<p>Tokens also brings about the idea of tokenization and the realization of a <a target="_blank" href="https://www.oreilly.com/library/view/what-is-the/9781492072973/ch01.html">token economy</a>.</p>
<p>Take, for example, the current state of building a software company. Someone comes up with an idea, but in order to start building they need money in order to support themselves.</p>
<p>To get the money, they take on venture capital and give away a percentage of the company. This investment immediately introduces mis-aligned incentives that will, in the long run, not align well with building out the best user experience.</p>
<p>Also, if the company ever does become successful, it will take a very long time for anyone involved to realize any of the value, often leading to years of work without any real return on investment.</p>
<p>Imagine, instead, that a new and exciting project is announced that solves a real problem. Anyone can participate in building it or investing in it from day one. The company announces the release of x number of tokens, and give 10% to the early builders, put 10% for sale to the public, and set the rest aside for future payment of contributors and funding of the project.</p>
<p>Stakeholders can use their tokens to vote on changes to the future of the project, and the people who helped build the project can sell some of their holdings to make money after the tokens have been released.</p>
<p>People who believe in the project can buy and hold ownership, and people who think the project is headed in the wrong direction can signal this by selling their stake.</p>
<p>Because blockchain data is all completely public and open, purchasers have complete transparency over what is happening. This is in contrast to buying equity in private or centralized businesses where many things are often cloaked in secrecy.</p>
<p>This is already happening in the web3 space.</p>
<p>One example is the app <a target="_blank" href="https://radicle.xyz/blog/introducing-rad.html">Radicle</a> (a decentralized GitHub alternative) which allows stakeholders to participate in the <a target="_blank" href="https://everest.link/category/0x46aff9a161267c2c01f5ce1b6e3b717a77f21480/">governance</a> of their project. <a target="_blank" href="https://gitcoin.co/">Gitcoin</a> is another that allows developers to get paid in cryptocurrency for jumping in and working on Open Source issues. <a target="_blank" href="https://docs.yearn.finance/faq#governance">Yearn</a> allows stakeholders to participate in decision making and voting on proposals. <a target="_blank" href="https://uniswap.org/blog/uni/">Uniswap</a>, <a target="_blank" href="https://superrare.com/rare">SuperRare</a>, <a target="_blank" href="https://thegraph.com/blog/the-graph-grt-token-economics">The Graph</a>, <a target="_blank" href="https://audius.co/">Audius</a>, and countless other protocols and projects have issued tokens as a way to enable ownership, participation, and governance.</p>
<p><a target="_blank" href="https://linda.mirror.xyz/Vh8K4leCGEO06_qSGx-vS5lvgUqhqkCz9ut81WwCP2o">DAOs</a> (Decentralized Autonomous Organizations), which offer an alternative way to build what we traditionally thought of as a company, are gaining tremendous momentum and investment from both traditional developers and venture capital firms. </p>
<p>These types of organizations are tokenized and turn the idea of organizational structure on its head, offering real, liquid, and equitable ownership to larger portions of stakeholders and aligning incentives in new and interesting ways. </p>
<p>For example, <a target="_blank" href="https://www.fwb.help/">Friends with Benefits</a> is a DAO of web3 builders and artists, is about a year old, has a market cap of around $125 million as of this writing, and recently received <a target="_blank" href="https://tittlepress.com/crypto/1146487/">a $10 million round</a> of investment from <a target="_blank" href="https://a16z.com/">a16z</a>. </p>
<p>DAOs could encompass an entire post in and of themselves, but for now I'll just say that I think that they are the future of building products and (what we in the past thought of as) companies. <a target="_blank" href="https://coopahtroopa.mirror.xyz/_EDyn4cs9tDoOxNGZLfKL7JjLo5rGkkEfRa_a-6VEWw">Here is a good post</a> outlining the current DAO landscape.</p>
<h3 id="heading-how-identity-works-in-web3"><strong>How Identity Works in Web3</strong></h3>
<p>In web3, <a target="_blank" href="http://sinahab.com/identity-and-reputation-in-web-3/">Identity</a> also works much differently than what we are used to today. Most of the time in web3 apps, identities will be tied to the wallet address of the user interacting with the application.</p>
<p>Unlike web2 authentication methods like OAuth or email + password (that almost always require users to hand over sensitive and personal information), wallet addresses are completely anonymous unless the user decides to tie their own identity to it publicly.</p>
<p>If the user chooses to use the same wallet across multiple dapps, their identity is also seamlessly transferable across apps, which lets them build up their reputation over time.</p>
<p>Protocols and tools like <a target="_blank" href="https://ceramic.network/">Ceramic</a> and <a target="_blank" href="https://idx.xyz/">IDX</a> already allow developers to build self-sovereign identity into their applications to replace traditional authentication and identity layers. The Ethereum foundation also has <a target="_blank" href="https://notes.ethereum.org/@djrtwo/sign-in-with-ethereum-RFP">a working RFP</a> for defining a specification for "Sign in with Ethereum" which would help provide a more streamlined and documented way to do this going forward. <a target="_blank" href="https://twitter.com/BrantlyMillegan/status/1402388133086367751">This</a> is also a good thread that outlines some of the ways that this would enhance traditional authentication flows.</p>
<h2 id="heading-how-to-build-on-web3"><strong>How to Build on Web3</strong></h2>
<p>I'm a developer who recently transitioned into the web3 space from a traditional development background. So I wanted to start building to get a sense of what the development experience felt like. And I wanted to get an understanding of the types of apps that we can build today.</p>
<p>I dove right in and decided to document some of the things I was doing in a couple of blog posts.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/breaking-into-ethereum-crypto-web3-as-a-developer/">How to Get Into Ethereum, Crypto, and Web3 as a Developer</a> – This is an introduction to the space in general, coming from a developer, for developers looking to break into the industry.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/full-stack-ethereum-development/">The Complete Guide to Full Stack Ethereum Development</a> – This is a tutorial that teaches you how to build out your first dapp.</p>
<p><a target="_blank" href="https://dev.to/dabit3/the-complete-guide-to-full-stack-solana-development-with-react-anchor-rust-and-phantom-3291">The Complete Guide to Full Stack Solana Development with React, Anchor, Rust, and Phantom</a> - This guide dives into Solana to show you how to build a full stack dapp.</p>
<p>If you are interested in learning more about web3 in general, you can check out these posts:</p>
<p><a target="_blank" href="https://dev.to/dabit3/the-new-creator-economy-daos-community-ownership-and-cryptoeconomics-lnl">The New Creator Economy - DAOs, Community Ownership, and Cryptoeconomics</a></p>
<p><a target="_blank" href="https://www.notboring.co/p/the-value-chain-of-the-open-metaverse">The Value Chain of the Open Metaverse</a></p>
<p><a target="_blank" href="https://coopahtroopa.mirror.xyz/gWY6Kfebs9wHdfoZZswfiLTBVzfKiyFaIwNf2q8JpgI">The Rise of Micro-Economies</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The New Creator Economy – DAOs, Community Ownership, and Cryptoeconomics ]]>
                </title>
                <description>
                    <![CDATA[ By Nader Dabit I first had what I can only describe as a spiritual awakening about 10 years ago to the fact that technology would (figuratively) rule the world. And since then, I've been obsessed with wanting to understand how software works and how ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-new-creator-economy-daos-community-ownership-and-cryptoeconomics/</link>
                <guid isPermaLink="false">66d46049e39d8b5612bc0dcc</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ community ]]>
                    </category>
                
                    <category>
                        <![CDATA[ crypto ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ethereum ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 27 Aug 2021 17:02:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/democratize.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nader Dabit</p>
<p>I first had what I can only describe as a spiritual awakening about 10 years ago to the fact that technology would (figuratively) rule the world. And since then, I've been obsessed with wanting to understand how software works and how to build it.</p>
<p>Since that moment, my life has changed significantly for the better. I can only attribute it to the simple fact that I have relied not only on my own instincts, but on those of people much smarter and more experienced than I am.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/kissingsky/status/1428368687644364805"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>My hypothesis is this: try to find and follow the lead of those who have exhibited a long track record of success, find interests in their wake, and do my best to excel at them (while continuing to explore my own curiosities).</p>
<p>This approach has led me to try and master JavaScript, and then React, and finally to build a successful consultancy. All this ultimately landed me on a team at AWS in a life changing experience that lasted a little over 3 years. All of this with <a target="_blank" href="https://twitter.com/dabit3/status/1259471051429478400">no high school diploma or college degree</a>.</p>
<p>During this time (like many developers) I've relentlessly dived into books, podcasts, blog posts, YouTube videos, and source code of every kind. But there has always been a topic that has captured my curiosity the most – futurism.</p>
<p>Futurists like <a target="_blank" href="https://twitter.com/gleonhard">Gerd Leonhard</a> and <a target="_blank" href="https://twitter.com/michiokaku">Michio Kaku</a> speak of a future that's sometimes beautiful and sometimes bleak. But it's always with the passion and phrasing that make your thoughts wander and move past the current moment in time and into a mind boggling world that does not yet exist.</p>
<p>I recently had another "aha" moment, similar to my technological awakening, that has completely changed the direction of my career and my life. In the spirit of these futurists, I want to talk about why <a target="_blank" href="https://www.freecodecamp.org/news/what-is-web3/">Web3</a> excites me just as much as their ideas, but is instead happening as we speak.</p>
<h2 id="heading-why-is-web3-so-exciting">Why is Web3 So Exciting?</h2>
<p>This post is meant to dive more into what I think are the benefits and repercussions of Web3. If you want to know my interpretation of what Web3 is, see my thoughts <a target="_blank" href="https://www.freecodecamp.org/news/what-is-web3/">here</a>.</p>
<p>Web3 represents a handful of ideas which together bring about entirely new mental models, organizational structures, and community incentives. These force us to rethink many things that we have become accustomed to.</p>
<p>All of the recent innovation happening is possible because of decentralized protocols. The internet itself has thrived because of native internet protocols that we use everyday, like HTTP, FTP, TCP, and SSH. </p>
<p>One of the reasons these protocols have been so successful was that they were widely adopted and not subject to change. If I build a site using HTTP, people can use it without any centralized intermediary – we can trust that it is going to work.</p>
<p>There are two major pieces of native functionality that have been left out up until recently – payments and state.</p>
<p>Blockchains have enabled both of these things, opening the door for programmable money and state without the need of a centralized server, bank, or any intermediary at all.</p>
<h3 id="heading-web3-enables-ownership">Web3 Enables Ownership</h3>
<p>One of the driving forces and the one that resonates with most people (and me) is that Web3 enables ownership.</p>
<h4 id="heading-gaming">Gaming</h4>
<p>At some point the internet and gaming became almost indistinguishable. Not only because most games continue to receive updates over time, but the most popular ones are often the most interactive ones.</p>
<p>Fortnite took a lot of people by surprise because it created an innovative new combination of gameplay, peer-to-peer connection, and a unique business model – and everyone gets the game for free. </p>
<p>The experience is very interactive, you can join old friends and make new ones, there are constant improvements and enhancements that just happen automatically – the game is consistently evolving.</p>
<p>The monetization strategy was also innovative. Fortnite allows players to buy in-game currency as well as skins that they can wear in the game. If you have a child you know that the $65 you may have spent on the game itself is probably peanuts compared to the amount of money kids spend over the lifetime of their gameplay.</p>
<p>The problem, though, is this: when the player decides to stop playing the game or outgrows it, where has all that money gone? More importantly, who is allowed as a creator to benefit from all of the purchasing power? The answer is, well, Fortnite (the platform).</p>
<p>What if, instead, players retained ownership of their items and were able to keep or sell them? Their items would maintain, increase, or decrease in value like any physical asset. </p>
<p>These types of experiences and communities are now being made possible via NFTs. NFTs enable scarcity in a world where there was in the past no scarcity.</p>
<p><a target="_blank" href="https://axieinfinity.com/">Axie Infinity</a> is an example of how this looks in practice. It is a blockchain-based game that is the most successful of its kind, and has recently had explosive growth, catapulting it to over <a target="_blank" href="https://hypebeast.com/2021/8/axie-infinity-ethereum-first-nft-game-1-bilion-sales-info">$1 billion in sales</a> with over $780 million in the 30 days ending August 10 2021.</p>
<p><a target="_blank" href="https://parallel.life/faq/">Parallel</a> is an online card game that has done over $100 million in sales and is still extremely early. <a target="_blank" href="https://zkga.me/">Dark Forest</a> enables players to <a target="_blank" href="https://twitter.com/BlaineBublitz/status/1399397415732400129">get paid to play the game</a>.</p>
<p>When players realize they can retain much of the value of their time and investments while still enjoying the benefit of the game, it changes the way they view gaming and where they spend their money. But it also aligns new incentives around the game itself. If the game succeeds, they can share in that success, therefore they become even more invested.</p>
<p>The combination of ownership, community, and creators who have built audiences creates a whirlwind of new and exciting opportunities that we are just starting to begin see explored.</p>
<p><a target="_blank" href="https://twitter.com/Fwiz">Ryan Watt</a>, the head of YouTube gaming agrees.</p>
<h3 id="heading-social-media-and-art">Social media and art</h3>
<p>Social media platforms were revolutionary. They allowed anyone from almost any background the ability to grow and foster large audiences using tools that were made free to anyone with a device and an internet connection. </p>
<p>There are no gatekeepers to becoming famous on social media as there have been in the past in film and TV. The intermediary was abstracted away and peer to peer connections and content sharing was made possible.</p>
<p>The flaw in these implementations is that they offer a terrible monetization system, not just for the platform but for the creator as well. </p>
<p>Advertising and the exploitation of user data is the go to play. Also almost all of the money generated by the platform, goes to the platform – the platform monetizes the content being created by its users in exchange for use of the platform itself. This is how social media works today.</p>
<p>In Web3, both creators and the community are able to gain and retain ownership within a platform, creating a synergy that, once experienced, makes the legacy interactions of the past seem archaic and undesirable. </p>
<p>When I say ownership, I don't only mean ownership of content, but actual equity as well.</p>
<p>We are seeing the beginnings of this in the art world of Web3. Artists who were, in the past, often barely making it are now able to leverage their platforms, often in collaboration with other community members or causes. They can create projects that leverage NFT collections to give community members as well as the public a way to participate and distribute equity all around. Art and code are also beginning to overlap.</p>
<p>Projects like <a target="_blank" href="https://generativemasks.on.fleek.co/#/">Generative Masks</a> allow talented creators like <a target="_blank" href="https://twitter.com/takawo">Takawo Shunsuke</a> to leverage the skills he's acquired throughout his career to generate over $3 million in sales for his collection in just a few minutes. He's able to spread awareness for himself and his cause, and create another new community (of owners) simultaneously. </p>
<p>The best part is that he's giving it all back to the communities he's benefited from. On top of that, smart contracts allow him to programmatically enable a commission for any future sale that happens going forward, and in just a couple of weeks that amounts to another $600,000.00+.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/dabit3/status/1427807893458497544"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>Generative art itself is an emerging category that combines code and creativity and is something that could alone warrant an entire post. But it suits the coming era particularly well, as it enables artists to scale their creativity, community, and distribution.</p>
<p>There will continue to be a larger and larger percentage of digital artists because they can use powerful tools and programs to create art that can then be used in an infinite number of ways. They can then put it for sale on an international, 24 hour, liquid market.</p>
<p>OpenSea, the top online art marketplace today, has seen an absolute explosion in growth the past few months.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/natechastain/status/1429965382849343490"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>Even recently surpassing Etsy in sales.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/xanderatallah/status/1427453596858294272"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>Whether this type of volume continues, I have no idea. My guess is that there will be some volatility and fairly large swings both up and down. But there is definitely <em>something</em> there.</p>
<p>Most of these NFT projects are launched on Ethereum. Ethereum is soon merging <a target="_blank" href="https://ethereum.org/en/eth2/">a new consensus mechanism</a> that will make NFTs orders of magnitude more environmentally friendly as a means of sales and transfer of art, which in the past all required ground transportation.</p>
<h4 id="heading-future-of-social-media">Future of social media</h4>
<p>As it stands today, users of social media platforms can begin leveraging Web3 tools, communities, and platforms to begin monetizing their audience. </p>
<p>I believe there will be a breakthrough app that will disrupt social media as we know it built in the in the next 1 - 3 years that blends all of these ideas together in a way that we haven't experienced yet.</p>
<p>Many people have echoed a similar sentiment. <a target="_blank" href="https://twitter.com/AaveAave">Aave</a>, a very successful DeFi protocol built on Ethereum, has already begun work on <a target="_blank" href="https://decrypt.co/76278/defi-project-aave-to-release-ethereum-based-twitter-alternative-this-year">a decentralized version of Twitter</a>:</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/stanikulechov/status/1416385933549654016"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>Jack Dorsey of Twitter is also working on a Decentralized version of Twitter, though I believe that this type of application will ultimately come from the community or a DAO.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/arcalinea/status/1427314482154414080"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<h3 id="heading-daos-grants-community-ownership-and-social-tokens">DAOs, grants, community ownership, and social tokens</h3>
<blockquote>
<p>DAO stands for Decentralized Autonomous Organization. You can read about what a DAO is <a target="_blank" href="https://www.notboring.co/p/the-dao-of-daos">here</a>, <a target="_blank" href="https://linda.mirror.xyz/Vh8K4leCGEO06_qSGx-vS5lvgUqhqkCz9ut81WwCP2o">here</a>, and <a target="_blank" href="https://decrypt.co/resources/decentralized-autonomous-organization-dao">here</a>, but I want to focus on how DAOs will play a part in the new creator economy.</p>
</blockquote>
<p>Shared ownership is a characteristic you'll see carried across all areas of Web3, including how we think about companies and incentive structures around how business is done.</p>
<p>In Web2 companies, cash usually comes from investors and there is no value returned to them for years. Ownership is largely concentrated in the first handful of employees along with their investors.</p>
<p>It usually takes years to reach a point where investors or employees with equity can begin to see any return on their investment and time spent, often through the old ways of advertising and exploitation of user data.</p>
<p>Web3 and blockchains bring about entirely new business models, made possible by <a target="_blank" href="https://www.gemini.com/cryptopedia/what-is-tokenization-definition-crypto-token#section-security-tokens-utility-tokens-and-cryptocurrencies">tokenization</a> and <a target="_blank" href="https://thegraph.com/blog/modeling-cryptoeconomic-protocols-as-complex-systems-part-1">cryptoeconomic protocols</a>.</p>
<p>There are quite literally countless ways that these tokens are being utilized to create new ways of collaboration and building, ranging from DAOs to web infrastructure to <a target="_blank" href="https://coopahtroopa.mirror.xyz/gWY6Kfebs9wHdfoZZswfiLTBVzfKiyFaIwNf2q8JpgI">micro-economies</a>:</p>
<p><a target="_blank" href="https://twitter.com/prtyDAO">PartyDAO</a> which <a target="_blank" href="https://twitter.com/nnnnicholas/status/1423428739589943300">created over $200,000 in revenue in its first day</a>, was "built in 3 months by a small group of internet friends working part-time", and is backed by a smart contract</p>
<p><a target="_blank" href="https://compound.finance/">Compound</a>, a decentralized finance protocol that allows you to lend and borrow cryptocurrency without trusting a third party with your funds has a market cap of over $2 billion as of this writing</p>
<p><a target="_blank" href="https://docs.superrare.com/the-superrare-dao">Super Rare</a> is a digital art platform that recently launched a token, <a target="_blank" href="https://twitter.com/DCLBlogger/status/1427860274808197124">airdropping as much as $140,000 to its earliest users</a></p>
<p><a target="_blank" href="https://gitcoin.co/">Gitcoin</a> is a platform that enables developers to get paid for working on open source projects</p>
<p><a target="_blank" href="https://thegraph.com/">Graph Protocol</a> is a decentralized web infrastructure protocol that allows developers to build APIs to enable the performant querying of blockchain data, all enabled by its native utility token</p>
<p><a target="_blank" href="https://twitter.com/seedclubhq">Seed Club</a> is a social token incubator that’s focused on helping creators launch and grow social tokens</p>
<p><a target="_blank" href="https://twitter.com/fwbtweets">Friends with Benefits</a> is a social DAO and community that I'm part of that is 100% owned and governed by the participants</p>
<p><a target="_blank" href="https://twitter.com/pleasrdao">PleasrDAO</a> allows investors to come together to purchase high-value non-fungible tokens like <a target="_blank" href="https://foundation.app/@Snowden/stay-free-edward-snowden-2021-24437">this piece</a> from Edward Snowden.</p>
<p>Most DAOs have <a target="_blank" href="https://thegraph.com/blog/wave-one-funding">desirable grants programs</a>, enabling developers and other participants to work with various teams and projects at their will, on things they find interesting or that fit their skill set. </p>
<p>There are more and more people beginning to work full time for grants and with DAOs vs traditional full time employment.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/dabit3/status/1418307358946701319"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If this sounds like something you're interested in being involved in, I'd suggest that you jump right in. Try P2E (play to earn), get involved with a DAO, or even mint your own NFT.</p>
<p>Also check out <a target="_blank" href="https://www.freecodecamp.org/news/breaking-into-ethereum-crypto-web3-as-a-developer/">How to Get into Crypto, Ethereum, and Web3 as a Developer</a> which is what I put together after getting my own start in the space.</p>
<p>If you want to learn more about these ideas, I encourage you to follow some of the people I mention in this post:</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/dabit3/status/1430865775011803137"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>Also, here are some of my favorite articles that touch on some of the stuff I've outlined here:</p>
<p><a target="_blank" href="https://coopahtroopa.mirror.xyz/gWY6Kfebs9wHdfoZZswfiLTBVzfKiyFaIwNf2q8JpgI">The Rise of Micro-Economies</a></p>
<p><a target="_blank" href="https://www.rushil2cents.com/the-creator-economy-today-vs-2025/">The Creator Economy: Today Vs. 2025</a></p>
<p><a target="_blank" href="https://www.notboring.co/p/the-value-chain-of-the-open-metaverse">The Value Chain of the Open Metaverse</a></p>
<p><a target="_blank" href="https://www.notboring.co/p/the-dao-of-daos">The DAO of DAOs</a></p>
<p>Thanks to <a target="_blank" href="https://twitter.com/adeets_22">Aditi</a> for helping me with ideas and edits as I was getting this across the finish line 🙏</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/dabit3/status/1430585405662011397"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Technical Guide to IPFS – the Decentralized Storage of Web3 ]]>
                </title>
                <description>
                    <![CDATA[ By Lukas Lukac When you think about developing a decentralized application, a blockchain like Ethereum probably comes to mind. Blockchain is fantastic for managing state, automating processes via Smart Contracts, and exchanging economic value. You ca... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/technical-guide-to-ipfs-decentralized-storage-of-web3/</link>
                <guid isPermaLink="false">66d46179d7a4e35e384349c3</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ decentralization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ipfs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 21 Jun 2021 16:38:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/06/tech_guide_ipfs_web3coach_banner-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Lukas Lukac</p>
<p>When you think about developing a decentralized application, a blockchain like Ethereum probably comes to mind.</p>
<p>Blockchain is fantastic for managing state, automating processes via Smart Contracts, and exchanging economic value.</p>
<p>You can <a target="_blank" href="https://www.freecodecamp.org/news/build-a-blockchain-in-golang-from-scratch/">follow this tutorial to learn blockchain by building one from scratch yourself</a> if you want to learn more.</p>
<p><strong>But where do you store your application's content?</strong> Images? Videos? The application's website front-end composed of all the HTML, CSS, and JS files? Are your application and your users' content loaded from a centralized AWS server?</p>
<p>Storing the content on the blockchain would be expensive and inefficient.</p>
<p>Your blockchain application needs decentralized storage!</p>
<p>In this tutorial, I will introduce you to the InterPlanetary File System, or IPFS. You will learn:</p>
<ol>
<li>How to store and retrieve content from a decentralized storage</li>
<li>How to run your IPFS node</li>
<li>All about the low-level internals of the IPFS protocol</li>
<li>And we'll read a Wikipedia website stored on IPFS</li>
</ol>
<p>Ready? Let's go.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-the-ipfs">What is the IPFS?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-setup-an-ipfs-node">How to setup an IPFS node</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-ipfs">How to store and retrieve IPFS content using the CLI and HTTP</a></li>
<li><a class="post-section-overview" href="#heading-how-ipfs-content-addressing-works">What is CID – the IPFS content-based identifier</a></li>
<li><a class="post-section-overview" href="#heading-how-ipfs-stores-content-on-the-file-system">How to reverse engineer the IPFS datastore</a></li>
<li><a class="post-section-overview" href="#heading-how-to-connect-an-ipfs-node-to-the-p2p-network">How to connect an IPFS node to a decentralized network</a></li>
<li><a class="post-section-overview" href="#heading-how-nodes-exchange-data-using-the-bitswap-protocol">How to exchange data using the peer-to-peer Bitswap protocol</a></li>
<li><a class="post-section-overview" href="#heading-how-to-persist-content-from-the-p2p-network">How to persist content from the peer-to-peer network</a></li>
</ul>
<h2 id="heading-what-is-the-ipfs">What is the IPFS?</h2>
<p>The InterPlanetary File System, or IPFS for short, is a peer-to-peer hypermedia protocol designed to make the web faster, safer, and more open.</p>
<p><strong>IPFS is a protocol for storing and sharing content.</strong> As in the blockchain world, every user is running its node (server). The nodes can communicate between each other and exchange files.</p>
<h3 id="heading-what-is-unique-about-ipfs">What is unique about IPFS?</h3>
<p>First of all, the <strong>IPFS is decentralized</strong> because it loads the content from thousands of peers instead of one centralized server. Every piece of data is cryptographically hashed, resulting in a safe, unique <strong>content identifier</strong>: CID.</p>
<p>Store your website in IPFS to avoid censorship and a single point of failure. Your personal IPFS node goes offline? Don't worry, the website will still load from other nodes across the globe serving it.</p>
<p>For example, suppose your government bans Wikipedia. In that case, you can still access a decentralized version of Wikipedia indexed on April 17th by loading it from the IPFS peer-to-peer network persisted under CID:</p>
<blockquote>
<p><strong>"</strong>QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX"</p>
</blockquote>
<p>Second, the integrity of <strong>IPFS content can be cryptographically verified.</strong></p>
<p>And finally, <strong>the IPFS content is de-duplicated.</strong> If you tried storing two identical 1MB files in the same IPFS node, they would be stored only once, eliminating the duplication, because their hash would produce an identical <strong>CID.</strong></p>
<h2 id="heading-how-to-setup-an-ipfs-node">How to Setup an IPFS Node</h2>
<h3 id="heading-install-ipfs">Install IPFS</h3>
<p>Open the <a target="_blank" href="https://docs.ipfs.io/install/">official IPFS docs</a> installation page and follow the instructions depending on your operating system (Windows, macOS, Linux). I will be documenting the Ubuntu installation process 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://docs.ipfs.io/install/command-line/#official-distributions">https://docs.ipfs.io/install/command-line/#official-distributions</a></div>
<p>I prefer compiling the <a target="_blank" href="http://github.com/ipfs/go-ipfs">ipfs/go-ipfs</a> repository from scratch to debug the code when needed, and let's be honest: GoLang rocks.</p>
<h4 id="heading-compile-the-codebase-in-go">Compile the codebase in Go</h4>
<p>Clone the repository and run the install script in the Makefile.</p>
<pre><code>git clone https:<span class="hljs-comment">//github.com/ipfs/go-ipfs.git</span>
cd go-ipfs
git checkout v0<span class="hljs-number">.8</span><span class="hljs-number">.0</span>-rc2
make install
</code></pre><p>Or download pre-compiled IPFS:</p>
<pre><code>sudo snap install ipfs
</code></pre><h3 id="heading-validate-the-installation">Validate the installation</h3>
<p>Let's be honest. Go is amazing and compiling the codebase yourself is bad-ass and decentralized. The resulted binary will be created in your <code>$GOPATH</code>.</p>
<pre><code>which ipfs
&gt; <span class="hljs-regexp">/home/</span>web3coach/go/bin/ipfs

ipfs version
&gt; ipfs version <span class="hljs-number">0.8</span><span class="hljs-number">.0</span>-rc2
</code></pre><h3 id="heading-initialize-a-new-node">Initialize a new node</h3>
<p>Run <code>ipfs init</code> to create your new node. By default, it will create a folder and store all the data in <code>~/.ipfs</code> You can tweak this by configuring the <code>IPFS_PATH</code> ENV variable.</p>
<pre><code>IPFS_PATH=<span class="hljs-regexp">/home/</span>web3coach/.ipfs_tutorial ipfs init

&gt; generating ED25519 keypair...done
&gt; peer identity: <span class="hljs-number">12</span>D3Koo...dNs
&gt; initializing IPFS node at /home/web3coach/.ipfs_tutorial
</code></pre><p>Your node is now fully initialized, awaiting your content.</p>
<h2 id="heading-how-to-use-ipfs">How to Use IPFS</h2>
<h3 id="heading-add-content">Add content</h3>
<p>IPFS can handle all kinds of different data types – from simple strings to images, videos, and websites.</p>
<p>Start by storing a short message <code>hello IPFS world by Web3Coach</code>:</p>
<pre><code>echo <span class="hljs-string">"hello IPFS world by Web3Coach. BTW: Ethereum FTW"</span> | ipfs add
</code></pre><p>The content is now stored and <strong>indexed by a cryptographic hash function</strong> returning its unique content identifier (CID):</p>
<pre><code>&gt; added QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
&gt; <span class="hljs-number">49</span> B / <span class="hljs-number">49</span> B [========] <span class="hljs-number">100</span>%
</code></pre><p>Your IPFS node will generate the same CID on your local file system as in this tutorial. That's because IPFS hashes the content and returns its unique fingerprint, and as we know, a secure hash function will always return the same output given the same input.</p>
<h3 id="heading-pin-content">Pin content</h3>
<p>When you <code>add</code> content, you add it ONLY to your local node. The <strong>content does NOT automatically replicate</strong> across the entire network – this is a common confusion between IPFS users and developers.</p>
<p>When you store content via the <code>add</code> command, IPFS will also execute the <code>pin</code> command by default:</p>
<pre><code>ipfs pin add QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
</code></pre><p>To replicate content, <strong>you must take your node online, join the p2p network, and <code>pin</code> the specific CID from another node.</strong> You will learn how to do this further in the tutorial and find out what happens in the background.</p>
<h3 id="heading-read-content">Read content</h3>
<p>Copy-paste the <strong>CID</strong> to IPFS <code>cat</code> command to read it from disk:</p>
<pre><code>ipfs cat QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
&gt; hello IPFS world by Web3Coach. BTW: Ethereum FTW
</code></pre><p>The <code>add</code> , <code>pin</code> and <code>cat</code> commands are the most significant IPFS functions, and you just learned them. Congrats, well done!</p>
<h2 id="heading-how-ipfs-content-addressing-works">How IPFS Content Addressing Works</h2>
<p>What is QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z?</p>
<p>It’s a self-describing content-based identifier.</p>
<p>What does "self-describing" actually mean? It means that by splitting the string following the IPFS specification, you will know everything you need to know about the data it indexes.</p>
<ul>
<li>what CID version it is</li>
<li>how to read the CID string (base32? base58? hex?)</li>
<li>how data is encoded</li>
<li>what hash function fingerprinted the data</li>
<li>the hash function's length</li>
</ul>
<p>The IPFS team built a convenient <a target="_blank" href="https://cid.ipfs.io/">website</a> for analyzing a CID:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/cid_analyse.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>By parsing the <strong>QmRBkKi1P…p6z</strong> CID, you discover:</p>
<ul>
<li>the CID follows version 0 spec because it starts with <strong>Qm</strong></li>
<li>the <strong>QmRBkKi1P…p6z</strong> string is encoded using <code>base58btc</code></li>
<li>the data "<strong>hello IPFS world by Web3Coach. BTW: Ethereum FTW</strong>" were encoded as <strong>DAG Protobuf</strong> under a codec <strong>0x70</strong> before being stored on disk</li>
<li>the hash code <strong>0x12</strong> signals the data fingerprint obtained using the <code>sha256</code> hash function, producing a unique 32 byte long digest</li>
</ul>
<p>"Slightly more complicated" than a simple auto-increment INT in a MySQL table... but extraordinarily potent and future proof. Let me explain.</p>
<h3 id="heading-cid-versions">CID Versions</h3>
<p>There are currently two CID versions: <strong>v0</strong> and <strong>v1</strong>.</p>
<p><strong>The CID v0</strong> is not flexible and limited to:</p>
<ul>
<li>start with characters "Qm"</li>
<li>where the CID string is encoded using base58btc</li>
<li>the data is encoded with dag-pb by default</li>
<li>can be converted to CID version 1, but not the other way around</li>
</ul>
<p><strong>The CID v1</strong> leverages several prefixes for maximum interoperability:</p>
<blockquote>
<p>CID v1 = Multibase + Multicodec + Multihash</p>
</blockquote>
<p>In another words, parsing the binary into a CID v1 string follows this spec:</p>
<p><code>&lt;base&gt;&lt;codec&gt;&lt;hash-function&gt;&lt;hash-length&gt;&lt;hash-digest&gt;</code></p>
<h3 id="heading-multihash">Multihash</h3>
<p>To be future-proof and enable different hashing algorithms, IPFS created the following standard:</p>
<p>CODE : SIZE : DIGEST</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> DecodedMultihash <span class="hljs-keyword">struct</span> {
   Code   <span class="hljs-keyword">uint64</span> <span class="hljs-comment">// 0x12</span>
   Name   <span class="hljs-keyword">string</span> <span class="hljs-comment">// sha2-256</span>
   Length <span class="hljs-keyword">int</span>    <span class="hljs-comment">// 32 bytes</span>
   Digest []<span class="hljs-keyword">byte</span> <span class="hljs-comment">// Digest holds the raw multihash bytes</span>
}
</code></pre>
<p>Multihash has many advantages. When computers are more powerful in 5 years, you could use a stronger hash function like <code>sha3-512</code> as long as you configure the corresponding <code>0x13</code> code as the Multihash in the CID prefix – the protocol will be ready to handle it.</p>
<h3 id="heading-multicodec">Multicodec</h3>
<p>The <code>Code</code> attribute tells you <strong>how data is encoded</strong> before being stored on disk, so you know <strong>how to decode</strong> it back when the user wants to read it. It could be anything CBOR, Protobuf, JSON…</p>
<p>IPFS maintains a public list of all <a target="_blank" href="https://github.com/multiformats/multicodec/blob/master/table.csv">possible codecs</a>. The most common codecs are:</p>
<pre><code>raw       | ipld      | <span class="hljs-number">0x55</span> | raw binary
dag-pb    | ipld      | <span class="hljs-number">0x70</span> | MerkleDAG protobuf
dag-cbor  | ipld      | <span class="hljs-number">0x71</span> | MerkleDAG cbor

<span class="hljs-comment">// but you could also encode Ethereum blocks on IPFS!</span>
eth-block | ipld      | <span class="hljs-number">0x90</span> | Ethereum Block (RLP)
</code></pre><h3 id="heading-multibase">Multibase</h3>
<p>The problem with CID v0 and the <code>base58btc</code> encoding is the lack of interoperability between environments. A multibase prefix adds support for different encodings like <code>base32</code> to achieve DNS-friendly names.</p>
<p><a target="_blank" href="https://github.com/multiformats/multibase/blob/master/multibase.csv">A table with all Multibase encodings</a>:</p>
<pre><code>encoding  | code
base32    | b
base58btc | z
base64    | m
</code></pre><p>You spot a Multibase encoding based on the first character:</p>
<p><strong>Q</strong>mRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z</p>
<ul>
<li>is CID <code>v0</code></li>
<li>the CID string is encoded with <code>base58btc</code></li>
</ul>
<p><strong>b</strong>afybeibkjmxftowv4lki46nad4arescoqc7kdzfnjkqux257i4jonk44w4</p>
<ul>
<li>CID <code>v1</code></li>
<li>the CID string is encoded with <code>base32</code></li>
</ul>
<p>Both CID versions can retrieve the same content because after you strip the encoding, it's the <strong>Multihash</strong> that indexes the blocks on the datastore level. In contrast, Multibase is only used to pass the CID correctly in different environments (CLI, URL, DNS).</p>
<pre><code>ipfs cat QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
&gt; hello IPFS world by Web3Coach. BTW: Ethereum FTW

<span class="hljs-comment">// equivalent to</span>
ipfs cat bafybeibkjmxftowv4lki46nad4arescoqc7kdzfnjkqux257i4jonk44w4
&gt; hello IPFS world by Web3Coach. BTW: Ethereum FTW
</code></pre><p>Phew. Things got "slightly complex" very quickly.</p>
<p>Speaking of complicated topics, IPFS is powerful because it doesn't treat content as just "data" but as <strong>data structures</strong> – specifically <strong>InterPlanetary Linked Data</strong> structure: <a target="_blank" href="https://docs.ipld.io/#what-is-ipld">IPLD</a>. In short, you can implement any file-system, database, or structure on top of IPLD.</p>
<p>For example, you can store all Ethereum blocks on IPFS as long as you set <code>eth-block</code> and <code>eth-tx</code> codecs and register an appropriate Decoder when working with the IPLD graph.</p>
<p>Let's dig into it and explore the default IPLD structure with the DAG Protobuf codec.</p>
<h2 id="heading-how-ipfs-stores-content-on-the-file-system">How IPFS Stores Content on the File-system</h2>
<p>“The <code>ipfs add</code> command will create a <strong>Merkle DAG</strong> out of the data following the <a target="_blank" href="https://github.com/ipfs/go-unixfs/blob/master/pb/unixfs.proto">UnixFS data format</a>. Your content is broken down into <strong>blocks</strong> using a <strong>Chunker</strong>, and then arranged in a <strong>tree-like structure using 'link nodes'</strong> to tie them together. The returned CID is the hash of the root node in the DAG.”</p>
<p>Confused?</p>
<p>Rolling back to basics.</p>
<h3 id="heading-lets-explore-the-nodes-data-directory">Let's explore the node’s data directory</h3>
<p>At the beginning of this tutorial, when you initialized your IPFS node with the <code>ipfs init</code> command, you generated the following directory:</p>
<pre><code><span class="hljs-keyword">export</span> IPFS_PATH=<span class="hljs-regexp">/home/</span>web3coach/.ipfs_tutorial
cd $IPFS_PATH
~/.ipfs_tutorial  tree

.
├── blocks
│   ├── <span class="hljs-number">6</span>Y
│   │   └── CIQA4XCGRCRTCCHV7XSGAZPZJOAOHLPOI6IQR3H6YQ.data
├── config
├── datastore
│   ├── <span class="hljs-number">000002.</span>ldb
│   ├── <span class="hljs-number">000003.</span>log
│   ├── CURRENT
│   ├── CURRENT.bak
│   ├── LOCK
│   ├── LOG
│   └── MANIFEST<span class="hljs-number">-000004</span>
├── datastore_spec
├── keystore
└── version
</code></pre><p>From a very <strong>high-level point of view:</strong></p>
<ul>
<li><code>blocks</code> — IPFS stores all the chunked data here, although the <code>go-ipfs</code> flexible interfaces <strong>allow you to swap the storage implementation</strong> for a different database</li>
<li><code>config</code> — Node’s settings (file-system, identity, specs, networking)</li>
<li><code>datastore</code> — Indexing and other logic</li>
</ul>
<p>Don't take my word for it. Create a new file with the following content on your local file system and then add it to IPFS:</p>
<pre><code>hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs

ls -la hello_world.txt
&gt; <span class="hljs-number">131</span> bytes hello_world.txt

ipfs add hello_world.txt
&gt; added QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH
</code></pre><p>Reverse engineering the <code>go-ipfs</code> codebase, this is what is happening behind the scenes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/IPFS_UNIX_FS_Protobuf.png" alt="Image" width="600" height="400" loading="lazy">
<em>IPFS UnixFS adding a new file and converting it to a block</em></p>
<p>Validate the persistence process by inspecting the blocks directory. You will find the content was written under the Multihash Datastore Key using <strong>DAG Protobuf encoding</strong> (131 bytes + Protobuf extra encoding).</p>
<pre><code>ls -la blocks/PV/
&gt; <span class="hljs-number">142</span> CIQAQIXXW2OAQSKZ6AQ2SDEYRZXWPDZNJUAFR3YORYN75I5CQ3LHPVQ.data

vim blocks/PV/CIQA...
&lt;<span class="hljs-number">8</span>b&gt;^A^H^B^R&lt;<span class="hljs-number">83</span>&gt;^Ahello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs^X&lt;<span class="hljs-number">83</span>&gt;^A
</code></pre><p>To interact with your raw content, use the <code>ipfs object</code> command.</p>
<pre><code>ipfs object get QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH | jq
</code></pre><pre><code class="lang-json">{
  <span class="hljs-attr">"Links"</span>: [],
  <span class="hljs-attr">"Data"</span>: <span class="hljs-string">"\b\u0002\u0012�\u0001hello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing DAGs\u0018�\u0001"</span>
}
</code></pre>
<ul>
<li>Because the content is only 131 bytes, it fits to one DAG Node</li>
<li>The Dag Node is persisted as one Block on disk</li>
<li>The DAG Node has zero links to other Nodes</li>
</ul>
<p>Time to experiment.</p>
<p>Add the same file again, but configure the Chunker to 64 bytes (or use a bigger file, but a smaller Chunker will demonstrate the concept better).</p>
<pre><code>ipfs add --chunker=size<span class="hljs-number">-64</span> hello_world.txt

&gt; <span class="hljs-number">131</span> bytes QmTwtTQgrTaait2qWXYjTsEZiF4sT7CD4U87VqQ27Wnsn8
</code></pre><p><strong>You get a new CID!</strong> </p>
<p>IPFS split the content into 4 DAG Nodes and wrote 4 Blocks with data encoded in DAG Protobuf format to disk.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/ipfs_chunker_4.png" alt="Image" width="600" height="400" loading="lazy">
<em>IPFS splits a file into multiple chunks (DAG Nodes + Blocks)</em></p>
<pre><code>ipfs object get QmTwtTQgrTaait2qWXYjTsEZiF4sT7CD4U87VqQ27Wnsn8 | jq
</code></pre><pre><code class="lang-json">{
  <span class="hljs-attr">"Links"</span>: [
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">""</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"QmTbsuUYzy3nT6NApb5t7VUq3iQKZXrJJJY2j1miMVgaJU"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">72</span>
    },
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">""</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"QmNy9iFF8uU1Cn7trxpSgqxMsjmi4zQ7xgyEgsWff5rnfH"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">72</span>
    },
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">""</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"QmdEitCfYgBNxLhxTNvdLaDmTypSAWkGErjw33VZxUbWK3"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">11</span>
    }
  ],
  <span class="hljs-attr">"Data"</span>: <span class="hljs-string">"\b\u0002\u0018�\u0001 @ @ \u0003"</span>
}
</code></pre>
<p>The ultimate test is to retrieve each DAG Node's data and verify the text is split into three chunks:</p>
<p><strong>DAG Protobuf Node 1:</strong></p>
<pre><code>ipfs object get QmTbsuUYzy3nT6NApb5t7VUq3iQKZXrJJJY2j1miMVgaJU | jq
</code></pre><pre><code class="lang-json">{
  <span class="hljs-attr">"Links"</span>: [],
  <span class="hljs-attr">"Data"</span>: <span class="hljs-string">"\b\u0002\u0012@hello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by \u0018@"</span>
}
</code></pre>
<p><strong>DAG Protobuf Node 2:</strong></p>
<pre><code>ipfs object get QmNy9iFF8uU1Cn7trxpSgqxMsjmi4zQ7xgyEgsWff5rnfH | jq
</code></pre><pre><code class="lang-json">{
  <span class="hljs-attr">"Links"</span>: [],
  <span class="hljs-attr">"Data"</span>: <span class="hljs-string">"\b\u0002\u0012@Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing D\u0018@"</span>
}
</code></pre>
<p><strong>DAG Protobuf Node 3:</strong></p>
<pre><code>ipfs object get QmdEitCfYgBNxLhxTNvdLaDmTypSAWkGErjw33VZxUbWK3 | jq
</code></pre><pre><code class="lang-json">{
  <span class="hljs-attr">"Links"</span>: [],
  <span class="hljs-attr">"Data"</span>: <span class="hljs-string">"\b\u0002\u0012\u0003AGs\u0018\u0003"</span>
}
</code></pre>
<h3 id="heading-whats-the-benefit-of-splitting-the-content-into-multiple-chunks-and-use-content-addressing-and-cids">What’s the benefit of splitting the content into multiple chunks and use content-addressing and CIDs?</h3>
<ul>
<li>Data deduplication</li>
<li>Decentralization</li>
</ul>
<p>Next time you want to store a file that would share part of the content with another file, IPFS wouldn't store a duplicate block! It would instead link to an already existing DAG Node and only store the new, unique chunks.</p>
<p>Converting content to a directed acyclic graph with many nodes also helps to load the content in parallel. For example, a blog post, image, entire Wikipedia website can load from multiple IPFS peer nodes. Your node then verifies the integrity of received blocks by re-hashing all the data content and asserting the constructed CID.</p>
<p>You've now learned the bread and butter of IPFS – excellent progress!</p>
<p>One more critical component left: <strong>Networking</strong>.</p>
<h2 id="heading-how-to-connect-an-ipfs-node-to-the-p2p-network">How to Connect an IPFS Node to the p2p Network</h2>
<p>Every node has its <code>config</code> file generated during the <code>ipfs init</code> execution.</p>
<p>Open it.</p>
<pre><code>vim $IPFS_PATH/config
</code></pre><p>Other settings aside, you find your node’s <strong>Identity (PeerID + Private Key):</strong></p>
<pre><code><span class="hljs-string">"Identity"</span>: {
    <span class="hljs-string">"PeerID"</span>: <span class="hljs-string">"12D3KooWCBmDtsvFwDHEr..."</span>,
    <span class="hljs-string">"PrivKey"</span>: <span class="hljs-string">"CAESQCj..."</span>
  },
</code></pre><p>And a list of <strong>Bootstrap addresses:</strong></p>
<pre><code class="lang-json"><span class="hljs-string">"Bootstrap"</span>: [
    <span class="hljs-string">"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59b...gU1ZjYZcYW3dwt"</span>,
    <span class="hljs-string">"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMG...UtfsmvsqQLuvuJ"</span>,
    <span class="hljs-string">"/ip4/104.131.131.82/udp/4001/quic/p2p/Qma...UtfsmvsqQLuvuJ"</span>,
    <span class="hljs-string">"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooD5...BMjTezGAJN"</span>,
    <span class="hljs-string">"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2Ec...J16u19uLTa"</span>,
    <span class="hljs-string">"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnM...Ucqanj75Nb"</span>
  ],
</code></pre>
<p>You connect to other peers in the IPFS network by running the <code>ipfs daemon</code> command. Your node will first establish a p2p connection with Protocol Labs (company behind IPFS) bootstrap nodes, and through these bootstrap nodes, you will further find hundreds of other peers.</p>
<pre><code>ipfs daemon 

&gt; Initializing daemon...

Swarm listening on /ip4/<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/tcp/<span class="hljs-number">4001</span>
Swarm listening on /ip4/<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/udp/<span class="hljs-number">4001</span>/quic
Swarm listening on /ip4/<span class="hljs-number">172.17</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/tcp/<span class="hljs-number">4001</span>
Swarm listening on /ip4/<span class="hljs-number">172.17</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/udp/<span class="hljs-number">4001</span>/quic
Swarm listening on /ip4/<span class="hljs-number">192.168</span><span class="hljs-number">.0</span><span class="hljs-number">.142</span>/tcp/<span class="hljs-number">4001</span>
Swarm listening on /ip4/<span class="hljs-number">192.168</span><span class="hljs-number">.0</span><span class="hljs-number">.142</span>/udp/<span class="hljs-number">4001</span>/quic
Swarm listening on /ip6/::<span class="hljs-number">1</span>/tcp/<span class="hljs-number">4001</span>
Swarm listening on /ip6/::<span class="hljs-number">1</span>/udp/<span class="hljs-number">4001</span>/quic
Swarm listening on /p2p-circuit
Swarm announcing /ip4/<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/tcp/<span class="hljs-number">4001</span>
Swarm announcing /ip4/<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/udp/<span class="hljs-number">4001</span>/quic
Swarm announcing /ip4/<span class="hljs-number">192.168</span><span class="hljs-number">.0</span><span class="hljs-number">.142</span>/tcp/<span class="hljs-number">4001</span>
Swarm announcing /ip4/<span class="hljs-number">192.168</span><span class="hljs-number">.0</span><span class="hljs-number">.142</span>/udp/<span class="hljs-number">4001</span>/quic
Swarm announcing /ip4/<span class="hljs-number">88.212</span><span class="hljs-number">.40</span><span class="hljs-number">.160</span>/udp/<span class="hljs-number">4001</span>/quic
Swarm announcing /ip6/::<span class="hljs-number">1</span>/tcp/<span class="hljs-number">4001</span>
Swarm announcing /ip6/::<span class="hljs-number">1</span>/udp/<span class="hljs-number">4001</span>/quic

API server listening on /ip4/<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/tcp/<span class="hljs-number">5001</span>
<span class="hljs-attr">WebUI</span>: http:<span class="hljs-comment">//127.0.0.1:5001/webui</span>

Gateway (readonly) server listening on /ip4/<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>/tcp/<span class="hljs-number">8080</span>
Daemon is ready!
</code></pre><p>Keep in mind, that by running the <strong>IPFS Daemon</strong>:</p>
<ol>
<li>Your node connects to the p2p net and can <strong>exchange blocks with other nodes</strong></li>
<li><strong>Other peers can access the content on your node</strong> – as long they know the CIDs</li>
<li>Peers will talk to you through TCP, UDP on port: <strong>4001</strong></li>
<li>If you have an application, start storing and consuming your node's content via the HTTP API listening on port: <strong>5001</strong>.</li>
</ol>
<p>For application development, I recommend the official <a target="_blank" href="https://www.npmjs.com/package/ipfs-http-client">ipfs-http-client</a> library in JS exposing all the core commands – add, cat, object and others. It will speed up your coding progress.</p>
<p>I will use <code>curl</code> to interact with the API to keep this tutorial "short."</p>
<h3 id="heading-how-to-use-the-ipfs-http-api">How to use the IPFS HTTP API:</h3>
<p><strong>Add content:</strong> :5001/api/v0/add</p>
<pre><code>curl -X POST -F file=@/home/web3coach/go/src/github.com/ipfs/go-ipfs/hello_world.txt <span class="hljs-string">"http://127.0.0.1:5001/api/v0/add"</span>
</code></pre><pre><code class="lang-json">{<span class="hljs-attr">"Name"</span>:<span class="hljs-string">"hello_world.txt"</span>,<span class="hljs-attr">"Hash"</span>:<span class="hljs-string">"QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH"</span>,<span class="hljs-attr">"Size"</span>:<span class="hljs-string">"142"</span>}
</code></pre>
<p><strong>Read content:</strong> :5001/api/v0/cat</p>
<pre><code>curl -X POST <span class="hljs-string">"http://127.0.0.1:5001/api/v0/cat?arg=QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH"</span>

hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
</code></pre><p>See the <a target="_blank" href="https://docs.ipfs.io/reference/http/api/#getting-started">official HTTP API docs</a> for the complete list of available commands.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/Screenshot-from-2021-05-26-19-54-49.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-peer-with-other-ipfs-nodes">How to peer with other IPFS nodes</h3>
<p>Fun experiment. Use the <code>ipfs swarm</code> command and check how many nodes you already discovered:</p>
<pre><code>ipfs swarm peers

&gt; 
<span class="hljs-regexp">/ip4/</span><span class="hljs-number">85.70</span><span class="hljs-number">.151</span><span class="hljs-number">.37</span>/tcp/<span class="hljs-number">4001</span>/p2p/QmSuCtR...aPq6h4AczBPZaoej
/ip4/<span class="hljs-number">91.121</span><span class="hljs-number">.168</span><span class="hljs-number">.96</span>/udp/<span class="hljs-number">54001</span>/quic/p2p/QmeC7H..<span class="hljs-number">.8</span>j2TQ99esS
...
...
...

ipfs swarm peers | wc -l
&gt; <span class="hljs-number">186</span>
</code></pre><p>Bravo! You are connected to 186 peers forming an unstoppable peer-to-peer web.</p>
<h3 id="heading-what-about-privacy">What about privacy?</h3>
<p>Other peers can access all the content you add to your IPFS node. There is <strong>no built-in privacy mechanism, so never add unencrypted, sensitive/personal content</strong> to IPFS!</p>
<h2 id="heading-how-nodes-exchange-data-using-the-bitswap-protocol">How Nodes Exchange Data Using the Bitswap Protocol</h2>
<p>So far, you only interacted with your local content. Imagine you live in a place where the local government decided to block access to Wikipedia. No bueno. </p>
<p>Fortunately, because someone added all the Wikipedia content to IPFS, you can run your node and access its knowledge by requesting the content from peers across the globe.</p>
<p><a target="_blank" href="http://localhost:8080/ipfs/QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX/wiki/Anasayfa.html">http://localhost:8080/ipfs/QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX/wiki/Anasayfa.html</a></p>
<p>The DAG Service will check the blocks in your datastore, but it won’t find any for QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX.</p>
<p>The node will therefore create a network request to its peers using the Bitswap protocol via <code>exchange</code> component:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getBlock</span><span class="hljs-params">(ctx context.Context, c cid.Cid, bs blockstore.Blockstore, fget <span class="hljs-keyword">func</span>()</span> <span class="hljs-title">exchange</span>.<span class="hljs-title">Fetcher</span>) <span class="hljs-params">(blocks.Block, error)</span></span> {
   err := verifcid.ValidateCid(c) <span class="hljs-comment">// hash security</span>
   <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>, err
   }

   block, err := bs.Get(c)
   <span class="hljs-keyword">if</span> err == <span class="hljs-literal">nil</span> {
      <span class="hljs-keyword">return</span> block, <span class="hljs-literal">nil</span>
   }

   <span class="hljs-keyword">if</span> err == blockstore.ErrNotFound &amp;&amp; fget != <span class="hljs-literal">nil</span> {
      f := fget() <span class="hljs-comment">// Don't load the exchange until we have to</span>

      log.Debug(<span class="hljs-string">"Blockservice: Searching bitswap"</span>)
      blk, err := f.GetBlock(ctx, c)
</code></pre>
<p>Internally, the CID is added to a <code>Wantlist</code> :</p>
<pre><code class="lang-go"><span class="hljs-comment">// Wantlist is a raw list of wanted blocks and their priorities</span>
<span class="hljs-keyword">type</span> Wantlist <span class="hljs-keyword">struct</span> {
   set <span class="hljs-keyword">map</span>[cid.Cid]Entry
}

<span class="hljs-comment">// Entry is an entry in a want list, consisting of a cid and its priority</span>
<span class="hljs-keyword">type</span> Entry <span class="hljs-keyword">struct</span> {
   Cid      cid.Cid
   Priority <span class="hljs-keyword">int32</span>
   WantType pb.Message_Wantlist_WantType
}
</code></pre>
<p>And the <code>PeerManager</code> will iterate over known peers and their peers until it finds an online node capable of providing the wanted Block:</p>
<pre><code class="lang-go"><span class="hljs-comment">// PeerManager manages a pool of peers and sends messages to peers in the pool.</span>
<span class="hljs-keyword">type</span> PeerManager <span class="hljs-keyword">struct</span> {
   pqLk sync.RWMutex

   peerQueues <span class="hljs-keyword">map</span>[peer.ID]PeerQueue
   pwm        *peerWantManager

   createPeerQueue PeerQueueFactory
   ctx             context.Context

   psLk         sync.RWMutex
   sessions     <span class="hljs-keyword">map</span>[<span class="hljs-keyword">uint64</span>]Session
   peerSessions <span class="hljs-keyword">map</span>[peer.ID]<span class="hljs-keyword">map</span>[<span class="hljs-keyword">uint64</span>]<span class="hljs-keyword">struct</span>{}

   self peer.ID
}
</code></pre>
<p>The result?</p>
<p>You can consume the forbidden fruits from Wikipedia directly from <strong>localhost:8080</strong>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/05/wikipedia_local_ipfs.png" alt="Image" width="600" height="400" loading="lazy">
<em>IPFS loading Wikipedia on your local node</em></p>
<p>Uncensorable, decentralized storage :)</p>
<h2 id="heading-how-to-persist-content-from-the-p2p-network">How to Persist Content from the p2p Network</h2>
<p>You must know a crucial thing about IPFS: the content you access from the network will be garbage collected unless you <strong>pin</strong> it.</p>
<h3 id="heading-pinning-and-garbage-collection">Pinning and Garbage Collection</h3>
<p>At the beginning of the article you learned that content added to your node via the <code>ipfs add</code> command or its HTTP equivalent is pinned by default.</p>
<pre><code>ipfs pin ls | grep QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH
&gt; QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH recursive
</code></pre><p><strong>Pinned blocks are marked as NOT TO BE DELETED</strong> when the Garbage Collection runs.</p>
<p>Why would the Garbage Collection delete some blocks? To keep your node healthy by controlling its storage size.</p>
<p>By reading Wikipedia or by accessing any other content from the p2p network, IPFS downloads its blocks. As the node's datastore grows in size, a periodic garbage collection process will prune unpinned blocks, so you don't run out of disk space.</p>
<p>If you want your content to be accessible 24/7 on the IPFS network, I recommend that you use a reliable remote provider to pin it: <strong><a target="_blank" href="https://infura.io/docs/ipfs?utm_source=web3coach&amp;utm_medium=article">Infura</a> -</strong> is the easiest way to get started, and you get 5GB free of decentralized storage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/Screenshot-from-2021-06-16-09-24-58.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Follow the <a target="_blank" href="https://infura.io/docs/ipfs?utm_source=web3coach&amp;utm_medium=article">getting started docs.</a></p>
<h3 id="heading-how-to-pin-wikipedia-locally">How to pin Wikipedia locally</h3>
<p>Verify that the Wikipedia root-level CID (highest DAG node) isn't yet pinned on your node:</p>
<pre><code>ipfs pin ls | grep QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX
&gt; no output, not pinned
</code></pre><p>IPFS stores specific versions of Wikipedia in the form of a DAG. I recommend inspecting its graph before pinning:</p>
<pre><code>ipfs object get QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX | jq
</code></pre><pre><code class="lang-json">{
  <span class="hljs-attr">"Links"</span>: [
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">"0C-"</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"QmSEwJo8Z5bqVX3AhocyimJzPWetr7HgbWbwCg6zbp43AP"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">1248085</span>
    },
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">"43I"</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"QmPW3kRjncDj145bP9DVNc791FowLPwYHnqbTzfe3whdyZ"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">2611324931</span>
    },
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">"58wiki"</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"QmRNXpMRzsTHdRrKvwmWisgaojGKLPqHxzQfrXdfNkettC"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">12295304394</span>
    },
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">"92M"</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"Qmbcvk7jpBTUKdgex139Nvv7BrKocE3pQVKhNJtTU77Qv5"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">793</span>
    },
    {
      <span class="hljs-attr">"Name"</span>: <span class="hljs-string">"A0index.html"</span>,
      <span class="hljs-attr">"Hash"</span>: <span class="hljs-string">"QmNqbYogAxH4mmt5WhuKN7NFEUDZ9V3Scxh7QbLwTKBJDk"</span>,
      <span class="hljs-attr">"Size"</span>: <span class="hljs-number">191</span>
    }
  ],
  <span class="hljs-attr">"Data"</span>: <span class="hljs-string">"\b\u0005\u0012\u0015\u0001\u0000\u0004\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\b\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000(\"0�\u0002"</span>
}
</code></pre>
<p>The root DAG object has five links. Four links are relatively small, but <strong>one link points to a DAG node with a total size of 12GB.</strong> If you inspect this DAG node, you will see 256 more links and a total cumulative (recursive) size of 12GB.</p>
<pre><code>ipfs object stat QmRNXpMRzsTHdRrKvwmWisgaojGKLPqHxzQfrXdfNkettC

<span class="hljs-attr">NumLinks</span>:       <span class="hljs-number">256</span>
<span class="hljs-attr">BlockSize</span>:      <span class="hljs-number">12075</span>
<span class="hljs-attr">LinksSize</span>:      <span class="hljs-number">12034</span>
<span class="hljs-attr">DataSize</span>:       <span class="hljs-number">41</span>
<span class="hljs-attr">CumulativeSize</span>: <span class="hljs-number">12295304394</span>
</code></pre><p>Every node with an important pinned article, video, documentary, or a cat meme makes the web more accessible, antifragile, decentralized, and robust.</p>
<pre><code>ipfs pin add QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX
</code></pre><p>The pinning process will recursively traverse the entire DAG node, fetch all its links from the Bitswap protocol and then pin every single Block to your local datastore.</p>
<p>Congratulations! In this article, you learned how decentralized storage works behind the scenes.</p>
<h3 id="heading-i-worked-47-hours-to-write-this-blog-post-but-you-can-re-tweet-it-in-just-5-seconds">I worked 47 hours to write this blog post… but you can re-tweet it in just 5 seconds:</h3>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/Web3Coach/status/1406997483281174528"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Break into Ethereum, Crypto, and Web3 as a Developer ]]>
                </title>
                <description>
                    <![CDATA[ By Nader Dabit Lately, I've been talking about my move into the Web3, Ethereum, and crypto space since making the switch from a traditional web, mobile, and cloud background. Since making that move, a shocking number of people have reached out to me ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/breaking-into-ethereum-crypto-web3-as-a-developer/</link>
                <guid isPermaLink="false">66d460407df3a1f32ee7f86f</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ crypto ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ethereum blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web3 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 18 May 2021 21:04:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/break-into-blockchain-article.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nader Dabit</p>
<p>Lately, I've been <a target="_blank" href="https://twitter.com/dabit3/status/1391171104757125122">talking</a> about <a target="_blank" href="https://twitter.com/dabit3/status/1379157277660299264">my move</a> into the <a target="_blank" href="https://ethereum.org/en/developers/docs/web2-vs-web3/">Web3</a>, Ethereum, and crypto space since making the switch from a traditional web, mobile, and cloud background.</p>
<p>Since making that move, a shocking number of people have reached out to me who are also thinking about doing the same. </p>
<p>It's really great to see so many other people interested in these fields. And if I'm being honest – it feels validating to know that so many others are also on the fence and are so deeply interested in the space as well.</p>
<p>As for me, I was nervous about making the career switch. Moving into a completely new area of specialization, with a technology I was still getting ramped up on, and a community I was not yet involved with, was a big leap. Especially compared to a very comfortable role with a FAANG company that paid really well (and a team that I really loved).</p>
<p>After over a month, I have zero regrets with the change. I'm also the happiest I've been in a long time, and am excited and energized about the things I have the opportunity to work on everyday.</p>
<p>I decided to write this post to give a blueprint for anyone looking to get into blockchain, crypto, Ethereum, and Web3 from a traditional development background. I can point people to this blog post the next time I get asked how to get into the space.</p>
<h3 id="heading-ill-break-this-article-up-into-a-few-main-parts">I'll break this article up into a few main parts:</h3>
<ol>
<li>Technologies and resources to learn</li>
<li>Tradeoffs and considerations</li>
<li>People to follow</li>
<li>Companies hiring and doing interesting stuff</li>
<li>General tips and landing a job</li>
</ol>
<p>Let's dive in.</p>
<h2 id="heading-technologies-and-resources-to-learn-about-ethereum-and-blockchain">Technologies and Resources to Learn About Ethereum and Blockchain</h2>
<p>What I'm most interested in is usually a function of where I predict technology will be in the near future and where I see the current momentum being. So that's what I will focus on here (and this is what I am doing personally).</p>
<p>To me, the most exciting parts of this space are decentralization, <a target="_blank" href="https://blog.coinbase.com/a-beginners-guide-to-decentralized-finance-defi-574c68ff43c4">DeFi</a>, <a target="_blank" href="https://docs.ethhub.io/ethereum-basics/governance/">governance</a> / <a target="_blank" href="https://www.investopedia.com/tech/what-dao/">DAOs</a>, and <a target="_blank" href="https://www.youtube.com/watch?v=j2rXJLW_93o">decentralized web infrastructure</a>.</p>
<p>Because of this, I'm focusing on both Ethereum development and Solidity. With the Solidity programming language ,you can program smart contracts for Ethereum as well as for many other <a target="_blank" href="https://chainid.network/">EVM compatible blockchains</a>. </p>
<p>As of this writing, Ethereum also has the powerful and important combination of momentum, developer mindshare, and existing production <a target="_blank" href="https://everest.link/">dapps</a>.</p>
<p>Ethereum is also currently moving to a new consensus mechanism, <a target="_blank" href="https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/">proof of stake</a>. This addresses the environmental concerns I used to have about how cryptocurrency works at a core level.</p>
<p>Once you learn how everything works fundamentally, I encourage you to then check out other blockchains and projects outside of Ethereum and EVM. </p>
<p>This will give you a better understanding of the industry as a whole. It will also help you see if there are other projects that attract you or that you believe are better approaches to achieving the goal that is Web3. </p>
<p>Consider looking into <a target="_blank" href="https://solana.com/">Solana</a>, <a target="_blank" href="https://polkadot.network/">Polkadot</a>, <a target="_blank" href="https://near.org/">Near</a>, <a target="_blank" href="https://www.avax.network/">Avalanche</a> or <a target="_blank" href="https://cosmos.network/">Cosmos</a>.</p>
<p>To get started learning blockchain development with Ethereum and Solidity, I suggest you do the following:</p>
<h3 id="heading-1-read-the-ethereum-docs">1. Read the Ethereum docs</h3>
<p>Scan through the <a target="_blank" href="https://ethereum.org/en/developers/docs/">Ethereum docs</a>. Be sure to check out the section <a target="_blank" href="https://ethereum.org/en/developers/docs/intro-to-ethereum/">Intro to Ethereum</a> as well as anything else that catches your eye.</p>
<p>Also be sure to check out the <a target="_blank" href="https://ethereum.org/en/dapps/">dapp showcase</a> to get a good understanding of the successful apps being built and used in the current ecosystem.</p>
<h3 id="heading-2-read-the-solidity-documentation">2. Read the Solidity documentation</h3>
<p>The <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.4/">Solidity docs</a> are a really good place to get started, especially <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.4/solidity-by-example.html">solidity by example</a>. This gives you a few examples of popular smart contracts like voting, an auction, remote purchase, and micropayments.</p>
<p>You can copy and paste these contracts in the <a target="_blank" href="https://remix.ethereum.org/">Remix IDE</a> to start executing and modifying them to see how they work.</p>
<p>I also did a video walkthrough of the voting contract <a target="_blank" href="https://www.youtube.com/watch?v=GB3hiiNNDjk">here</a>.</p>
<h3 id="heading-3-get-comfortable-with-the-remix-ide">3. Get comfortable with the Remix IDE</h3>
<p>It's really easy to play around with and start building smart contracts without having to set up any type of development environment by using the <a target="_blank" href="https://remix.ethereum.org/">Remix IDE</a>. It's part of the <a target="_blank" href="https://remix-project.org/">Remix Project</a> which is funded by the <a target="_blank" href="https://ethereum.foundation/">Ethereum Foundation</a>.</p>
<p>This Remix IDE allows you to create, edit, and execute smart contracts directly from your browser. It offers a perfect environment for learning how solidity works. It's also great for building out various types of smart contracts and playing around with them as you are learning both solidity and how to interact with Ethereum</p>
<h3 id="heading-4-try-building-out-a-full-stack-dapp">4. Try building out a full stack dapp</h3>
<p>In addition to Solidity, the other parts of the the development stack include a local Ethereum environment like <a target="_blank" href="https://hardhat.org/">Hardhat</a> or <a target="_blank" href="https://www.trufflesuite.com/">Truffle</a>, a wallet like <a target="_blank" href="https://metamask.io/">Metamask</a>, as well as a client-side library that allows you to interact with the blockchain, like either <a target="_blank" href="https://docs.ethers.io/">Ethers.js</a> or <a target="_blank" href="https://web3js.readthedocs.io/">Web3.js</a>.</p>
<p>To understand how all of this all fits together, it's useful to build out a full stack dapp on this stack from scratch. You can set up the front end project as well as the local development environment and deploy, run, and interact with a smart contract on the blockchain.</p>
<p>Here are two introductory courses to get you going with this:</p>
<ol>
<li><a target="_blank" href="https://www.youtube.com/watch?v=xWFba_9QYmc">Ethereum Programming Tutorial - DeFi, Solidity, Truffle, Web3.js</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=a0osIaAOFSE">The Complete Guide to Full Stack Ethereum Development</a> (<a target="_blank" href="https://www.freecodecamp.org/news/full-stack-ethereum-development/">and here it is in article form, too</a>)</li>
</ol>
<h3 id="heading-5-consider-reading-these-books">5. Consider reading these books</h3>
<p>The space itself moves very quickly, so technical books often get out of date just as quickly. The fundamentals of what Web3 is, though, have not changed much at all. </p>
<p>There are a few really great books that helped me not only grasp the current state of everything, but that also helped open my eyes to the future possibilities and opportunities that lie within it.</p>
<h4 id="heading-token-economy-how-the-web3-reinvents-the-internet">Token Economy - How the Web3 reinvents the internet</h4>
<p>If you only read one of these books, this is the one I'd say is the most important. It is a masterful deep dive into all of the shortcomings of the web as we know it, what Web3 aims to be, how it will affect various parts of our lives as we know it, and what needs to happen for this vision to be realized.</p>
<p>You can view the book <a target="_blank" href="https://shermin.net/token-economy-book/">here</a>.</p>
<h4 id="heading-the-infinite-machine-how-an-army-of-crypto-hackers-is-building-the-next-internet-with-ethereum">The Infinite Machine - How an Army of Crypto-hackers Is Building the Next Internet with Ethereum</h4>
<p>This is the amazing story of how Ethereum came to be, walking you through the history of it all. It is a very thorough and entertaining account of the origin story of Ethereum, I highly recommend checking it out.</p>
<p>You can view the book <a target="_blank" href="https://www.harpercollins.com/products/the-infinite-machine-camila-russo?variant=32123333836834">here</a>.</p>
<h4 id="heading-new-village-power-back-to-people">New Village - Power Back to People</h4>
<p>This is a really cool story of how blockchain technologies and decentralization will affect the future of the world.</p>
<p>You can view the book <a target="_blank" href="https://www.amazon.com/New-Village-Power-Back-People-Blockchain/dp/1718045743">here</a></p>
<h4 id="heading-how-to-defi">How to DeFi</h4>
<p>As you can probably tell by the title, this book focuses on how you can start using DeFi today. It gives you a good understanding about how you can use it today as well as some applications of it that we will see at some time in the future.</p>
<p>You can view the book <a target="_blank" href="https://landing.coingecko.com/how-to-defi/">here</a></p>
<h4 id="heading-the-spatial-web">The Spatial Web</h4>
<p>The Spatial Web is a book that explores the future of the web and all of the implications, not only of Web3 and decentralization, but how everything will come together to enable things that we may have not yet considered. </p>
<p>It does a good job weighing the positive and negatives as well as ways that we may be able to address any negative outcomes of what is to come.</p>
<p>You can view the book <a target="_blank" href="https://www.goodreads.com/book/show/52816204-the-spatial-web">here</a></p>
<p>And here are a couple of solidity books:</p>
<ul>
<li><a target="_blank" href="https://www.oreilly.com/library/view/hands-on-smart-contract/9781492045250/">Hands-On Smart Contract Development with Solidity and Ethereum</a></li>
<li><a target="_blank" href="https://www.oreilly.com/library/view/mastering-ethereum/9781491971932/">Mastering Ethereum</a></li>
</ul>
<h3 id="heading-6-listen-to-these-podcasts">6. Listen to these podcasts</h3>
<p>Here are some good podcasts:</p>
<ul>
<li><a target="_blank" href="https://outlierventures.io/podcasts/">Founders of Web 3</a> – The people that are creating and building the next phase of the internet.</li>
<li><a target="_blank" href="http://podcast.banklesshq.com/">Bankless</a> – The Ultimate Guide to Crypto Finance</li>
<li><a target="_blank" href="https://podcast.ethhub.io/">Into the Ether</a> – Podcast about Ethereum</li>
<li><a target="_blank" href="https://player.fm/series/crypto-101">Crypto 101</a></li>
<li><a target="_blank" href="https://player.fm/series/epicenter-learn-about-crypto-blockchain-ethereum-bitcoin-and-distributed-technologies-41400">Epicenter</a> – Learn about Crypto, Blockchain, Ethereum, Bitcoin and Distributed Technologies</li>
</ul>
<h3 id="heading-7-watch-these-youtube-channels">7. Watch these YouTube channels</h3>
<ul>
<li><a target="_blank" href="https://www.youtube.com/channel/UCNOfzGXD_C9YMYmnefmPH0g">Ethereum Foundation</a></li>
<li><a target="_blank" href="https://www.youtube.com/channel/UCZM8XQjNOyG2ElPpEUtNasA">Eat the Blocks</a> – Short videos on blockchain development</li>
<li><a target="_blank" href="https://www.youtube.com/c/Finematics/videos">Finematics</a> – Sharing interesting DeFi videos</li>
<li><a target="_blank" href="https://www.youtube.com/channel/UCY0xL8V6NzzFcwzHCgB8orQ">Dapp University</a> – Videos in the Ethereum space</li>
<li><a target="_blank" href="https://www.youtube.com/c/BlockGeeks/featured">BlockGeeks</a> – General Blockchain Training</li>
<li><a target="_blank" href="https://www.youtube.com/channel/UCvCp6vKY5jDr87htKH6hgDA">The Daily Gwei</a></li>
<li><a target="_blank" href="https://www.youtube.com/channel/UC_HI2i2peo1A-STdG22GFsA">Austin Griffith</a></li>
</ul>
<p>I've also begun doing videos and tutorials on Ethereum and Solidity, so consider checking out <a target="_blank" href="https://www.youtube.com/channel/UC7mca3O0DmdSG2Cr80sOD7g">my YouTube</a> channel.</p>
<h2 id="heading-tradeoffs-and-considerations-of-switching-careers">Tradeoffs and Considerations of Switching Careers</h2>
<p>There are always things to consider when making a career transition, but especially when considering this space.</p>
<p>There are a lot of positives, but there are also unknowns as well as negatives. Let's talk about some of them.</p>
<h3 id="heading-its-nascent-tech">It's nascent tech</h3>
<p>While there are many existing dapps and companies already flourishing, this space is very much still coming into existence in many ways.</p>
<p>There are a lot of problems that we still need to solve, and there are no clear answers for many questions you'll have. The problems being solved are often complex, sometimes combining one or more aspects of distributed systems, game theory, cryptography, economics, social and political science, identity, psychology, and more.</p>
<p>Because of this, there are still things that we cannot yet build with the existing solutions that are available.</p>
<p>I personally think this is one of the more exciting things about all of it it, but it's not for everyone.</p>
<h3 id="heading-its-a-volatile-space">It's a volatile space</h3>
<p>Many of the projects are built around various types of tokens. The value of many of these tokens rises and falls dramatically, and you often see that people gain and lose excitement in the entire space based on these swings.</p>
<p>If you haven't fundamentally bought into the ideas behind decentralization itself, you may find these ups and downs mentally taxing.</p>
<h3 id="heading-its-full-of-speculation">It's full of speculation</h3>
<p>Because a lot of people only buy into certain tokens in a speculative way, it attracts some people who are in it only for the money.</p>
<p>You see things like scammers trying to get over on people and steal their money, endless talk about price swings from people who are speculating, and outright scam projects that often discredit the industry as a whole.</p>
<p>This is an annoying part of it and I don't really see it going away anytime soon.</p>
<h3 id="heading-this-thread">This thread</h3>
<p>I would also check out <a target="_blank" href="https://twitter.com/jonsyu/status/1389635626698297344">this Twitter thread</a>. Although I have not experienced all of these things, he is definitely shining a light on some of the things I have seen.</p>
<h2 id="heading-general-tips-and-how-to-land-a-blockchain-or-crypto-related-job">General Tips and How to Land a Blockchain or Crypto-Related Job</h2>
<p>There are many areas within the space that you can focus on and provide a positive impact on a team. I'd look into the different areas like governance, DeFi, NFTs, and decentralized web protocols to see what interests you the most and then focus on that.</p>
<p>There are a lot of opportunities and a lot of ways to stand out and get noticed. If you find an interesting project and would like to get involved, jump right into their community and ecosystem and start learning. Then see where you may be able to help out. Join their Discord or look at their GitHub issues to find ways that you can contribute.</p>
<p>This will give you an opportunity to meet people involved in the project and will open up discussions for potentially landing a role with them. In fact, it is very common for people within the teams to take notice of active community participants, they will then often reach out and try to recruit you without you even applying.</p>
<p>The pay is usually <a target="_blank" href="https://cryptocurrencyjobs.co/salaries/solidity-developer/">good</a>. Depending on where you are coming from, it could be more or less, but it's probably not going to be at the high levels of what you see at FAANG companies. </p>
<p>There is probably more potential upside. Most companies offer a combination of base pay + equity in the form of their digital token, so if you stick around and can help make the project successful and the value of the token goes up, you can often make more than what you would in many other areas.</p>
<h2 id="heading-people-to-follow-on-twitter">People to follow on Twitter</h2>
<p>Here are a few people who you may consider following on Twitter:</p>
<p><a target="_blank" href="https://twitter.com/VitalikButerin">Vitalik</a><br><a target="_blank" href="https://twitter.com/ashleighschap">Ashleigh Schapp</a><br><a target="_blank" href="https://twitter.com/CryptoHayes">Arthur Hayes</a><br><a target="_blank" href="https://twitter.com/StaniKulechov">Stani Kulechov</a><br><a target="_blank" href="https://twitter.com/gkimbwala">Gloria Kimbwala</a><br><a target="_blank" href="https://twitter.com/niran">Niran Babalola</a><br><a target="_blank" href="https://twitter.com/ricburton">Ric Burton</a><br><a target="_blank" href="https://twitter.com/dennisonbertram">Dennison Bertram</a><br><a target="_blank" href="https://twitter.com/manasilvora">Mana Silvora</a><br><a target="_blank" href="https://twitter.com/austingriffith">Austin Griffith</a><br><a target="_blank" href="https://twitter.com/smpalladino">Santiago Palladino</a><br><a target="_blank" href="https://twitter.com/zmanian">Zaki Manian</a><br><a target="_blank" href="https://twitter.com/sassal0x">Anthony Sassano</a></p>
<p>I also found <a target="_blank" href="https://twitter.com/i/lists/869994563691319296/members">this comprehensive list</a> created by someone on Twitter.</p>
<p>A few people on my team at <a target="_blank" href="https://twitter.com/edgeandnode">Edge &amp; Node</a>:<br><a target="_blank" href="https://twitter.com/yanivgraph">Yaniv Tal</a><br><a target="_blank" href="https://twitter.com/theklineventure">Tegan Kline</a><br><a target="_blank" href="https://twitter.com/evabeylin">Eva Beylin</a><br><a target="_blank" href="https://twitter.com/azacharyf">Adam Fuller</a><br><a target="_blank" href="https://twitter.com/RezBrandon">Brandon Ramirez</a></p>
<h2 id="heading-teams-doing-interesting-stuff-and-hiring">Teams doing interesting stuff (and hiring)</h2>
<p><a target="_blank" href="https://compound.finance/about#jobs">Compound</a><br><a target="_blank" href="https://jobs.lever.co/Uniswap">Uniswap</a><br><a target="_blank" href="https://chainlinklabs.com/careers">Chainlink</a><br><a target="_blank" href="https://jobs.lever.co/SkynetLabs">Skynet Labs</a><br><a target="_blank" href="https://aave.com/careers/">Aave</a><br><a target="_blank" href="https://matic.network/careers/">Matic</a><br><a target="_blank" href="https://livepeer.org/jobs">Livepeer</a><br><a target="_blank" href="https://consensys.net/open-roles/">Consensys</a><br><a target="_blank" href="https://medium.com/the-ethereum-name-service/ens-is-hiring-come-build-a-new-decentralized-internet-with-us-24398dea3ac">ENS</a><br><a target="_blank" href="https://openzeppelin.com/jobs/">OpenZeppelin</a><br><a target="_blank" href="https://foundation.app/careers">Foundation</a><br><a target="_blank" href="https://cryptocurrencyjobs.co/startups/zora/">Zora</a><br><a target="_blank" href="https://synthetix.com/careers">Synthetix</a><br><a target="_blank" href="https://jobs.dcg.co/companies">Digital Currency Group</a></p>
<p>You can also find a pretty decent list of job opportunities in cryptocurrency <a target="_blank" href="https://cryptocurrencyjobs.co/">here</a>.</p>
<p>Also, my team at <a target="_blank" href="https://edgeandnode.com/jobs">Edge &amp; Node is hiring</a>!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Did I mention this space is volatile? Be ready for some high highs and low lows, but also for some of the most fun you may have in your career. </p>
<p>You'll be working alongside some of the smartest people in tech trying to solve some of the most complex problems that I think will ultimately have a massive positive impact on humanity.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
