<?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" version="2.0"><channel><title><![CDATA[EmmaOdia DevNotes]]></title><description><![CDATA[I build applications with JavaScript and Solidity. I publish technical articles on JavaScript, Solidity, Blockchain Infra and the EVM.]]></description><link>https://emmaodia.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 20 Jun 2026 23:49:52 GMT</lastBuildDate><atom:link href="https://emmaodia.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Build a Sonic Testnet Telegram DEX Bot with Covalent GoldRush]]></title><description><![CDATA[Imagine trading tokens directly from Telegram and getting real-time prices, portfolio balances, and transaction history in a clean, human-readable format.
In this guide, we’ll build exactly that: a Telegram trading bot that executes swaps on a custom...]]></description><link>https://emmaodia.hashnode.dev/sonic-testnet-tg-bot-covalent-goldrush</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/sonic-testnet-tg-bot-covalent-goldrush</guid><category><![CDATA[covalent goldrush]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[sonic blockchain]]></category><category><![CDATA[Covalent]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 29 Sep 2025 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767090352423/22f296a9-1b11-4b80-8030-02e8565cc82d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine trading tokens directly from <strong>Telegram</strong> and getting real-time prices, portfolio balances, and transaction history in a clean, human-readable format.</p>
<p>In this guide, we’ll build exactly that: a <strong>Telegram trading bot</strong> that executes swaps on a custom DEX deployed to the <strong>Sonic Testnet</strong> and enriches the experience with <strong>Covalent’s GoldRush API</strong>. Here is the Test version: @GoldrushAPISonicChainDEX_bot</p>
<p>By the end of this tutorial, you will have:</p>
<ul>
<li><p>A <strong>minimal DEX</strong> (Uniswap V2 style) deployed on Sonic Testnet</p>
</li>
<li><p>A working <strong>Telegram bot</strong> that can quote, swap, and check balances</p>
</li>
<li><p>Integrated <strong>Covalent GoldRush APIs</strong> to show prices in USD, portfolio breakdowns, and recent transactions</p>
</li>
</ul>
<p>This is a hands-on build and a great demonstration of how <strong>on-chain execution and Covalent’s off-chain enrichment</strong> create powerful developer tools.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>To follow along, you’ll need:</p>
<ul>
<li><p><strong>Node.js</strong> (v18+)</p>
</li>
<li><p>A <strong>Telegram account</strong> and bot token from @BotFather</p>
</li>
<li><p>A <strong>Sonic Testnet wallet</strong> with tokens (get some at the <a target="_blank" href="https://testnet.soniclabs.com/?utm_source=chatgpt.com">Sonic faucet</a>)</p>
</li>
<li><p><strong>Remix IDE</strong> (remix.ethereum.org) for deploying contracts</p>
</li>
<li><p>A <strong>Covalent API key</strong> (free at CovalentHQ)</p>
</li>
</ul>
<p>We’ll use a test wallet throughout—never paste your mainnet keys into tutorials.</p>
<h2 id="heading-minimal-dex-on-sonic"><strong>Minimal DEX on Sonic</strong></h2>
<p>Sonic Testnet doesn’t ship with a default router, I have deployed a <strong>minimal Uniswap V2-style DEX, which you can also rely on</strong>.</p>
<h3 id="heading-smart-contracts"><strong>Smart Contracts</strong></h3>
<p>ROUTER_V2=0x2e7f682863a9DCb32Dd298cCf8724603728d0edd<br />TOKEN_A=0x6c1C9a79AA84EB4026D80337a5EeC2677E367c2e<br />TOKEN_B=0x89b7Bc09d97Fc0A64b6EcBb7E2995f528F584312</p>
<h2 id="heading-initialize-the-project"><strong>Initialize the Project</strong></h2>
<p>Create a new project folder and install dependencies:</p>
<pre><code class="lang-bash">mkdir sonic-goldrush-dex

<span class="hljs-built_in">cd</span> sonic-goldrush-dex

npm init -y

npm install telegraf ethers node-fetch dotenv
</code></pre>
<p>We’ll use:</p>
<ul>
<li><p><code>telegraf</code> for Telegram bot commands</p>
</li>
<li><p><code>ethers</code> for contract calls</p>
</li>
<li><p><code>node-fetch</code> for API calls</p>
</li>
<li><p><code>dotenv</code> for environment config</p>
</li>
</ul>
<p>To add Environment Variables Cceate a <code>.env</code> file in the project root and add the following:</p>
<pre><code class="lang-bash">BOT_TOKEN=123456:ABC...           <span class="hljs-comment"># Telegram bot token from @BotFather</span>
PRIVATE_KEY=0xabc123...           <span class="hljs-comment"># Sonic Testnet wallet private key</span>
RPC_URL=https://rpc.testnet.soniclabs.com
CHAIN_ID=14601
ROUTER_V2=0xYourRouterAddress
TOKEN_WS=0xTokenAAddress          <span class="hljs-comment"># map TokenA to “WS”</span>
TOKEN_USDC=0xTokenBAddress        <span class="hljs-comment"># map TokenB to “USDC”</span>
COVALENT_API_KEY=ckey_xxx
COVALENT_CHAIN_ID=sonic-testnet
COVALENT_QUOTE=USD
</code></pre>
<ul>
<li><p>BOT_TOKEN allows your Node.js bot to speak to Telegram.</p>
</li>
<li><p>PRIVATE_KEY signs transactions on Sonic Testnet.</p>
</li>
<li><p>ROUTER_V2, TOKEN_WS, and TOKEN_USDC point to the contracts you deployed.</p>
</li>
<li><p>COVALENT_* configure GoldRush for price + portfolio enrichment.</p>
</li>
</ul>
<p>The bot doesn’t need full ABIs. Save this as abi.js:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {

  <span class="hljs-attr">ERC20_ABI</span>: [
    <span class="hljs-string">"function name() view returns (string)"</span>,
    <span class="hljs-string">"function symbol() view returns (string)"</span>,
    <span class="hljs-string">"function decimals() view returns (uint8)"</span>,
    <span class="hljs-string">"function totalSupply() view returns (uint256)"</span>,
    <span class="hljs-string">"function balanceOf(address) view returns (uint256)"</span>,
    <span class="hljs-string">"function allowance(address,address) view returns (uint256)"</span>,
    <span class="hljs-string">"function approve(address,uint256) returns (bool)"</span>,
    <span class="hljs-string">"function transfer(address,uint256) returns (bool)"</span>,
    <span class="hljs-string">"function transferFrom(address,address,uint256) returns (bool)"</span>
  ],

  <span class="hljs-attr">ROUTER_V2_ABI</span>: [
    <span class="hljs-string">"function getAmountsOut(uint amountIn, address[] calldata path) view returns (uint[] memory amounts)"</span>,
    <span class="hljs-string">"function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) returns (uint[] memory amounts)"</span>,
    <span class="hljs-string">"function addLiquidity(address,address,uint,uint) returns (uint liquidity)"</span>,
    <span class="hljs-string">"function removeLiquidity(address,address,uint) returns (uint,uint)"</span>
  ]
};
</code></pre>
<p>This keeps the bot lightweight while still able to interact with ERC-20s and the Router.</p>
<h2 id="heading-bot-core-quotes-swaps-balances"><strong>Bot Core (Quotes, Swaps, Balances)</strong></h2>
<p>In index.js, we start with <strong>environment validation</strong> and <strong>setup</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">require</span>(<span class="hljs-string">'dotenv'</span>).config();

<span class="hljs-keyword">const</span> { Telegraf } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'telegraf'</span>);
<span class="hljs-keyword">const</span> { ethers } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'ethers'</span>);
<span class="hljs-keyword">const</span> fetch = <span class="hljs-built_in">require</span>(<span class="hljs-string">'node-fetch'</span>);
<span class="hljs-keyword">const</span> { ERC20_ABI, ROUTER_V2_ABI } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./abi'</span>);

<span class="hljs-comment">// validate &amp; parse env</span>

<span class="hljs-keyword">const</span> provider = <span class="hljs-keyword">new</span> ethers.JsonRpcProvider(process.env.RPC_URL, process.env.CHAIN_ID);
<span class="hljs-keyword">const</span> wallet   = <span class="hljs-keyword">new</span> ethers.Wallet(process.env.PRIVATE_KEY, provider);
<span class="hljs-keyword">const</span> router   = <span class="hljs-keyword">new</span> ethers.Contract(process.env.ROUTER_V2, ROUTER_V2_ABI, wallet);
<span class="hljs-keyword">const</span> TOKENS = { <span class="hljs-attr">WS</span>: process.env.TOKEN_WS, <span class="hljs-attr">USDC</span>: process.env.TOKEN_USDC };
</code></pre>
<p>We now add <strong>helpers</strong>:</p>
<ul>
<li><p><code>parseToken()</code> → resolve a symbol or address</p>
</li>
<li><p><code>toUnits / fromUnits</code> → convert user input into correct decimals</p>
</li>
<li><p><code>getAmountsOut()</code> → router price quotes</p>
</li>
<li><p><code>ensureAllowance()</code> → auto-approve router if not approved</p>
</li>
<li><p><code>swapExactTokens()</code> → main swap function with slippage + deadline</p>
</li>
</ul>
<h3 id="heading-telegram-commands"><strong>Telegram commands</strong></h3>
<ul>
<li><p><code>/start</code> → shows wallet and commands</p>
</li>
<li><p><code>/price &lt;A&gt; &lt;B&gt; &lt;amount&gt;</code> → quotes a trade</p>
</li>
<li><p><code>/buy &lt;A&gt; &lt;B&gt; &lt;amount&gt;</code> → executes a swap</p>
</li>
<li><p><code>/balance &lt;token&gt;</code> → shows ERC-20 balance</p>
</li>
<li><p><code>/slippage &lt;bps&gt;</code> → sets tolerance per chat</p>
</li>
<li><p><code>/deadline &lt;mins&gt;</code> → sets deadline per chat</p>
</li>
</ul>
<p>At this point, you can <strong>quote and trade</strong> tokens from Telegram.</p>
<h2 id="heading-enrich-with-covalent-goldrush"><strong>Enrich with Covalent GoldRush</strong></h2>
<p>Raw on-chain data is functional but not human-friendly. Enter <strong>Covalent GoldRush</strong>.</p>
<p>We add a generic covalentFetch:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">covalentFetch</span>(<span class="hljs-params">path, params = {}</span>) </span>{
  <span class="hljs-keyword">const</span> qs = <span class="hljs-keyword">new</span> URLSearchParams({ <span class="hljs-attr">key</span>: process.env.COVALENT_API_KEY, ...params }).toString();
  <span class="hljs-keyword">const</span> url = https:<span class="hljs-comment">//api.covalenthq.com/v1/${process.env.COVALENT_CHAIN_ID}/${path}?${qs};</span>
  <span class="hljs-keyword">const</span> r = <span class="hljs-keyword">await</span> fetch(url);
  <span class="hljs-keyword">const</span> j = <span class="hljs-keyword">await</span> r.json();
  <span class="hljs-keyword">return</span> j;
}
</code></pre>
<h3 id="heading-usd-prices"><strong>USD Prices</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">covalentLatestPriceByContract</span>(<span class="hljs-params">contractAddress</span>) </span>{
  <span class="hljs-keyword">const</span> path = pricing/historical_by_addresses_v2/USD/${contractAddress}/;
  <span class="hljs-keyword">const</span> j = <span class="hljs-keyword">await</span> covalentFetch(path, { <span class="hljs-string">"page-size"</span>: <span class="hljs-number">1</span> });
  <span class="hljs-keyword">const</span> series = j?.data?.items?.[<span class="hljs-number">0</span>]?.prices || [];
  <span class="hljs-keyword">const</span> last = series[series.length - <span class="hljs-number">1</span>];
  <span class="hljs-keyword">return</span> last?.price ?? <span class="hljs-literal">null</span>;
}
</code></pre>
<h3 id="heading-portfolio-balances"><strong>Portfolio balances</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">covalentPortfolio</span>(<span class="hljs-params">address</span>) </span>{
  <span class="hljs-keyword">const</span> j = <span class="hljs-keyword">await</span> covalentFetch(<span class="hljs-string">`address/<span class="hljs-subst">${address}</span>/balances_v2/`</span>, { <span class="hljs-string">"quote-currency"</span>: <span class="hljs-string">"USD"</span>, <span class="hljs-attr">nft</span>: <span class="hljs-literal">false</span> });
  <span class="hljs-keyword">return</span> j?.data?.items || [];
}
</code></pre>
<h3 id="heading-transactions"><strong>Transactions</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">covalentLatestTxs</span>(<span class="hljs-params">address, n=<span class="hljs-number">5</span></span>) </span>{
  <span class="hljs-keyword">const</span> j = <span class="hljs-keyword">await</span> covalentFetch(<span class="hljs-string">`address/<span class="hljs-subst">${address}</span>/transactions_v3/`</span>, { <span class="hljs-string">"page-size"</span>: n });
  <span class="hljs-keyword">return</span> j?.data?.items || [];
}
</code></pre>
<h2 id="heading-gold-commands"><code>/gold</code> <strong>Commands</strong></h2>
<p>We group analytics under /gold:</p>
<ul>
<li><p><code>/gold price &lt;token&gt;</code> → latest USD/token from Covalent</p>
</li>
<li><p><code>/gold portfolio</code> → token balances with USD values</p>
</li>
<li><p><code>/gold txs me 5</code> → last 5 transactions</p>
</li>
</ul>
<p>For example:</p>
<pre><code class="lang-javascript">/gold portfolio

Portfolio (USD):
WS: <span class="hljs-number">5000</span> (~$<span class="hljs-number">4900.00</span>)
<span class="hljs-attr">USDC</span>: <span class="hljs-number">2500</span> (~$<span class="hljs-number">2500.00</span>)
</code></pre>
<h2 id="heading-demo-run"><strong>Demo Run</strong></h2>
<ol>
<li>Start the bot:</li>
</ol>
<p><code>node index.js</code></p>
<p>2. Run the following prompts in Telegram:</p>
<ul>
<li><p><code>/price WS USDC 1</code> → “1 WS → 0.99 USDC (~0.99 USD)”</p>
</li>
<li><p><code>/buy WS USDC 1</code> → “Swap sent ✅ tx: 0x1234…abcd”</p>
</li>
<li><p><code>/gold txs me 3</code> → shows last 3 bot wallet transactions</p>
</li>
</ul>
<p>Now your Telegram chat is a full trading and analytics interface.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>We combined <strong>on-chain execution</strong> (a minimal Sonic DEX + swaps) with <strong>off-chain enrichment</strong> (Covalent GoldRush) inside a <strong>Telegram bot</strong>. </p>
<p>Developers now have a blueprint to build high-frequency bots, portfolio dashboards, or automated strategies—all in a chat UX. Get your Covalent API key at covalenthq.com/platform and start experimenting today.</p>
]]></content:encoded></item><item><title><![CDATA[How to Vet GitHub Profiles Using JavaScript and the GitHub API]]></title><description><![CDATA[Introduction
Recently, I encountered a scenario where I needed to clean and validate data submitted via a form. The intent was to source developers, and therefore, the Form fields included names, emails, GitHub profiles, etc. Due to the nature of the...]]></description><link>https://emmaodia.hashnode.dev/how-to-vet-github-profiles-using-javascript-and-the-github-api</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-vet-github-profiles-using-javascript-and-the-github-api</guid><category><![CDATA[GitHub API]]></category><category><![CDATA[data cleaning ]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[axios]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 27 Jan 2025 16:03:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737992629280/58a6e662-9658-428c-b6a3-2c5ff0127198.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>Recently, I encountered a scenario where I needed to clean and validate data submitted via a form. The intent was to source developers, and therefore, the Form fields included names, emails, GitHub profiles, etc. Due to the nature of the form being made public, many responses were received, including from non-developers. The response was in thousands, so a db cleanup was then activated. To achieve the cleanup, I initiated a process of vetting the responses using GitHub profiles to ensure the information provided was accurate and meaningful. Using JavaScript and the GitHub API, I developed a solution that:</p>
<ol>
<li><p>Verified if a GitHub profile exists.</p>
</li>
<li><p>Checked if the profile has more than three repositories.</p>
</li>
<li><p>Checked if the profile has made more than five commits across all repositories.</p>
</li>
<li><p>Exported the results to a CSV file for further processing.</p>
</li>
</ol>
<p>This tutorial walks you through the process of building this solution.</p>
<hr />
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before diving into the code, make sure you have the following:</p>
<ol>
<li><p><strong>Node.js</strong> installed on your machine.</p>
</li>
<li><p>A <strong>GitHub Personal Access Token</strong> (optional but recommended to avoid hitting API rate limits). You can create one by following <a target="_blank" href="https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token">GitHub's guide</a>.</p>
</li>
<li><p>Basic knowledge of JavaScript and Node.js.</p>
</li>
</ol>
<hr />
<h2 id="heading-set-up-the-project"><strong>Set Up the Project</strong></h2>
<h3 id="heading-initialize-the-project"><strong>Initialize the Project</strong></h3>
<p>Open your Terminal to start a new project</p>
<pre><code class="lang-bash">mkdir github-profile-vetting
<span class="hljs-built_in">cd</span> github-profile-vetting
</code></pre>
<pre><code class="lang-bash">npm init -y
</code></pre>
<pre><code class="lang-bash">npm install axios
</code></pre>
<h3 id="heading-create-the-script-file"><strong>Create the Script File</strong></h3>
<p>Create a file named <code>vetProfiles.js</code> and paste the following code. Below is a breakdown of each function in the script:</p>
<h4 id="heading-import-the-required-libraries"><strong>Import the required Libraries</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">'axios'</span>);
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
</code></pre>
<p><code>axios</code> is used to make HTTP requests to GitHub's API endpoints, allowing the script to fetch data.</p>
<p><code>fs</code> enables file creation and writing, which is crucial for exporting the processed data (in this case, to a CSV file) that can be shared or analyzed further.</p>
<p><code>path</code> ensures the portability of file paths across operating systems without path-related errors.</p>
<h4 id="heading-set-up-the-axios-instance"><strong>Set Up the Axios Instance</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-comment">// GitHub API base URL</span>
<span class="hljs-keyword">const</span> GITHUB_API_BASE_URL = <span class="hljs-string">'https://api.github.com'</span>;

<span class="hljs-comment">// Replace with your GitHub personal access token (optional but recommended for higher rate limits)</span>
<span class="hljs-keyword">const</span> GITHUB_PERSONAL_ACCESS_TOKEN = <span class="hljs-string">'your_personal_access_token'</span>;

<span class="hljs-keyword">const</span> axiosInstance = axios.create({
  <span class="hljs-attr">baseURL</span>: GITHUB_API_BASE_URL,
  <span class="hljs-attr">headers</span>: GITHUB_PERSONAL_ACCESS_TOKEN
    ? { <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">${GITHUB_PERSONAL_ACCESS_TOKEN}</span>`</span> }
    : {},
});
</code></pre>
<p>This initializes an Axios instance with the base URL for GitHub's API. If a personal access token is provided, it includes an Authorization header for authenticated requests, which helps avoid API rate limits.</p>
<h4 id="heading-function-checkgithubprofile"><strong>Function:</strong> <code>checkGitHubProfile</code></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkGitHubProfile</span>(<span class="hljs-params">username</span>) </span>{

  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> userResponse = <span class="hljs-keyword">await</span> axiosInstance.get(<span class="hljs-string">`/users/<span class="hljs-subst">${username}</span>`</span>);
    <span class="hljs-keyword">const</span> publicReposCount = userResponse.data.public_repos;

    <span class="hljs-keyword">if</span> (publicReposCount &lt;= <span class="hljs-number">3</span>) {
      <span class="hljs-keyword">return</span> { username, <span class="hljs-attr">exists</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">meetsCriteria</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">isProspect</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'Less than 3 repositories'</span> };
    }

    <span class="hljs-keyword">let</span> totalCommits = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">let</span> page = <span class="hljs-number">1</span>;

    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
      <span class="hljs-keyword">const</span> reposResponse = <span class="hljs-keyword">await</span> axiosInstance.get(<span class="hljs-string">`/users/<span class="hljs-subst">${username}</span>/repos`</span>, {
        <span class="hljs-attr">params</span>: { <span class="hljs-attr">per_page</span>: <span class="hljs-number">100</span>, page },
      });

      <span class="hljs-keyword">const</span> repos = reposResponse.data;
      <span class="hljs-keyword">if</span> (repos.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> repo <span class="hljs-keyword">of</span> repos) {
        <span class="hljs-keyword">const</span> commitsResponse = <span class="hljs-keyword">await</span> axiosInstance.get(<span class="hljs-string">`/repos/<span class="hljs-subst">${repo.owner.login}</span>/<span class="hljs-subst">${repo.name}</span>/commits`</span>, {
          <span class="hljs-attr">params</span>: { <span class="hljs-attr">author</span>: username, <span class="hljs-attr">per_page</span>: <span class="hljs-number">1</span> },
        });
        totalCommits += commitsResponse.headers[<span class="hljs-string">'x-total-count'</span>]
          ? <span class="hljs-built_in">parseInt</span>(commitsResponse.headers[<span class="hljs-string">'x-total-count'</span>], <span class="hljs-number">10</span>)
          : <span class="hljs-number">0</span>;
      }
      page++;
    }

    <span class="hljs-keyword">if</span> (totalCommits &lt;= <span class="hljs-number">5</span>) {
      <span class="hljs-keyword">return</span> { username, <span class="hljs-attr">exists</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">meetsCriteria</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">isProspect</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'Less than 5 commits'</span> };
    }
    <span class="hljs-keyword">return</span> { username, <span class="hljs-attr">exists</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">meetsCriteria</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">isProspect</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'Meets all criteria'</span> };
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">if</span> (error.response &amp;&amp; error.response.status === <span class="hljs-number">404</span>) {
      <span class="hljs-keyword">return</span> { username, <span class="hljs-attr">exists</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">meetsCriteria</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">isProspect</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'Profile does not exist'</span> };
    }
    <span class="hljs-keyword">return</span> { username, <span class="hljs-attr">exists</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">meetsCriteria</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">isProspect</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'Error occurred'</span> };
  }
}
</code></pre>
<p>This function checks if a GitHub profile exists and evaluates it based on repository count and commit history.</p>
<ul>
<li><ol>
<li><p>Verify if the profile exists using the /users/:username endpoint.</p>
<ol start="2">
<li><p>Check the number of public repositories.</p>
</li>
<li><p>Fetch commit data from each repository and calculate the total commits.</p>
</li>
<li><p>Return the result, including whether the profile meets the criteria.</p>
</li>
</ol>
</li>
</ol>
</li>
</ul>
<h4 id="heading-function-checkprofiles"><strong>Function:</strong> <code>checkProfiles</code></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkProfiles</span>(<span class="hljs-params">profiles</span>) </span>{

  <span class="hljs-keyword">const</span> results = [];

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> username <span class="hljs-keyword">of</span> profiles) {
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> checkGitHubProfile(username);
    results.push(result);
  }

  <span class="hljs-keyword">const</span> csvContent = [
    <span class="hljs-string">'Username,Exists,MeetsCriteria,IsProspect,Reason'</span>,
    ...results.map(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${r.username}</span>,<span class="hljs-subst">${r.exists}</span>,<span class="hljs-subst">${r.meetsCriteria}</span>,<span class="hljs-subst">${r.isProspect}</span>,"<span class="hljs-subst">${r.reason}</span>"`</span>),
  ].join(<span class="hljs-string">'\n'</span>);

  <span class="hljs-keyword">const</span> outputPath = path.join(__dirname, <span class="hljs-string">'github_profiles_check.csv'</span>);
  fs.writeFileSync(outputPath, csvContent);

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Results exported to <span class="hljs-subst">${outputPath}</span>`</span>);
}
</code></pre>
<p>This function processes multiple GitHub profiles and generates a CSV file with the results. It iterates through the list of usernames and calls checkGitHubProfile for each. The response is then formatted into a CSV string and exported to a file named github_profiles_check.csv</p>
<h4 id="heading-example-usage"><strong>Example Usage</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> githubProfiles = [<span class="hljs-string">'octocat'</span>, <span class="hljs-string">'torvalds'</span>, <span class="hljs-string">'nonexistentprofile'</span>];
checkProfiles(githubProfiles);
</code></pre>
<p>Pass some GitHub profiles to the checkProfiles function with a list of sample usernames in an array string.</p>
<hr />
<h2 id="heading-run-the-script"><strong>Run the Script</strong></h2>
<pre><code class="lang-bash">node vetProfiles.js
</code></pre>
<p>The script will verify each GitHub profile and check for repositories and commits. The results will be exported to a CSV file named github_profiles_check.csv.</p>
<hr />
<h2 id="heading-export-and-analyze-the-data"><strong>Export and Analyze the Data</strong></h2>
<ul>
<li><p>Open the CSV file in Google Sheets or Excel to review the results.</p>
</li>
<li><p>Use <strong>Conditional Formatting</strong> in Google Sheets to highlight cells where MeetsCriteria is TRUE.</p>
</li>
<li><p>Use the COUNTIF function to count how many profiles meet the criteria:</p>
<pre><code class="lang-bash">  =COUNTIF(ColumnA:ColumnZ, <span class="hljs-string">"TRUE"</span>)
</code></pre>
</li>
</ul>
<hr />
<h2 id="heading-lessons-learned"><strong>Lessons Learned</strong></h2>
<p>This process helped clean up and validate user-submitted data efficiently. The GitHub API allowed me to automate a significant part of the work, reducing manual effort and errors. The experience reinforced the importance of leveraging APIs to streamline workflows.</p>
<hr />
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>By combining JavaScript, the GitHub API, and some simple scripting, I was able to build a powerful tool to vet GitHub profiles and export the results for analysis. This tutorial can be adapted to other use cases requiring data validation and processing.</p>
<p>Feel free to modify the <a target="_blank" href="https://gist.github.com/emmaodia/42c22c780136bb4b0df2a5c89d91d065">script</a> to suit your needs and happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Building the Next.js Frontend for Your Prediction Game - Part 2]]></title><description><![CDATA[Building the Next.js Frontend for Your Prediction Game - Part 2

Introduction
In this second part of the tutorial, I'll guide you through building a Frontend application using Next.js to interact with the smart contract you deployed in Part 1. This f...]]></description><link>https://emmaodia.hashnode.dev/build-on-linea-blockchain-part-2</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/build-on-linea-blockchain-part-2</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Linea Blockchain]]></category><category><![CDATA[consensys]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 02 Sep 2024 02:09:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725238230566/3e22efea-2cba-4b1b-b1d9-9a6c58f2d450.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-building-the-nextjs-frontend-for-your-prediction-game-part-2"><strong>Building the Next.js Frontend for Your Prediction Game - Part 2</strong></h3>
<hr />
<p><strong>Introduction</strong></p>
<p>In this second part of the tutorial, I'll guide you through building a Frontend application using Next.js to interact with the smart contract you deployed in Part 1. This frontend will allow users to connect their MetaMask wallets, make predictions, place bets, and see the results of their game.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites:</strong></h3>
<p>Before diving into the tutorial, ensure you have the following:</p>
<ul>
<li><p>A basic understanding of React and Next.js.</p>
</li>
<li><p>Node.js and npm installed on your machine.</p>
</li>
<li><p>The Smart Contract deployed to the Linea Sepolia Testnet (from Part 1).</p>
</li>
<li><p>The Smart Contract address and ABI from the deployed contract.</p>
</li>
</ul>
<h3 id="heading-step-1-setting-up-the-nextjs-project"><strong>Step 1: Setting Up the Next.js Project</strong></h3>
<ol>
<li><strong>Create a New Next.js Project:</strong></li>
</ol>
<p>Open your terminal and create a new Next.js project and navigate to the project directory using the following command:</p>
<pre><code class="lang-bash">npx create-next-app prediction-game &amp;&amp; <span class="hljs-built_in">cd</span> prediction-game
</code></pre>
<ol start="2">
<li><strong>Install Dependencies:</strong></li>
</ol>
<p>Install the <a target="_blank" href="https://viem.sh/">viemjs</a> for interacting with the blockchain:</p>
<pre><code class="lang-bash">npm install viem ethers
</code></pre>
<ol start="3">
<li>Install Tailwind CSS for styling:</li>
</ol>
<pre><code class="lang-bash">npx tailwindcss init -p
</code></pre>
<p>Configure Tailwind by adding the following to your tailwind.config.js:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
<span class="hljs-attr">content</span>: [
    <span class="hljs-string">"./pages/**/*.{js,ts,jsx,tsx}"</span>,
    <span class="hljs-string">"./components/**/*.{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>Add Tailwind to your global CSS file in styles/globals.css:</p>
<pre><code class="lang-javascript">@tailwind base;
@tailwind components;
@tailwind utilities;
</code></pre>
<h3 id="heading-step-2-setting-up-the-environment-variables"><strong>Step 2: Setting Up the Environment Variables</strong></h3>
<p><strong>Create a .env.local file in your project root:</strong></p>
<p>Store your Smart Contract address:</p>
<pre><code class="lang-javascript">NEXT_PUBLIC_CONTRACT_ADDRESS=<span class="hljs-number">0</span>xYourContractAddress
</code></pre>
<p><strong>Add the ABI File:</strong></p>
<p>Create a new file named <code>abi.js</code> in the root directory.</p>
<p>Copy the ABI of your smart contract (from Part 1) and paste in an <code>export const</code> declaration.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ABI = [<span class="hljs-comment">//paste ABI here]</span>
</code></pre>
<h3 id="heading-step-3-connecting-to-metamask"><strong>Step 3: Connecting to MetaMask</strong></h3>
<p><strong>Create a MetaMask Connection Component:</strong></p>
<p>In your <code>pages/index.js</code>, remove all the template code. Set up a basic structure to connect to MetaMask:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> {
  createWalletClient,
  custom,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"viem"</span>;
<span class="hljs-keyword">import</span> { lineaSepolia } <span class="hljs-keyword">from</span> <span class="hljs-string">"viem/chains"</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">const</span> [client, setClient] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [address, setAddress] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [connected, setConnected] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> connectToMetaMask = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span> !== <span class="hljs-string">"undefined"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span>.ethereum !== <span class="hljs-string">"undefined"</span>) {
      <span class="hljs-keyword">try</span> {
        <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">const</span> walletClient = createWalletClient({
          <span class="hljs-attr">chain</span>: lineaSepolia,
          <span class="hljs-attr">transport</span>: custom(<span class="hljs-built_in">window</span>.ethereum),
        });
        <span class="hljs-keyword">const</span> [userAddress] = <span class="hljs-keyword">await</span> walletClient.getAddresses();
        setClient(walletClient);
        setAddress(userAddress);
        setConnected(<span class="hljs-literal">true</span>);
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Connected account:"</span>, userAddress);
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"User denied account access:"</span>, error);
      }
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"MetaMask is not installed or not running in a browser environment!"</span>);
    }
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>
      <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">flex</span> <span class="hljs-attr">min-h-screen</span> <span class="hljs-attr">flex-col</span> <span class="hljs-attr">items-center</span> <span class="hljs-attr">justify-between</span> <span class="hljs-attr">p-24</span>`}
    &gt;</span>
      {!connected ? (
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{connectToMetaMask}</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>
        &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">p</span>&gt;</span>Connected as: {address}<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">main</span>&gt;</span></span>
  );
}
</code></pre>
<p>This component allows users to connect their MetaMask wallet.</p>
<h3 id="heading-step-4-building-the-form-for-the-play-method"><strong>Step 4: Building the Form for the</strong> <code>play</code> Method</h3>
<p><strong>Add the Form UI:</strong></p>
<p>Modify your <code>Home</code> component to include a form that allows users to input their prediction and bet amount. We will add various states to manage the form inputs.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> ABI <span class="hljs-keyword">from</span> <span class="hljs-string">"../abi"</span>;

<span class="hljs-keyword">const</span> publicClient = createPublicClient({
  <span class="hljs-attr">chain</span>: lineaSepolia,
  <span class="hljs-attr">transport</span>: http(),
});

<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">// Add new States</span>
  <span class="hljs-keyword">const</span> [houseBalance, setHouseBalance] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [prediction, setPrediction] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [betAmount, setBetAmount] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [transactionHash, setTransactionHash] = useState(<span class="hljs-string">""</span>);

    <span class="hljs-keyword">const</span> handlePlay = <span class="hljs-keyword">async</span> (event) =&gt; {
      event.preventDefault();

      <span class="hljs-keyword">if</span> (!client || !address) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Client or address not available"</span>);
        <span class="hljs-keyword">return</span>;
      }

      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> { request } = <span class="hljs-keyword">await</span> publicClient.simulateContract({
          <span class="hljs-attr">account</span>: address,
          <span class="hljs-attr">address</span>: process.env.NEXT_PUBLIC_CONTRACT_ADDRESS,
          <span class="hljs-attr">abi</span>: ABI,
          <span class="hljs-attr">functionName</span>: <span class="hljs-string">"play"</span>,
          <span class="hljs-attr">args</span>: [<span class="hljs-built_in">parseInt</span>(prediction, <span class="hljs-number">10</span>)],
          <span class="hljs-attr">value</span>: parseEther(betAmount),
        });

        <span class="hljs-keyword">if</span> (!request) {
          <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Simulation failed to return a valid request object."</span>);
          <span class="hljs-keyword">return</span>;
        }

        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Simulation successful. Request object:"</span>, request);

        <span class="hljs-keyword">const</span> hash = <span class="hljs-keyword">await</span> client.writeContract(request);
        setTransactionHash(hash);
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Transaction sent: <span class="hljs-subst">${hash}</span>`</span>);

        <span class="hljs-keyword">const</span> receipt = <span class="hljs-keyword">await</span> client.waitForTransactionReceipt({hash});
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Transaction confirmed: <span class="hljs-subst">${receipt.transactionHash}</span>`</span>);
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Simulation or transaction failed:"</span>, error);
      }
    };

    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handlePlay}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mt-4"</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-4"</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 text-sm font-bold mb-2"</span>&gt;</span>
              Prediction (0-9):
            <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">type</span>=<span class="hljs-string">"number"</span>
              <span class="hljs-attr">min</span>=<span class="hljs-string">"0"</span>
              <span class="hljs-attr">max</span>=<span class="hljs-string">"9"</span>
              <span class="hljs-attr">value</span>=<span class="hljs-string">{prediction}</span>
              <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setPrediction(e.target.value)}
              required
              className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
            /&gt;
          <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-4"</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 text-sm font-bold mb-2"</span>&gt;</span>
              Bet Amount (in ETH):
            <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">type</span>=<span class="hljs-string">"text"</span>
              <span class="hljs-attr">value</span>=<span class="hljs-string">{betAmount}</span>
              <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setBetAmount(e.target.value)}
              required
              className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
            /&gt;
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</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>
          &gt;</span>
            Play
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

        {transactionHash &amp;&amp; (
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mt-4"</span>&gt;</span>Transaction sent: {transactionHash}<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>
    );
}
</code></pre>
<p><strong>Form Input:</strong> Users can input their prediction (a number between 0 and 9) and the amount they want to bet.</p>
<p><strong>Transaction Handling:</strong> The form submits the data, simulates the transaction, and sends it if successful. The transaction hash is displayed on the UI.</p>
<h3 id="heading-step-5-handling-contract-events"><strong>Step 5: Handling Contract Events</strong></h3>
<p><strong>Fetch and Display Game Results:</strong></p>
<p>Add a function to handle events emitted by the contract:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fetchGameEvents = <span class="hljs-keyword">async</span> (blockNumber, transactionHash) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> logs = <span class="hljs-keyword">await</span> publicClient.getContractEvents({
      <span class="hljs-attr">client</span>: publicClient,
      <span class="hljs-attr">address</span>: process.env.NEXT_PUBLIC_CONTRACT_ADDRESS,
      <span class="hljs-attr">abi</span>: ABI,
      <span class="hljs-attr">eventName</span>: <span class="hljs-string">"GamePlayed"</span>,
      <span class="hljs-attr">fromBlock</span>: blockNumber,
      <span class="hljs-attr">toBlock</span>: blockNumber,
    });

    <span class="hljs-keyword">if</span> (logs.length &gt; <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">const</span> event = logs[<span class="hljs-number">0</span>];
      <span class="hljs-keyword">const</span> { args } = event;
      <span class="hljs-keyword">const</span> { player, amount, prediction, houseNumber } = args;
      setGameResult(<span class="hljs-string">`Game Played: Player <span class="hljs-subst">${player}</span> predicted <span class="hljs-subst">${prediction}</span>, House Number: <span class="hljs-subst">${houseNumber}</span>, Bet Amount: <span class="hljs-subst">${amount}</span>`</span>);
    }

    <span class="hljs-keyword">const</span> wonLogs = <span class="hljs-keyword">await</span> publicClient.getContractEvents({
      <span class="hljs-attr">client</span>: publicClient,
      <span class="hljs-attr">address</span>: process.env.NEXT_PUBLIC_CONTRACT_ADDRESS,
      <span class="hljs-attr">abi</span>: ABI,
      <span class="hljs-attr">eventName</span>: <span class="hljs-string">"GameWon"</span>,
      <span class="hljs-attr">fromBlock</span>: blockNumber,
      <span class="hljs-attr">toBlock</span>: blockNumber,
    });

    <span class="hljs-keyword">if</span> (wonLogs.length &gt; <span class="hljs-number">0</span>) {
      setGameResult(<span class="hljs-string">`You won the game!`</span>);
    }

    <span class="hljs-keyword">const</span> lostLogs = <span class="hljs-keyword">await</span> publicClient.getContractEvents({
      <span class="hljs-attr">client</span>: publicClient,
      <span class="hljs-attr">address</span>: process.env.NEXT_PUBLIC_CONTRACT_ADDRESS,
      <span class="hljs-attr">abi</span>: ABI,
      <span class="hljs-attr">eventName</span>: <span class="hljs-string">"GameLost"</span>,
      <span class="hljs-attr">fromBlock</span>: blockNumber,
      <span class="hljs-attr">toBlock</span>: blockNumber,
    });

    <span class="hljs-keyword">if</span> (lostLogs.length &gt; <span class="hljs-number">0</span>) {
      setGameResult(<span class="hljs-string">`You lost the game.`</span>);
    }
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Failed to fetch game events:"</span>, error);
  }
};
</code></pre>
<p>This function listens for the <code>GamePlayed</code>, <code>GameWon</code>, and <code>GameLost</code> events and updates the UI with the appropriate message.</p>
<p>Update the States, the <code>play</code> function and the UI to display the results.</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// State to store game result</span>
    <span class="hljs-keyword">const</span> [gameResult, setGameResult] = useState(<span class="hljs-string">""</span>);

 <span class="hljs-comment">// After confirmation in handle play, fetch and handle events</span>
    <span class="hljs-keyword">await</span> fetchGameEvents(receipt.blockNumber, receipt.transactionHash);

 <span class="hljs-comment">// In the UI After Hash is displayed, return Game Result</span>
    {gameResult &amp;&amp; (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"mt-4"</span>&gt;</span>{gameResult}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
    )}
</code></pre>
<h3 id="heading-step-6-running-the-application"><strong>Step 6: Running the Application</strong></h3>
<p><strong>Start the Development Server:</strong></p>
<p>Run the following command to start the Next.js development server</p>
<pre><code class="lang-javascript">npm run dev
</code></pre>
<p>Open your browser and navigate to <a target="_blank" href="http://localhost:3000"><code>http://localhost:3000</code></a>.</p>
<p><strong>Testing the App:</strong></p>
<p>Connect your MetaMask wallet, place bets, and see the game results in real-time.</p>
<h3 id="heading-conclusion"><strong>Conclusion:</strong></h3>
<p>In this second part of the tutorial, you've built a complete Frontend application for your blockchain-based prediction game using Next.js. Users can connect their MetaMask wallets, place bets, and view game results directly in the browser. You've successfully bridged the gap between blockchain and web development, creating a seamless user experience.</p>
<p>Feel free to customize and extend this application further. You might want to add features like historical game data, leaderboards, or more sophisticated game mechanics.</p>
<p>You can find the complete code <a target="_blank" href="https://github.com/emmaodia/ath">here</a>. Live <a target="_blank" href="https://ath-nu.vercel.app/">Website</a>.</p>
<p>Happy coding! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[Writing and Deploying a Smart Contract to Linea Blockchain - Part 1]]></title><description><![CDATA[Introduction
In this tutorial, I'll guide you through writing and deploying a Solidity Smart Contract on the Linea blockchain. This smart contract will form the backbone of a simple prediction game where users can wager Ether, make predictions, and e...]]></description><link>https://emmaodia.hashnode.dev/build-on-linea-blockchain-part-1</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/build-on-linea-blockchain-part-1</guid><category><![CDATA[Linea Blockchain]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[consensys]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 02 Sep 2024 02:06:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725234960041/275a9f2c-2e62-4e65-a94b-5d83c747993e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>In this tutorial, I'll guide you through writing and deploying a Solidity Smart Contract on the Linea blockchain. This smart contract will form the backbone of a simple prediction game where users can wager Ether, make predictions, and either win or lose based on the outcome.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites:</strong></h3>
<p>Before diving into the tutorial, ensure you have the following:</p>
<ul>
<li><p>Basic knowledge of Solidity and Smart Contracts.</p>
</li>
<li><p>Familiarity with Ethereum development tools like Remix, MetaMask, and a code editor (e.g., VS Code).</p>
</li>
<li><p>MetaMask wallet installed and connected to the Linea Sepolia Testnet.</p>
</li>
<li><p>Some test Ether in your MetaMask wallet for deployment and testing.</p>
<p>  Please note: You need some Ether on Linea Mainnet to get Test Ether on the Linea <a target="_blank" href="https://docs.linea.build/users/move-funds/fund#linea-sepolia">Faucets</a>.</p>
</li>
</ul>
<h3 id="heading-step-1-setting-up-your-development-environment"><strong>Step 1: Setting Up Your Development Environment</strong></h3>
<ol>
<li><p><strong>Install MetaMask:</strong></p>
<ul>
<li><p>If you haven't already, install the MetaMask browser extension.</p>
</li>
<li><p>Connect MetaMask to the Linea Sepolia testnet. You can add the Linea Sepolia network by visiting <a target="_blank" href="https://chainlist.org/">ChainList</a> . You can optionally add Linear Network information using the following <a target="_blank" href="https://docs.linea.build/developers/quickstart/info-contracts#network-information">details</a>:</p>
<ul>
<li><p><strong>Network Name:</strong> Linea Sepolia</p>
</li>
<li><p><strong>New RPC URL:</strong> <code>https://rpc.sepolia.linea.build</code></p>
</li>
<li><p><strong>Chain ID:</strong> <code>59141</code></p>
</li>
<li><p><strong>Currency Symbol:</strong> ETH</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Access Remix IDE:</strong></p>
<ul>
<li><p>Open <a target="_blank" href="https://remix.ethereum.org/">Remix IDE</a> in your browser.</p>
<p>  Remix is an online IDE that allows you to write, compile, and deploy Solidity Smart Contracts directly from your browser.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-step-2-writing-the-smart-contract"><strong>Step 2: Writing the Smart Contract</strong></h3>
<p>Let's start by writing the Solidity smart contract for the prediction game.</p>
<ol>
<li><p><strong>Create a New File:</strong></p>
<ul>
<li>In Remix, create a new file named <code>PredictionGame.sol</code>.</li>
</ul>
</li>
<li><p><strong>Write the Contract:</strong></p>
<ul>
<li>Copy and paste the following Solidity code into your new file:</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    solidityCopy code<span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
    pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.0</span>;

    contract PredictionGame {
        address public owner;
        uint256 public houseBalance;

        event GamePlayed(address indexed player, uint256 amount, uint256 prediction, uint256 houseNumber);
        event GameWon(address indexed player, uint256 amountWon);
        event GameLost(address indexed player, uint256 amountLost);

        <span class="hljs-keyword">constructor</span>() {
            owner = msg.sender;
        }

        modifier onlyOwner() {
            <span class="hljs-built_in">require</span>(msg.sender == owner, <span class="hljs-string">"Only the owner can call this function"</span>);
            _;
        }

        modifier sufficientFunds(uint256 amount) {
            <span class="hljs-built_in">require</span>(msg.value &gt;= amount, <span class="hljs-string">"Insufficient funds to play"</span>);
            _;
        }

        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">depositToHouse</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> <span class="hljs-title">onlyOwner</span> </span>{
            houseBalance += msg.value;
        }

        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdrawHouseFunds</span>(<span class="hljs-params">uint256 amount</span>) <span class="hljs-title">public</span> <span class="hljs-title">onlyOwner</span> </span>{
            <span class="hljs-built_in">require</span>(amount &lt;= houseBalance, <span class="hljs-string">"Not enough funds in the house"</span>);
            houseBalance -= amount;
            payable(owner).transfer(amount);
        }

        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateRandomNumber</span>(<span class="hljs-params"></span>) <span class="hljs-title">private</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> uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % <span class="hljs-number">10</span>;
        }

        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">play</span>(<span class="hljs-params">uint256 userPrediction</span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> <span class="hljs-title">sufficientFunds</span>(<span class="hljs-params"><span class="hljs-number">0.0001</span> ether</span>) </span>{
            <span class="hljs-built_in">require</span>(houseBalance &gt;= msg.value * <span class="hljs-number">10</span> / <span class="hljs-number">100</span>, <span class="hljs-string">"House doesn't have enough balance to cover potential winnings"</span>);
            <span class="hljs-built_in">require</span>(msg.value &gt;= <span class="hljs-number">0.0001</span> ether, <span class="hljs-string">"Must bet at least 0.0001 Ether"</span>);
            <span class="hljs-built_in">require</span>(userPrediction &gt;= <span class="hljs-number">0</span> &amp;&amp; userPrediction &lt;= <span class="hljs-number">9</span>, <span class="hljs-string">"Prediction must be between 0 and 9"</span>);

            uint256 houseNumber = generateRandomNumber();
            emit GamePlayed(msg.sender, msg.value, userPrediction, houseNumber);

            <span class="hljs-keyword">if</span> (userPrediction == houseNumber) {
                uint256 winnings = msg.value + msg.value * <span class="hljs-number">10</span> / <span class="hljs-number">100</span>;
                houseBalance -= winnings - msg.value;
                payable(msg.sender).transfer(winnings);
                emit GameWon(msg.sender, winnings);
            } <span class="hljs-keyword">else</span> {
                uint256 loss = msg.value * <span class="hljs-number">15</span> / <span class="hljs-number">100</span>;
                houseBalance += loss;
                payable(owner).transfer(loss);
                payable(msg.sender).transfer(msg.value - loss);
                emit GameLost(msg.sender, loss);
            }
        }

        receive() external payable {
            houseBalance += msg.value;
        }
    }
</code></pre>
<h3 id="heading-step-3-understanding-the-smart-contract"><strong>Step 3: Understanding the Smart Contract</strong></h3>
<p>This contract allows users to wager an amount and predict a number between 0 and 9, where they are playing "against the house." If the user guesses correctly, they win their bet amount plus 10% from the house. If they lose, the house takes 15% of their bet. The "house" stakes an amount in the Smart Contract that users can wager against.</p>
<ul>
<li><p><strong>Key Functions:</strong></p>
<ul>
<li><p><code>depositToHouse</code>: Allows the owner of the Smart Contract to deposit Ether into the house balance.</p>
</li>
<li><p><code>withdrawHouseFunds</code>: Allows the owner to withdraw Ether from the house balance.</p>
</li>
<li><p><code>play</code>: The primary function where users place their bet and make a prediction.</p>
</li>
<li><p><code>generateRandomNumber</code>: Generates a pseudo-random number between 0 and 9.</p>
</li>
<li><p><code>receive</code>: Fallback function to receive Ether.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-step-4-compiling-the-smart-contract"><strong>Step 4: Compiling the Smart Contract</strong></h3>
<ol>
<li><p><strong>Compile the Contract:</strong></p>
<ul>
<li><p>In Remix, navigate to the "Solidity Compiler" tab on the left sidebar.</p>
</li>
<li><p>Ensure the correct Solidity version (<code>^0.8.18</code>) is selected.</p>
</li>
<li><p>Click "Compile PredictionGame.sol".</p>
</li>
<li><p>You should see a green checkmark next to the compilation button if there are no errors.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-step-5-deploying-the-smart-contract-to-linea-sepolia"><strong>Step 5: Deploying the Smart Contract to Linea Sepolia</strong></h3>
<ol>
<li><p><strong>Deploy the Contract:</strong></p>
<ul>
<li><p>Go to the "Deploy &amp; Run Transactions" tab in Remix.</p>
</li>
<li><p>Ensure the "Environment" is set to "Injected Web3" (MetaMask should be connected).</p>
</li>
<li><p>Select the <code>PredictionGame</code> contract from the dropdown.</p>
</li>
<li><p>Click "Deploy" and confirm the transaction in MetaMask.</p>
</li>
</ul>
</li>
<li><p><strong>Verify Deployment:</strong></p>
<ul>
<li><p>Once the transaction is confirmed, your contract will be deployed on the Linea Sepolia network.</p>
</li>
<li><p>Copy the contract address for use in the next part of the tutorial.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-step-6-interacting-with-the-smart-contract"><strong>Step 6: Interacting with the Smart Contract</strong></h3>
<ol>
<li><p><strong>Interacting via Remix:</strong></p>
<ul>
<li><p>In the "Deploy &amp; Run Transactions" tab, you'll see the deployed contract under "Deployed Contracts".</p>
</li>
<li><p>You can interact with the contract by calling functions like <code>play</code>, <code>depositToHouse</code>, <code>withdrawHouseFunds</code>, and <code>houseBalance</code>.</p>
</li>
</ul>
</li>
<li><p><strong>Testing the Contract:</strong></p>
<ul>
<li><p>Test the <code>play</code> function by making predictions and placing bets.</p>
</li>
<li><p>Use <code>houseBalance</code> to check the balance of the contract and <code>withdrawHouseFunds</code> to withdraw funds as the owner.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-conclusion"><strong>Conclusion:</strong></h3>
<p>In this first part of the tutorial, you learned how to write a Solidity smart contract for a prediction game and deploy it to the Linea Sepolia Testnet. You also tested the Smart Contract to ensure it works as expected. You can find my Smart Contract version <a target="_blank" href="https://sepolia.lineascan.build/address/0x8fa509ab0087755fdd5fb49df1d5fad95f9d9eb7">here</a>.</p>
<p>In the next part of the tutorial, we'll build a frontend application using Next.js to interact with this Smart Contract. The application will allow users to connect their wallets, place bets, and see the outcomes.</p>
]]></content:encoded></item><item><title><![CDATA[How to Build a Tipping Smart Contract Using Solidity]]></title><description><![CDATA[As a creative, it goes without saying that you’d like to be rewarded for your work. While there exists a plethora of platforms that you can use to receive monetary rewards from your fans, it goes without saying such platforms still collect a “middlem...]]></description><link>https://emmaodia.hashnode.dev/how-to-build-a-tipping-smart-contract-using-solidity</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-build-a-tipping-smart-contract-using-solidity</guid><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Solidity]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 10 Jul 2023 20:05:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694172098777/1f511251-b387-4f06-b0a9-eced5436a085.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a creative, it goes without saying that you’d like to be rewarded for your work. While there exists a plethora of platforms that you can use to receive monetary rewards from your fans, it goes without saying such platforms still collect a “middleman’s fee” from you! Well, what if there exists a solution where you can get all tips/payments/donations made to you 100%? Therein lies the power of Smart Contract Technology.</p>
<p>In this article, we will build a Tipping Contract that you can deploy on any EVM compatible chain. The contract will ensure the following:</p>
<ul>
<li><p>You can receive tips/payments/donations in any ERC20 Tokens.</p>
</li>
<li><p>You can withdraw the Tokens from the contract to your Externally Owned Address (EOA) also known as your Wallet Address.</p>
</li>
<li><p>As the owner of the contract, you are the only one who can carry out the withdrawal function.</p>
</li>
<li><p>You can set the minimum tips/payment/donations amount.</p>
</li>
</ul>
<p>The breakdown above has given an insight into the full functionality of the Smart Contract we are going to build. You can immediately get a sense of the various functions we will write, the modifiers, events that we will also want to be emitted, and the original constructor arguments we will deploy the contract with. To be certain that we are aligned in that regard, here are the functions:</p>
<ul>
<li><p>ReceiveTips(): This is the function that users will call and send tips to the Smart Contract.</p>
</li>
<li><p>WithdrawTips(): This is the function that you will call to withdraw tips sent to the Smart Contract.</p>
</li>
<li><p>getContractBalance(): This is the function you can call to ascertain the amount of an ERC20 token balance in your Smart Contract.</p>
</li>
<li><p>UpdateWithdrawAddress(): This is the function where you can set a new address to withdraw tokens and send to.</p>
</li>
</ul>
<p>With each of the functions, we can immediately understand the various events that we want to emit.</p>
<ul>
<li><p>Receive</p>
</li>
<li><p>WithDraw</p>
</li>
</ul>
<p><strong>OK. It is important to note that your approach to building Dapps might be different. Some developers will rather jump straight into an IDE and start hacking away on their keyboards, but, as the popular saying goes: “Measure Twice, and cut once.”</strong></p>
<p>The next step will be to open our Remix IDE and start to write the Smart Contract code:</p>
<p>As with every Smart Contract, we begin by declaring the License type used, and the solidity version using a pragma statement.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.19</span>;
</code></pre>
<p>This contract is set up so that creatives can receive any ERC20 Tokens, for this to be possible in the Smart Contract that we want to deploy, we have to create an interface that will enable us to interact with an already deploy an instance of an ERC20 token. To do this, we will be using the OpenZeppelin library. Import the library:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC20/IERC20.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"</span>;
</code></pre>
<p>The IERC20 is the interface all ERC20 implementations should conform to. That is typically made in the name, decimal and token symbols convention. You can read the EIP20 to learn more. The SafeERC20 is a wrapper around the IERC20 interface that eliminates the need to handle boolean return values.</p>
<p>In this contract, we are going to ensure that only the owner of the contract can carry out certain functions such as withdrawal and changing the EOA of the owner. To do this, we will also import an OpenZeppelin library for access control.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;
</code></pre>
<p>Having completed the steps above, we can start writing the Smart Contract</p>
<pre><code class="lang-javascript">contract TipMe {
...
}
</code></pre>
<p>The first step in writing the main contract is to declare an instance of the interface using the SafeERC20 wrapper, as we will use this for a tranferFrom() method call, and also the Interface for token we will deploy as an example in this lesson.</p>
<pre><code class="lang-javascript">using SafeERC20 <span class="hljs-keyword">for</span> IERC20;
</code></pre>
<p>Instantiate the ERC20 protocol using the interface from OpenZepellin:</p>
<pre><code class="lang-javascript">IERC20 public token;
</code></pre>
<p>The token will be set in the constructor argument, with an already deployed token address parsed as an argument to the interface.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">constructor</span> (IERC20 _token) {
  token = _token;
}
</code></pre>
<p>In the constructor, we parse the token by data type. It is an ERC20 token and not an address. Its functions can be accessed via the interface IERC20, hence why its data type.</p>
<p>Now the contract looks like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.19</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC20/IERC20.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;

contract TipMe {

using SafeERC20 <span class="hljs-keyword">for</span> IERC20;
IERC20 public token;

  <span class="hljs-keyword">constructor</span> (IERC20 _token) {
      token = _token;
  }

}
</code></pre>
<p>We will write our functions, with the first function being the <code>receiveTips</code> function</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">receiveTips</span>(<span class="hljs-params">uint256 _amount</span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> <span class="hljs-title">returns</span>(<span class="hljs-params">uint256</span>) </span>{
  <span class="hljs-built_in">require</span>(_amount &gt; <span class="hljs-number">0</span>, “Amount MUST be more than <span class="hljs-number">0</span>”);
  token.safeTransferFrom(address(msg.sender), address(<span class="hljs-built_in">this</span>), _amount);
  <span class="hljs-keyword">return</span> _amount;
}
</code></pre>
<p>In the <code>receiveTips()</code>, any EOA that holds an ERC20 can call the function and deposit any amount greater than zero. The deposited amount is held in the contract. It is important to illustrate that before any ERC20 token can be deposited by an address into a Smart Contract, it is crucial for the address to call <code>approve()</code> function on the token contract, with the Smart Contract as receiver before the Smart Contract can call <code>safeTransferFrom()</code>.</p>
<p>Next step, we can then update the function to emit an event on a successful deposit.</p>
<p>First, we will create an emit event method. Add the following line after the constructor arguments</p>
<pre><code class="lang-javascript">event TipReceived(address sender, uint256 amount);
</code></pre>
<p>Add the following line to the end of <code>receiveTips()</code> function just before the return statement:</p>
<pre><code class="lang-javascript">emit TipReceived(msg.sender, _amount);
</code></pre>
<p>Whenever a tip is sent to the contract, it will emit the <code>Receive</code> event detailing the EOA that sent the tip, and the tip amount.</p>
<p>The next function is the <code>withdrawTips</code> function. The withdrawTips function is to enable the contract owner to withdraw all tips that they have received. This function has a unique property wherein only the contract owner should be able to make a withdrawal.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdrawTips</span>(<span class="hljs-params">uint256 _amount</span>) <span class="hljs-title">public</span> <span class="hljs-title">onlyOwner</span> <span class="hljs-title">returns</span>(<span class="hljs-params">uint256</span>) </span>{
        <span class="hljs-built_in">require</span>(_amount &gt; <span class="hljs-number">0</span>, <span class="hljs-string">"Amount MUST &gt; 0"</span>);
        token.approve(msg.sender, _amount);
        token.safeTransfer( msg.sender,  _amount);
        <span class="hljs-keyword">return</span> _amount;
}
</code></pre>
<p>This function is different from the <code>receiveTips</code> function in the following ways:</p>
<ul>
<li><p>Only the owner of the Smart Contract can call this function.</p>
</li>
<li><p>We can call the <code>approve</code> method for the token to carry out the transfer method. We do not have to go to the token contract to do this.</p>
</li>
</ul>
<p>Other than that, it is not so much different as, you can set the amount to withdraw, use a require statement to ensure that said amount is greater than zero.</p>
<p>We will also add an event to log successful withdrawals. Add the following event:</p>
<pre><code class="lang-javascript">event WithDrawalSuccessfull(uint256 amount);
</code></pre>
<p>Add the following line to the end of <code>wthdrawTips()</code> function just before the return statement:</p>
<pre><code class="lang-javascript">emit WithDrawalSuccessfull(_amount);
</code></pre>
<p>The next function is the getContractBalance(), which you can call to ascertain the amount of an ERC20 token balance in your Smart Contract.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getContractBalance</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">uint</span>)</span>{
       <span class="hljs-keyword">return</span> IERC20(token).balanceOf(address(<span class="hljs-built_in">this</span>));
 }
</code></pre>
<p>The last function required is where you can change the <code>owner</code> address to a different EOA. The OpenZeppelin ownable library already offers the opportunity for a user address to be set by default and offers a method called <code>transferOwnership</code>. We can write a new function called changeOwner which you can wrap a function around and make the call.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeOwner</span>(<span class="hljs-params">address _owner</span>) <span class="hljs-title">public</span> <span class="hljs-title">returns</span>(<span class="hljs-params">bool</span>) </span>{
    transferOwnership(_owner);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>Note that you can only call this function once, and then the owner address is changed.</p>
<p>Here is the full contract:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.19</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC20/IERC20.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/access/Ownable.sol"</span>;


contract Tip is  Ownable {

    using SafeERC20 <span class="hljs-keyword">for</span> IERC20;
    IERC20 public token;

    <span class="hljs-keyword">constructor</span>(IERC20 _token){
        token = _token;
    }


    event TipReceived(address sender, uint256 amount);
    event WithDrawalSuccessfull(uint256 amount);


    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">receiveTips</span>(<span class="hljs-params">uint256 _amount</span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> <span class="hljs-title">returns</span>(<span class="hljs-params">uint256</span>)</span>{
        <span class="hljs-built_in">require</span>(_amount &gt; <span class="hljs-number">0</span>, <span class="hljs-string">"Amount MUST &gt; 0"</span>);
        token.safeTransferFrom(address(msg.sender), address(<span class="hljs-built_in">this</span>), _amount);
        emit TipReceived(msg.sender, _amount);
        <span class="hljs-keyword">return</span> _amount;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdrawTips</span>(<span class="hljs-params">uint256 _amount</span>) <span class="hljs-title">public</span> <span class="hljs-title">onlyOwner</span> <span class="hljs-title">returns</span>(<span class="hljs-params">uint256</span>)</span>{
        <span class="hljs-built_in">require</span>(_amount &gt; <span class="hljs-number">0</span>, <span class="hljs-string">"Amount MUST &gt; 0"</span>);
        token.approve(msg.sender, _amount);
        token.safeTransfer( msg.sender,  _amount);
        emit WithDrawalSuccessfull(_amount);
        <span class="hljs-keyword">return</span> _amount;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTokenBalance</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">uint</span>)</span>{
        <span class="hljs-keyword">return</span> IERC20(token).balanceOf(address(<span class="hljs-built_in">this</span>));
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeOwner</span>(<span class="hljs-params">address _owner</span>) <span class="hljs-title">public</span> <span class="hljs-title">returns</span>(<span class="hljs-params">bool</span>) </span>{
        transferOwnership(_owner);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }

}
</code></pre>
<p>In the next article, we will build a front end to interact with the contract.</p>
]]></content:encoded></item><item><title><![CDATA[How to Build Your First NextJS Project Using ReactJS Hooks]]></title><description><![CDATA[In this article, I will walk through building your first NextJs project using React without Typescript. Next.js is a React framework for building full-stack web applications. NextJS is versatile and lets you create React apps of any size—from a mostl...]]></description><link>https://emmaodia.hashnode.dev/how-to-build-your-first-nextjs-project-using-reactjs-hooks</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-build-your-first-nextjs-project-using-reactjs-hooks</guid><category><![CDATA[Next.js]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[fetch API]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Thu, 04 May 2023 21:11:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694466311745/1f5ee0a6-0d8c-401b-9518-1f72ef0cdb8f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I will walk through building your first NextJs project using React without Typescript. Next.js is a React framework for building full-stack web applications. NextJS is versatile and lets you create React apps of any size—from a mostly static blog to a complex dynamic application. Under the hood, Next.js abstracts and automatically configures tooling needed for React, like bundling, compiling, and more.</p>
<p>According to the React Developer Docs:</p>
<blockquote>
<p>If you want to build a new app or a new website entirely with React, NextJS is one of the recommended React-powered frameworks popular in the community. </p>
</blockquote>
<p>In this article, I’ll introduce NextJS, and we will build a simple app that fetches data from an API and displays it to a UI. It is an app that displays information on Countries, listing the Country Name, Capital and Flag.We will make use of the <a target="_blank" href="https://restcountries.com/">https://restcountries.com/</a> API. This article assumes that you have build applications in ReactJS, and want to learn how to start building applications with NextJS.</p>
<p>This tutorial is useful for you if you want to understand how to make <code>fetch API</code> queries and pass down props to components in NextJS using plain ReactJS without TypeScript. </p>
<p>To start our project, create a directory where you wish the project to live, and start a NextJS project</p>
<pre><code class="lang-javascript">mkdir rest-countries-example &amp;&amp; cd rest-countries-example

npx create-next-app@latest
</code></pre>
<p>The following prompts will run, select the answers I highlighted in CAPS.</p>
<pre><code class="lang-javascript">What is your project named? rest-countries-example

Would you like to use TypeScript? NO / Yes

Would you like to use ESLint? NO / Yes

Would you like to use Tailwind CSS? No / YES

Would you like to use src/ directory? No / YES

Would you like to use App Router? (recommended) No / YES

Would you like to customize the <span class="hljs-keyword">default</span> <span class="hljs-keyword">import</span> alias? No / YES

What <span class="hljs-keyword">import</span> alias would you like configured? @<span class="hljs-comment">/*</span>
</code></pre>
<p>We have selected not to use TypeScript, and do not have ESLINT setup for the project, and we will use Tailwind, App Router (as against Page Routing) and as a result, have our files located in a directory called <code>src</code>.</p>
<p>Open a terminal and run the following commands</p>
<pre><code class="lang-javascript">npm run dev
</code></pre>
<p>Open your browser and go to <a target="_blank" href="https://localhost:3000">https://localhost:3000</a> to see the project running.</p>
<p>Our Project Folder looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691009477612/89fc045d-9f79-4a06-bcdc-d34dde64bc05.png" alt class="image--center mx-auto" /></p>
<p>You can explore the <code>tailwind.config.js</code> file to see how Tailwind is configured for use in the application.</p>
<p>Open the <code>page.js</code> app. Remove the default code and leave a div with <code>Hello World</code> text in the component. Check your browser to the updated page with the text <code>Hello World</code> displayed on the screen. </p>
<pre><code class="lang-javascript"><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;<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hello World!<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>
    );
}
</code></pre>
<p>There are 2 phases to our project. In the first phase, we will write a function to fetch the responses from the API, we can test the success of the calls by console logging the responses and also by parsing to the UI. We will create a UI using tailwind-style components, and render the responses to a beautiful UI. We will then create a component to demonstrate how to pass down props, which is no different from how it is done using plain ReactJS.</p>
<p>A steep learning curve for learning to build on NextJs is understanding the difference between <a target="_blank" href="https://nextjs.org/docs/getting-started/react-essentials">Server Components and Client Components</a>. As a result of the Reacts Hook <code>useEffect</code> which we will use in our app, we are leveraging Client components. Therefore, at the top of the <code>pages.js</code> we have to indicate this using the <code>use client</code> directive. At the top of the pages.js file add the line:</p>
<pre><code class="lang-javascript">“use client”;
</code></pre>
<h2 id="heading-phase-1">Phase 1.</h2>
<p>We will use the JavaScript fetch API in our method to call the Rest Countries API. When the response is returned, we will hold the response in a <code>useState</code> array. Thus, as we write the method, we will also create a <code>useState</code> hook. We will also use the <code>useEffect</code> hook to prevent our page from rerendering.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [countries, setCountries] = useState([]);

<span class="hljs-keyword">const</span> getCountries = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(
        https:<span class="hljs-comment">//restcountries.com/v3.1/all</span>
    );
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
    setCountries(data);
};

useEffect(<span class="hljs-function">() =&gt;</span> {
    getCountries();
}, []);

<span class="hljs-built_in">console</span>.log(countries);
</code></pre>
<p>Open the Developer Tools on your Browser to see the Countries logged into the console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691009795168/61127152-79ec-4777-b88e-7ab439833bd1.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-phase-2">Phase 2:</h2>
<p>We have the data being returned from the API and parsed to the app, the next step is to create a beautiful UI using Tailwind CSS, and map over the responses in the Countries array held in the app state.</p>
<pre><code class="lang-javascript">&lt;div className={<span class="hljs-string">`grid gap-4 grid-cols-3 grid-rows-3 m-6`</span>}&gt;
    {recipes.map(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</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">"max-w-sm rounded overflow-hidden shadow-lg"</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{result.flag}</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-gray-900 text-xl"</span>&gt;</span>{result.name.common}<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">"text-gray-700"</span>&gt;</span> Capital: {result.capital}<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>
    ))}
&lt;/div&gt;
</code></pre>
<p>Now, you have a UI Displaying the Countries, and their respective capital.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691010014315/592085d2-598f-468a-9adb-abbe1bc4cd2e.png" alt class="image--center mx-auto" /></p>
<p>At the onset of the article, we will display the Countries Name, Capital and Flag. Displaying images in NextJS provides a great learning curve. NextJS has it’s own <code>Image</code> component for handling image display. To use the component in our project, we have to import it:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">'next/image'</span>
</code></pre>
<p>The component has its own default attributes such <code>src</code>, <code>width</code>, <code>height</code> etc. In our case where we are consuming an API that parses image assets, we have to configure our NextJS app to render the images from the URL paths we are parsing the image assets. </p>
<p>Open the <code>next.config.js</code> file where we will configure an Image Component attribute called <code>remotePatterns</code>. remotePatterns protects your application from malicious users. The configuration is required in order to use external images. This ensures that only external images parsed to remotePatterns can be served from the Next.js Image Optimization API. Update your next config like so:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> nextConfig = {
  <span class="hljs-attr">images</span>: {
    <span class="hljs-attr">remotePatterns</span>: [
      {
        <span class="hljs-attr">protocol</span>: <span class="hljs-string">"https"</span>,
        <span class="hljs-attr">hostname</span>: <span class="hljs-string">"flagcdn.com"</span>,
        <span class="hljs-attr">port</span>: <span class="hljs-string">""</span>,
        <span class="hljs-attr">pathname</span>: <span class="hljs-string">"/w320/**"</span>,
      },
      {
        <span class="hljs-attr">protocol</span>: <span class="hljs-string">"https"</span>,
        <span class="hljs-attr">hostname</span>: <span class="hljs-string">"*.wikimedia.org"</span>,
        <span class="hljs-attr">port</span>: <span class="hljs-string">""</span>,
        <span class="hljs-attr">pathname</span>: <span class="hljs-string">"/**"</span>,
      },
    ],
  },
};
</code></pre>
<p>Next, we will update the UI to display the flags. Right above the &lt;p&gt; tags, add the following Image component:</p>
<pre><code class="lang-javascript">&lt;Image
 src={flag}
 alt=<span class="hljs-string">"Country flag"</span>
 width={<span class="hljs-number">3200</span>}
 height={<span class="hljs-number">100</span>}
/&gt;
</code></pre>
<p>The app is updated, and we can view the Countries Map. Name and Capital.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691010295464/c3fe1bf3-03ae-453d-8883-2c6491e7c956.png" alt class="image--center mx-auto" /></p>
<p>To illustrate the lesson on parsing down props to components, we can create a Countries component, move our Countries UI information to it, and pass down the props via the Component.</p>
<p>Create a file <code>countries.js</code>. We want to return the Country information, we can simply copy the code used in displaying the info to the UI in <code>pages.js</code>. Update the component:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">"next/image"</span>;


<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Countries</span>(<span class="hljs-params">{ label, flag, capital }</span>) </span>{
   <span class="hljs-keyword">return</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">"max-w-sm rounded overflow-hidden shadow-lg"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
        <span class="hljs-attr">src</span>=<span class="hljs-string">{flag}</span>
        <span class="hljs-attr">alt</span>=<span class="hljs-string">"Sunset in the mountains"</span>
        <span class="hljs-attr">width</span>=<span class="hljs-string">{3200}</span>
        <span class="hljs-attr">height</span>=<span class="hljs-string">{100}</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-gray-900 text-xl"</span>&gt;</span>{label}<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">"text-gray-700"</span>&gt;</span> Capital: {capital}<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>
  );
}
</code></pre>
<p>In our <code>pages.js</code> app, import the Countries component</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Countries } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/recipes"</span>;
</code></pre>
<p>Update the information being mapped over:</p>
<pre><code class="lang-javascript">{recipes.map(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> (
     <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Recipes</span>
          <span class="hljs-attr">key</span>=<span class="hljs-string">{result.flag}</span>
          <span class="hljs-attr">label</span>=<span class="hljs-string">{result.name.common}</span>
          <span class="hljs-attr">flag</span>=<span class="hljs-string">{result.flags.png}</span>
          <span class="hljs-attr">capital</span>=<span class="hljs-string">{result.capital}</span>
     /&gt;</span></span>
))}
</code></pre>
<p>Now, the props are passed down via the component, and rendered by the Countries UI.</p>
<p>If you made it to the end of this lesson, Congratulations! The key learning takeaways is an understanding of how to use ReactJS Hooks in your NextJs app, handling image using the Image Component, and using the <code>renderPatterns</code> to “whitelist” addresses where you are parsing image assets via an API.</p>
<h2 id="heading-here-is-the-entire-app-for-reference">Here is the entire app for reference:</h2>
<p><code>pages.js</code></p>
<pre><code class="lang-javascript"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Countries } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/countries"</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">const</span> [countries, setCountries] = useState([]);
  <span class="hljs-keyword">const</span> getCountries = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(
      https:<span class="hljs-comment">//restcountries.com/v3.1/all</span>
    );

    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
    setCountries(data);
  };


  useEffect(<span class="hljs-function">() =&gt;</span> {
    getCountries();
  }, []);


   <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">{</span>`<span class="hljs-attr">grid</span> <span class="hljs-attr">gap-4</span> <span class="hljs-attr">grid-cols-3</span> <span class="hljs-attr">grid-rows-3</span> <span class="hljs-attr">m-6</span>`}&gt;</span>
        {recipes.map((result) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">Recipes</span>
            <span class="hljs-attr">key</span>=<span class="hljs-string">{result.flag}</span>
            <span class="hljs-attr">label</span>=<span class="hljs-string">{result.name.common}</span>
            <span class="hljs-attr">flag</span>=<span class="hljs-string">{result.flags.png}</span>
            <span class="hljs-attr">capital</span>=<span class="hljs-string">{result.capital}</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>
]]></content:encoded></item><item><title><![CDATA[BNB Chain Web3 Mastery Public Report - Africa Region 🌍🐘]]></title><description><![CDATA[I am pleased to present a comprehensive report on the successful execution of the Web3 Master Program during my tenure as the Developer Community Manager for the African region at BNB Chain. The program was designed to provide participants with a hol...]]></description><link>https://emmaodia.hashnode.dev/bnb-chain-web3-mastery-public-report-africa-region</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/bnb-chain-web3-mastery-public-report-africa-region</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Web3]]></category><category><![CDATA[Solidity]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Thu, 13 Apr 2023 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694027373922/8798ed56-b0eb-4a56-a2e9-43fc0b107cd9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I am pleased to present a comprehensive report on the successful execution of the Web3 Master Program during my tenure as the Developer Community Manager for the African region at BNB Chain. The program was designed to provide participants with a holistic understanding of blockchain technology, Binance Smart Chain, Solidity programming, smart contract development, decentralized application building, and smart contract security.</p>
<h2 id="heading-program-overview">Program Overview</h2>
<p>The Web3 Master Program was a six-week intensive training series aimed at equipping participants from across Africa with the skills and knowledge needed to navigate the dynamic landscape of blockchain and Web3 technologies. The program covered a wide range of topics, from the fundamentals of blockchain to advanced smart contract security considerations.  </p>
<h2 id="heading-program-breakdown">Program Breakdown</h2>
<p>1. Week 1: Blockchain Basics by <a target="_blank" href="https://www.linkedin.com/in/amoweolubusayo">Amowe Busayo</a></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.youtube.com/watch?v=mcijhksKqM8">https://www.youtube.com/watch?v=mcijhksKqM8</a></div>
<p> </p>
<p>2. Week 2: Binance Smart Chain by <a target="_blank" href="https://www.linkedin.com/in/emmaodia/">ME</a>!</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.youtube.com/watch?v=2Vh2kw1-Vas">https://www.youtube.com/watch?v=2Vh2kw1-Vas</a></div>
<p> </p>
<p>3. Week 3: Solidity Programming by <a target="_blank" href="https://www.linkedin.com/in/fatma-abdulqadir">A.Q Fatma</a></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.youtube.com/watch?v=XoND_u0z5OU">https://www.youtube.com/watch?v=XoND_u0z5OU</a></div>
<p> </p>
<p>4. Week 4: Smart Contract Development by ME, again! 🥳</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.youtube.com/watch?v=qmgX7S0NsSs">https://www.youtube.com/watch?v=qmgX7S0NsSs</a></div>
<p> </p>
<p>5. Week 5: Building a Decentralized Application by <a target="_blank" href="https://www.linkedin.com/in/godspower-eze-6785ab252">Godspower Eze</a></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.youtube.com/watch?v=ghnCH_j9gCs">https://www.youtube.com/watch?v=ghnCH_j9gCs</a></div>
<p> </p>
<p>6. Week 6: Smart Contract Security by <a target="_blank" href="https://www.linkedin.com/in/chukwu-ephraim-chinonso">Ephraim Chukwu</a></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.youtube.com/watch?v=jptjcAz-4UY">https://www.youtube.com/watch?v=jptjcAz-4UY</a></div>
<p> </p>
<h2 id="heading-achievements">Achievements</h2>
<p>- Participant Engagement: The program attracted an impressive registration of over 400 participants hailing from diverse regions across Africa. This indicated a strong interest in blockchain and Web3 technologies within the continent.</p>
<p>- Curriculum Development: As the architect of the program, I meticulously designed the course curriculum to ensure a seamless progression of topics, catering to both beginners and those seeking more advanced insights.</p>
<p>- Instructor Collaboration: I sourced and collaborated with expert instructors for each week's topic. This ensured that participants received the highest quality instruction from practitioners deeply immersed in their respective fields.</p>
<p>- Teaching Contribution: During the course, I personally delivered two classes, including a code lab session. My direct involvement in teaching solidified my connection with participants and allowed me to impart knowledge from a practical standpoint.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The Web3 Master Program marked a significant milestone in the enhancement of blockchain and Web3 literacy within Africa. The program's reach, content quality, and my direct contribution as a course instructor underscored my commitment to nurturing developer communities and fostering education within the Web3 ecosystem.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694027756398/60646115-5f9d-4156-9d15-9e311c6cd050.png" alt class="image--center mx-auto" /></p>
<p>I am grateful for the opportunity to have spearheaded this initiative and contributed to the growth of blockchain awareness and expertise in the African region.</p>
]]></content:encoded></item><item><title><![CDATA[How to Verify Smart Contracts that rely on Imported External Libraries]]></title><description><![CDATA[Introduction
I have encountered the problem of verifying Smart Contracts when I use external libraries like OpenZeppelin or ChainLink. You will find that the simple process of using the explorer verification options doesn't work and neither will atte...]]></description><link>https://emmaodia.hashnode.dev/how-to-verify-smart-contracts-that-rely-on-imported-external-libraries</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-verify-smart-contracts-that-rely-on-imported-external-libraries</guid><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[How to verify Smart Contract]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Wed, 08 Mar 2023 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1698439867976/f08e08f3-7ad2-42b4-a663-c66a82e3541f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>I have encountered the problem of verifying Smart Contracts when I use external libraries like OpenZeppelin or ChainLink. You will find that the simple process of using the explorer verification options doesn't work and neither will attempting the verification via the CLI. In this article, I'll demonstrate the use of the <code>Flattened</code> Smart Contracts feature available in Remix IDE to carry out the verification of a Smart Contract.</p>
<h2 id="heading-smart-contract">Smart Contract</h2>
<p>Go to Open Zeppelin, and open the Smart Contract Wizard. We will build a simple Access Control with ONLY OWNER modifier can transferOwnership of the Smart Contract</p>
<p>Open the Remix IDE and paste the code:</p>
<pre><code class="lang-solidity"><span class="hljs-comment">//SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.20;</span>

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

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">MyContract</span> <span class="hljs-keyword">is</span> <span class="hljs-title">Ownable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> initialOwner</span>) </span>{
        transferOwnership(initialOwner);
    }
}
</code></pre>
<p>Compile the Smart Contract. Add your MetaMask to Remix via the <code>Injected Provider</code> option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698435098467/029fa05c-815d-4e2c-9bba-d10bbb215606.png" alt class="image--center mx-auto" /></p>
<p>Deploy the Smart Contract to any selected Testnet of your choice. The deployed Smart Contract gives us access to the following functions:</p>
<p><code>RenounceOwnership</code> , <code>transferOwnership</code> and <code>owner</code></p>
<h2 id="heading-verification">Verification</h2>
<p>If we attempt to verify the Contract on Etherscan, it will give us an error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698435210003/bd48a4eb-ab3e-4348-ad47-341e284d211e.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698435241575/7222bd58-ce5b-4b4f-8bc7-a3167d254f0c.png" alt class="image--right mx-auto mr-0" /></p>
<p>To fix this error, we will "flatten the Smart Contract". The Flattener plugin is an “internal plugin” in the Remix IDE making it a part of the Remix codebase.</p>
<p>Prior to the update, it was required to be loaded as a plugin in the Plugin Manager, but can now just right-click on a file in the File Explorer to pop up the context menu. The Flattener is available as the <strong>Flatten</strong> option in the context menu.</p>
<h2 id="heading-flatten-smart-contract">Flatten Smart Contract</h2>
<p>Open the Remix IDE, left click on the Smart Contract file in directory and click on <code>Flatten</code> This will generate a "flattened" version of the codebase which we can pass to EtherScan for Verification.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698435565137/1e901f02-7768-498a-8d68-f5f14b63608b.png" alt class="image--center mx-auto" /></p>
<p>Copy the contents of the flattened version of the codebase and follow the steps to do the EtherScan verification.</p>
<pre><code class="lang-solidity">
<span class="hljs-comment">// File: @openzeppelin/contracts/utils/Context.sol</span>
<span class="hljs-comment">// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.0;</span>

<span class="hljs-comment">/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Context</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_msgSender</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">address</span></span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_msgData</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bytes</span> <span class="hljs-keyword">calldata</span></span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">data</span>;
    }
}

<span class="hljs-comment">// File: @openzeppelin/contracts/access/Ownable.sol</span>
<span class="hljs-comment">// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.0;</span>

<span class="hljs-comment">/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Ownable</span> <span class="hljs-keyword">is</span> <span class="hljs-title">Context</span> </span>{
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">private</span> _owner;

    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">OwnershipTransferred</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> previousOwner, <span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> newOwner</span>)</span>;

    <span class="hljs-comment">/**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        _transferOwnership(_msgSender());
    }

    <span class="hljs-comment">/**
     * @dev Throws if called by any account other than the owner.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">onlyOwner</span>(<span class="hljs-params"></span>) </span>{
        _checkOwner();
        <span class="hljs-keyword">_</span>;
    }

    <span class="hljs-comment">/**
     * @dev Returns the address of the current owner.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">owner</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">address</span></span>) </span>{
        <span class="hljs-keyword">return</span> _owner;
    }

    <span class="hljs-comment">/**
     * @dev Throws if the sender is not the owner.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_checkOwner</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> </span>{
        <span class="hljs-built_in">require</span>(owner() <span class="hljs-operator">=</span><span class="hljs-operator">=</span> _msgSender(), <span class="hljs-string">"Ownable: caller is not the owner"</span>);
    }

    <span class="hljs-comment">/**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * <span class="hljs-doctag">NOTE:</span> Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">renounceOwnership</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> <span class="hljs-title">onlyOwner</span> </span>{
        _transferOwnership(<span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>));
    }

    <span class="hljs-comment">/**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferOwnership</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> newOwner</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> <span class="hljs-title">onlyOwner</span> </span>{
        <span class="hljs-built_in">require</span>(newOwner <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>), <span class="hljs-string">"Ownable: new owner is the zero address"</span>);
        _transferOwnership(newOwner);
    }

    <span class="hljs-comment">/**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_transferOwnership</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> newOwner</span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> </span>{
        <span class="hljs-keyword">address</span> oldOwner <span class="hljs-operator">=</span> _owner;
        _owner <span class="hljs-operator">=</span> newOwner;
        <span class="hljs-keyword">emit</span> OwnershipTransferred(oldOwner, newOwner);
    }
}

<span class="hljs-comment">// File: MyContract.sol</span>
<span class="hljs-comment">//SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.20;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">MyContract</span> <span class="hljs-keyword">is</span> <span class="hljs-title">Ownable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> initialOwner</span>) </span>{
        transferOwnership(initialOwner);
    }
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698436906466/06638ea9-0350-4fba-b056-97af1e1e9765.png" alt class="image--center mx-auto" /></p>
<p>AND, that is how it is done, Ladies and Gentlemen, Boys and Girls! 🥂</p>
<p>Reference: <a target="_blank" href="https://medium.com/remix-ide/remix-ide-v0-30-0-release-8ee6bb8bcb5f">https://medium.com/remix-ide/remix-ide-v0-30-0-release-8ee6bb8bcb5f</a></p>
]]></content:encoded></item><item><title><![CDATA[Functions, Function Types, Function Visibility, and Function Modifiers in Solidity]]></title><description><![CDATA[Solidity Functions as I like to explain are a lot like functions/methods in JavaScript, with similarities extending to the structure of a function
function( params ) { args }
The difference between the structure of functions in Solidity and JavaScrip...]]></description><link>https://emmaodia.hashnode.dev/functions-function-types-function-visibility-and-function-modifiers-in-solidity</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/functions-function-types-function-visibility-and-function-modifiers-in-solidity</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Solidity]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 09 Jan 2023 13:17:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1684761308232/289a2b9e-c2d8-4d6c-b931-b27c11374625.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Solidity Functions as I like to explain are a lot like functions/methods in JavaScript, with similarities extending to the structure of a function</p>
<p><code>function( params ) { args }</code></p>
<p>The difference between the structure of functions in Solidity and JavaScript is that Solidity being a statically typed programming language has extra requirements for defining the data types of params, return statements, and args, and also has to be indicated by what is called visibility levels.</p>
<p><strong>Solidity Functions are the executable units of code.</strong> Functions are usually defined inside a contract, but they can also be defined outside of contracts. Functions outside of a contract, also called “free functions”, always have implicit <code>internal</code> visibility.</p>
<pre><code class="lang-javascript">contract HelloWorld {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">send</span>(<span class="hljs-params">string _greeting</span>) <span class="hljs-title">public</span> <span class="hljs-title">returns</span>(<span class="hljs-params">string memory</span>) </span>{
   <span class="hljs-comment">// ...</span>
   }
}
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// Helper function defined outside of a contract</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">helper</span>(<span class="hljs-params">uint x</span>) <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint</span>) </span>{
    <span class="hljs-keyword">return</span> x * <span class="hljs-number">2</span>;
}
</code></pre>
<h2 id="heading-function-visibility"><strong>Function Visibility</strong></h2>
<p>In the above example, you can see that the function defined in the contract has what is called a visibility type. Visibility type is best understood given the explanation that Function calls in Solidity are categorized into 2: </p>
<ol>
<li><p>Functions that make state changes to the EVM. These are generally referred to as “<code>External Functions</code>”</p>
</li>
<li><p>Functions that do not make state changes to the EVM are also referred to as “<code>Internal Functions</code>”</p>
</li>
</ol>
<p>These 2 general categories of functions then give rise to 4 different function visibility types:</p>
<ul>
<li><p>External</p>
</li>
<li><p>Public</p>
</li>
<li><p>Internal</p>
</li>
<li><p>Private </p>
</li>
</ul>
<h3 id="heading-external"><strong>External:</strong></h3>
<p>External functions are part of the contract interface, which means they can be called from other contracts and via transactions. An external function f cannot be called internally (i.e. f() does not work, but this.f() works).</p>
<pre><code class="lang-javascript">contract Apple { 
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">externalFunc</span>(<span class="hljs-params"></span>) <span class="hljs-title">external</span> <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"external function called"</span>;
    }
}
</code></pre>
<pre><code class="lang-javascript">contract Bee {
  address contractApple = “<span class="hljs-number">0</span>x….”;

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callExternalFuncInApple</span>(<span class="hljs-params"></span>) <span class="hljs-title">internal</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span>(<span class="hljs-params">string memory</span>) </span>{

  <span class="hljs-keyword">const</span> B = contractApple.externalFunc();
  <span class="hljs-keyword">return</span> B; <span class="hljs-comment">//this will return the string "external function called"</span>
  }
}
</code></pre>
<p>The above example illustrates 2 different contracts, where one function with the visibility of <code>external</code> can be called in another separately deployed contract. </p>
<h3 id="heading-public"><strong>Public:</strong></h3>
<p>Public functions are part of the contract interface and can be either called internally or via message calls i.e. any contract that inherits the contract where the public function exists and <code>address account</code> can call these kinds of functions.</p>
<pre><code class="lang-javascript">contract Apple {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">publicFunc</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"public function called"</span>;
    }
}
</code></pre>
<h3 id="heading-internal"><strong>Internal:</strong></h3>
<p>Internal functions can only be accessed from within the current contract or contracts deriving from it i.e. inside contracts that inherit the contract holding the internal function. They cannot be accessed externally. Since they are not exposed to the outside through the contract’s ABI, they can take parameters of internal types like mappings or storage references.</p>
<pre><code class="lang-javascript">Contract Apple {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">internalFunc</span>(<span class="hljs-params"></span>) <span class="hljs-title">internal</span> <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"internal function called"</span>;
    }
}
</code></pre>
<h3 id="heading-private"><strong>Private:</strong></h3>
<p>Private functions are like internal ones but they are not visible in derived contracts i.e Private functions can only be called within the instance of the deployed contract.</p>
<pre><code class="lang-javascript">contract Bees {
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">privateFunc</span>(<span class="hljs-params"></span>) <span class="hljs-title">private</span> <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"private function called"</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testPrivateFunc</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">string memory</span>) </span>{
        <span class="hljs-keyword">return</span> privateFunc();
    }
}
</code></pre>
<hr />
<p>In addition to learning about Function Visibility, it is essential to talk about the ability of function types to modify state. <strong>State mutability</strong> is a concept in Solidity that defines the behavior of functions and how they interact with data stored on the blockchain. The two major state mutability modifiers in solidity are: </p>
<ul>
<li><p>View </p>
</li>
<li><p>Pure</p>
</li>
</ul>
<h3 id="heading-view-functions"><strong>View Functions:</strong></h3>
<p>Functions can be declared <code>view</code> in which case they promise not to modify the state.</p>
<h3 id="heading-pure-functions"><strong>Pure Functions:</strong></h3>
<p>Functions can be declared <code>pure</code> in which case they promise not to read from or modify the state. In particular, it should be possible to evaluate a pure function at compile-time given only its inputs</p>
<pre><code class="lang-javascript">contract ViewAndPure {

    uint public x = <span class="hljs-number">1</span>;

    <span class="hljs-comment">// will not modify the state.</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addToX</span>(<span class="hljs-params">uint y</span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint</span>) </span>{
        <span class="hljs-keyword">return</span> x + y;
    }

    <span class="hljs-comment">// will not modify or read from the state.</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">uint i, uint j</span>) <span class="hljs-title">public</span> <span class="hljs-title">pure</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint</span>) </span>{
        <span class="hljs-keyword">return</span> i + j;
    }
}
</code></pre>
<p>Again, <code>pure</code> function can not read state variables and also cannot write to state variables whereas a View function can read state variable but can not modify it.</p>
<h3 id="heading-where-to-use-various-visibility-types">Where to use various visibility types?</h3>
<p>The choice of the use of any of the 4 visibility types is up to the Developer, a handy guide is:</p>
<p><code>public</code> - use for functions that any contract and address account can call.</p>
<p><code>private</code> - use only for functions used inside the contract to define such functions</p>
<p><code>internal</code>- use this for functions only inside the <code>contract</code> that inherits an internal function</p>
<p><code>external</code> - use for functions that any deployed contract and address account can call.</p>
<hr />
<h2 id="heading-function-modifiers"><strong>Function Modifiers</strong></h2>
<p><code>Modifiers</code> can be used to change the behaviour of Solidity functions in a declarative way. For example, you can use a modifier to automatically check a condition prior to executing the function i.e. Modifiers are code that can be run before and/or after a function call.</p>
<p>Modifiers are inheritable properties of contracts and may be overridden by derived contracts, but only if they are marked <code>virtual</code>.</p>
<p>Modifiers can be used to: Restrict access, Validate inputs and Guard against reentrancy hacks.</p>
<p>You can think of a Modifier as an argument passed against a function that could have also been a part of the function. Modifiers are very useful in scenarios where multiple functions have the same line of code passed to them.</p>
<pre><code class="lang-javascript">contract Bees {

  address owner;

  <span class="hljs-keyword">constructor</span> ( ) {
    owner = msg.sender
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setName</span>(<span class="hljs-params">_greeting</span>) <span class="hljs-title">public</span> </span>{
      <span class="hljs-built_in">require</span>(msg.sender == owner)
      <span class="hljs-keyword">const</span> newGreeting = _greeting
  } 

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateGreeting</span>(<span class="hljs-params">_greeting</span>) <span class="hljs-title">public</span> </span>{
      <span class="hljs-built_in">require</span>(msg.sender == owner)
      <span class="hljs-keyword">const</span> newGreeting = _greeting
  } 

}
</code></pre>
<p>In the above example, you can see the line <code>require(msg.sender == owner)</code> repeated, which implies that even if we have over 50 different functions that we require only the owner of the deployed contract to be the only person able to call it, we will have to repeat the same line of code over and over again. A way to keep this short is the use of function modifiers. </p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Modifier to check that the caller is the owner of the contract.</span>
    modifier onlyOwner() {
        <span class="hljs-built_in">require</span>(msg.sender == owner, <span class="hljs-string">"Not owner"</span>);
        <span class="hljs-comment">// Underscore is a special character only used inside a    function modifier and it tells     </span>
      <span class="hljs-comment">//Solidity to execute the rest of the code.</span>
        _;
    }
</code></pre>
<p>The functions can thus be rewritten as:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setName</span>(<span class="hljs-params">_greeting</span>) <span class="hljs-title">public</span> <span class="hljs-title">onlyOwner</span> </span>{
    <span class="hljs-keyword">const</span> newGreeting = _greeting
} 

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateGreeting</span>(<span class="hljs-params">_greeting</span>) <span class="hljs-title">public</span> <span class="hljs-title">onlyOwner</span> </span>{
   <span class="hljs-keyword">const</span> newGreeting = _greeting
}
</code></pre>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>That is all there is about Functions Visibility, Types and Modifiers. Congratulations if you read to the very end of this article. You can rely on the guide to understand what visibility types to set your functions and also how to write custom function modifiers. If you have any questions, you can message me on Twitter @emma_odia I look forward to hearing from you! Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[How to Deploy Single and Multiple Smart Contracts using Hardhat.]]></title><description><![CDATA[In this article, I’ll show you how you can deploy a Smart Contract to any EVM chain using Hardhat.
This article assumes that you already know how to write Smart Contracts. For our example, we will deploy a Simple Storage Smart Contract and a message ...]]></description><link>https://emmaodia.hashnode.dev/how-to-deploy-single-and-multiple-smart-contracts-using-hardhat</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-deploy-single-and-multiple-smart-contracts-using-hardhat</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Deploy ]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 14 Nov 2022 11:34:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695251258000/c147bba4-8c11-4c38-b750-ddd16c0912fc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I’ll show you how you can deploy a Smart Contract to any EVM chain using Hardhat.</p>
<p>This article assumes that you already know how to write Smart Contracts. For our example, we will deploy a Simple Storage Smart Contract and a message retrieval contract. This will aid in understanding how to interact with multiple contracts relying on each other.</p>
<p>This article requires that you have <a target="_blank" href="https://hardhat.org/docs">Hardhat</a> installed.</p>
<ol>
<li><p>Create a Directory, cd into it and start a Hardhat project.</p>
<pre><code class="lang-json"> mkdir SampleProject &amp;&amp; cd SampleProject

 npm init hardhat -y
</code></pre>
</li>
<li><p>Open the project in a Terminal, you will find a default TimeLock Contract. For our first scenario, we are deploying a single Smart Contract. Replace the TimeLock Smart Contract, with a Simple Storage Smart Contract:</p>
<pre><code class="lang-solidity"> <span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span>
 <span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.19;</span>

 <span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">SimpleStorage</span> </span>{
     <span class="hljs-keyword">uint</span> storedData;

     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">set</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> x</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
         storedData <span class="hljs-operator">=</span> x;
     }

     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>) </span>{
         <span class="hljs-keyword">return</span> storedData;
     }
 }
</code></pre>
<p> It is a Simple Contract that stores a number and returns a number. </p>
</li>
<li><p>Compile the Smart Contract to confirm that there are no errors. Run the following command:</p>
<pre><code class="lang-json"> npm hardhat compile
</code></pre>
</li>
<li><p>Given that the Smart Contract has successfully compiled, the next step is to write a script that will help us deploy the Smart Contract, and also to configure the network or networks where we want to deploy the Smart Contract. First the script.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> hre = <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</span>);
 <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
     <span class="hljs-keyword">const</span> Contract = <span class="hljs-keyword">await</span> hre.ethers.getContractFactory(<span class="hljs-string">"SimpleStorage"</span>);
     <span class="hljs-keyword">const</span> contract = <span class="hljs-keyword">await</span> Contract.deploy();

     <span class="hljs-keyword">await</span> contract.deployed();
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Contract deployed to <span class="hljs-subst">${contract.address}</span>`</span>);
 }

 main()
     .then(<span class="hljs-function">() =&gt;</span> process.exit(<span class="hljs-number">0</span>))
     .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
          <span class="hljs-built_in">console</span>.error(error);
          process.exitCode = <span class="hljs-number">1</span>;
 });
</code></pre>
<p> Hardhat library offers the ability to interact with the EthersJS Ethereum Libary, which allows developers to interact with the Ethereum blockchain in a simple way.</p>
</li>
</ol>
<p>    In this script, we are calling an instance of it, and making the methods available. You can see the various methods available <a target="_blank" href="https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-ethers">here</a>. </p>
<p>    The Line <code>hre.ethers.getContractFactory("SimpleStorage");</code> gives us access to the Smart Contract, and the hardhat wrapper is wrapped around the EthersJS <code>ContractFactory</code> Class  </p>
<p>    The <a target="_blank" href="https://docs.ethers.org/v6/single-page/#api_contract__ContractFactory">ContractFactory</a> is used to deploy a Contract to the blockchain. It gives access to the <code>deploy()</code> method. Once the contract is deployed, the console log statement prints the address to the console.</p>
<p>    The <code>error catch</code> is implemented on the function, and it will throw any errors and fail to complete the process.  </p>
<p>    The next step is to specify the network where you want your Smart Contract to be deployed.</p>
<ol>
<li><p>To configure the networks or networks where we want the Smart Contract deployed, open the <code>hardhat.config.js</code> file, and you will find the <code>module.export</code> instance only contains the solidity version. We can add a network object to specify the list of networks where we want to deploy the Smart Contract.  </p>
<p> It is important to note the following:</p>
</li>
</ol>
<ul>
<li><p>You need the private keys of an EOA to deploy a Smart Contract and enough native token to pay for the transaction.</p>
</li>
<li><p>If you are deploying to a network other than <a target="_blank" href="http://localhost">localhost</a>, you will need the service of a Node Provider, that will help you bundle your transaction into a Block. To use the services of a Node Provider, you have to sign up to use the services of the Node Provider, and get an API Key. Popular Node Providers are Alchemy and Infura.</p>
</li>
<li><p>You will also be required to parse your private keys to the Node Provider. To hide your keys, you can simply use the <code>dotenv</code> library.</p>
</li>
</ul>
<p>    For this next step, have a Private Key ready. In the <code>hardhat.config.js</code> file, add a new object called <code>networks</code>, in the first example, we will deploy to the Ganache Local Blockchain:</p>
<pre><code class="lang-javascript">    <span class="hljs-built_in">module</span>.exports = {
      <span class="hljs-attr">solidity</span>: <span class="hljs-string">"0.8.18"</span>,
      <span class="hljs-attr">networks</span>: {
        <span class="hljs-attr">ganache</span>: {
          <span class="hljs-attr">url</span>: <span class="hljs-string">"http://127.0.0.1:8545"</span>,
          <span class="hljs-attr">chainId</span>: <span class="hljs-number">1337</span>,
          <span class="hljs-attr">accounts</span>: [
                 <span class="hljs-string">"0x&lt;your-private-key&gt;"</span>,
          ],
        },
      },
    };
</code></pre>
<p>    The networks typically contains the following object keys: network name, it’s url, your private private key which when pasting, you can precede with <code>0x</code>. Go back to terminal, and deploy the Smart Contract, using the command:</p>
<pre><code class="lang-json">    npx hardhat run scripts/deploy.js --network ganache
</code></pre>
<p>    Your Smart Contract will successfully deploy to the local Ganache Blockchain.</p>
<p>    To deploy to other networks, as mentioned earlier, you will need API Keys from a Node Provider. Just as the Ganache Network was specified (You do not need a Node Provider to interact with the Ganache Blockchain, as it is running on your Machine), you will specify the network information, and in the url, pass the Node Provider endpoint for interacting with the blockchain. For example to deploy to the Sepolia network:</p>
<pre><code class="lang-javascript">    sepolia: {
          <span class="hljs-attr">url</span>: https:<span class="hljs-comment">//eth-sepolia.g.alchemy.com/v2/${ALCHEMY_KEY},</span>
          accounts: [PRIVATE_KEY],
        },
</code></pre>
<p>    Then run the command:</p>
<pre><code class="lang-json">    npx hardhat run scripts/deploy.js --network sepolia
</code></pre>
<ol>
<li>To deploy multiple Smart Contracts, where one Smart Contract Address needs to be parsed as an argument to the next Smart Contract, you do not need multiple scripts. You can deploy the contract one before the other, and parse the address of an already deployed contract to another.</li>
</ol>
<p>    Given an example where you have 2 Smart Contracts: TokenContract.sol and StakingContract.sol, and you need to pass TokenContract address to StakingContract at deployment. Where StakingContract has the following constructor arguments:</p>
<pre><code class="lang-solidity">     <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params">
       TokenContract _token,
       <span class="hljs-keyword">uint256</span> _tokenPerBlock,
       <span class="hljs-keyword">uint256</span> _startBlock
     </span>)</span>
</code></pre>
<p>    Here is the Script to run the deployment:</p>
<pre><code class="lang-javascript">    <span class="hljs-keyword">const</span> hre = <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</span>);

    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">const</span> TOKEN = <span class="hljs-keyword">await</span> hre.ethers.getContractFactory(<span class="hljs-string">"TokenContract"</span>);
        <span class="hljs-keyword">const</span> token = <span class="hljs-keyword">await</span> TOKEN.deploy(<span class="hljs-number">10000000</span>);

        <span class="hljs-keyword">await</span> token.deployed();
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Token deployed to:"</span>, token.address);

        <span class="hljs-keyword">const</span> Contract = <span class="hljs-keyword">await</span> hre.ethers.getContractFactory(<span class="hljs-string">"StakingContract"</span>);
        <span class="hljs-keyword">const</span> contract = <span class="hljs-keyword">await</span> Contract.deploy(token.address, <span class="hljs-number">10000</span>, <span class="hljs-number">1</span>);

        <span class="hljs-keyword">await</span> contract.deployed();
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Contract deployed to:"</span>, contract.address);
    }

    main()
         .then(<span class="hljs-function">() =&gt;</span> process.exit(<span class="hljs-number">0</span>))
         .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
            <span class="hljs-built_in">console</span>.error(error);
            process.exit(<span class="hljs-number">1</span>);
    });
</code></pre>
<p>    You will observe that the code runs synchronously as a result, the success of the first request will return, and make the <code>token.address</code> of the first contract available for use in the second.</p>
<p>You can follow this guide, and implement deploying multiple Smart Contracts numbers over two.</p>
<p>In this article, I have walked you through how you can easily deploy a single contract, or multiple contracts to a local Ganache Blockchain for testing, or to a Testnet or Mainnet Blockchain using a Node Provider.</p>
]]></content:encoded></item><item><title><![CDATA[How to Deploy a Smart Contract using Remix]]></title><description><![CDATA[In this article, I’ll walk you through how to deploy a Smart Contract via remix to any EVM chain, or your Localhost. This is important when you do not want to spin up a Trufflesuiite or Hardhat project, you can simply write the Smart Contract(s) in R...]]></description><link>https://emmaodia.hashnode.dev/how-to-deploy-a-smart-contract-using-remix</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-deploy-a-smart-contract-using-remix</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[Remix]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Thu, 10 Nov 2022 11:17:51 GMT</pubDate><content:encoded><![CDATA[<p>In this article, I’ll walk you through how to deploy a Smart Contract via remix to any EVM chain, or your Localhost. This is important when you do not want to spin up a Trufflesuiite or Hardhat project, you can simply write the Smart Contract(s) in Remix, connected to a Wallet Provider e.g MetaMask, select a network and deploy the Smart Contract to the selected network.  </p>
<p>This approach gives you access to the Smart Contract methods which you can interact with via Remix, and the ABI which you can copy and use in building out a UI and/or verifying your Smart Contract code.</p>
<p>This article assumes that you already know how to write Smart Contracts. For our example, we will deploy a Simple Storage Smart Contract. This knowledge will open up your mind to the possibility of deploying multiple Smart Contracts, where possibly each Smart Contract relies on another.</p>
<p>To begin open up <a target="_blank" href="https://remix.ethereum.org/">Remix</a> in your Browser of choice, where you already have MetaMask installed.</p>
<p> In Remix, among the example Smart Contracts. You will find an example Simple Storage Contract:</p>
<pre><code class="lang-solidity"><span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> &gt;=0.4.16 &lt;0.9.0;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">SimpleStorage</span> </span>{
    <span class="hljs-keyword">uint</span> storedData;

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">set</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> x</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        storedData <span class="hljs-operator">=</span> x;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>) </span>{
        <span class="hljs-keyword">return</span> storedData;
    }
}
</code></pre>
<p>It is a Simple Storage Contract that stores a number and returns the number. You can compile it and deploy it in MetaMask to interact with it.   </p>
<p>To deploy the Smart Contract to a network outside the Remix local environment. In the <code>ENVIRONMENT</code> dropdown select <code>Injected Provider - MetaMask</code> This will give Remix access to your MetaMask wallet (Note that this does not give access to your private keys), and the network selected at the time in your MetaMask, is set as the network you will be interacting with.   </p>
<p><img src="https://lh3.googleusercontent.com/-AqP83GnlZyZIQNrr4cP5UU-zJqwLL-wMrjFGv_GuiX6N5jzBkvHSWTmRwvc0WuJBy9_Zjs-E4lRW7WuAtQ9bhn9TamH9ZTiA991FIC_67pVlSyYSTTds8xbLgouFs3TNakNhpT6BQs9K6RqGs7vuE8" alt /></p>
<p>Let’s begin with a local network deployed to the Ganache Blockchain.</p>
<p>Launch Ganache. Open a workspace and note the <code>Network ID</code> and <code>RPC Server Address</code>. </p>
<p><img src="https://lh5.googleusercontent.com/1QHo-D7Tc3wQM9GXso7qKBttfjhJHZBTy8dsGiGIU69UZFbJzxgBzQk5uuMj84oVljirfORHyS0GBAQ_G4QD5xIsZGvE8FOoR3hePsZG1RpRNYPyQLyvMrM_sI2H5vGkYacT1jFIaZ5_0LV-W9r2s9g" alt /></p>
<p>Open your MetaMask and select the option to add a Network. </p>
<p><img src="https://lh6.googleusercontent.com/EUcNjFybelmr6aMFwuSz1DsSI92CQsKtljgEhEGuODDc3fQueBoHxie9tmBWOiox84TaB4TBbeGkrXdRndfHonzfhR2jGY0q1PK12cNmguEuie5jp9RbkUf5fwrINJnVr8xOhOD6qFzLQjgO5bJE6ic" alt /></p>
<p>Click on <code>Add network manually</code>  </p>
<p>Fill in the fields and click <code>Save</code>. The fields correspond with the Ganache Blockchain settings.</p>
<p><img src="https://lh5.googleusercontent.com/sA0mivvVXwkpBHITdiEzh48TOoFxjAN17dz1H1uhFWSpTP8BrMrmosdKESEwTkXMw-JkgbCkDl4bxCZlBUDMk2sZF7XmwUegj7hZ9zSdg_h9e9wdUAeMQCbdtLNINBPct7dLl8_WoJ90DEISrplLFfQ" alt /></p>
<p>You can then select <a target="_blank" href="http://Localhost">Localhost</a> as your network in MetaMask, and in Remix, right under the ENVIRONMENT dropdown, you will see the network specified, and the wallet address listed as your MetaMask address. At this point it is optional for you to add an address from Ganache to MetaMask, this way you have access to test ETH with which to carry out transactions. </p>
<p><img src="https://lh5.googleusercontent.com/7W_Dpg-vJxhzlf35Hlc93sPKZjiCqC_g1nAqBlFVlUGwLC40lr7_W5tIhJYChE7k1Ts3fHihGmS-zo2xYLqv3Zq7pqfF4LyGEqq13eBpUGszd267g_LTdVW8XfsA-NE-V6NyMBtceeVBeSHZlStSzUo" alt /></p>
<p>Compile the Smart Contract. Go to the deploy tab. When you click on deploy the Smart Contract will be deployed to the network selected in MetaMask. Wait for a few seconds, this will depend on the selected network and the confirmation time required. Once the transaction is confirmed, you will see it on the terminal, and the Smart Contract will be available for you to interact with.</p>
<p><img src="https://lh6.googleusercontent.com/LsXctRIO12Q_zL_BOjPvoqSfbtrGtfhZOjL8CnrQJN3Lcez2RcuJmInzC2QKmbh4GJMEAv_9gnSr1YgdLsu3MDH_tt2ySVUzrylSGEFUkcnC6ysl_3jCqfWFFFRFodId1wulQxgSm9nGEz-41D-q2Dg" alt /></p>
<p><img src="https://lh5.googleusercontent.com/6-Q5jiLPkFzOzBMqTLj9zi_YQ3BNDHO2_6aECCso43sw0QPCAOHC504nf3GvO1lKZYTuTeZTBkRt1zL-x-KOljWqmjPcQIVzfDgPUirLPS_v-ye1I8_dAa2-2EepVYmB1_lCdqlAhlgItU1J3oCzO7E" alt /></p>
<p>If you deployed to a Blockchain network away from <a target="_blank" href="http://localhost">localhost</a>, you can copy the transaction hash and paste it into the explorer of the network where the Smart Contract is deployed and you will find it.</p>
<p>You can deploy any Smart Contract, or even multiple Smart Contracts using this approach. Always ensure that you have the native token of the particular network you are deploying to, for Gas Payment.</p>
]]></content:encoded></item><item><title><![CDATA[The Ethereum Merge: Block 15537394]]></title><description><![CDATA[The Ethereum merge, ever since Vitalik Buterin first touted it, has since been heralded with great promise of the possibilities that it would accrue to the Ethereum network: reduction in carbon footprint! Although first scheduled to happen in 2019, "...]]></description><link>https://emmaodia.hashnode.dev/the-ethereum-merge-block-15537394</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/the-ethereum-merge-block-15537394</guid><category><![CDATA[The Ethereum Merge]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[the merge]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Fri, 28 Oct 2022 03:36:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1666927945487/9I7pQy5wH.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Ethereum merge, ever since Vitalik Buterin first touted it, has since been heralded with great promise of the possibilities that it would accrue to the Ethereum network: reduction in carbon footprint! Although first scheduled to happen in 2019, "the merge" did not occur not until September 15, 2022, 6:42 AM UTC+1. What is the merge, and why did it take such a while after it was announced to be finalized?</p>
<p>Ethereum is now using the Proof of Stake (PoS) consensus mechanism and previously used the Proof of Work consensus (PoW) mechanism. The PoW consensus relied on "Node Validators" who create blocks of transactions relying upon heavy mathematical algorithms where the Validator will calculate the block difficulty in order to validate a Block. The more computing power the node validator has, the better its chance of calculating a new block. This process requires a lot of computing power and, as a result, large energy consumption. PoS was then proposed as an alternative consensus mechanism.</p>
<p>PoS requires validators to stake ETH. The validators then check that new blocks proposed for the Ethereum network are not malicious. The Validator is also held to account by other network actors to ensure that no validator proposes the wrong block information. The staked ETH is used as collateral, such that when a validator authorizes/proposes a bad block, their staked ETH is then slashed. In the Proof of Stake mechanism, there is thus no need for heavy computation to propose new Blocks, thus leading directly to direct energy consumption in the Ethereum network.</p>
<p>The Ethereum network was not "switched off, then updated" for the merge. A famous analogy used to describe the merge event is that of a racing car whose engine was switched from a diesel engine to an electrical engine while the car is being driven on a highway; This underscores the level of the technical difficulty of the merge event. To achieve this, the newly proposed PoS mechanisms had to undergo critical testing alongside the PoW mechanism. </p>
<p>The Ethereum engineers proposed a road map that started with introducing a separate Ethereum chain called the "Beacon Chain" in December 2020. The PoS model was then used on the Beacon chain. The Ethereum Mainnet was still running on the PoW model at the time, and both chains ran parallel. This was so that errors that could happen due to the switch to the PoS model were quickly discovered. In the course of running the Beacon chain, "Shadow forks" were also implemented. Shadow forks were running PoS, and when bugs were found, they were immediately dropped.</p>
<p>The extensive testing continued, and in the course of the time, Testnets were successfully migrated to the PoS without any resultant errors. The significant change occurred when the Beacon chain was merged into the mainnet with all the state history and finalized at <a target="_blank" href="https://etherscan.io/block/15537394">Block 15537394</a>.</p>
]]></content:encoded></item><item><title><![CDATA[How to build a Dashboard to return all NFT tokens a user holds using NFTPort.]]></title><description><![CDATA[In this guide, developers will take a sequence of steps to build a dashboard that returns all the tokens owned by a user, using the NFTPort endpoint: “Retrieve NFTs owned by an account.”
What are NFTs?
I make a personal recommendation to developers t...]]></description><link>https://emmaodia.hashnode.dev/how-to-build-a-dashboard-to-return-all-nft-tokens-a-user-holds-using-nftport</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-build-a-dashboard-to-return-all-nft-tokens-a-user-holds-using-nftport</guid><category><![CDATA[NFTPort]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Wed, 19 Oct 2022 19:29:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1666207259428/hINg5JDUL.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this guide, developers will take a sequence of steps to build a dashboard that returns all the tokens owned by a user, using the NFTPort endpoint: <a target="_blank" href="https://docs.nftport.xyz/docs/nftport/b3A6MjE0MDYzNzM-retrieve-nf-ts-owned-by-an-account">“Retrieve NFTs owned by an account.”</a></p>
<h2 id="heading-what-are-nfts">What are NFTs?</h2>
<p>I make a personal recommendation to developers to always read the ethereum improvement proposals on the website: eips.ethereum.org, there you will find that prior to settling on the name choice of “NFTs”, one of the first name choices was the word “Deeds”. In legal terms “A deed is a legal document that grants ownership to a piece of real estate or other property asset.” An understanding of NFTs as deeds opens up the developer to a plethora of use cases that can be builT using NFTs. Popular today is ownership of tokenized art. A user can own many NFTs deployed across multiple chains and deployed by various contracts. To demonstrate or check ownership of such assets by a user, one has to go to various blockchain explorers and input the user address to return all the NFTs owned by the user of that particular chain. This is a problem that NFTPort has solved using her APIs.</p>
<h2 id="heading-what-is-nftport">What is NFTPort?</h2>
<p>NFTPort grants users ONE API Key to unlock access to NFTs across multiple chains. NFTPort prides itself on its ability to “Bring your NFT application to market in hours instead of months.” In this guide, we will rely on one of the API endpoints available in NFTPort and build a user dashboard where you can parse any ethereum address and return all the NFTs owned by that address. We will build the entire DApp using one API in the suite of APIs from NFTPort.</p>
<h2 id="heading-sample-dapp">Sample DApp</h2>
<p>We will build a <a target="_blank" href="https://emmaodia.github.io/rnoba/index.html?">simple app</a> using HTML and JS. The app will call the API: <a target="_blank" href="https://docs.nftport.xyz/docs/nftport/b3A6MjE0MDYzNzM-retrieve-nf-ts-owned-by-an-account">Retrieve NFTs owned by an account</a></p>
<p>This endpoint Returns NFTs owned by a given account (i.e. wallet) address.
It is useful for:
For checking if a user owns a specific NFT and then unlocking specific activity.
Adding NFT portfolio section to your apps.</p>
<p>The next step will walk you through building a simple dapp.</p>
<h3 id="heading-html">HTML</h3>
<p>Using any code editor of your choice, kindly create a folder and create the following files <code>index.html</code> and <code>index.js</code>. In the <code>index.html</code> file, paste the following code. </p>
<pre><code>&lt;html&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"</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">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.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-sm-12"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Sample DApp<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"setData"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"setDataInput"</span>&gt;</span>Enter Address into the Input:<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">id</span>=<span class="hljs-string">"setDataInput"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">input</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">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</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>Total NFTs held: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"totalNFTs"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</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;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre><p>If you are using vscode as your primary editor, use the liveserver extension to launch the app, you will see the following screen:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666204491262/NxHXGCkMK.png" alt="Screenshot 2022-10-02 at 08.21.52.png" /></p>
<p>This is a landing page where a user can input any ethereum address and return all the NFTs held by that address. The next step is to write javascript code that will return the data to the user. Follow the sequence of steps to gain a firm understanding of the process.</p>
<h3 id="heading-javascript">JavaScript</h3>
<ol>
<li><p>Go to the NFTPort website and sign up to get a free API Key. </p>
</li>
<li><p>Open your <code>index.js</code> file and enter the code:</p>
<pre><code><span class="hljs-keyword">const</span> options = {
<span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</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">Authorization</span>: <span class="hljs-string">'your-api-key'</span>
}
};

fetch(<span class="hljs-string">'https://api.nftport.xyz/v0/accounts/address?chain=ethereum'</span>, options)
.then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())
.then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(response))
.catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> <span class="hljs-built_in">console</span>.error(err));
</code></pre><p>This is a GET request where a call is made to the Retrieve NFTs owned by an account endpoint. The endpoint url is <code>https://api.nftport.xyz/v0/accounts/address?chain=ethereum</code> where <code>address</code> can be any ethereum externally owned address, and the chain we are exploring is ethereum. The Fetch API is used to query the endpoint and the response is formatted to json before it is logged to the console in this step.</p>
<p>Copy any ethereum address from etherscan and enter it into the address, the url will look like this <code>https://api.nftport.xyz/v0/accounts/0x….?chain=ethereum</code> </p>
</li>
<li><p>Open the browser page where the index file is running, and open the console. You will see an <code>object</code> response. Click on the object to see all the data return by the endpoint.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666204662111/dv-epbT6J.png" alt="Screenshot 2022-10-02 at 08.38.31.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666204681574/dkFj0ccXV.png" alt="Screenshot 2022-10-02 at 08.43.33.png" /></p>
<p>You can also click on the <code>nfts</code> dropdown where you will see all the json values returned: <code>contract_address</code>, <code>token_id</code> and <code>contract_name</code></p>
</li>
<li><p>To return more data, there is the <code>include</code> query where you can add the option to return nft <code>metadata</code> to the url path.</p>
<pre><code>https:<span class="hljs-comment">//api.nftport.xyz/v0/accounts/address?chain=ethereum&amp;include=metadata</span>
</code></pre><p>This returns more information about the token.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666204750800/qazFjqHGl.png" alt="Screenshot 2022-10-02 at 08.44.07.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666204769192/yuL3_9P9Q.png" alt="Screenshot 2022-10-02 at 08.44.31.png" /></p>
</li>
<li><p>We have successfully confirmed that we can connect to the API using our API KEY, query an endpoint and return data to the app using the fetch api. The next step is to write a function that will take any address parsed as an argument and when a user clicks <code>submit</code> return the response. Add the following code to <code>index.js</code></p>
<pre><code>…
<span class="hljs-keyword">const</span> $setData = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"setData"</span>);
$setData.addEventListener(<span class="hljs-string">"submit"</span>, <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
e.preventDefault();

<span class="hljs-keyword">const</span> data = e.target.elements[<span class="hljs-number">0</span>].value;
<span class="hljs-built_in">console</span>.log(data);
});
</code></pre><p>The is a DOM manipulation script where the user targets the form by its id <code>setData</code>. An event listener is added with an action triggered by <code>submit</code>, where an async function is run and whatever is parsed into the input is logged to the console. Go ahead and test it out by typing anything into the input field. </p>
</li>
<li><p>The next step is to ensure that we can parse an ethereum address into the input and it will be resolved as part of the api url query. This will be done in a try catch block inside the event listener. In this step, we will refactor the code we have already written, and add the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/URL/URL">URL object query method</a> to create a url path that can be resolved using the fetch api. Make the function inside the event listener an async function. Delete or comment out the fetch method already in the code, and add the following lines inside the event listener function.</p>
<pre><code><span class="hljs-keyword">const</span> url = <span class="hljs-keyword">new</span> URL(
  <span class="hljs-string">`https://api.nftport.xyz/v0/accounts/<span class="hljs-subst">${data}</span>?chain=ethereum&amp;include=metadata`</span>
);
<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(url, options);
  <span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-built_in">console</span>.log(results);
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-built_in">console</span>.log(error);
}
</code></pre><p>Copy any ethereum address and enter it into the input, click ‘submit’, the response will be logged to the console! From the point, you can build any UI to return the data to users via the interface. </p>
<p>In this sample dapp, we will return the data via a simple table that will list the following:</p>
<ul>
<li>Contract Address</li>
<li>Token Name</li>
<li>Token ID</li>
<li>Image URL</li>
<li>Contract Creator Address</li>
<li>Total Number of NFTs held by the address</li>
</ul>
</li>
<li><p>To return the total number of nfts held by the address, we will target the <code>&lt;span&gt;</code> tag on the frontend, this has an id <code>totalNFTs</code>, target the <code>totalNFTs</code> id from the DOM using:</p>
<pre><code><span class="hljs-keyword">let</span> $totalNFTs = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"totalNFTs"</span>);
</code></pre><p>add the following code to the try block:</p>
<pre><code>$totalNFTs.innerHTML = results.total;
</code></pre><p>You will see the total number of NFTs returned to the UI.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666204821326/KTYkfpOcm.png" alt="Screenshot 2022-10-02 at 09.30.28.png" /></p>
<p>The final step is to return the remaining data to the UI using the table.</p>
</li>
<li><p>Add the following line into the <code>index.html</code> file under the Total NFTs div</p>
<pre><code>&lt;table id=<span class="hljs-string">"tokenTable"</span> <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"table table-striped"</span>&gt;&lt;/table&gt;
</code></pre><p>This is a <code>&lt;table&gt;</code> div from getBootstrap that creates a pleasant looking table, we have assigned it an id <code>tokenTable</code>. </p>
</li>
<li><p>Target the DOM using the <code>tokenTable</code> id</p>
<pre><code><span class="hljs-keyword">let</span> tableRef = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"tokenTable"</span>);
tableRef.innerHTML = <span class="hljs-string">`&lt;thead class="thead-dark"&gt;
           &lt;tr&gt;
               &lt;th&gt;Contract Address&lt;/th&gt;
               &lt;th&gt;Token Name&lt;/th&gt;
               &lt;th&gt;Token ID&lt;/th&gt;
                &lt;th&gt;Image URL&lt;/th&gt;
               &lt;th&gt;Creator Address&lt;/th&gt;
           &lt;/tr&gt;
       &lt;/thead&gt;
       &lt;tbody&gt;
       &lt;/tbody&gt;`</span>;
</code></pre></li>
</ol>
<p>Update the try block:</p>
<pre><code> <span class="hljs-keyword">const</span> nfts = results.nfts;
 nfts.map(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
       tableRef.insertRow().innerHTML =
         <span class="hljs-string">`&lt;td&gt; &lt;a href="https://etherscan.io/address/<span class="hljs-subst">${result.contract_address}</span>" 
 target="_blank"&gt;<span class="hljs-subst">${result.contract_address}</span>&lt;/a&gt;&lt;/td&gt;`</span> +
         <span class="hljs-string">`&lt;td&gt; <span class="hljs-subst">${result.name}</span> &lt;/td&gt;`</span> +
         <span class="hljs-string">`&lt;td&gt; <span class="hljs-subst">${result.token_id}</span> &lt;/td&gt;`</span> +
         <span class="hljs-string">`&lt;td&gt; &lt;a href="<span class="hljs-subst">${result.metadata.image}</span>" target="_blank"&gt;image&lt;/a&gt;&lt;/td&gt;`</span> +
         <span class="hljs-string">`&lt;td&gt; &lt;a href="https://etherscan.io/address/<span class="hljs-subst">${result.creator_address}</span>" 
 target="_blank"&gt;<span class="hljs-subst">${result.creator_address}</span>&lt;/a&gt;&lt;/td&gt;`</span>;
     });
</code></pre><p> Enter an ethereum address and click submit!</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666204848420/tfUPZ59z5.png" alt="Screenshot 2022-10-02 at 09.34.28.png" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Here is the complete <a target="_blank" href="https://github.com/emmaodia/emmaodia.github.io/tree/master/rnoba">code</a> for your reference. In this guide, we explored the “Retrieve NFTs owned by an account” API endpoint. We explored its relevance in building NFT applications. We build a simple application to establish a primary understanding of the endpoint. In conclusion, this guide represents a frame of reference that a developer can start with and build any form of use case using the single API endpoint.</p>
<p>View a video demo  and code walkthrough of the app <a target="_blank" href="https://emmaodia.github.io/rnoba/index.html?">here</a></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.youtube.com/watch?v=D749myFvDLU">https://www.youtube.com/watch?v=D749myFvDLU</a></div>
]]></content:encoded></item><item><title><![CDATA[A Guide on How to Interact with Smart Contracts using HTML, CSS and JS.]]></title><description><![CDATA[One of the many steep learning curves for web2 developers getting into web3 is: How do I interact (use) Smart Contracts via a frontend app? i.e., How can users interact with my Smart Contract? It is not enough to share your Smart Contract address and...]]></description><link>https://emmaodia.hashnode.dev/a-guide-on-how-to-interact-with-smart-contracts-using-html-css-and-js</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/a-guide-on-how-to-interact-with-smart-contracts-using-html-css-and-js</guid><category><![CDATA[ethersjs]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[Web3]]></category><category><![CDATA[hardhat]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 10 Oct 2022 04:56:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/ruSoEmT0IBg/upload/v1665377783248/0mBplUQnK.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the many steep learning curves for web2 developers getting into web3 is: How do I interact (use) Smart Contracts via a frontend app? i.e., How can users interact with my Smart Contract? It is not enough to share your Smart Contract address and then direct your users to interact with the Contract on an explorer such as etherscan. In this guide, we will walk through a process that teaches you how to interact with your Smart Contract via a frontend UI.</p>
<h3 id="heading-contents">Contents:</h3>
<ul>
<li><p>Blockchain Explorers.</p>
</li>
<li><p>Smart Contract frontend Libraries.</p>
</li>
<li><p>EthersJS.</p>
</li>
<li><p>Sample App using HTML and JS.</p>
</li>
</ul>
<h1 id="heading-blockchain-explorers">Blockchain Explorers</h1>
<p>Different Blockchains have a User Interface where all transactions and other information (blocks, token information, contract data) are displayed in an easy to read and “interact with” format, usually a web page. The Blockchain explorer for ethereum is etherscan. According to its website: “Built and launched in 2015, it is one of the earliest and longest running independent projects built around Ethereum and its community with the mission of providing equitable access to blockchain data.”</p>
<p>It is vital for the Smart Contract developer to learn how to use the explorer for a particular chain that you deploy your Smart Contract code on. More so when the explorer grants the ability to upload your Smart Contract code and ABI, thus making available an interactive UI for your Smart Contract onchain.</p>
<p>Kindly read this <a target="_blank" href="https://emmaodia.hashnode.dev/a-guide-on-compiling-and-deploying-your-first-smart-contract-to-the-goerli-testnet-using-hardhat">guide</a>, where I walk through deploying a Smart Contract to the Goerli testnet. In the guide, I walk you through the process of reading and writing to the Smart Contract via the explorer.</p>
<p>It is not an optimal process for users to read and write to your contract via an explorer. It is more convenient to build a user interface that will make the process easy. It is vital to understand how the Smart Contract information can be read and write from a chain. The ethereum.org guides sufficiently explain this process:</p>
<blockquote>
<p>“<em>In order for a software application (UI) to interact with the Ethereum blockchain - either by reading blockchain data or sending transactions to the network - it must connect to an Ethereum node.</em></p>
<p><em>For this purpose, every Ethereum client implements a JSON-RPC specification, so there are a uniform set of methods that applications can rely on regardless of the specific node or client implementation.</em></p>
<p><em>JSON-RPC is a stateless, lightweight remote procedure call (RPC) protocol. It defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over HTTP, or in many various message passing environments. It uses JSON (RFC 4627) as data format. [sic].</em>”</p>
</blockquote>
<p>“<em>While you may choose to interact directly with Ethereum clients via the JSON-RPC API, there are often easier options for dapp developers. Many JavaScript and backend API libraries exist to provide wrappers on top of the JSON-RPC API. With these libraries, developers can write intuitive, one-line methods in the programming language of their choice to initialize JSON-RPC requests (under the hood) that interact with Ethereum.</em>”</p>
<h1 id="heading-smart-contract-frontend-libraries">Smart Contract Frontend Libraries</h1>
<p>The frontend JavaScript Library for interacting with Smart Contracts and building UIs are Web3JS and EthersJS</p>
<p><strong>Web3JS:</strong> “web3.js is a collection of libraries that allow you to interact with a local or remote ethereum node using HTTP, IPC or WebSocket.”</p>
<p><strong>EthersJS:</strong> “The ethers.js library aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem.”</p>
<p>To demonstrate how EthersJS works, we will build out a Sample App using plain HTML and JavaScript. This approach allows you to learn how to interact with Smart Contracts at the basic implementation level. This approach will cement your knowledge and thus lay a proper foundation for building with other JavaScript libraries such as ReactJS and VueJS.</p>
<h1 id="heading-sample-app-using-html-and-js">Sample App using HTML and JS.</h1>
<p>For our sample dapp, we will use the Smart Contract from a previous article. It is a simple “Hello, World!” contract. We will use the Hardhat tool to compile and deploy the Smart Contract to a local blockchain, and then we will deploy it to the Goerli testnet. You can read my Guide on <a target="_blank" href="https://emmaodia.hashnode.dev/a-guide-on-compiling-and-deploying-your-first-smart-contract-to-the-goerli-testnet-using-hardhat">How to compile and deploy Smart Contracts using Hardhat</a>.</p>
<p>Here are the steps:</p>
<ol>
<li>Choose a dir name for your project and create one</li>
</ol>
<pre><code class="lang-json">mkdir hello_world &amp;&amp; cd hello_world
</code></pre>
<ol>
<li>Initialize a project using npm default init command:</li>
</ol>
<pre><code class="lang-json">npm init -y
</code></pre>
<ol>
<li>Hardhat is a Library and will have to be installed as a project dependency:</li>
</ol>
<pre><code class="lang-json">npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
<span class="hljs-comment">//@nomicfoundation/hardhat-toolbox is a hardhat plugin which has everything you need for developing smart contracts.</span>
</code></pre>
<ol>
<li>Set up hardhat in the project by running the command:</li>
</ol>
<pre><code class="lang-json">npx hardhat
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665375783669/IQJwR2AQh.png" alt="Screenshot 2022-10-04 at 18.18.40.png" /></p>
<p>Select the option: <code>“Create a javascript Project.”</code></p>
<ol>
<li>Open the ‘hello_world’ project in your IDE of choice, the directory will look something like this:</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665375806643/i7h_dH88V.png" alt="Screenshot 2022-10-04 at 18.21.05.png" /></p>
<p>Open the Contracts dir and create a new file: <code>HelloWorld.sol</code>, where <code>.sol</code> is an extension denoting that it is a solidity file. This is where our Smart Contract code will be written. Copy the code below into the file:</p>
<pre><code class="lang-json"><span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span>

pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.17</span>;

contract HelloWorld {

  address public owner;
  string greeting;

  constructor(){
    owner = msg.sender;
  }

  function setGreeting(string memory _greeting) public {
     greeting = _greeting;
  }

  function getGreeting() public view returns(string memory) {
    return greeting;
  }

}
</code></pre>
<p>This article assumes that you have a basic understanding of how Solidity works. If you want a line by line breakdown of this code, you can read my guide: “Welcome to Solidity!”</p>
<ol>
<li>The next step is to compile of Contract. This process will generate the Contract ByteCode that gets deployed to a chain and the Contract ABI, which we will need to interact with the Contract via a UI.</li>
</ol>
<pre><code class="lang-json">npx hardhat compile
</code></pre>
<p>You will see a message in the terminal:</p>
<pre><code class="lang-json">Compiling <span class="hljs-number">1</span> file with <span class="hljs-number">0.8</span><span class="hljs-number">.17</span>
</code></pre>
<p>After the compilation has completed, hardhat will create two folders in the project directory: <code>artifacts</code> and <code>cache</code>. Open the <code>artifacts</code> dir and go to <code>contracts/HellowWorld.sol</code> and open the file: <code>HelloWorld.json</code>, here you will find the <code>abi</code> in an array. The last step of this session will be to deploy the Smart Contract to a local hardhat node.</p>
<ol>
<li>Building Smart Contracts with Hardhat requires writing a script that is needed to indicate the network to deploy the Smart Contract. We will write a script that will deploy the Smart Contract to a local node. Open the scripts folder in the directory and create a new file <code>deploy_helloWorld.js</code>, add the following code to the file:</li>
</ol>
<pre><code class="lang-json">const hre = require(<span class="hljs-string">"hardhat"</span>);

async function main() {
  const Contract = await hre.ethers.getContractFactory(<span class="hljs-attr">"HelloWorld"</span>);
  const contract = await Contract.deploy();

  await contract.deployed();

  console.log(`Contract deployed to ${contract.address}`);
}

main().catch((error) =&gt; {
  console.error(error);
  process.exitCode = 1;
});
</code></pre>
<ol>
<li>The last step of this session will be to deploy the Smart Contract to a local hardhat node. Run the command: npx hardhat run --network localhost scripts/deploy_helloWorld.js You will see a message in the terminal:</li>
</ol>
<pre><code class="lang-json">Contract deployed to <span class="hljs-number">0</span>x….
</code></pre>
<p>The Contract has been deployed successfully! The next step is to build a UI to interact with the Contract. It is going to be a simple UI that contains an input field and a Button to send data to the deployed Contract, and a span tag to read data from the deployed Contract.</p>
<h2 id="heading-building-the-ui">Building the UI</h2>
<p>There are a collection of UI Libraries that developers can use to start building interfaces to connect with Smart Contracts. In this guide, we will build a UI using plain old HTML and JS. This is so that developers can understand, line by line, how the interaction works between Smart Contracts and UI at the very basic level.</p>
<p>To connect to the Smart Contract from the UI, we will use the ethers js to handle all the abstraction calls to the JSON-RPC.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665376827993/V_5lmd5i7.png" alt="Screenshot 2022-09-19 at 10.58.28.png" /></p>
<p>Kindly create a directory in the root of the folder containing the <code>Hello World</code> files, name the directory <code>frontend</code>. Inside the frontend directory, create the following files: <code>index.html</code>, <code>index.js</code> and ethers.js</p>
<p>To add ethers js to the project, kindly visit the ethers js <a target="_blank" href="https://cdn.ethers.io/lib/ethers-5.6.esm.min.js">cdn</a> copy the entire file and paste it inside <code>ethers.js</code> . It is better practice (for security reasons) to copy the ethers library to your own webserver and serve it yourself, which is what we are doing in this sample dapp.</p>
<h2 id="heading-html">HTML</h2>
<p>We are going to use the BootStrap Library to build out a basic UI. Open the <code>index.html</code> file and paste this code:</p>
<pre><code class="lang-json">&lt;html&gt;
  &lt;head&gt;
    &lt;link rel=<span class="hljs-string">"stylesheet"</span> href=<span class="hljs-string">"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"</span> integrity=<span class="hljs-string">"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"</span> crossorigin=<span class="hljs-string">"anonymous"</span>&gt;
     &lt;script type=<span class="hljs-string">"module"</span> src=<span class="hljs-string">"index.js"</span>&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=<span class="hljs-string">"container"</span>&gt;
      &lt;div class=<span class="hljs-string">"row"</span>&gt;
        &lt;div class=<span class="hljs-string">"col-sm-12"</span>&gt;
          &lt;h1&gt;Hello World!&lt;/h1&gt;
          &lt;form id=<span class="hljs-string">"setGreeting"</span>&gt;
            &lt;div class=<span class="hljs-string">"form-group"</span>&gt;
              &lt;label for=<span class="hljs-string">"setGreetingInput"</span>&gt;Enter Text into the Input:&lt;/label&gt;
              &lt;input id=<span class="hljs-string">"setGreetingInput"</span> type=<span class="hljs-string">"text"</span> class=<span class="hljs-string">"form-control"</span>&gt;&lt;/input&gt;
            &lt;/div&gt;
            &lt;button type=<span class="hljs-string">"submit"</span> class=<span class="hljs-string">"btn btn-primary"</span>&gt;Submit&lt;/button&gt;
          &lt;/form&gt;
          &lt;div&gt;Response: &lt;span id=<span class="hljs-string">"greeting"</span>&gt;&lt;/span&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>We will walk through the code and explain each line.</p>
<p>This is a HTML file with a <code>&lt;head&gt;</code> and <code>&lt;body&gt;</code> section. The <code>&lt;head&gt;...&lt;/head&gt;</code> section contains the <code>BootStrap CDN</code> link that enables us style the page using the BootStrap Library without writing any extra CSS. It also contains the <code>index.js</code> file; this is the file where we will write the JavaScript and import the ethers js library. The script type must be set to <code>module</code>, as it prevents any errors due to the use of the <code>import</code> statement in the script.</p>
<p>The <code>&lt;body&gt;...&lt;/body&gt;</code> section makes use of class definitions from BootStrap to align the page content: <code>container</code>, <code>row</code>, <code>col-sm-12</code> and <code>form</code>, you can read about them in the BootStrap <a target="_blank" href="https://getbootstrap.com/docs/5.2/getting-started/introduction/">docs</a>. It also contains a <code>form</code> which is a <code>simple input</code>, and a <code>button</code>, the input is where the user will enter an input to be sent to the Smart Contract. The <code>&lt;div&gt;</code> containing the <em>Response</em> also contains a <code>&lt;span&gt;...&lt;/span&gt;</code>, where the response from the contract will be displayed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665376888467/Kxqp2hXeS.png" alt="Screenshot 2022-09-19 at 17.42.21.png" /></p>
<p>The next step is to write the JavaScript code.</p>
<h2 id="heading-js">JS</h2>
<p>All the code here is written in the <code>index.js</code> file, and we will walk through it line by line. Connecting the UI to the Smart Contracts can be broken into three distinct steps: Import the Ethers JS Library Connect the Smart Contract to the UI Implement functions to Write and Read the Smart Contract.</p>
<ol>
<li>Import the Ethers JS Library: At the top of the <code>index.js</code> file, declare the import</li>
</ol>
<pre><code class="lang-json">Import { ethers } from `./ethers.js`;
</code></pre>
<p>This is a named import type that makes the <code>ethers.js</code> library module available in the file as <code>ethers</code>. This imports the <code>ethers.js</code> Library.</p>
<ol>
<li>Connect the Smart Contract to the UI: In this step, we will need the Smart Contract address, ABI, and the Ethers <code>getSigner()</code> to create a connection to the UI, which we will confirm via the UI console. Here is the code:</li>
</ol>
<pre><code class="lang-json">    const HelloWorldAddress = `<span class="hljs-number">0</span>x…..`;
    const ABI = [
 {
      <span class="hljs-attr">"inputs"</span>: [],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"nonpayable"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"constructor"</span>
    },
    {
      <span class="hljs-attr">"inputs"</span>: [],
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"getGreeting"</span>,
      <span class="hljs-attr">"outputs"</span>: [
        {
          <span class="hljs-attr">"internalType"</span>: <span class="hljs-string">"string"</span>,
          <span class="hljs-attr">"name"</span>: <span class="hljs-string">""</span>,
          <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>
        }
      ],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"view"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"function"</span>
    },
    {
      <span class="hljs-attr">"inputs"</span>: [],
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"owner"</span>,
      <span class="hljs-attr">"outputs"</span>: [
        {
          <span class="hljs-attr">"internalType"</span>: <span class="hljs-string">"address"</span>,
          <span class="hljs-attr">"name"</span>: <span class="hljs-string">""</span>,
          <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>
        }
      ],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"view"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"function"</span>
    },
    {
      <span class="hljs-attr">"inputs"</span>: [
        {
          <span class="hljs-attr">"internalType"</span>: <span class="hljs-string">"string"</span>,
          <span class="hljs-attr">"name"</span>: <span class="hljs-string">"_greeting"</span>,
          <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>
        }
      ],
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"setGreeting"</span>,
      <span class="hljs-attr">"outputs"</span>: [],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"nonpayable"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"function"</span>
    }

];

    const signer = getSigner();

    const Contract = new ethers.getContractFactory(HelloWorldAddress, ABI, signer);

    console.log(Contract);
</code></pre>
<p>Open the developer console in the browser where the <code>index.html</code> file is running, and you will see the <code>Hello World</code> contract logged in the console. Click the drop-down arrow, and you will see all the functions deployed in the contract available as JavaScript method calls.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665377086520/8dhTbe12f.png" alt="Screenshot 2022-09-19 at 23.39.55.png" /></p>
<ol>
<li>Implement functions to Write and Read the Smart Contract. There are three functions in the Smart Contract: <code>getGreeting</code>, <code>owner</code> and <code>setGreeting</code>. We will create a function called <code>doGreeting</code> and inside it, we will write instructions for <code>setGreeting</code> and return the response in the console, then, we will write functions to set the <code>owner</code> and another to return <code>getGreeting</code>.</li>
</ol>
<pre><code class="lang-json">function doGreeting() {
const setGreeting = document.getElementById(“setGreeting”)
const greeting = document.getElementById(“greeting”)

setGreeting.addEventListener(“submit”, e =&gt; {
    e.preventDefault;

    const greeting = e.target.element[0].value
    Contract.setGreeting(greeting); <span class="hljs-comment">//This will write the argument to the contract.</span>
    console.log(greeting); 
})

}
</code></pre>
<p>The next step is to write the function to <code>getGreeting</code> and set it in the <code>&lt;span&gt;...&lt;/span&gt;</code>. Continue inside the <code>doGreeting</code> block:</p>
<p>const $getGreeting = async () =&gt; { Contract.getGreeting().then(result =&gt; { $data.innerHTML = result; }) }</p>
<p>To return the greeting as it is set via the $setData method, call the $getGreeting function in $setGreeting, after the console.log statement add:</p>
<pre><code class="lang-json">$getGreeting();
</code></pre>
<p>The last step step in the section is to trigger a DOM event to render the javascript. At the end of the file and outside the <code>doSomething</code> function, add add event listener:</p>
<p>addEventListener(“DOMContentLoaded”, doSomething());</p>
<p>This means that when the DOM is completely loaded, carry out the JavaScript actions. The entire <code>idex.js</code> file now looks like this:</p>
<pre><code class="lang-json">const HelloWorldAddress = `<span class="hljs-number">0</span>x…..`;
    const ABI = [
 {
      <span class="hljs-attr">"inputs"</span>: [],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"nonpayable"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"constructor"</span>
    },
    {
      <span class="hljs-attr">"inputs"</span>: [],
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"getGreeting"</span>,
      <span class="hljs-attr">"outputs"</span>: [
        {
          <span class="hljs-attr">"internalType"</span>: <span class="hljs-string">"string"</span>,
          <span class="hljs-attr">"name"</span>: <span class="hljs-string">""</span>,
          <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>
        }
      ],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"view"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"function"</span>
    },
    {
      <span class="hljs-attr">"inputs"</span>: [],
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"owner"</span>,
      <span class="hljs-attr">"outputs"</span>: [
        {
          <span class="hljs-attr">"internalType"</span>: <span class="hljs-string">"address"</span>,
          <span class="hljs-attr">"name"</span>: <span class="hljs-string">""</span>,
          <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>
        }
      ],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"view"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"function"</span>
    },
    {
      <span class="hljs-attr">"inputs"</span>: [
        {
          <span class="hljs-attr">"internalType"</span>: <span class="hljs-string">"string"</span>,
          <span class="hljs-attr">"name"</span>: <span class="hljs-string">"_greeting"</span>,
          <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>
        }
      ],
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"setGreeting"</span>,
      <span class="hljs-attr">"outputs"</span>: [],
      <span class="hljs-attr">"stateMutability"</span>: <span class="hljs-string">"nonpayable"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"function"</span>
    }

];

const signer = getSigner();
const Contract = new ethers.getContractFactory(HelloWorldAddress, ABI, signer);
console.log(Contract);


function doGreeting() {
const setGreeting = document.getElementById(“setGreeting”)
const greeting = document.getElementById(“greeting”)

setGreeting.addEventListener(“submit”, e =&gt; {
    e.preventDefault;
      const greeting = e.target.element[0].value
      Contract.setGreeting(greeting); <span class="hljs-comment">//This will write the argument to the contract.</span>
      console.log(greeting); 
  $getGreeting();
  })
}

const $getGreeting = async () =&gt; {
   Contract.getGreeting().then(result =&gt; {
      $data.innerHTML = result;
  })
}
</code></pre>
<h2 id="heading-interact-with-the-ui">Interact with the UI</h2>
<p>You have completed a full Dapp. Written the Smart Contract and deployed it to the local Hardhat environment. Built a UI using HTML and JavaScript. You start sending content to the Contract and have it returned. As a challenge, write the function to return the owner address to the UI.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This guide is a learning curve to help you understand the basics of interacting with functions in solidity from any UI, by using the Ethers JS library to abstract the JSON-RPC calls. It serves as a background to understanding how you can build a UI for any contract deployed to any EVM-compatible chain.</p>
]]></content:encoded></item><item><title><![CDATA[A Guide on compiling and deploying your first Smart Contract to the Goerli Testnet using Hardhat.]]></title><description><![CDATA[This guide will teach you how to use the Hardhat library to compile your Smart Contract and deploy it to a Testnet. This guide assumes that you have read my guide on: Welcome to Solidity, and as a result, we will not go over the primary definitions o...]]></description><link>https://emmaodia.hashnode.dev/a-guide-on-compiling-and-deploying-your-first-smart-contract-to-the-goerli-testnet-using-hardhat</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/a-guide-on-compiling-and-deploying-your-first-smart-contract-to-the-goerli-testnet-using-hardhat</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Goerli]]></category><category><![CDATA[hardhat]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Tue, 04 Oct 2022 18:01:50 GMT</pubDate><content:encoded><![CDATA[<p>This guide will teach you how to use the Hardhat library to compile your Smart Contract and deploy it to a Testnet. This guide assumes that you have read my guide on: <a href="https://emmaodia.hashnode.dev/welcome-to-solidity">Welcome to Solidity</a>, and as a result, we will not go over the primary definitions of Smart Contracts, we will jump right into a simple <code>Hello, World</code> contract code, which we deployed in Remix, in the Welcome to Solidity guide, and then we will set up the project on our local machine deploy to the local Hardhat blockchain before we deploy it to the testnet (Goerli), where you can then interact with the Smart Contract using the Goerli etherscan explorer.</p>
<p>As a practice, I find it convenient to write the Smart Contract in Remix and test it exhaustively using the Remix compile and deploy tools to ensure no errors in the Contract. Here is the code:</p>
<pre><code>  <span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span>

pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.9</span>;

contract HelloWorld {

  address public owner;
  string greeting;

  <span class="hljs-keyword">constructor</span>(){
    owner = msg.sender;
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setGreeting</span>(<span class="hljs-params">string memory _greeting</span>) <span class="hljs-title">public</span> </span>{
     greeting = _greeting;
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getGreeting</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">string memory</span>) </span>{
    <span class="hljs-keyword">return</span> greeting;
  }

}
</code></pre><p>You can test in Remix and interact with it. Next, we will use Hardhat to build it on a local machine. Follow the instructions:</p>
<p>Choose a dir name for your project and create one</p>
<pre><code>mkdir hello_world &amp;&amp; cd hello_world
</code></pre><p>Initialize a project using npm default init command:</p>
<pre><code>npm init -y
</code></pre><p>Hardhat is a Library and will have to be installed as a project dependency:</p>
<pre><code>npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
</code></pre><p><code>@nomicfoundation/hardhat-toolbox</code>is a hardhat plugin that has everything you need for developing smart contracts.</p>
<p>Set up hardhat in the project by running the command:</p>
<pre><code>npx hardhat
</code></pre><p>Select the option: “Create a Javascript project”, follow the instructions and answer the prompts.</p>
<p>Open the ‘hello_world’ project in your IDE of choice. The directory will look something like the image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664905482562/VcjCz7xsJ.png" alt="Screenshot 2022-10-04 at 18.21.05.png" /></p>
<p>Open the Contracts dir. Delete the <strong>Lock.sol</strong> contract  and create a new file: <code>HelloWorld.sol</code>, where <code>.sol</code> is an extension denoting that it is a solidity file. This is where our Smart Contract code will be written. Copy the <code>HelloWorld</code> code from Remix and paste into the file.</p>
<p>This article assumes that you have a basic understanding of how Solidity works. If you want a line-by-line breakdown of this code, you can read my guide: “Welcome to Solidity!”</p>
<p>The next step is to compile the Contract. This process will generate the Contract ByteCode that gets deployed to a chain and the Contract ABI, which we will need to interact with the Contract via a UI. In the terminal, run:</p>
<pre><code>npx hardhat compile
</code></pre><p>You will see a message in the terminal:</p>
<pre><code>Compiling <span class="hljs-number">1</span> file <span class="hljs-keyword">with</span> <span class="hljs-number">0.8</span><span class="hljs-number">.17</span>
Compiled <span class="hljs-number">1</span> Solidity file successfully
</code></pre><p>After the compilation has completed, hardhat will create two folders in the project directory: <code>artifacts</code> and <code>cache</code>. Open the <code>artifacts</code> dir and go to <code>contracts/HellowWorld.sol</code> and open the file: <code>HelloWorld.json</code>. Here you will find the <code>abi</code> in an array. The last step of this session will be to deploy the Smart Contract to a local hardhat node.</p>
<p>Building Smart Contracts with Hardhat requires writing a script that is needed to indicate the network to deploy the Smart Contract. We will write a script to deploy the Smart Contract to a local node. Open the scripts folder in the directory and create a new file <code>deploy_helloWorld.js</code>, add the following code to the file:</p>
<pre><code><span class="hljs-keyword">const</span> hre = <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> Contract = <span class="hljs-keyword">await</span> hre.ethers.getContractFactory(<span class="hljs-string">"HelloWorld"</span>);
  <span class="hljs-keyword">const</span> contract = <span class="hljs-keyword">await</span> Contract.deploy();

  <span class="hljs-keyword">await</span> contract.deployed();

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Contract deployed to <span class="hljs-subst">${contract.address}</span>`</span>);
}

main().catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.error(error);
  process.exitCode = <span class="hljs-number">1</span>;
});
</code></pre><p>This script is an async function. First we imported the <code>hre</code> method from Hardhat. <code>hre</code> contains the sub methods that will enable us get access to a deployed instance of the code which we can connect with. </p>
<p><code>ethers.getContractFactory</code> locates the contract <code>HelloWorld</code> in the contracts directory and assigns it to the <code>Contract</code> variable, which is then deployed by calling <code>Contract.deploy()</code> the result is assigned to the <code>contract</code> variable. An instance of the deployed <code>contract</code> is now available to be interacted with.</p>
<p>The last step of this session will be to deploy the Smart Contract to a local hardhat node. We first run the hardhat blockchain on our machine to deploy to a local hardhat node. This creates a local network and a set of private keys that can be used to deploy the contract to the local chain. </p>
<p>Open a separate terminal and run the command:</p>
<pre><code>npx hardhat node
</code></pre><p>This will run a local hardhat node. </p>
<p>To deploy to the hardhat node, run the command:</p>
<pre><code>npx hardhat run --network localhost scripts/deploy_helloWorld.js
</code></pre><p>You will see a message in the terminal:</p>
<pre><code>Contract deployed to <span class="hljs-number">0</span>x….
</code></pre><p>In the terminal where the Hardhat node is running, you will see an instance of the contract deployed.</p>
<p>The Contract has been deployed successfully! The next step is to deploy the Contract to the Goerli Testnet.</p>
<p>The command for deploying the Contract to the Goerli testnet is similar to the command for deploying the contract to a local hardhat node. </p>
<p>There is an extra requirement to get an API Key from a node infrastructure service such as <a href="https://www.alchemy.com/">Alchemy</a>. Alchemy provides a suite of infrastructure tools making it easy for developers to interact with various blockchain networks. </p>
<p>Sign up for an API key on Alchemy.</p>
<p>Click on <strong>Apps &gt;&gt;&gt; Create an App</strong></p>
<p>Fill in the input fields. Select <strong>Ethereum &gt;&gt; Goerli</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664905445649/_vSITOt2k.png" alt="Screenshot 2022-10-04 at 11.42.09.png" /></p>
<p>On the newly created App dashboard, click on <strong>VIEW KEY</strong> and copy the <strong>HTTPS</strong> field. The key is the last string in the HTTPS url field.</p>
<p>In the Dapp, we will update the <code>hardhat.config.js</code> file. This file has a <code>networks</code> section where you can specify the various networks that you want to deploy your Smart Contract. During the course of deploying to the Goerli network, we will also need a private ethereum key, this can easily be obtained from your metamask wallet. This is a requirement because, you can only create contracts from a EOA. </p>
<p>To deploy the contract from the EOA you have selected, you will need some test ether. Get some test ether from the <a href="https://goerlifaucet.com/">Alchemy Goerli faucet</a></p>
<p>It is recommended to mask the API keys especially if you are going to be pushing your code to a cloud repository. You can use the <code>dotenv</code> library to achieve this. To add the <code>dotenv</code> library to the code, open the terminal and install the dotenv library: </p>
<pre><code>npm install --save-dev dotenv
</code></pre><p>In the root of the project directory, create a file <code>.env</code> This is where the Alchemy Key and the EOA Private Key will be saved. Update the file:</p>
<pre><code>ALCHEMY_KEY=”your-alchemy-api-key”
PRIVATE_KEY=”your-metamask-private-key”
</code></pre><p>The next step is to update the <code>hardhat.config.js</code> file.
Import and set up the dotenv configuration.</p>
<pre><code><span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();
</code></pre><p>Import the KEYS using <code>process.env</code> from <code>dotenv</code> and assign them to variables.</p>
<pre><code><span class="hljs-keyword">const</span> PRIVATE_KEY = process.env.PRIVATE_KEY;
<span class="hljs-keyword">const</span> ALCHEMY_KEY = process.env.ALCHEMY_KEY;
</code></pre><p>In the networks modules, add the configuration for deploying to Goerli:</p>
<pre><code>goerli: {
      <span class="hljs-attr">url</span>: <span class="hljs-string">`https://eth-goerli.g.alchemy.com/v2/<span class="hljs-subst">${ALCHEMY_KEY}</span>`</span>,
      <span class="hljs-attr">accounts</span>: [PRIVATE_KEY],
    },
</code></pre><p>The configuration is ready and the Smart Contract can be deployed to the Goerli network using the command:</p>
<pre><code>npx hardhat run --network goerli scripts/deploy_helloWorld.js
</code></pre><p>Your Smart Contract is successfully deployed to Goerli Testnet!</p>
<p><a href="https://github.com/emmaodia/tutorials-code/tree/main/solidity_hello_world">Here’s a link to the complete code</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Welcome to Solidity!]]></title><description><![CDATA[Hi there! Welcome to this guide! First, congratulations on taking the step that led you to this resource. It means that you are ready to take the next set of actions that will give you an insight into building on the Blockchain and just enough knowle...]]></description><link>https://emmaodia.hashnode.dev/welcome-to-solidity</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/welcome-to-solidity</guid><category><![CDATA[Solidity]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Fri, 09 Sep 2022 07:20:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/L2QB-rG5NM0/upload/v1662707633136/N73SPL89r.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi there! Welcome to this guide! First, congratulations on taking the step that led you to this resource. It means that you are ready to take the next set of actions that will give you an insight into building on the Blockchain and just enough knowledge to get you started with writing code on the Blockchain!</p>
<p>In this guide, we will cover a few concepts in which you may already have some background knowledge.</p>
<p>Contents: </p>
<ol>
<li>What is a Blockchain?</li>
<li>How is web2 different from web3?</li>
<li>Why web3, and what are its use cases?</li>
<li>Programming in web3</li>
<li>Solidity - Syntax Overview</li>
<li>"Hello, World!" in Solidity.</li>
</ol>
<h2 id="heading-what-is-a-blockchain">What is a Blockchain?</h2>
<p>An insightful way to explain Blockchains is to first reiterate how the centralized internet works. The centralized internet is organized so that companies that own platforms can open their services to users and, in return, store the data of such users on their servers (databases). A typical example is Social Media companies that give users access to their platform and allow users "own space" on their servers to store their information using associated tables in a database from which they can easily retrieve the data.</p>
<p>A Blockchain is a decentralized distributed ledger technology where user information is not stored in centralized databases. The Blockchain is designed so that many actors can come together to participate in a decentralized network. The Blockchain is a collection of computers called nodes, with each computer running a piece of software that is not a copy of the same software running on other computers in the network. Instead, it is the actual replica (not a clone) of the software across the network. In this network, the Data on a computer in the network 'compA' is the same Data on 'compB'.</p>
<p>In a Blockchain network, the user data is stored using hashes and recorded on the distributed ledger. The user can interact with the Blockchain from one computer in the node, and the node will broadcast the information that the user wants to save on the Blockchain, and then all computers will take note of the Data that the user just saved on the network and keep a record of it on the ledger.</p>
<p>Various blockchains exist, with famous examples being Bitcoin and Ethereum. In this article, we will focus on the Ethereum blockchain.
The Blockchain ledger is arranged, so that information saved on the Blockchain is chained sequentially. The point where a user saves Data on the Blockchain and other computers in the network and then records it is called a Block. Each Block is identified by a unique hash and assigned a Block number. Now, pay attention to the following illustration.</p>
<p>When a user saves data containing their name, e.g. "name=john doe", to the Blockchain at a point when the block number was 10001, the user can not edit the data. The Data is chained to the following block number: 10002 and so on, where n+1. Blockchain is commonly referred to as web3 due to several improvements it has over the traditional internet relayed over HTTPS, and this is one of the critical areas where web2 is different from web3.</p>
<h2 id="heading-how-is-web2-different-from-web3">How is web2 different from web3?</h2>
<p>Before explaining how web2 differs from web3, it is essential to mention that web3 is not a new kind of internet. Although it uses its own set of protocols for interaction, the web3 can be accessed via web browsers over HTTPS. The difference between web2 and web3 is primary in the structural and interactional make-up.</p>
<p>One component in the interactional make-up of Blockchains is the use of Addresses. Given that the Blockchain is a Ledger, user interactions with Data on chain happen via the use of Addresses. Address is of 2 types: Wallet address (also called External Owned Address EOA) and Contract Addresses (Smart Contract code deployed on the Blockchain). A user is also identified by their EOA on chain.</p>
<p>The table below uses a comparison method to outline the differences between web2 and web3.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Web2</td><td>Web3</td></tr>
</thead>
<tbody>
<tr>
<td>Users must join a platform that sometimes requires them to create an account.</td><td>A user can interact with any platform using their wallet address.</td></tr>
<tr>
<td></td><td>The data that a user post on the Blockchain is owned by the user.</td></tr>
<tr>
<td>A user can be kicked out of a platform.</td><td>The user cannot be kicked out of using any platform on the Blockchain</td></tr>
<tr>
<td>Stored Data can be edited and deleted.</td><td>Stored Data cannot be edited nor deleted.</td></tr>
<tr>
<td>It can be closed and it is mostly private to platform users only.</td><td>It is open and public.</td></tr>
<tr>
<td>Data is not transparent.</td><td>Data is transparent.</td></tr>
<tr>
<td>Sometimes relies on the use of intermediaries.</td><td>Does not need any intermediaries.</td></tr>
<tr>
<td>Data is stored on a central server.</td><td>Data is stored on a decentralized server.</td></tr>
</tbody>
</table>
</div><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662706271492/-V0IyZq3p.png" alt="Web2.png" />
Web2</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662706293241/ZRVT8oTp5.png" alt="Web3.png" />
Web3</p>
<h2 id="heading-why-web3-and-what-are-its-use-cases">Why web3, and what are its use cases?</h2>
<p>Given the listed differences between web2 and web3, one can identify many use cases in that web3 is most suited to guarantee implementations that will serve a real-world need. Such examples include Identity verification, Finance, Insurance and Ownership, to mention a few.</p>
<p>An identity use case involves a user entering their record on the Blockchain at a particular block number. Given that information stored on a chain cannot be edited, user identity can be verifiable in such an instance.</p>
<p>To build applications that can meet such use on Blockchain involves writing code that can save data on Blockchains.</p>
<h2 id="heading-programming-in-web3">Programming in web3.</h2>
<p>Programming in web3 involves writing computer logic and pushing it on blockchains. The code cannot be edited when this piece of computer code lives on the Blockchain. The code is written as a business logic where all interactions with it respond with programmed outcomes. This code that executes the business instruction is called a Smart Contract. </p>
<p>In this article, you will write and deploy your first Smart Contract. You must understand the environment where Smart Contracts run and the language in which to write the code.</p>
<p>In Ethereum, the network, as we described earlier, has a piece of software (Operating System, if you like) called the Ethereum Virtual Machine (EVM) running in each computer (node) in the network. The EVM can only read Bytecode. The Solidity Programming Langauge is available to developers to program Smart Contracts, which are then compiled to Bytecode and deployed to the Blockchain.</p>
<p>Smart Contract code can be written in Solidity, Vyper and the newly released Huff programming language. Solidity is easy to learn. We are going to write our first program in Solidity. In this example, we will write and deploy the code in Remix. Remix is an interactive online tool that makes it easy to write, deploy, and interact with Smart Contract.</p>
<h2 id="heading-solidity-syntax">Solidity Syntax</h2>
<p>Solidity is a statically typed programming language much like C++; this means that every data type in Solidity must be declared as it is initialized.</p>
<h3 id="heading-hello-world-in-solidity">"Hello, World!" in Solidity.</h3>
<p>For our first Smart Contract, kindly go to remix and paste the following code.</p>
<pre><code><span class="hljs-comment">//SPDX-Licenses-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.16;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">HelloWorld</span> </span>{
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">public</span> owner;
    <span class="hljs-keyword">string</span> greeting;

     <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>)</span>{
        owner <span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>;
     }

     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setGreeting</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        greeting <span class="hljs-operator">=</span> <span class="hljs-string">"Hello, World!"</span>;
     }

     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getGreeting</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span></span>) </span>{
        <span class="hljs-keyword">return</span> greeting;
     }
}
</code></pre><p>This Smart Contract is written in Solidity. For developers familiar with JavaScript, you will see a similarity in the function statements. This Smart Contract implements a function that writes "Hello, World!" to the Blockchain and another that returns it. We will walk through the code and explain each line.</p>
<pre><code><span class="hljs-comment">//SPDX-Licenses-Identifier: MIT</span>
</code></pre><p>The Solidity Compiler encourages using machine readable SPDX license identifiers to ensure trust in Smart Contracts. This line indicates the type of licenses with which this Smart Contract is published.</p>
<pre><code><span class="hljs-attribute">pragma</span> solidity ^<span class="hljs-number">0</span>.<span class="hljs-number">8</span>.<span class="hljs-number">16</span>;
</code></pre><p>The pragma statement indicates the version of Solidity that the Smart Contract should be compiled in.</p>
<pre><code><span class="hljs-selector-tag">Contract</span> <span class="hljs-selector-tag">HelloWorld</span> {
}
</code></pre><p>The Smart Contract Logic is entirely written in curly braces initialized with the <code>Contract</code> keyword followed by the name of the particular Smart COntract, in this instance: <strong>HelloWorld</strong></p>
<pre><code>address <span class="hljs-built_in">public</span> <span class="hljs-keyword">owner</span>;
</code></pre><p>Variables in Solidity are statically typed. This line is a declaration of a variable named <code>owner</code>. It is of a data type <code>address</code> and set to a visibility type of <code>public</code>. Solidity functions can be specified in 4 different visibility forms: Public, External, Internal and Private. A function set as public means that anyone interacting with the Contract can call the particular function.</p>
<pre><code><span class="hljs-keyword">string</span> greeting;
</code></pre><p>This declaration of a <code>greeting</code> variable of data type <code>string</code>. It will be used to initialize the greeting in the <code>setGreeting</code> function.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>)</span>{
  owner <span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>;
}
</code></pre><p>When a Smart Contract is deployed on a Blockchain, the constructor keyword is used to initialize variables that are used in the implementation. The constructor is only run when the code is first deployed. The constructor in this example is initializing the <code>owner</code> variable and assigning it a particular value, <code>msg.sender</code>
<code>msg.sender</code> where <code>msg</code> is an abbreviation for <code>message</code>. This keyword denotes the wallet address that pushed the Contract onto the Blockchain.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setGreeting</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
  greeting <span class="hljs-operator">=</span> <span class="hljs-string">"Hello, World!"</span>;
}
</code></pre><p>This is the function statement where we set the "Hello, World" greeting. When the Contract is first deployed, it will be set at a Block number on chain.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getGreeting</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span>(<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span></span>) </span>{
  <span class="hljs-keyword">return</span> greeting;
}
</code></pre><p>This is the call to return the greeting saved on chain. There are new unique keywords here, <code>view</code> and <code>returns</code>. The <code>view</code> keyword indicates functions that return data and do not make further changes to the Blockchain. The <code>returns</code> keyword indicates the data type being returned in the function call, indicating the location it is stored, which in this case is <code>memory</code>.</p>
<p>To understand how this Smart Contract will work on an actual blockchain, we will simulate its interaction by compiling it and deploying it in Remix.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662707269050/TzEg4ObHU.png" alt="Web3-DnR.png" /></p>
<p>To compile the Contract, kindly click on the <strong>Solidity Compiler</strong> tab and select the compiler version from the dropdown. Click on the <strong>Compile HelloWorld</strong> button. You should see the <em>green tick</em> appear on the tab upon a successful compilation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662707328405/VfVnG7VcQ.png" alt="Web3-SCompiler.png" /></p>
<p>The Contract is compiled into Bytecode. You can click on the Bytecode icon to copy the Bytecode and paste it into a notepad file to view opcodes.</p>
<p>After the successful compilation, the next step is to deploy the Smart Contract. Click on the <strong>Deploy and Run Transactions</strong> tab. Understanding the various UI components before clicking the <strong>deploy</strong> button is essential.</p>
<p><strong>ENVIRONMENT:</strong> This is the Blockchain where the Smart Contract code will be deployed. It is default set to a "<a target="_blank" href="https://ethereum.org/en/history/#london">London Fork</a>" Remix Virtual Machine.</p>
<p><strong>ACCOUNT:</strong> These are a set of 10 Wallet Addresses. The addresses hold test Ether. You can use any of the addresses when interacting with the Smart Contract.</p>
<p><strong>GAS LIMIT:</strong> Gas is the unit of measure to ascertain the amount of computation your interaction with the Blockchain will cost. The default limit is set as 3 Million units.</p>
<p><strong>VALUE:</strong> This field is used when you want to pass units of ether to spend when interacting with a Smart Contract.</p>
<p>Ensure that the HelloWorld Contract is highlighted in the CONTRACT dropdown. Click <strong>Deploy</strong> This will deploy your Smart Contract. You can view your deployed Contract in the <strong>Deployed Contracts</strong> section. Click on <code>HelloWorld</code>. This will open a dropdown where you can see all the functions written in your Smart Contract getGreeting,<code>setGreeting</code>, including the <code>Owner</code> variable.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662707388044/ub4X54-xp.png" alt="Web3-Functions.png" /></p>
<p><em>NOTE:</em> When a variable is initialized, and its accessibility is set to <code>public</code>, that variable can be returned as a view function on chain.</p>
<p>Click the various function buttons to interact with the Contract on chain. Begin with checking the <code>owner</code> and then the <code>getGreeting</code>. The owner will return the address highlighted in the ACCOUNT section when the Smart Contract was deployed. That is the address that owns the Smart Contract.</p>
<p>The <code>getGreeting will return</code>0<code>. This is because we have not</code>setGreeting<code>on the Blockchain; we have only deployed the Contract! Now, go ahead and click</code>setGreeting<code>. This will store "Hello, World!" on the Blockchain. Click on</code>getGreeting`, and it will return the text: "Hello, World!"</p>
<p>You have successfully deployed your first Smart Contract written in Solidity on the Blockchain. This piece of logic is a hello world program, and it can not be changed! Well, you can adjust the <code>setGreeting</code> function and parse in an argument such that you can return any greeting as you please.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setGreeting</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> _greeting</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
  <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> s <span class="hljs-operator">=</span> <span class="hljs-string">"Hello "</span>;
  greeting <span class="hljs-operator">=</span> <span class="hljs-keyword">string</span>.concat(s, _greeting);
}
</code></pre><p>This is an update to the <code>setGreeting</code> function. This update has the <code>concat</code> keyword, used to concatenate strings. This was introduced in solidity version 0.8.12
The string <code>s</code> is held in memory before it is pushed on chain.</p>
<h2 id="heading-conclusion">Conclusion.</h2>
<p>This is your: "Welcome to Solidity" tutorial. This article has laid out for you a baseline that you can use to get a feel for what to expect when you start writing more Solidity code. 
Here are recommended references that will significantly aid your quest to learn Solidity.</p>
<h2 id="heading-resources">Resources.</h2>
<p>Ethereum.org
<a target="_blank" href="https://docs.soliditylang.org/en/latest/">Solidity Docs</a>.</p>
]]></content:encoded></item><item><title><![CDATA[How to Create Upgradeable Solidity Smart Contracts]]></title><description><![CDATA[Why Upgrade Smart Contracts?
Smart Contracts are meant to be immutable! After all, that is a principal pillar on which decentralization rests. Why then do we have to need to create new versions of Smart Contracts (read upgrade)? Well, same reason why...]]></description><link>https://emmaodia.hashnode.dev/how-to-create-upgradeable-solidity-smart-contracts</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/how-to-create-upgradeable-solidity-smart-contracts</guid><category><![CDATA[Proxy Pattern]]></category><category><![CDATA[upgradable smart contracts]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[UUPS]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Wed, 08 Jun 2022 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694171645696/91cd3bc9-2b0e-45bd-ad72-80d5af607b15.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-why-upgrade-smart-contracts">Why Upgrade Smart Contracts?</h1>
<p>Smart Contracts are meant to be immutable! After all, that is a principal pillar on which decentralization rests. Why then do we have to need to create new versions of Smart Contracts (read upgrade)? Well, same reason why the V2 of software is better than V1. Duh! That was obvious, no?</p>
<p>OK! Granted. Why then do you not write another Smart Contract code and then redirect the users to a new version via the DApps frontend? Hmmm, fair point, until you have to take into account such things as:</p>
<ol>
<li><p>Tracking state changes.</p>
</li>
<li><p>Developers interacting with the Smart Contract code.</p>
</li>
<li><p>Maintenance…</p>
</li>
</ol>
<p>Just to mention a few reasons why upgrading Smart Contracts is necessary.</p>
<p>Now that the reason has been established, how then can a developer upgrade their Smart Contracts, knowing fully well that a Smart Contract once deployed to a Contract address cannot be deleted?</p>
<p>This is where we get into the Technical deets of upgrading Smart Contracts. We will rely on the Open Zeppelin Proxy patterns to understand the concept. It is important to note that upgrading Smart Contracts does not just mean adding code to an already existing Contract. In the example we are going to use for demonstration, we will write a Proxy Smart Contract that will point to the V2 of the contract V1. Where V2 is an updated version of V2 with all the functions still in use and more added, or some functions removed or an algorithm rewrite. The Proxy ensures that the same address is what points to V1, V2,... Vn of the said Smart Contract. This way, the user sends a txn to the Proxy Contract, which then interacts with whatever version it is pointed to. Yes, each version and the proxy are immutable!</p>
<p><img src="https://lh3.googleusercontent.com/Ow9DhgxuXaJQoD0sG7Lsj997bbya8i93H39LVLPvkUeIZx6sNazPnRjNk9iwgt8mEZfP4DpRK1x5I8T6FxJsQe5ubLgPy9KyLGhz-Ct7aUIhHwHHR3oE1QGiUA9OHPuBE3xR62l6OmDbhHgkCCsDbQ" alt /></p>
<blockquote>
<p>Open Zeppelin has a great resource on explaining Proxy Contracts: <a target="_blank" href="https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies">https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies</a> You can learn about the various methods for upgrading Smart Contracts by reading the article.</p>
</blockquote>
<h1 id="heading-introduction">Introduction</h1>
<p>In this article, I’m going to demonstrate to you the Transparent Proxy pattern. To do this, we will build a simple Contract that we will likely upgrade to new versions in the future. The Contract sets the price for a train ticket. Given that there are no rising Economic costs, the tickets cost the same wherever the destination, so there is room for increasing the Ticket Price if ever there is a need. To do this, we will follow the steps:</p>
<ul>
<li><p>Write the code for v1 of the Train Ticket Smart Contract using Hardhat and deploy it to the Goerli Testnet.</p>
</li>
<li><p>We will use an Open Zeppelin library called the hardhat upgrades in the deployment scripts. The Hardhat upgrades contain a method called <code>deployProxy</code>. This method ensures that when the contract is deployed, it creates a Proxy Contract as well.</p>
</li>
<li><p>We will then write V2 of the Contract and then using hardhat upgrades, we will call the method <code>upgradeProxy</code> and point the deployed Contract to the proxy contract!</p>
</li>
</ul>
<p>The <code>upgradeProxy</code> method takes 2 args and any other args passed to the Contract call:</p>
<p><code>upgradeProxy(PROXY, Contract, [any args passed to the Contract])</code></p>
<h1 id="heading-smart-contract-v1">Smart Contract v1</h1>
<p>I have a standard practice of writing Smart Contracts in Remix and then initializing a Hardhat Project on my machine. Thus, we will write the <strong>TrainTicketV1</strong> using Remix.</p>
<p>Here is <strong>TrainTicketV1.sol</strong></p>
<pre><code class="lang-solidity"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.14;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">TrainTicketV1</span> </span>{
    <span class="hljs-keyword">uint</span> amount;
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">public</span> owner;

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setOwner</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        owner <span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setTicketPrice</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        <span class="hljs-built_in">require</span>(owner <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-string">"Only the owner can set price"</span>);
        amount <span class="hljs-operator">=</span> <span class="hljs-number">10000000000</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTicketPrice</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>)</span>{
        <span class="hljs-keyword">return</span> amount;
    }

}
</code></pre>
<p><strong><mark>Please note that this is for illustration purposes only and should not be deployed to production, especially given the reason that you do not want to give anyone the power to set the contract address and change ticket prices!</mark></strong></p>
<p>OK! I have confirmed that the Smart Contract code works and now we are going to set up a Hardhat Project and deploy the code to the Goerli Testnet using Hardhat deploy script and Open Zeppelin Hardhat deploy.</p>
<p>This article assumes that you understand how to set up a Hardhat project, if you do not, kindly follow the Hardhat guides for creating a new hardhat project: <a target="_blank" href="https://hardhat.org/tutorial/creating-a-new-hardhat-project.html">https://hardhat.org/tutorial/creating-a-new-hardhat-project.html</a></p>
<p>If you used the guide above, then, Hardhat generated a <code>Greeter.sol</code> file in the Contracts dir. Delete the content and replace it with the TrainTicketV1 code above. If you are familiar with writing Solidity, you could be surprised that the contract is not initiated with a Constructor argument. This was a gotcha moment for me too as I got to learn that Smart Contracts that are designed to be upgraded via the Transparent Proxy pattern are not initiated with a Constructor!</p>
<p>We are going to deploy the Contracts to the Goerli Testnet. You can use any EOA via Metamask or Ganache UI. What you will need are the Private Keys and some ETH from the Goerli Faucet here: <a target="_blank" href="https://goerlifaucet.com/">https://goerlifaucet.com/</a> <em>N.B: You will need to have an Alchemy account to receive tokens from this faucet.</em> This is fine anyway, as we will rely on Alchemy as a provider to deploy the Smart Contracts to Goerli.</p>
<ul>
<li><p>Wallet Private Key (from Metamask preferably) ready, check…</p>
</li>
<li><p>Received Tokens from the Faucet, check…</p>
</li>
</ul>
<p>Sign in to Alchemy, create a Project and get the API KEY for the Project.</p>
<h2 id="heading-deploy-smart-contract-v1">Deploy Smart Contract v1</h2>
<p>This is where we get to the section where we will use the Open Zeppelin library to deploy our Smart Contract.</p>
<p>We will add this dependency to the package.json file: <a target="_blank" href="https://www.npmjs.com/package/@openzeppelin/hardhat-upgrades">https://www.npmjs.com/package/@openzeppelin/hardhat-upgrades</a></p>
<p>According to the documentation: “You can use this plugin in a Hardhat script to deploy an upgradeable instance of one of your contracts via the deployProxy function.” This is just as I had explained earlier!</p>
<p>Seeing as we are installing dependencies, kindly throw in installing the dotenv library. Shsss… It is for secrets!</p>
<p>After the installation has been completed (which I’m certain you know how to do, or if you have forgotten, it is</p>
<p><code>npm install --save-dev @openzeppelin/hardhat-upgrades dotenv</code></p>
<p>Now we are ready to write a script to deploy our Smart Contract to the Goerli Testnet.</p>
<ul>
<li>Alchemy API… Check!</li>
</ul>
<p>To deploy to an actual network using Hardhat, we have to add a Network configuration to the <code>hardhat.config.js</code> file.</p>
<p>Deleted the <code>tasks</code> block of code, delete the hardhat-waffle dependency that came default with the file, add the required dependencies and update the module.exports config:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">require</span>(<span class="hljs-string">"@nomiclabs/hardhat-ethers"</span>);
<span class="hljs-built_in">require</span>(<span class="hljs-string">"@openzeppelin/hardhat-upgrades"</span>);
<span class="hljs-built_in">require</span>(<span class="hljs-string">'dotenv'</span>).config();

<span class="hljs-keyword">const</span> ALCHEMY_API_KEY = process.env.ALCHEMY_API_KEY;
<span class="hljs-keyword">const</span> EOA_PRIVATE_KEY = process.env.EOA_PRIVATE_KEY;

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">solidity</span>: <span class="hljs-string">"0.8.14"</span>,
  <span class="hljs-attr">networks</span>: {
    <span class="hljs-attr">goerli</span>: {
      <span class="hljs-attr">url</span>: https:<span class="hljs-comment">//eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY},</span>
      accounts: [<span class="hljs-string">`<span class="hljs-subst">${EOA_PRIVATE_KEY}</span>`</span>]
    }
  }
};
</code></pre>
<p>We will need the Alchemy API Keys and EOA Private Key hidden somewhere! As I mentioned earlier, it is a secret we will keep in a <code>.env</code> file! Remember to add the <code>.env</code> file to your <code>.gitignore</code> if you are planning to push your code using a version management tool to any cloud service.</p>
<p>The Alchemy API KEY and the EOA Private Key are rendered to the hardhat config file using <code>dotenv</code>. Dotenv uses <code>process.env</code> to read files from the <code>.env</code> file.</p>
<p>It is in the hardhat configuration that we also require the Hardhat upgrades and the hardhat ethers. Both are required for when we have to deploy the Smart Contract.</p>
<p>Now, we have the hardhat configuration ready, let’s compile the Contract to generate the artifacts and the cache dir.</p>
<p><code>$ npx hardhat compile</code></p>
<p>When the contract is successfully compiled, a success message is returned to the terminal:</p>
<p><code>Compiled 1 Solidity file successfully</code></p>
<p>Next is our deploy script! Just so you recall, we are deploying the TrainTicketV1.sol Smart Contract which as already been compiled. Open the scripts folder and delete the sample scripts file created by Hardhat. Create a new file, you can name it <code>deploy_v1.js</code>, add the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { ethers, upgrades } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> Contract = <span class="hljs-keyword">await</span> ethers.getContractFactory(<span class="hljs-string">"TrainTicketV1"</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Deploying Train Tikcet v1..."</span>);

  <span class="hljs-keyword">const</span> contract = <span class="hljs-keyword">await</span> upgrades.deployProxy(Contract)
  <span class="hljs-keyword">await</span> contract.deployed();
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Contract deployed to:"</span>, contract.address);
}

main()
  .then(<span class="hljs-function">() =&gt;</span> process.exit(<span class="hljs-number">0</span>))
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error);
    process.exit(<span class="hljs-number">1</span>);
  });
</code></pre>
<p>Let’s breakdown what happened here line by line:</p>
<p><code>const { ethers, upgrades } = require("hardhat");</code></p>
<p><code>ethers</code> is available to us as a class function on which we call the <code>getContractFactory</code> method. <code>upgrades</code> is available via the hardhat library and we call the <code>deployProxy</code> method on it. As has been explained earlier, <code>deployProxy</code> is the magic function.</p>
<p><code>await contract.deployed()</code> is to ensure we can read the deployed contract methods if we had a frontend for instance.</p>
<p>To deploy the Contract to the Goerli Testnet and experience the beauty of upgrading a contract using TransferProxy, run the following command:</p>
<p><code>npx hardhat run scripts/deploy_v1.js --network goerli</code></p>
<p>It will return the console.log message prompts we added to the deploy_v1.js file</p>
<p><code>Deploying Train Ticket v1...;</code></p>
<p>When successful</p>
<p><code>Contract deployed to:", &lt;contract.address&gt;</code></p>
<p>Open the Goerli Testnet Explorer: <a target="_blank" href="https://goerli.etherscan.io">https://goerli.etherscan.io</a></p>
<p>Do not go to the Contract Address immediately, first, look up the EOA that you used in deploying the Smart Contract and view the Txns that took place! Wait for it… You will find 3 txns and not 1! Haha! Fascinating!</p>
<p><img src="https://lh3.googleusercontent.com/gOJ_0yHV9chMoMu2cZBoZI1AyWtRs79__dTET2zOaXL13rLz2YTqPVLnrzeo8dZ4pzr9kEx35e41_gerx03bgjMVTQEJokwpcPB9-lDhNJcFevpn4GG6VqEuu4IUI4823-Yh1_Q6RcoE4VeRh2oEkw" alt /></p>
<p>Rank from top to bottom:</p>
<ol>
<li><p>This is the <code>TransparentUpgradeableProxy</code>, this holds the Contract address where all new versions of Train Ticket will be interacted with.</p>
</li>
<li><p>This is the ProxyAdmin where all Transactions between upgrades and <code>TransparentUpgradeableProxy</code> will be routed.</p>
</li>
<li><p>This is the actual version 1 of the Train Ticket Contract!</p>
</li>
</ol>
<p>To interact with the Contracts via Etherscan, we will</p>
<ul>
<li><p>Verify and Publish the Smart Contract Code</p>
</li>
<li><p>Verify the <code>TransparentUpgradeableProxy</code> and set it as a Proxy (i.e The Contract that will be interacted with.)</p>
</li>
</ul>
<p>Via Etherscan, follow the steps to verify and publish the TrainTicketV1 contract. Once verification is done, go to the Proxy Contract (i.e <code>TransparentUpgradeableProxy</code>), open the Contract Tab and click on the dropdown button: ‘<strong>more options</strong>’</p>
<p><img src="https://lh5.googleusercontent.com/OMIYRTJQyPIMcZ2jtlG3-GoEgYmqkBJsL2pWYN3nxPeJkJHmMXSMvN0xW-XHp5HAGACZqA1JCbG-0Nm-7bcEMvinTQdvMXCROnH9wttKwGwKOVxqQpPenfyhfZq8kei0Q6Ejdxcv9cfGQtELnBH7RA" alt /></p>
<p>Click on: ’<strong>Is this a Proxy?</strong>’</p>
<p>On the next screen, click on: ‘<strong>Verify</strong>’</p>
<p><img src="https://lh5.googleusercontent.com/zvdjFiCB3v1xJdb9HmEjShpHngMxKb9SDLBIBz4cM2s57UqZA5zfK5hT0JBJwmALQwEkE1tsZjW3BjJAJG1TBrtOXBax9Jy6dT77SjXzcQO2GjaR1MsOnWF_ktZzbl5gI2UBRkIWzbLNrP_ejgo0GA" alt /></p>
<p>Click: ‘<strong>Save</strong>’</p>
<p>The Contract is now verified 🎉 and you have the ‘Read As Proxy’ and ‘Write as Proxy’ buttons!</p>
<p><img src="https://lh5.googleusercontent.com/cutW1OyHc8o_RmA6WhJzO28MXnjddSkkCdVM1LS8PU0XAun5hcvQ_QcPt-pkCCCwYR0YxoIv9zK9hGdFMudxlWVrLaI9OIidbOJfklqaER6avCcmseMP357rSBRjZuuBfpqTQrb1FSDB3x9n3ryToQ" alt /></p>
<p>Go test it! Here is my implementation: <a target="_blank" href="https://goerli.etherscan.io/address/0x5f5a9b36780f111417db19ffbe2f04876344009e#code">https://goerli.etherscan.io/address/0x5f5a9b36780f111417db19ffbe2f04876344009e#code</a></p>
<h1 id="heading-smart-contract-v2">Smart Contract v2</h1>
<p>This is version 1 of the TrainTicket Smart Contract successfully deployed! We will deploy version 2 next. To do that, we need to</p>
<ul>
<li><p>Write <code>TrainTicketV2.sol</code></p>
</li>
<li><p>Compile the Contract.</p>
</li>
<li><p>Write <code>deploy_v2.js</code> script.</p>
</li>
<li><p>Deploy the Contract as a Proxy!</p>
</li>
</ul>
<p>Just like eating sweet cake!</p>
<p>First, <code>TrainTicketV2.sol</code></p>
<pre><code class="lang-solidity"><span class="hljs-comment">// SPDX-License-Identifier: GPL-3</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.14;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">TrainTicketV1</span> </span>{
    <span class="hljs-keyword">uint</span> amount;
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">public</span> owner;

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setOwner</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        owner <span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setTicketPrice</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        <span class="hljs-built_in">require</span>(owner <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-string">"Only the owner can set price"</span>);
        amount <span class="hljs-operator">=</span> <span class="hljs-number">10000000000</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTicketPrice</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>)</span>{
        <span class="hljs-keyword">return</span> amount;
    }
}
</code></pre>
<p>If you look closely, the only difference here is the new price set for purchasing Train Tickets! Inflation? I hope not!</p>
<p>Compile the Contract. It should compile successfully.</p>
<h2 id="heading-deploy-v2">Deploy v2</h2>
<p>Next, the deploy script! Here is where it all gets interesting, watch closely. This time, name the file <code>deploy_v2.js</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { ethers, upgrades } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</span>);

<span class="hljs-keyword">const</span> PROXY_CONTRACT = <span class="hljs-string">"0x022aA95A1fB518607eEF4093Bd82eAe4dAF97337"</span>;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> Contract = <span class="hljs-keyword">await</span> ethers.getContractFactory(<span class="hljs-string">"TrainTicketV2"</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Deploying Train Ticket v2..."</span>);

  <span class="hljs-keyword">await</span> upgrades.upgradeProxy(PROXY_CONTRACT, Contract)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Contract Upgraded"</span>);
}

main()
  .then(<span class="hljs-function">() =&gt;</span> process.exit(<span class="hljs-number">0</span>))
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error);
    process.exit(<span class="hljs-number">1</span>);
  });
</code></pre>
<p>I explained the method call <code>getContractFactory</code> on class ethers. What is different here is this:</p>
<ul>
<li><p>We set the <code>PROXY_CONTRACT</code> address so that the new version of the Train Ticket contract can point to it.</p>
</li>
<li><p>The above is achieved when we call <code>upgradeProxy</code> method on <code>upgrades</code> class.</p>
</li>
</ul>
<p>Deploy the new version!</p>
<p><code>npx hardhat run scripts/deploy_v2.js --network goerli</code></p>
<p>Once, you have successfully deployed as confirmed from the messages logged to the console, go take a look at the new transactions on the address, this time you will find 2.</p>
<p><img src="https://lh3.googleusercontent.com/IIsa6PHvQ49WkN4W2foXDzYNBal-AaF7h5nGACwGnO0sD1FwJp6VcQqaNI9g9MpnVVmrapYMspmuEVcQhVAOWJhN_WghLAWDgSsbKSaS03XEGOSWVYLR0SSNeMvTvpgAOSfS2Mmco_0YgT1mgFeWzg" alt /></p>
<p>Rank from top to bottom:</p>
<ol>
<li><p>This is the NEW ProxyAdmin where all Transactions between upgrades and <code>TransparentUpgradeableProxy</code> will be routed.</p>
</li>
<li><p>This is the actual version 2 of the Train Ticket Contract!</p>
</li>
</ol>
<p>If you already realized that the <code>TransparentUpgradeableProxy</code> from the first deployment is where you contract is pointed to, then you are a-mazing!</p>
<p>All, you have to do now is:</p>
<ul>
<li><p>Verify and Publish the TrainTicketV2 contract</p>
</li>
<li><p>Set as Proxy using the same steps as above!</p>
</li>
</ul>
<p>Once that is complete, users will be interacting with V2 of your Smart Contract! You can upgrade as much as you want up to Vn…</p>
<p>That my dear reader is how to upgrade a Smart Contract!</p>
<p>Here is my V2 implementation: <a target="_blank" href="https://goerli.etherscan.io/address/0x53bbdb042997ddbf2be8116e6c6d3c9205026ab7#code">https://goerli.etherscan.io/address/0x53bbdb042997ddbf2be8116e6c6d3c9205026ab7#code</a></p>
<p>Here is my Proxy Contract Implementation: <a target="_blank" href="https://goerli.etherscan.io/address/0x022aa95a1fb518607eef4093bd82eae4daf97337">https://goerli.etherscan.io/address/0x022aa95a1fb518607eef4093bd82eae4daf97337</a></p>
<p>Thank you for reading this far! If you found the content useful, please kindly share it with your network.</p>
<h1 id="heading-source-code">Source Code</h1>
<p>You can find the complete source code here: <a target="_blank" href="https://github.com/emmaodia/tutorials-code/tree/main/train-ticket">https://github.com/emmaodia/tutorials-code/tree/main/train-ticket</a></p>
]]></content:encoded></item><item><title><![CDATA[Build and Deploy a Smart Contract on NEAR Blockchain]]></title><description><![CDATA[In this article, we will build a decentralized donor app where anyone in any part of the world can send near tokens to victims of violence. The article is broken into the following sections:

Brief Overview of NEAR

Installing dependencies

Smart Con...]]></description><link>https://emmaodia.hashnode.dev/build-and-deploy-a-smart-contract-on-near-blockchain</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/build-and-deploy-a-smart-contract-on-near-blockchain</guid><category><![CDATA[NEAR blockchain]]></category><category><![CDATA[Smart Contracts]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Thu, 21 Apr 2022 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1698673399175/8e70bc64-1067-4f5f-afe9-0b60c139b7fb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>In this article, we will build a decentralized donor app where anyone in any part of the world can send near tokens to victims of violence. The article is broken into the following sections:</strong></p>
<ul>
<li><p><strong>Brief Overview of NEAR</strong></p>
</li>
<li><p><strong>Installing dependencies</strong></p>
</li>
<li><p><strong>Smart Contract</strong></p>
</li>
<li><p><strong>Frontend</strong></p>
</li>
<li><p><strong>Conclusion</strong></p>
</li>
</ul>
<h2 id="heading-brief-overview-of-near"><strong>Brief Overview of NEAR</strong></h2>
<p><strong>There are many blockchain networks which exist. This is great as it fully underscores the primary idea behind decentralization. One such Blockchain network is the NEAR Blockchain. NEAR is described as a Layer 1 (L1), sharded, proof-of-stake Blockchain. Let’s define the words used to describe NEAR in the context of use in this article.</strong></p>
<h3 id="heading-l1">L1</h3>
<p><strong>Layer 1 also commonly referred to as L1 is simply the base (primary) blockchain network for a particular protocol. It is easier to grasp the concept when it is compared side by side with Layer 2 (L2) blockchains which are protocols built on top of the L1 chains and sometimes also include sidechains and other offerings depending on the network. All transactions that take place on an L1 chain are finalized on the network according to the rules embedded in the network protocol. An example is a finality for transactions which on NEAR is 2 seconds. An L2 may be built to improve on this. The NEAR blockchain is still, at this time, an L1 solution.</strong></p>
<h3 id="heading-sharding">Sharding</h3>
<p><strong>Blockchain sharding refers to a blockchain network separated/broken into smaller components called shards. Transactions are then carried out on the shards. Sharding is done to help increase the number of transactions that can be carried on a blockchain and thus leading to an increase in its throughput and possibly, latency. Harmony is an example of a blockchain that relies on sharding to increase its overall performance. As a result, each shard of Harmony is treated as its own network, holding transaction state in its block changes. Each Harmony shard has its own network id. NEAR is a sharded blockchain, unlike Harmony, NEAR shards through individual networks, do not have their own network ids. This sharding implementation of NEAR is called the Simple Nightshade.</strong></p>
<h3 id="heading-proof-of-stake">Proof Of Stake</h3>
<p><strong>Blockchains as open ledgers require participants to validate all transactions which will lead to state changes. That means that all participants must reach a consensus on the data in every block. There are 2 methods for reaching consensus: Proof of Work (PoW) and Proof of State (PoS). Proof of Work consensus relies on the calculation of a mathematical algorithm using computers to validate blockchain data. This uses a lot of computing power. On the other hand, Proof of State relies on validators who have staked a bond in the blockchain network to act as data verifiers. This does not require much computation and as a result, it places a low demand on hardware. NEAR blockchain is often referred to as being carbon neutral because it uses the Proof of Stake consensus approach.</strong></p>
<hr />
<p><strong>Now that we have established a definition for the NEAR blockchain, we are going to be building a DApp and deploying it on the Blockchain. Just a quick reference guide, I’ll briefly explain why sharding as technology is important to a developer’s decision in deciding on a Blockchain to build on.</strong></p>
<p><strong>Ethereum blockchain can carry out less than 20 Transactions per second. This means that the transaction finality on Ethereum is about 1.2 minutes. This is a low throughput that is associated with other challenges such as an increase in fees for validating transactions and latency. Ethereum is also an L1 solution. The NEAR blockchain was premised on solving the low throughput and latency problems for Ethereum. From the onset, the developer of the NEAR chain decided to rely on sharding to ensure that NEAR would be able to do a minimum of 2500-3000 Transactions per second, with a finality of 1.2 seconds. This is a whole lot faster than Ethereum L1. This should be given thought to developers who wish to build on an L1.</strong></p>
<hr />
<p><strong>In this article, we will build a NEAR Dapp for making donations to a charity for victims of violence. The donations will include notes from the donors.</strong>  </p>
<p><strong>We can build Blockchains on NEAR using Rust programming language or Assembly script. We are going to be using Rust.</strong> </p>
<h2 id="heading-installing-dependencies">Installing Dependencies</h2>
<p><strong>First, if you have yet to, you need to install RUST on your local machine. You can follow the guide here:</strong> <a target="_blank" href="https://www.rust-lang.org/tools/install"><strong>https://www.rust-lang.org/tools/install</strong></a></p>
<p><strong>Also, install the</strong> <code>near-cli</code> <strong>via the terminal</strong></p>
<pre><code class="lang-javascript">$ npm install -g near-cli
</code></pre>
<p><strong>Please note that this article is not a guide on Rust programming language. The motif of this article is to demonstrate to you how easy it is to write Smart Contract code in Rust and deploy it on the NEAR Blockchain. NEAR has its library for spinning up projects similar to the</strong> <code>Create React App</code><strong>. It is called the</strong> <code>Create NEAR App</code><strong>. It is bundled with a React frontend library that has a lot of existing features for quickly building apps. We will use the Create NEAR App to demonstrate how to build the project.</strong></p>
<h2 id="heading-smart-contract-code"><strong>Smart Contract Code</strong></h2>
<p><strong>To begin writing the Smart Contract, run the command:</strong></p>
<pre><code class="lang-javascript">$ npx-create-near-app near-donor-dapp
</code></pre>
<p><strong>It will prompt you to add the assembly script wasm file, respond yes.</strong></p>
<p><img src="https://lh7-us.googleusercontent.com/IVqUjDKjd5yk_fQTg2r5Vl6GmMtL-u_qm-teYGXJWZ60IfUoK-KBkN4PPrMxrE_ZszvKPYGHjyAiwUt426MkM0BuIwaxqaZQ39VwLAYMaH-eACorQJDV4hcqtEkMGMz1cQroaqAhnzYSNzdfYzuMEw" alt /></p>
<p><strong>When the dependencies have finished installing, cd into the project directory:</strong></p>
<pre><code class="lang-javascript">$ cd near-donor-dapp
</code></pre>
<p><strong>If you are used to building projects using ReactJS, you will observe a similarity in the project directory. Open the project in an IDE like VSCode, the dir structure looks like this:</strong></p>
<p><img src="https://lh7-us.googleusercontent.com/mUjWfPel2-dU4imGzc-CYpyIjuaaPr-2XqGv7DzTg4CljIuTB5NfITLtLEmVBXDBEY--rWNBHFWImoNt768HfoGRZ-16tcpP2DPS7lVTMtEYa3TxtoKrVMdJofSRB898B0fVhtQQOtMbmCBilf6tLw" alt /></p>
<p><strong>To have the Dapp running locally, run</strong></p>
<pre><code class="lang-javascript">$ yarn build

$ yarn run dev
</code></pre>
<p><strong>Go to</strong> <a target="_blank" href="https://www.rust-lang.org/tools/install"><strong>localhost:1234</strong></a> <strong>to see the app running:</strong></p>
<p><img src="https://lh7-us.googleusercontent.com/N8oM2hoh8Ui2tRXXBF2ONk_ztO_CjwcSaEJhrZkmZZVUibUFT-y7dGpqm6GjcW8dMOMSLtAv8GLSaBtRajUgVh_ZODpkOBDmDvyJUYxJ9P5LvUDty4Wwx5wryWCmyfpcvuLdkxltulIkXVwHbFt6kw" alt /></p>
<p><strong>You can try interacting with the Dapp by clicking the “Sign in” button. The Dapp is running on the NEAR testnet and it is safe. When you click the button, you will be prompted to give the Dapp access to your NEAR account:</strong></p>
<p><img src="https://lh7-us.googleusercontent.com/X5kgm3s3MUDE7ZBWHa1oKG36R1Hr3YFFWizb7RN0QIXbgc_VGu7NOFrzHm5bE-Anv_1hR5wdiQCeqsw_evNgdR3cwMEEE_EfgKc2MJRaots5XTMiVnNSmC_0fUV3vogJ3UUhmr4MdncZGVqHakjZzw" alt /></p>
<p><strong>That is a default greeting DApp, you can go ahead, and interact with it!</strong></p>
<p><strong>We have successfully used the</strong> <code>create NEAR App</code><strong>. Next will be to write the Smart Contract code for the implementation of the donor Dapp and deploy</strong> it <strong>to a NEAR address of our choosing.</strong></p>
<p><strong>As a guide, let’s design the Smart Contract logic using an illustration.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698671702509/8950c484-6a8e-4ef7-b5d0-70f351e5c459.png" alt class="image--center mx-auto" /></p>
<p><strong>It is a simple DApp.</strong></p>
<h2 id="heading-smart-contract"><strong>Smart Contract</strong></h2>
<p>The Smart Contract code will be written in Rust. Open the <code>src</code> folder and you will find the <a target="_blank" href="https://www.rust-lang.org/tools/install"><code>lib.rs</code></a> file. Open the <a target="_blank" href="https://www.rust-lang.org/tools/install">lib.rs</a> file, you will find the example greeting contract. For our donor app, we are not going to write any tests, so you can go ahead and delete the lines of code from line 45 to the end, the tests module.</p>
<p>Before we delete the example greeting contract, study the comments for the implementation and the functions in the contract. There is a <code>set_greeting</code> method and a <code>get_greeting method</code>. The <code>set_greeting</code> method changes the state of the blockchain as it is used for sending data. The <code>get_greeting</code> method is a <code>view</code> function that does not impact the state of the blockchain. </p>
<p>The Near Donor app will have 3 functions:</p>
<ul>
<li><p>A function for sending tokens to a selected address. This function will take 3 arguments: <code>amount</code>, <code>receiver_address</code> and <code>note</code>.</p>
</li>
<li><p>A function for getting the transactions sent to the contract.</p>
</li>
<li><p>A view function for returning the transaction information sent on-chain.</p>
</li>
</ul>
<p>In the <a target="_blank" href="https://www.rust-lang.org/tools/install">lib.rs</a> file, delete the default message line, delete the message of String data type in the Contract struct, and delete the functions inside the Default and Contract implementation you, will be left with barebones code like this: </p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> near_sdk::borsh::{<span class="hljs-keyword">self</span>, BorshDeserialize, BorshSerialize};
<span class="hljs-keyword">use</span> near_sdk::{log, near_bindgen};

<span class="hljs-comment">// Define the contract structure</span>
<span class="hljs-meta">#[near_bindgen]</span>
<span class="hljs-meta">#[derive(BorshDeserialize, BorshSerialize)]</span>

<span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Contract</span></span> {

}

<span class="hljs-comment">// Define the default, which automatically initializes the contract</span>
<span class="hljs-keyword">impl</span> <span class="hljs-built_in">Default</span> <span class="hljs-keyword">for</span> Contract{

}

<span class="hljs-comment">// Implement the contract structure</span>
<span class="hljs-meta">#[near_bindgen]</span>
<span class="hljs-keyword">impl</span> Contract {

}
</code></pre>
<p>I’ll go over each line of code and explain what they are meant for:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> near_sdk::borsh::{<span class="hljs-keyword">self</span>, BorshDeserialize, BorshSerialize};
</code></pre>
<p>We are using the near_sdk for writing the contracts, Borsh is “a non self-describing binary serialization format. It is designed to serialize any objects to a canonical and deterministic set of bytes”. It is designed for storing contract state efficiently on the NEAR chain to save <a target="_blank" href="https://docs.near.org/docs/concepts/storage#other-ways-to-keep-costs-down">storage</a> and <a target="_blank" href="https://docs.near.org/docs/concepts/gas">gas</a> costs.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> near_sdk::{log, near_bindgen};
</code></pre>
<p>These are macros in the NEAR sdk that we will be calling in our project</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[near_bindgen]</span>
<span class="hljs-meta">#[derive(BorshDeserialize, BorshSerialize)]</span>
</code></pre>
<p>The macro <code>near_bindgen</code> is wrapped around the struct to generate the smart contract. Every Rust contract is preceded with this macro as it allows it to make calls that change the contract state and receive calls.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Contract</span></span> {...}
</code></pre>
<p>The public method implementation of an <code>impl</code> method will be defined in this struct</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> Contract{ … }
</code></pre>
<p>Defines the default method call, which automatically initializes the contract</p>
<pre><code class="lang-rust"><span class="hljs-meta">#[near_bindgen]</span>
<span class="hljs-keyword">impl</span> Contract { … }
</code></pre>
<p>The contract implementation will live here. The method calls for setting the state and viewing the state will be defined here.</p>
<p>We will add some macros to the <code>near_sdk</code> that we will need in the course of writing the Contract. They are: <code>AccountId</code> and <code>Promise</code>.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> near_sdk::{log, near_bindgen, AccountId, Promise, env};
</code></pre>
<p><code>AccountId</code> is a near_sdk type definition for a user who is transferring tokens. The concept of a Promise here is similar to its use in JavaScript. <code>env</code> contains the information on the user who will interact with the methods in the contract. It provides an easy way to call the user address. </p>
<p>The contract is going to store data on-chain and that will cost gas to store. To optimize the cost of storage, we will use a <code>LookupMap</code> to store the data. A LookupMap stores key and value once. requires only one storage read to get the stored value.</p>
<p>The LookupMap is a method of the std_collection library. We will import it into the project via the <code>near_sdk</code></p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> near_sdk::collections::LookupMap;
</code></pre>
<p>Now that we have added the LookupMap, we can store the <code>key: value</code> pair of the data type that we wish to return using the LookupMap. We will implement this in the struct for the Contract:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Contract</span></span> {
  note: LookupMap&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Vec</span>&lt;<span class="hljs-built_in">String</span>&gt;&gt;
}
</code></pre>
<p>This is simply holding the note in a LookupMap. LookupMaps are non-iterable.</p>
<p>Define the Default impl:</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> Contract{
   <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">default</span></span>() -&gt; <span class="hljs-keyword">Self</span> {
       <span class="hljs-keyword">Self</span> { 
            note:LookupMap::new::(<span class="hljs-string">b"note"</span>.to_vec())
        }
   }
}
</code></pre>
<p>The Default stores the data parsed via the LookupMap on the chain in an ordered index of array items, identified by numbers which can easily be looked up and returned and also easily save the data as stated above.</p>
<p>Next, we will implement the state methods and view method for the contract! These methods will be in the <code>impl Contract</code>.</p>
<p>The easy state change method, to begin with, is the donate function:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">donate</span></span>(&amp;<span class="hljs-keyword">mut</span> <span class="hljs-keyword">self</span>, account_id:AccountId, amount:<span class="hljs-built_in">f64</span>) {
Promise::new(account_id).transfer(amount <span class="hljs-keyword">as</span> <span class="hljs-built_in">u128</span>);
}
</code></pre>
<p>It is a publicly called function hence, the <code>pub</code> definition. The function is called: <code>donate</code>, and it takes 2 args. The <code>&amp;mut self</code> is Rust's way to confirm that it is a mutable function call. The AccountId from the near_sdk collection is parsed to account_id, this will be the wallet id of the user making a donation, the <code>amount</code> is of primitive data type <code>f64</code>.</p>
<p>It is a Promise call, where the <code>transfer</code> method is called on the account_id to transfer the specified sum which is on int type 128.</p>
<p>Now we can call the donate function and transfer tokens. Let’s add a heartfelt note to the donations:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">note</span></span>(&amp;<span class="hljs-keyword">mut</span> <span class="hljs-keyword">self</span>, note_text: <span class="hljs-built_in">String</span>, amount: <span class="hljs-built_in">String</span>) {
<span class="hljs-keyword">let</span> account_id = env::signer_account_id();
<span class="hljs-keyword">let</span> user = <span class="hljs-keyword">self</span>.note.get(account_id);
}
</code></pre>
<p>This is the note function, it is mutable hence the <code>&amp;mut self</code> arg. It takes two argos, <code>note_text</code> and <code>amount</code> which it stores on chain. The args are of type <code>String</code>.  </p>
<p>Here we see the use of the near_sdk <code>env</code>, it helps retrieve the details of the user who is signing the contract interaction. We declared a variable <code>account_id</code> to hold the <code>amount</code> information. The second variable <code>user</code> assigns the account information by calling the <code>get()</code> method to associate the account_id to the user in the LookupMap.</p>
<p>We are not done with this function as we still have to push the arg passed to the function on-chain when the function is called. There is a condition to check for when we implement this: Do we already have available information on the user calling the method?  </p>
<p>We will use an if else statement to check for when we have the associated user information. When we do, we will push the data to a vector of arrays.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">if</span> user {
<span class="hljs-keyword">let</span> <span class="hljs-keyword">mut</span> list = <span class="hljs-keyword">match</span> <span class="hljs-keyword">self</span>.note.get(&amp;account_id) {
<span class="hljs-literal">Some</span>(var) =&gt; var;
<span class="hljs-literal">None</span> =&gt; <span class="hljs-built_in">vec!</span>[];
};
list.push(note_text + “||” +&amp;amount + “ NEAR.”);
<span class="hljs-keyword">self</span>.note.insert(&amp;account_id, &amp;list);
} <span class="hljs-keyword">else</span> {
<span class="hljs-keyword">let</span> list = <span class="hljs-built_in">vec!</span>[note_text + “||” +&amp;amount + “ NEAR.”];
<span class="hljs-keyword">self</span>.note.insert(&amp;account_id, &amp;list);
}
</code></pre>
<p>This is an <code>if else</code> statement. The critical information to highlight here is the </p>
<pre><code class="lang-rust"><span class="hljs-literal">Some</span>(var) =&gt; var;
<span class="hljs-literal">None</span> =&gt; <span class="hljs-built_in">vec!</span>[]
</code></pre>
<p>This is the rust array macro argument which checks if a user information exists in the list variable and creates an array if it does not.</p>
<p>The <code>push</code> method sends the information on chain.</p>
<p>We are done with the functions that change the state of the contract and will now write our last function to view/return the data on chain. The view functions do not incur gas costs.</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">view_donations</span></span>(<span class="hljs-keyword">self</span>, user:<span class="hljs-built_in">String</span>) -&gt; <span class="hljs-built_in">Vec</span>&lt;<span class="hljs-built_in">String</span>&gt; {
<span class="hljs-keyword">match</span> <span class="hljs-keyword">self</span>.note.get(&amp;user) {
<span class="hljs-literal">Some</span>(var) =&gt; var;
<span class="hljs-literal">None</span> =&gt; <span class="hljs-built_in">vec!</span>[]
}
}
</code></pre>
<p>This is not a mutable function as view functions are not mutable. You do have to indicate the <code>self</code> keyword. It takes in the user info and returns a <code>Vec</code> of String. This is the format in which the info was saved on-chain.  </p>
<p>Using the <code>match</code> keyword, we can check through the array vectors if a user exists or not. </p>
<p>We are done with the functions needed for the Smart Contract. We can compile the contract and deploy it to the NEAR Testnet to interact with it. To compile the Smart Contract, run</p>
<pre><code class="lang-javascript">$ yarn build
</code></pre>
<p>The Smart Contract will compile without errors. Every time you make a change to the Smart Contract code, you will have to compile it. When the compilation is complete, the next step will be to deploy the Smart Contract. The deployment will be done in your terminal using the <code>near-cli</code>.</p>
<p>Open a terminal and ensure you are in your project directory, First we have to login to NEAR. This is to create a connection the testnet account where we will deploy the Smart Contract. Run th e command:</p>
<pre><code class="lang-javascript">$ near login
</code></pre>
<p>This will open a window in your browser where you will be prompted to login to your Testnet wallet. The <code>near login</code> command connects to the NEAR testnet by default. This is to ensure a layer of security so you do not spend actual tokens in error. To connect to the Mainnet account, you can see the instructions in the NEAR <a target="_blank" href="https://www.rust-lang.org/tools/install">docs</a>.</p>
<p><img src="https://lh7-us.googleusercontent.com/2DCAYThTdo_5wi5lbxtFHCcGvdTgo_8PFHYtoVX3ShYmC4lr3YVCS-HnJOYSjUoTVqtOtZlkFS-hVLfebNi2WDD2efXtf1cezWO-fNlo0OEHSqeOemK3j9SH9iMfBzB-eVvyr0Ty20l07ofWxm5HWw" alt /></p>
<p><img src="https://lh7-us.googleusercontent.com/vXaYHVGePk4xgLmE15Dqi3lGZNoZkyiRDVVIhU-4fShADMwFNkePwaNlCSeLd_emAlx-67I9FUFjNjE86d70VK5uJQIejD-gBxb_aTUVsj1ub9Q3tY5-VhXwNhYn07gU_zfy6el1I0i3e48yuL23Mw" alt /></p>
<p><img src="https://lh7-us.googleusercontent.com/P1_EuS6VD_nR88RIwdOE0OPCHiPDKAh6E2Ruivbg5OJnjY12t8rRXu92ZyCVoMnH_w5oVHxlNvrWpH9Gkw4VA1sThl6CC_DF-xN9L5vE62afAR33yX4b34SVR3cXXUGmr9DqR2JpXoVJBMHDbSasCQ" alt /></p>
<p>If you look closely, you will notice a difference here from where we connected to the dapp we initialized at the beginning. This is a connection to the NEAR blockchain from our computer and we are requesting full access to all the account privileges associated with our NEAR account.  </p>
<p>To deploy the contract on-chain, run the command:</p>
<pre><code class="lang-javascript">$ near deploy --wasmFile target/wasm32-unknown-unknown/release/rust_counter_tutorial.wasm --accountId YOUR_ACCOUNT_HERE
</code></pre>
<p>Where <code>YOUR_ACCOUNT_HERE</code> is the account where you deployed the code, e.g: <strong>oaikhenan.testnet</strong></p>
<p>Once the contract has successfully deployed, we can begin interacting with it by calling the function via our cli using <code>near-cli</code> commands.</p>
]]></content:encoded></item><item><title><![CDATA[Blockchains! What now?]]></title><description><![CDATA[I first got involved with the Blockchain in 2017 out of curiosity and then became fascinated, even though I had known all about Blockchain technology since about 2015. I earned my first pay in the space in 2018 on a contract role and then some via Gi...]]></description><link>https://emmaodia.hashnode.dev/blockchains-what-now</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/blockchains-what-now</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Fri, 11 Feb 2022 11:49:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/9pCV2MB65y8/upload/v1644419905765/XJ-t_c3Rl.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I first got involved with the Blockchain in 2017 out of curiosity and then became fascinated, even though I had known all about Blockchain technology since about 2015. I earned my first pay in the space in 2018 on a contract role and then some via Gitcoin. Why is this the premise for this piece? Many folks in the Blockchain space first got drawn in because of the promise of the technology. At the time I first got involved, I immediately saw the use case for “decentralization” and it is important to mention that at the time I was fascinated by the idea of verification of data and payments settlement away from the Banks. Of course, it made so much sense as it is still does now that: </p>
<blockquote>
<p>“The Blockchain is a distributed ledger system that can validate ownership of a token ensuring that a user can transfer the said token to another user and pay a small fee to mining participants in the system to verify the transaction”.
I immediately saw the use case for identity management, ownership of assets, cross-border payment systems, logistics tracking, and patient management in healthcare.</p>
</blockquote>
<p>That said, it is commonplace right now for a lot of people to associate Blockchain technology with crypto settlements (read: payments). The technology differentiates itself from “centralized” systems by the introduction of a token system to affirm data ownership and validate transactions. It is so much more more than payment systems. Blockchains ensures ownership of data by the use of token to verify transactions. These same tokens used for payment settlements can be used for identity verification and all other use case listed above.</p>
<p>One very common misconception a lot of people have is when they try to separate Blockchain technology from the “Internet”. Internet for context here refers to the HTTP protocol. Not to go so much into the explanation of the technical scope of Blockchains, it is imperative to mention that at the user level - wallet transactions, et all - Blockchains are communicated with via HTTPS procedural calls. This is not an article on nodes and RPC. More often than not we have a lot of people in recent years coming into the Blockchain for the promise of economic gain, where they hope to 10000x on a token. It is critical to mention therefore that Blockchains do not exist solely for the purpose of minting tokens and creating Billionaires “out of thin air”. The technology also exists to solve a myriad of problems in sectors as I have mentioned in the first paragraph.</p>
<h2 id="heading-blockchains-what-now">Blockchains, what now?</h2>
<p>As I mention often, it is still very much early days for Blockchains. The promise for a lot more use cases beyond just payment settlements and other financial services is enormous. It is critical that everyone gets involved. The barriers to entry (e.g Bad UX) have to be reduced. The critical component of learning how to build has to be made even simpler for developers getting into the space. The prevailing idea of using the term web3 to define the Blockchain makes it seem like a new technology that lives away from the internet needs to be addressed by stakeholders in the space. The primary reason is to ensure that more people understand that Blockchain is a technology for verification of ownership, hence: tokens exist for the purpose.</p>
<p>I do recommend that if you are yet to get involved in Blockchain technology, do so now! I opened my first Blockchain Wallet on the Bitcoin Network in 2015. Sad to mention that at the time, I really did not understand the token aspects of the technology. I saw a piece of tech that made cross-border settlements easier. I was blown away when I discovered Ethereum and the very fact that one can do a whole lot more with Ethereum Smart Contracts. To get started in Blockchain technology now in 2022, you have to first decide on a Blockchain network you want to partake in and open a Wallet. I’ll not recommend you join any network in particular, rather, I suggest joining any EVM compatible network and get your Wallet Address from MetaMask. </p>
<p><em>This is an opinion piece and I hope to write a whole lot more of these on Blockchain technology. You can initiate a conversation with me on <a target="_blank" href="https://twitter.com/emma_odia">Twitter</a> to share your thoughts as well. See you in the next one. Cheers!
</em></p>
]]></content:encoded></item><item><title><![CDATA[Web3, another angle.]]></title><description><![CDATA["I live in Nigeria". That is a sentence in 2021 which is enough to explain all the apparent problems that citizens are experiencing by way of bad government policies grossly affecting the economy and thus undermining the ability of citizens to create...]]></description><link>https://emmaodia.hashnode.dev/web3-another-angle</link><guid isPermaLink="true">https://emmaodia.hashnode.dev/web3-another-angle</guid><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[Blockchain]]></category><dc:creator><![CDATA[Emmanuel Oaikhenan]]></dc:creator><pubDate>Mon, 20 Sep 2021 09:11:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631427004512/MSq8cQVew.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>"I live in Nigeria". That is a sentence in 2021 which is enough to explain all the apparent problems that citizens are experiencing by way of bad government policies grossly affecting the economy and thus undermining the ability of citizens to create wealth. It is the proverbial saying of: “throwing away the baby with the bathwater” as seen in the singular moves of banning the sale of crypto for fiat (Naira) using the local Banks. Then, banning Twitter! Arrrgh! Well, this article is not a Political discourse and quite naturally: </p>
<blockquote>
<p><strong>“I’m not one to complain about situations beyond my immediate control and ability to impact”. </strong></p>
</blockquote>
<p>🏋️‍♀️</p>
<p><strong>In this article, I’m going to make a submission on how Nigerians and Africans at large can leverage the web3 technologies and “act outside of bad government policies” to create wealth and achieve democratic consensus in tandem with the rest of the world. Unfortunately, many African countries are at the mercy of bad government policies!
</strong></p>
<p>In this article we take about: </p>
<ul>
<li>What is the web3 - Explain like I am 5. </li>
<li>Why do I need to pay attention? Crypto payment use case</li>
</ul>
<h2 id="enter-the-web3">Enter the Web3!</h2>
<p>I’m going to explain the web3 as I would to a 5-year-old child. Let’s call the child “<em>Themba</em>”</p>
<p><em>Themba</em>: What is the web3.</p>
<p><em>Me</em>: {<em>Struggles in my head as to how I’ll break down terms such as Democracy, Open, Trust, Transparent to a child and then takes a deep sigh</em>} Themba… Let me tell you a story…</p>
<p>Themba, you recall the story I told you about the Rat and the Lion and why Lions do not eat rats? {Thema nods heads affirmatively}. Yes. I told you that the Rat released the Lion when he was caught in a trap net and the Lion promised not to eat him and also he mentioned that his descendants will never eat the descendants of the rat. The Lion gave the rat his word and he wrote it down on a piece of paper, and also he shared this same piece of information with other Lions and the rat shared his with other rats. That started the process where whenever a Lion sees the rat, the rat simply showed the Lion the piece reminding it that it cannot be eaten. Each encounter that they have is recorded on a large register and all Lions and Rats have the register to make sure no Lion eats a rat. It is a very large register when every meeting is not noted and bundles together and whenever the Rats and Lions want to know what happened on particular days there was an exchange between rats and Lions, they look up the information in the register using the bundle information. The is the web3 for Lions and Rats. They hold a piece of information, you can think of this as a Smart Contract, each encounter between a Lion and a rat is a transaction and it is written on the register which is a Ledger. When the encounters (transactions) reach a certain number they are bundled and that is a block. This makes it easy to look up information. The blocks are stringed together to keep a chain record. Making up a network (the Blockchain) where Lions and Rats hold consensus on a contract that Lions will never eat rats in an environment called the web3.</p>
<p>It is an OPEN process needing no INTERMEDIARIES and it is DEMOCRATIC. The Lion and the Rats agree and do not need other forest animals to ensure the Lion does not break his contract. The record exists to prove this!</p>
<p>Yes, that is exactly (well, maybe not so exact) what the web3 is. The most popular use case globally and which still needs to be harnessed for Africa is payments. Cross continental payments and P2P for daily transactions. Payments in the context of the Rat and Lion is then a contract which indicates that every time the Lion and Rat meet, they meet to exchange money as a form of payback for ancestor Rat saving ancestor Lion!</p>
<h2 id="solving-the-money-problem">Solving the Money Problem</h2>
<p>This is where I explain to you still in technical speak, but using technical analogues what the web3 means in terms of payments. Crypto as currencies on the web3 is popularly called is a coined from the root word cryptography. Which also when further broken down is formed from the word cryptic. Which means a message which is difficult to understand without clues. When a cryptic message is sent from a sender to the recipient, the sender must add a key to the message which the recipient will then use as a guide to get the meaning of the message. Thus ensuring that only the intended recipient gets a message and no one else. This is a somewhat oversimplification of what cryptocurrencies are in the light of cryptography. The point here is this: A cryptocurrency can be regarded as a number of cryptic messages written originally by miners who then send out these messages to people who want to own a piece of each message and hand over the keys to read the messages, each message (in this case a token) is regarded as a store of value and is given a price figure because it has the following properties:
No one else can access the message asides from the one who holds the keys. Not even the miner
When a person does a task, they can be paid using a piece of the message (token) as it is an agreed-upon value exchange commodity. 
It is a lot like trade by barter, wherein in this instance, I can give you a piece of cryptic message (cryptocurrency) which no one else holds in the world. A duplicate copy cannot be made of it. There is an open book (ledger) distributed globally which tracks the transfer of the crypto-message from one hand to another.</p>
<p>When a user can grasp the importance of owning a piece of these crypto-messages, understand why it is a store of value and wants to own a piece of it, a user will then have to join the web3, which unlike the web3 has its own particular protocols, tools and interface.</p>
<h2 id="how-to-get-into-web3">How to get into web3</h2>
<p>In this context, getting into web3 means: “How do I convert my fiat currency to cryptocurrency?”</p>
<p>But first, it is important to understand that, the first set of crypto and up till now was created by miners. Now, you can buy from someone who already holds crypto to own a piece. You can also mine, though the set-up is quite expensive. This could be from a crypto exchange that you can give cash and in exchange you receive crypto. Right now, given the recent ban by the Central Bank of Nigeria on the use of crypto, you can no longer connect your Bank account to crypto exchanges to purchase crypto. There are a number of exchanges, you simply have to find the particular exchanges that serve your country.</p>
<p>You still are able to open an account with one of these exchanges and purchase your initial crypto from other vendors on the platform. This method is called P2P (Peer to Peer). With P2P, you send a request to purchase crypto after you have signed up and completed KYC on the platform. When you sign up with an exchange, you are given an address to hold your crypto assets. This is called a wallet address. When you request to buy crypto, you are then given a list of crypto sellers that you can then pair with, who is able to supply crypto on the exchange for cash. You then request to trade with a selected user and then they provide you with their account details while you provide them with your wallet address generated on the platform. The amount of crypto-asset you are purchasing is valued in fiat (like a forex exchange where you can see USD and your local currency pair). You send the money to the seller’s amount and they send the crypto to your wallet address.</p>
<p><strong>There, you made your first crypto purchase!</strong> 🎉</p>
<p>A quick search on Google will return the crypto exchanges operating in your country.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I set out with the intent to explain the web3 to you without the mention of crypto and I achieved this using the “Rat and the Lion” story to explain contracts and transactions. After laying that foundation, I then explained web3 using crypto. Crypto still is the easiest point of entry into the web3. There are other use cases that I will share as time goes on.</p>
<p>I do hope you learn a thing or two from the article! Let me hear your thoughts! You can  <a target="_blank" href="https://twitter.com/emma_odia">Tweet</a>  at me, Let’s connect! </p>
<p><strong>Fun fact: It is said that Lions do not eat rats as the calories reward for eating rats will not fill for the energy expended chasing them!</strong> 😂</p>
]]></content:encoded></item></channel></rss>