<?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[Dev with Codemon 💀]]></title><description><![CDATA[Welcome to my official blog where I share most of the issues I encounter while programming and my solutions to them using my favourite javascript libraries and frameworks. Author - Alfred Johnson Awa]]></description><link>https://blog.codemon.me</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1609869136935/92TzAOGOw.jpeg</url><title>Dev with Codemon 💀</title><link>https://blog.codemon.me</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 14:38:55 GMT</lastBuildDate><atom:link href="https://blog.codemon.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The Tech Industry in 2026: What Engineers Should Prepare For]]></title><description><![CDATA[The tech industry is changing fast—but not in the way most people think. By 2026, success in engineering won’t be about chasing the newest tools or stacking buzzwords on a résumé. It will be about depth, ownership, and usefulness. Here’s a grounded l...]]></description><link>https://blog.codemon.me/the-tech-industry-in-2026-what-engineers-should-prepare-for</link><guid isPermaLink="true">https://blog.codemon.me/the-tech-industry-in-2026-what-engineers-should-prepare-for</guid><category><![CDATA[AI]]></category><category><![CDATA[engineering]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Tue, 23 Dec 2025 11:33:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/QRKJwE6yfJo/upload/f74fdafcf2f61f444881b1a65942a8fc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The tech industry is changing fast—but not in the way most people think. By 2026, success in engineering won’t be about chasing the newest tools or stacking buzzwords on a résumé. It will be about <strong>depth, ownership, and usefulness</strong>. Here’s a grounded look at what the tech industry is likely to look like in 2026—and the advice every engineer should take seriously.</p>
<hr />
<h2 id="heading-1-ai-will-become-infrastructure-not-a-product"><strong>1. AI Will Become Infrastructure, Not a Product</strong></h2>
<p>By 2026, AI will no longer feel “special.”</p>
<p>It won’t just be a standalone product you build or integrate once. Instead, it will be <strong>embedded into everything</strong>:</p>
<ul>
<li><p>Databases</p>
</li>
<li><p>CI/CD pipelines</p>
</li>
<li><p>Monitoring and observability</p>
</li>
<li><p>APIs and internal tooling</p>
</li>
</ul>
<p>The winning engineers won’t be those who can “prompt well,” but those who understand <strong>how to integrate AI into real systems safely and efficiently</strong>.</p>
<p>Prompting is not a skill.</p>
<p>System thinking plus AI integration is.</p>
<hr />
<h2 id="heading-2-backend-and-infrastructure-engineers-will-become-more-valuable"><strong>2. Backend and Infrastructure Engineers Will Become More Valuable</strong></h2>
<p>Frontend development is increasingly being abstracted by:</p>
<ul>
<li><p>AI UI builders</p>
</li>
<li><p>Design-to-code tools</p>
</li>
<li><p>No-code and low-code platforms</p>
</li>
</ul>
<p>But backend and infrastructure work cannot be safely abstracted away.</p>
<p>By 2026, demand will increase for engineers who understand:</p>
<ul>
<li><p>Distributed systems</p>
</li>
<li><p>Payments and financial flows</p>
</li>
<li><p>Identity and authentication</p>
</li>
<li><p>Security and access control</p>
</li>
<li><p>Databases and data pipelines</p>
</li>
<li><p>Blockchain and protocol infrastructure</p>
</li>
</ul>
<p>These systems power real businesses—and failures here are expensive.</p>
<hr />
<h2 id="heading-3-blockchain-will-quietly-become-financial-infrastructure"><strong>3. Blockchain Will Quietly Become Financial Infrastructure</strong></h2>
<p>The hype phase is ending.</p>
<p>By 2026:</p>
<ul>
<li><p>There will be fewer speculative chains</p>
</li>
<li><p>More purpose-built blockchains</p>
</li>
<li><p>Strong focus on stablecoins, RWAs, payments, and settlement layers</p>
</li>
</ul>
<p>The protocols that survive won’t be flashy.</p>
<p>They will be boring, reliable, compliant—and valuable.</p>
<p>Blockchain engineers who focus on <strong>UX, security, and real-world use cases</strong> will outperform those chasing short-term yield.</p>
<hr />
<h2 id="heading-4-engineering-teams-will-get-smaller-but-stronger"><strong>4. Engineering Teams Will Get Smaller but Stronger</strong></h2>
<p>AI copilots will change team dynamics.</p>
<p>Five strong engineers will outperform fifteen average ones.</p>
<p>Companies will prioritize engineers who:</p>
<ul>
<li><p>Can own problems end-to-end</p>
</li>
<li><p>Understand the business impact of their work</p>
</li>
<li><p>Can ship, maintain, and improve systems without heavy supervision</p>
</li>
</ul>
<p>Responsibility per engineer will increase—but so will influence.</p>
<hr />
<h2 id="heading-5-apis-and-integration-skills-will-explode-in-demand"><strong>5. APIs and Integration Skills Will Explode in Demand</strong></h2>
<p>Every company is becoming:</p>
<ul>
<li><p>A payments company</p>
</li>
<li><p>A data company</p>
</li>
<li><p>An integration company</p>
</li>
</ul>
<p>By 2026, engineers who can:</p>
<ul>
<li><p>Design clean, intuitive APIs</p>
</li>
<li><p>Handle edge cases and failure scenarios</p>
</li>
<li><p>Think in workflows, not just endpoints</p>
</li>
<li><p>Build reliable, scalable services</p>
</li>
</ul>
<p>…will always be in demand.</p>
<hr />
<h2 id="heading-hard-advice-for-engineers-no-sugarcoating"><strong>Hard Advice for Engineers (No Sugarcoating)</strong></h2>
<h3 id="heading-1-stop-chasing-tools-master-fundamentals"><strong>1. Stop Chasing Tools. Master Fundamentals.</strong></h3>
<p>Frameworks change.</p>
<p>Languages evolve.</p>
<p>Fundamentals compound.</p>
<p>Double down on:</p>
<ul>
<li><p>Networking basics</p>
</li>
<li><p>Databases (indexes, transactions, locks)</p>
</li>
<li><p>Concurrency and parallelism</p>
</li>
<li><p>System design</p>
</li>
<li><p>Security fundamentals</p>
</li>
</ul>
<p>Tools are rented.</p>
<p>Fundamentals are owned.</p>
<hr />
<h3 id="heading-2-learn-to-think-like-a-product-owner"><strong>2. Learn to Think Like a Product Owner</strong></h3>
<p>By 2026, engineers who ask:</p>
<blockquote>
<p>“Why are we building this?”</p>
</blockquote>
<p>will outperform those who only ask:</p>
<blockquote>
<p>“What ticket am I assigned?”</p>
</blockquote>
<p>Understand:</p>
<ul>
<li><p>How the company makes money</p>
</li>
<li><p>User pain points</p>
</li>
<li><p>Cost of failure and downtime</p>
</li>
</ul>
<p>Engineering is no longer isolated from business reality.</p>
<hr />
<h3 id="heading-3-ai-will-expose-weak-engineers-not-replace-strong-ones"><strong>3. AI Will Expose Weak Engineers, Not Replace Strong Ones</strong></h3>
<p>AI will not replace engineers—but it will <strong>expose gaps</strong>.</p>
<p>Engineers who will struggle:</p>
<ul>
<li><p>Can’t debug without AI</p>
</li>
<li><p>Don’t understand why code works</p>
</li>
<li><p>Can’t reason beyond copied solutions</p>
</li>
</ul>
<p>Engineers who will thrive:</p>
<ul>
<li><p>Use AI as an accelerator</p>
</li>
<li><p>Can review, correct, and improve AI-generated code</p>
</li>
<li><p>Understand systems deeply</p>
</li>
</ul>
<p>Treat AI like a junior engineer—not your boss.</p>
<hr />
<h3 id="heading-4-ownership-will-matter-more-than-titles"><strong>4. Ownership Will Matter More Than Titles</strong></h3>
<p>Your value in 2026 will be defined by <strong>what you own</strong>.</p>
<p>Own:</p>
<ul>
<li><p>A service</p>
</li>
<li><p>A protocol</p>
</li>
<li><p>A deployment pipeline</p>
</li>
<li><p>A critical business system</p>
</li>
</ul>
<p>“I built this and it runs in production” will matter more than job titles or certificates.</p>
<hr />
<h3 id="heading-5-public-proof-will-matter-more-than-private-skill"><strong>5. Public Proof Will Matter More Than Private Skill</strong></h3>
<p>Resumes matter less.</p>
<p>Proof matters more.</p>
<p>Engineers should focus on:</p>
<ul>
<li><p>Shipping real products</p>
</li>
<li><p>Contributing to open source</p>
</li>
<li><p>Writing technical content</p>
</li>
<li><p>Running systems in production</p>
</li>
</ul>
<p>Visibility plus competence creates opportunity.</p>
<hr />
<h2 id="heading-final-thought"><strong>Final Thought</strong></h2>
<blockquote>
<p><strong>2026 will not reward the loudest engineers.</strong></p>
<p><strong>It will reward the most useful ones.</strong></p>
</blockquote>
<p>Engineers who build reliable systems, understand fundamentals, and take ownership will always be relevant—regardless of how fast technology changes.</p>
]]></content:encoded></item><item><title><![CDATA[gRPC Streaming Patterns]]></title><description><![CDATA[1. Server Streaming RPC:

Description: In this type of RPC, the client sends a single request to the server, and the server responds with a stream of messages. The client reads from this stream of responses until there are no more messages.

Use Case...]]></description><link>https://blog.codemon.me/grpc-streaming-patterns</link><guid isPermaLink="true">https://blog.codemon.me/grpc-streaming-patterns</guid><category><![CDATA[gRPC]]></category><category><![CDATA[RPC]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Wed, 23 Oct 2024 20:36:40 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-1-server-streaming-rpc">1. <strong>Server Streaming RPC:</strong></h3>
<ul>
<li><p><strong>Description</strong>: In this type of RPC, the client sends a single request to the server, and the server responds with a stream of messages. The client reads from this stream of responses until there are no more messages.</p>
</li>
<li><p><strong>Use Case Example</strong>: <strong>Real-time Market Data Feed</strong>.</p>
<ul>
<li><p><strong>Scenario</strong>: A client requests live market data (e.g., stock prices) from a server. The client sends a request for data about a specific stock, and the server streams updated stock prices as they change over time.</p>
</li>
<li><p><strong>Example</strong>:</p>
<ul>
<li><p>The client sends a request to get updates for "Stock X".</p>
</li>
<li><p>The server continuously sends back a stream of stock price updates for "Stock X" every time the price changes until the client decides to stop the feed.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="lang-plaintext">    service StockService {
        rpc GetStockUpdates(StockRequest) returns (stream StockUpdate);
    }

    message StockRequest {
        string stockSymbol = 1;
    }

    message StockUpdate {
        string stockSymbol = 1;
        double price = 2;
        int64 timestamp = 3;
    }
</code></pre>
<h3 id="heading-2-client-streaming-rpc">2. <strong>Client Streaming RPC:</strong></h3>
<ul>
<li><p><strong>Description</strong>: In this type of RPC, the client sends a stream of requests to the server, and the server responds with a single response once it has received and processed all the requests.</p>
</li>
<li><p><strong>Use Case Example</strong>: <strong>File Upload</strong>.</p>
<ul>
<li><p><strong>Scenario</strong>: A client wants to upload a large file to the server. Instead of sending the entire file in one request, it sends it in chunks (as a stream). Once the server receives all the chunks, it processes them and responds with the result (e.g., success, failure).</p>
</li>
<li><p><strong>Example</strong>:</p>
<ul>
<li><p>The client sends the file in chunks, one chunk at a time.</p>
</li>
<li><p>The server waits for the entire file, processes it, and returns a response (e.g., "File uploaded successfully").</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="lang-plaintext">    service FileUploadService {
        rpc UploadFile(stream FileChunk) returns (UploadStatus);
    }

    message FileChunk {
        bytes content = 1;
        int32 chunkNumber = 2;
    }

    message UploadStatus {
        string message = 1;
        bool success = 2;
    }
</code></pre>
<h3 id="heading-3-bidirectional-streaming-rpc">3. <strong>Bidirectional Streaming RPC:</strong></h3>
<ul>
<li><p><strong>Description</strong>: Both the client and the server send streams of messages to each other. The two streams operate independently, so the client and server can read and write in any order.</p>
</li>
<li><p><strong>Use Case Example</strong>: <strong>Real-time Chat Application</strong>.</p>
<ul>
<li><p><strong>Scenario</strong>: Imagine a real-time chat application where both the client and the server need to continuously send and receive messages. The client sends messages to the server, and the server sends messages back to the client, creating a real-time, two-way conversation.</p>
</li>
<li><p><strong>Example</strong>:</p>
<ul>
<li><p>The client sends messages as they are typed, one by one.</p>
</li>
<li><p>The server streams messages from other participants back to the client.</p>
</li>
<li><p>Both streams happen simultaneously, and the server and client can send messages independently.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="lang-plaintext">    service ChatService {
        rpc Chat(stream ChatMessage) returns (stream ChatMessage);
    }

    message ChatMessage {
        string username = 1;
        string message = 2;
        int64 timestamp = 3;
    }
</code></pre>
<h3 id="heading-practical-example-for-each">Practical Example for Each:</h3>
<ol>
<li><p><strong>Server Streaming</strong>: You request the server for all your order statuses, and the server sends them one by one (think of a service that keeps sending delivery status updates as new information comes in).</p>
</li>
<li><p><strong>Client Streaming</strong>: You’re uploading multiple sensor data readings from a device to a server in batches. The server processes all the data and responds with an analysis result after the entire batch is received.</p>
</li>
<li><p><strong>Bidirectional Streaming</strong>: You’re in a video conference where both parties are sending audio and video data streams at the same time, without waiting for each other's data streams to finish.</p>
</li>
</ol>
<h3 id="heading-conclusion">Conclusion:</h3>
<ul>
<li><p><strong>Server Streaming</strong>: Good for scenarios where the server needs to keep sending updates over time for a single request.</p>
</li>
<li><p><strong>Client Streaming</strong>: Suitable for cases where the client has a lot of data to send but the server only needs to respond once.</p>
</li>
<li><p><strong>Bidirectional Streaming</strong>: Ideal for real-time, interactive use cases where both the client and server need to continuously communicate in real-time.</p>
</li>
</ul>
<p>Each streaming pattern has specific use cases and trade-offs in terms of latency, throughput, and complexity.</p>
]]></content:encoded></item><item><title><![CDATA[Sending Raw Emails with Attachments using AWS SES in Go]]></title><description><![CDATA[Email communication is a crucial aspect of many applications, and Amazon Simple Email Service (SES) provides a reliable and scalable solution for sending emails in the Amazon Web Services (AWS) environment. I've created a go package that facilitates ...]]></description><link>https://blog.codemon.me/sending-raw-emails-with-attachments-using-aws-ses-in-go</link><guid isPermaLink="true">https://blog.codemon.me/sending-raw-emails-with-attachments-using-aws-ses-in-go</guid><category><![CDATA[golang]]></category><category><![CDATA[AWS]]></category><category><![CDATA[email]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Tue, 16 Jan 2024 17:17:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705425406099/9cb87603-ad56-4d26-be39-f80aedb204d0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Email communication is a crucial aspect of many applications, and Amazon Simple Email Service (SES) provides a reliable and scalable solution for sending emails in the Amazon Web Services (AWS) environment. I've created a go package that facilitates sending raw emails with attachments using AWS SES.</p>
<h1 id="heading-full-code">Full Code</h1>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> oaws

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"io/ioutil"</span>
    <span class="hljs-string">"os"</span>

    <span class="hljs-string">"github.com/aws/aws-sdk-go/aws/session"</span>
    <span class="hljs-string">"github.com/rs/zerolog/log"</span>
    <span class="hljs-string">"github.com/aws/aws-sdk-go/aws"</span>
    <span class="hljs-string">"github.com/aws/aws-sdk-go/aws/awserr"</span>
    <span class="hljs-string">"github.com/aws/aws-sdk-go/service/ses"</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewSession</span><span class="hljs-params">(region <span class="hljs-keyword">string</span>)</span> <span class="hljs-params">(sess *session.Session, err error)</span></span> {
    <span class="hljs-keyword">if</span> region == <span class="hljs-string">""</span> {
        log.Fatal().Msg(<span class="hljs-string">"Missing region in oaws.NewSession"</span>)
    }
    sess, err = session.NewSession(&amp;aws.Config{
        Region: aws.String(region)})
    <span class="hljs-keyword">return</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">SendRawEmailWithAttachment</span><span class="hljs-params">(sender, recipient, subject, html, text, fileName, region <span class="hljs-keyword">string</span>, attachmentFile *os.File)</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-comment">// Create a new session using AWS SDK</span>
    sess, err := NewSession(region)

    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(err.Error())
        <span class="hljs-keyword">return</span> err
    }

    _, err = attachmentFile.Seek(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error seeking to the beginning of the file:"</span>, err)
        <span class="hljs-keyword">return</span> err
    }

    <span class="hljs-comment">// Read the content of the attachment file</span>
    attachmentContent, err := ioutil.ReadAll(attachmentFile)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error reading attachment:"</span>, err)
        <span class="hljs-keyword">return</span> err
    }

    <span class="hljs-comment">// Convert the attachment content to base64</span>
    attachmentData := aws.NewWriteAtBuffer(attachmentContent)

    <span class="hljs-comment">// Construct the raw email content including the attachment</span>
    rawEmail := fmt.Sprintf(<span class="hljs-string">`From: %s
To: %s
Subject: %s
Content-Type: multipart/mixed;
    boundary="a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: multipart/alternative;
    boundary="sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

%s

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

%s

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/plain; name="%s"
Content-Description: %s
Content-Disposition: attachment;filename="%s";
    creation-date="Sat, 05 Aug 2017 19:35:36 GMT";
Content-Transfer-Encoding: base64

%s

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--
`</span>, sender, recipient, subject, text, html, fileName, fileName, fileName, attachmentData.Bytes())

    <span class="hljs-comment">// Create a new SES service client</span>
    svc := ses.New(sess)

    <span class="hljs-comment">// Create the input for sending raw email</span>
    input := &amp;ses.SendRawEmailInput{
        RawMessage: &amp;ses.RawMessage{
            Data: []<span class="hljs-keyword">byte</span>(rawEmail),
        },
    }

    <span class="hljs-comment">// Send the raw email with the attachment</span>
    _, err = svc.SendRawEmail(input)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        handleSendEmailError(err)
        <span class="hljs-keyword">return</span> err
    }

    <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>
}

<span class="hljs-comment">// Helper function to handle SES send email errors</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">handleSendEmailError</span><span class="hljs-params">(err error)</span></span> {
    <span class="hljs-keyword">if</span> aerr, ok := err.(awserr.Error); ok {
        <span class="hljs-keyword">switch</span> aerr.Code() {
        <span class="hljs-keyword">case</span> ses.ErrCodeMessageRejected:
            fmt.Println(ses.ErrCodeMessageRejected, aerr.Error())
        <span class="hljs-keyword">case</span> ses.ErrCodeMailFromDomainNotVerifiedException:
            fmt.Println(ses.ErrCodeMailFromDomainNotVerifiedException, aerr.Error())
        <span class="hljs-keyword">case</span> ses.ErrCodeConfigurationSetDoesNotExistException:
            fmt.Println(ses.ErrCodeConfigurationSetDoesNotExistException, aerr.Error())
        <span class="hljs-keyword">default</span>:
            fmt.Println(aerr.Error())
        }
    } <span class="hljs-keyword">else</span> {
        fmt.Println(err.Error())
    }
}
</code></pre>
<h1 id="heading-sample-usage">Sample Usage</h1>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">GenerateTXTContent</span><span class="hljs-params">(contentArray []<span class="hljs-keyword">string</span>)</span> <span class="hljs-title">string</span></span> {
    <span class="hljs-comment">// Create a buffer to hold the contents in memory</span>
    <span class="hljs-keyword">var</span> buffer bytes.Buffer

    <span class="hljs-comment">// Loop through the array and write contents to the buffer</span>
    <span class="hljs-keyword">for</span> _, content := <span class="hljs-keyword">range</span> contentArray {
        buffer.WriteString(content + <span class="hljs-string">"\n"</span>)
    }

    <span class="hljs-comment">// Convert the buffer to a string</span>
    <span class="hljs-keyword">return</span> buffer.String()
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">GenerateTempFileContent</span><span class="hljs-params">(txtContent, fileName <span class="hljs-keyword">string</span>)</span> <span class="hljs-params">(*os.File, error)</span></span> {
    <span class="hljs-comment">// Create a temporary file in memory</span>
    tmpFile, err := os.CreateTemp(<span class="hljs-string">"."</span>, fileName+<span class="hljs-string">"*.txt"</span>)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error creating temporary file:"</span>, err)
        <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>, err
    }
    <span class="hljs-keyword">defer</span> os.Remove(tmpFile.Name()) <span class="hljs-comment">// Clean up the temporary file</span>

    <span class="hljs-comment">// Write the contents to the temporary file</span>
    _, err = tmpFile.WriteString(txtContent)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error writing to temporary file:"</span>, err)
        <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>, err
    }

    <span class="hljs-keyword">return</span> tmpFile, <span class="hljs-literal">nil</span>
}

        <span class="hljs-keyword">var</span> vouchers []<span class="hljs-keyword">string</span>
            <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i &lt; <span class="hljs-built_in">len</span>(generateVoucherResponse.Item); i++ {
                vouchers = <span class="hljs-built_in">append</span>(vouchers, generateVoucherResponse.Item[i].Code)
            }

            txtContent := GenerateTXTContent(vouchers)

            file, err := GenerateTempFileContent(txtContent, schoolDetailsRequest.Item.ID.String())
            <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
                <span class="hljs-keyword">return</span> utils.ReturnError(w, err, http.StatusInternalServerError)
            }

            <span class="hljs-keyword">defer</span> file.Close()
            recipient := Email

            SendRawEmailWithAttachment(consts.SenderEmail, recipient, <span class="hljs-string">"Registration Confirmation"</span>, <span class="hljs-string">`Welcome`</span>, <span class="hljs-string">"Welcome"</span>, <span class="hljs-string">"filename.txt"</span>, cfg.AWSSESRegion, file)
</code></pre>
<p>Let's break down the key components of this code and understand how it achieves the task of sending emails with attachments.</p>
<h3 id="heading-1-importing-packages">1. Importing Packages</h3>
<p>The code begins by importing necessary packages, including the AWS SDK for Go and other standard Go packages.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> oaws

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"io/ioutil"</span>
    <span class="hljs-string">"os"</span>

    <span class="hljs-string">"github.com/aws/aws-sdk-go/aws"</span>
    <span class="hljs-string">"github.com/aws/aws-sdk-go/aws/awserr"</span>
    <span class="hljs-string">"github.com/aws/aws-sdk-go/service/ses"</span>
)
</code></pre>
<h3 id="heading-2-function-to-send-raw-email-with-attachment">2. Function to Send Raw Email with Attachment</h3>
<p>The <code>SendRawEmailWithAttachment</code> function is the core of this package. It takes various parameters such as sender, recipient, subject, HTML and plain text content, file name, AWS region, and an attachment file. It constructs a raw email with a multipart structure that includes both the email body and the attachment.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">SendRawEmailWithAttachment</span><span class="hljs-params">(sender, recipient, subject, html, text, fileName, region <span class="hljs-keyword">string</span>, attachmentFile *os.File)</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-comment">// ... (code continues below)</span>
}
</code></pre>
<h3 id="heading-3-creating-an-aws-session">3. Creating an AWS Session</h3>
<p>The function starts by creating an AWS session using a helper function named <code>NewSession</code>. If an error occurs during session creation, it prints an error message and returns the error.</p>
<h3 id="heading-4-preparing-attachment-content">4. Preparing Attachment Content</h3>
<p>The code reads the content of the attachment file and converts it to base64 format. It then constructs the raw email content by combining the email body and attachment.</p>
<h3 id="heading-5-constructing-raw-email">5. Constructing Raw Email</h3>
<p>The raw email is constructed as a multipart message, including both alternative text/plain and text/html content for the email body. It also includes the attachment with relevant metadata.</p>
<h3 id="heading-6-creating-ses-service-client">6. Creating SES Service Client</h3>
<p>A new SES service client is created using the AWS session.</p>
<pre><code class="lang-go">svc := ses.New(sess)
</code></pre>
<h3 id="heading-7-creating-input-for-sending-raw-email">7. Creating Input for Sending Raw Email</h3>
<p>The input for sending raw email is created with the raw email data.</p>
<pre><code class="lang-go">input := &amp;ses.SendRawEmailInput{
    RawMessage: &amp;ses.RawMessage{
        Data: []<span class="hljs-keyword">byte</span>(rawEmail),
    },
}
</code></pre>
<h3 id="heading-8-sending-raw-email">8. Sending Raw Email</h3>
<p>Finally, the function attempts to send the raw email using the SES service client. If an error occurs, the <code>handleSendEmailError</code> function is called to handle specific SES-related errors.</p>
<h3 id="heading-9-handling-ses-send-email-errors">9. Handling SES Send Email Errors</h3>
<p>A helper function, <code>handleSendEmailError</code>, is defined to handle errors that may occur during the SES send email operation. It checks the error type and prints specific error messages based on the SES error code.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>This Go package provides a convenient way to send raw emails with attachments using AWS SES. Just copy what you need, my usage would not be the same as yours. So far as you provide the right paramters to the sendEmail function, you should be good to go.</p>
]]></content:encoded></item><item><title><![CDATA[SHA HMAC signature verification for Paystack Webhook in Go lang]]></title><description><![CDATA[Introduction
This article shows a complete setup on how you can verify a signature sent by paystack when they make a POST request to your server. I'm using the bun http router as my go lang framework. I really do not have strength for long talks, so ...]]></description><link>https://blog.codemon.me/sha-hmac-signature-verification-for-paystack-webhook-in-go-lang</link><guid isPermaLink="true">https://blog.codemon.me/sha-hmac-signature-verification-for-paystack-webhook-in-go-lang</guid><category><![CDATA[paystack]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[webhooks]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Wed, 10 Jan 2024 12:16:01 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>This article shows a complete setup on how you can verify a signature sent by paystack when they make a <code>POST</code> request to your server. I'm using the bun http router as my go lang framework. I really do not have strength for long talks, so i'll show you the code.</p>
<h2 id="heading-code-section">Code Section</h2>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> service

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"crypto/hmac"</span>
    <span class="hljs-string">"crypto/sha512"</span>
    <span class="hljs-string">"encoding/hex"</span>
    <span class="hljs-string">"encoding/json"</span>
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"io"</span>
    <span class="hljs-string">"net/http"</span>

    <span class="hljs-string">"github.com/uptrace/bunrouter"</span>
    <span class="hljs-string">"github.com/uptrace/bunrouter/extra/reqlog"</span>

    <span class="hljs-string">"github.com/SAMBA-Research/microservice-shared/paystack"</span>
    <span class="hljs-string">"github.com/SAMBA-Research/microservice-shared/utils"</span>
)

<span class="hljs-keyword">type</span> WebhookResponse <span class="hljs-keyword">struct</span> {
    Event <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"event"`</span>
    Data  <span class="hljs-keyword">struct</span> {
        ID               <span class="hljs-keyword">int</span>         <span class="hljs-string">`json:"id"`</span>
        Domain           <span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"domain"`</span>
        Status           <span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"status"`</span>
        Reference        <span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"reference"`</span>
        Amount           <span class="hljs-keyword">int</span>         <span class="hljs-string">`json:"amount"`</span>
        <span class="hljs-comment">// Message          interface{} `json:"message"`</span>
        GatewayResponse  <span class="hljs-keyword">string</span>      <span class="hljs-string">`json:"gateway_response"`</span>
        PaidAt           time.Time   <span class="hljs-string">`json:"paid_at"`</span>
        CreatedAt        time.Time   <span class="hljs-string">`json:"created_at"`</span>
        <span class="hljs-comment">// Channel          string      `json:"channel"`</span>
        <span class="hljs-comment">// Currency         string      `json:"currency"`</span>
        <span class="hljs-comment">// IPAddress        string      `json:"ip_address"`</span>
        <span class="hljs-comment">// Metadata         interface{} `json:"metadata"`</span>
        <span class="hljs-comment">// Log              Log         `json:"log"`</span>
        <span class="hljs-comment">// Fees             interface{} `json:"fees"`</span>
        <span class="hljs-comment">// Customer         Customer    `json:"customer"`</span>
        <span class="hljs-comment">// Authorization    Authorization `json:"authorization"`</span>
        <span class="hljs-comment">// Plan             interface{} `json:"plan"`</span>
    } <span class="hljs-string">`json:"data"`</span>
}



<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(srv *Microservice)</span> <span class="hljs-title">paystackPaymentWebHook</span><span class="hljs-params">(w http.ResponseWriter, r bunrouter.Request)</span> <span class="hljs-params">(err error)</span></span> {

    body, err := io.ReadAll(r.Body)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error reading request body:"</span>, err)
        http.Error(w, <span class="hljs-string">"Internal Server Error"</span>, http.StatusInternalServerError)
        <span class="hljs-keyword">return</span>
    }


    <span class="hljs-keyword">var</span> paystackRequestBody WebhookResponse
    <span class="hljs-keyword">defer</span> r.Body.Close()
    err = json.Unmarshal(body, &amp;paystackRequestBody)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(<span class="hljs-string">"Error decoding JSON:"</span>, err)
        <span class="hljs-keyword">return</span>
    }

    signature := r.Header.Get(<span class="hljs-string">"x-paystack-signature"</span>)
    <span class="hljs-keyword">if</span> isValidSignature(body, signature, srv.cfg.PaystackSecret) {
        <span class="hljs-comment">// Unmarshal the JSON payload</span>

        fmt.Println(<span class="hljs-string">"valid signature"</span>)

        <span class="hljs-keyword">if</span> paystackRequestBody.Event == <span class="hljs-string">"charge.success"</span> {
            <span class="hljs-comment">// extract tenant and payment_id from reference</span>
            ref := paystackRequestBody.Data.Reference

            <span class="hljs-comment">// make request to your service or update your database here.</span>
            paystackWebhookRequest, err := utils.POSTJSON[types.CommonResponse](srv.getPaymentService(fmt.Sprintf(<span class="hljs-string">"/v1/payment/webhook/paystack"</span>,)), paystackRequestBody)

            <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
                <span class="hljs-keyword">return</span> utils.ReturnError(w, err, http.StatusInternalServerError)
            }
            <span class="hljs-keyword">if</span> paystackWebhookRequest.ErrorCode != <span class="hljs-number">0</span> {
                <span class="hljs-keyword">return</span> utils.ReturnError(w, fmt.Errorf(<span class="hljs-string">"service error: %s"</span>, paystackWebhookRequest.Message), http.StatusInternalServerError)
            }

        }

        <span class="hljs-keyword">return</span> utils.ReturnJSON(w, <span class="hljs-literal">nil</span>, http.StatusOK)

    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">return</span> utils.ReturnError(w, fmt.Errorf(<span class="hljs-string">"invalid signature %s"</span>, signature), http.StatusBadRequest)
    }
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isValidSignature</span><span class="hljs-params">(payload []<span class="hljs-keyword">byte</span>, signature, secretKey <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">bool</span></span> {
    mac := hmac.New(sha512.New, []<span class="hljs-keyword">byte</span>(secretKey))
    mac.Write(payload)
    expectedMAC := hex.EncodeToString(mac.Sum(<span class="hljs-literal">nil</span>))

    <span class="hljs-keyword">return</span> expectedMAC == signature
}
</code></pre>
<h2 id="heading-things-to-note">Things to note</h2>
<p>Don't bother trying to install the package below, it's not for public use. they are just libraries that help me perform certain tasks like making http request and retrieving shared types.</p>
<pre><code class="lang-javascript">
    <span class="hljs-string">"github.com/SAMBA-Research/microservice-shared/paystack"</span>
    <span class="hljs-string">"github.com/SAMBA-Research/microservice-shared/utils"</span>
</code></pre>
<h1 id="heading-conclusion">Conclusion</h1>
<p>So that's how you would typically handle webhook requests in go lang. Hopefully in the feature paystack adds this implementation to their documenation. Thanks Guys, thanks for reading.</p>
]]></content:encoded></item><item><title><![CDATA[2023: I Escaped]]></title><description><![CDATA[Funny title, but that's the reality from January to December. So, you're here to hear some gist about my 2023, say less.
First I just want to take a moment to laugh small, 😂😂😂😂 why? the plans I had for 2023 come be like say na small pikin write a...]]></description><link>https://blog.codemon.me/2023-i-escaped</link><guid isPermaLink="true">https://blog.codemon.me/2023-i-escaped</guid><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Sun, 31 Dec 2023 17:48:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704044844012/0c096080-34ed-4a77-9813-68ec175d134b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Funny title, but that's the reality from January to December. So, you're here to hear some gist about my 2023, say less.</p>
<p>First I just want to take a moment to laugh small, 😂😂😂😂 why? the plans I had for 2023 come be like say na small pikin write am, because none of those things really happened.</p>
<p>Secondly, 2023 in conclusion was a rough one for me.. what I ordered was not what I got but in all things, I'm greatly to God for not shaming me regardless. I really wish I had enough strength to give more details about how each month went, the ups and downs, and the stories learned and taught 😂.</p>
<h1 id="heading-some-quick-statistics">Some Quick Statistics</h1>
<p>A lot more happened but this is all I can remember, happy reading.</p>
<p>Physical Status - Had zero major problems, hit the gym like it was the last, and added some flesh I struggled to gain thanks to supplements and of course, muscles to steal your babe.</p>
<p>Mental Status - This particular period when I lowkey could not help being unproductive coupled with confusion. This happened because, for a long period, i inhaled so much camphor and did not realize it was messing me up mentally.</p>
<p>Spiritual Status - I understood more that everyone needs to have where they get their power from ( Babalawo included), just pick a side.</p>
<p>Social Status - Someone I saw as a big brother scammed me and I had to end that relationship. Connected with more females than ever this year (don't get me wrong but feel free). Linked up with my previous employee. Convocation happened.</p>
<p>Financial Status - I barely saved this year. Cost me over 10 Million naira to go through the year in one piece.</p>
<p>Career Status - My Contract expired around April and I did not bother applying for new roles particularly because I was not prepared for that mental stress just yet. I completed all freelance projects except one. Started a new role around November. I was in Lagos for OSCA Fest 2023. Tried making sense of my startup 😪. Spoke at Devfest Owerri and Polygon Guild Enugu.</p>
<h1 id="heading-plans-for-2024">Plans for 2024</h1>
<p>I'll spend my time upskilling and improving on existing skills. And making good money. 2024 would make it 7 Years in Tech (clap hand for Jesus). For a long while, I've always wanted to do some ethical hacking stuff, so 2024 is the year of cybersecurity with a focus on Cloud Security, Penetration Testing, and network engineering. I'll recommend you do the same.</p>
<p>I hope to help more people as much as I can in 2024.</p>
<p>I also look forward to daily income.</p>
<p>My Catch phrase for next year would be "Hide your devices", e get why.</p>
]]></content:encoded></item><item><title><![CDATA[Generating a Bitcoin Address from a Private Key Using JavaScript]]></title><description><![CDATA[Bitcoin, the pioneering cryptocurrency, relies on cryptographic keys for secure transactions. This article walks through a JavaScript code snippet that demonstrates how to generate a Bitcoin address from a private key using the bitcoinjs-lib library....]]></description><link>https://blog.codemon.me/generating-a-bitcoin-address-from-a-private-key-using-javascript</link><guid isPermaLink="true">https://blog.codemon.me/generating-a-bitcoin-address-from-a-private-key-using-javascript</guid><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Mon, 04 Dec 2023 10:12:12 GMT</pubDate><content:encoded><![CDATA[<p>Bitcoin, the pioneering cryptocurrency, relies on cryptographic keys for secure transactions. This article walks through a JavaScript code snippet that demonstrates how to generate a Bitcoin address from a private key using the <code>bitcoinjs-lib</code> library. We'll explore the key steps involved in the process and provide a clear explanation for each segment of the code.</p>
<h3 id="heading-section-1-setting-up-the-environment"><strong>Section 1: Setting Up the Environment</strong></h3>
<p>In this code snippet, we start by importing necessary modules such as <code>ECPairFactory</code>, <code>tiny-secp256k1</code> (for elliptic curve cryptography), and the <code>bitcoinjs-lib</code> library. The <code>ECPair</code> class is instantiated using <code>ECPairFactory</code>, which is then utilized for handling private keys.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> ECPairFactory <span class="hljs-keyword">from</span> <span class="hljs-string">'ecpair'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> ecc <span class="hljs-keyword">from</span> <span class="hljs-string">'tiny-secp256k1'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> bitcoin <span class="hljs-keyword">from</span> <span class="hljs-string">'bitcoinjs-lib'</span>

<span class="hljs-keyword">const</span> ECPair = ECPairFactory.ECPairFactory(ecc);
</code></pre>
<h3 id="heading-section-2-generating-a-wif-encoded-private-key"><strong>Section 2: Generating a WIF-Encoded Private Key</strong></h3>
<p>The next part of the code generates a Wallet Import Format (WIF) encoded private key from a raw private key. The raw private key is a hexadecimal string, and it is converted to a WIF private key using the <code>ECPair.fromPrivateKey</code> method.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> rawPrivateKey = <span class="hljs-string">'1b4cccacd2c5cb084ae0d34a21605a00ad7f967d2c806b2608b2c0d841caf7a3'</span>;
<span class="hljs-keyword">const</span> keyPair = ECPair.fromPrivateKey(Buffer.from(rawPrivateKey, <span class="hljs-string">'hex'</span>));
<span class="hljs-keyword">const</span> wif = keyPair.toWIF();

<span class="hljs-built_in">console</span>.log(wif);
</code></pre>
<h3 id="heading-section-3-deriving-a-bitcoin-address"><strong>Section 3: Deriving a Bitcoin Address</strong></h3>
<p>The subsequent part demonstrates how to create a key pair from the WIF private key and derive a corresponding Bitcoin address using the <code>bitcoinjs-lib</code> library.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> keyPair2 = ECPair.fromWIF(wif);
<span class="hljs-keyword">const</span> { address } = bitcoin.payments.p2pkh({ <span class="hljs-attr">pubkey</span>: keyPair2.publicKey });

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Bitcoin Address: "</span>, address);
</code></pre>
<h3 id="heading-conclusion"><strong>Conclusion:</strong></h3>
<p>In summary, this JavaScript code snippet showcases a streamlined process for generating a Bitcoin address from a private key. Understanding the steps involved—importing necessary libraries, converting a raw private key to a WIF-encoded format, and deriving a Bitcoin address—provides developers with valuable insights into working with cryptographic keys in the Bitcoin ecosystem. The combination of <code>tiny-secp256k1</code> and <code>bitcoinjs-lib</code> libraries make the process efficient and accessible for JavaScript developers.</p>
<p>Feel free to experiment with the code, explore additional features of the libraries, and incorporate these techniques into your Bitcoin-related projects.</p>
]]></content:encoded></item><item><title><![CDATA[[Code Snippet]Generate Bitcoin Address Using bitcoinjs-lib]]></title><description><![CDATA[import * as bitcoin  from 'bitcoinjs-lib'
import ECPairFactory from 'ecpair';
import * as ecc from 'tiny-secp256k1';

// Generate a new random key pair

const ECPair =  ECPairFactory.ECPairFactory(ecc)
const keyPair = ECPair.makeRandom();
// // Get t...]]></description><link>https://blog.codemon.me/code-snippetgenerate-bitcoin-address-using-bitcoinjs-lib</link><guid isPermaLink="true">https://blog.codemon.me/code-snippetgenerate-bitcoin-address-using-bitcoinjs-lib</guid><category><![CDATA[Bitcoin]]></category><category><![CDATA[code]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Mon, 04 Dec 2023 09:54:35 GMT</pubDate><content:encoded><![CDATA[<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> bitcoin  <span class="hljs-keyword">from</span> <span class="hljs-string">'bitcoinjs-lib'</span>
<span class="hljs-keyword">import</span> ECPairFactory <span class="hljs-keyword">from</span> <span class="hljs-string">'ecpair'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> ecc <span class="hljs-keyword">from</span> <span class="hljs-string">'tiny-secp256k1'</span>;

<span class="hljs-comment">// Generate a new random key pair</span>

<span class="hljs-keyword">const</span> ECPair =  ECPairFactory.ECPairFactory(ecc)
<span class="hljs-keyword">const</span> keyPair = ECPair.makeRandom();
<span class="hljs-comment">// // Get the private and public keys</span>
<span class="hljs-keyword">const</span> privateKey = keyPair.privateKey.toString(<span class="hljs-string">'hex'</span>);
<span class="hljs-keyword">const</span> publicKey = keyPair.publicKey.toString(<span class="hljs-string">'hex'</span>);

 <span class="hljs-keyword">const</span> { address } = bitcoin.payments.p2pkh({ <span class="hljs-attr">pubkey</span>: keyPair.publicKey });
<span class="hljs-comment">// // Get the Bitcoin address associated with the public key</span>
<span class="hljs-comment">// const address = keyPair.getAddress();</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Private Key:'</span>, privateKey);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Public Key:'</span>, publicKey);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Bitcoin Address:'</span>, address);
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Go: Handle OTP creation & validation in memory]]></title><description><![CDATA[To generate a unique token/OTP for each verification request and associate it with the user's email or session in Go, you can use a combination of cryptographic libraries and data structures. Here's an example implementation:
package main

import (
 ...]]></description><link>https://blog.codemon.me/go-handle-otp-creation-validation-in-memory</link><guid isPermaLink="true">https://blog.codemon.me/go-handle-otp-creation-validation-in-memory</guid><category><![CDATA[Go Language]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Wed, 31 May 2023 17:07:39 GMT</pubDate><content:encoded><![CDATA[<p>To generate a unique token/OTP for each verification request and associate it with the user's email or session in Go, you can use a combination of cryptographic libraries and data structures. Here's an example implementation:</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"crypto/rand"</span>
    <span class="hljs-string">"encoding/base64"</span>
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"sync"</span>
    <span class="hljs-string">"time"</span>
)

<span class="hljs-comment">// OTP struct represents an OTP with its associated email and expiration time</span>
<span class="hljs-keyword">type</span> OTP <span class="hljs-keyword">struct</span> {
    Email       <span class="hljs-keyword">string</span>
    Token       <span class="hljs-keyword">string</span>
    ExpiresAt   time.Time
}

<span class="hljs-comment">// OTPManager manages the generation and verification of OTPs</span>
<span class="hljs-keyword">type</span> OTPManager <span class="hljs-keyword">struct</span> {
    otps <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]OTP
    mu   sync.Mutex
}

<span class="hljs-comment">// NewOTPManager creates a new OTPManager instance</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewOTPManager</span><span class="hljs-params">()</span> *<span class="hljs-title">OTPManager</span></span> {
    <span class="hljs-keyword">return</span> &amp;OTPManager{
        otps: <span class="hljs-built_in">make</span>(<span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]OTP),
    }
}

<span class="hljs-comment">// GenerateOTP generates a unique OTP for the given email with a specified expiration time</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(m *OTPManager)</span> <span class="hljs-title">GenerateOTP</span><span class="hljs-params">(email <span class="hljs-keyword">string</span>, expiration time.Duration)</span> <span class="hljs-params">(<span class="hljs-keyword">string</span>, error)</span></span> {
    m.mu.Lock()
    <span class="hljs-keyword">defer</span> m.mu.Unlock()

    <span class="hljs-comment">// Generate a random token</span>
    tokenBytes := <span class="hljs-built_in">make</span>([]<span class="hljs-keyword">byte</span>, <span class="hljs-number">32</span>) <span class="hljs-comment">// Adjust the length as per your requirements</span>
    _, err := rand.Read(tokenBytes)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>, fmt.Errorf(<span class="hljs-string">"failed to generate OTP: %w"</span>, err)
    }

    token := base64.URLEncoding.EncodeToString(tokenBytes)

    <span class="hljs-comment">// Calculate the expiration time</span>
    expiresAt := time.Now().Add(expiration)

    <span class="hljs-comment">// Store the OTP in the manager</span>
    m.otps[email] = OTP{
        Email:     email,
        Token:     token,
        ExpiresAt: expiresAt,
    }

    <span class="hljs-keyword">return</span> token, <span class="hljs-literal">nil</span>
}

<span class="hljs-comment">// VerifyOTP verifies the provided OTP for the given email</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(m *OTPManager)</span> <span class="hljs-title">VerifyOTP</span><span class="hljs-params">(email, token <span class="hljs-keyword">string</span>)</span> <span class="hljs-title">bool</span></span> {
    m.mu.Lock()
    <span class="hljs-keyword">defer</span> m.mu.Unlock()

    <span class="hljs-comment">// Retrieve the stored OTP for the email</span>
    otp, ok := m.otps[email]
    <span class="hljs-keyword">if</span> !ok {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
    }

    <span class="hljs-comment">// Check if the OTP is expired</span>
    <span class="hljs-keyword">if</span> time.Now().After(otp.ExpiresAt) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
    }

    <span class="hljs-comment">// Compare the provided token with the stored OTP token</span>
    <span class="hljs-keyword">return</span> otp.Token == token
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Example usage</span>
    manager := NewOTPManager()

    <span class="hljs-comment">// Generate OTP for a specific email with an expiration time of 5 minutes</span>
    email := <span class="hljs-string">"example@example.com"</span>
    token, err := manager.GenerateOTP(email, <span class="hljs-number">5</span>*time.Minute)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Printf(<span class="hljs-string">"Error generating OTP: %v\n"</span>, err)
        <span class="hljs-keyword">return</span>
    }

    <span class="hljs-comment">// Simulate sending the OTP via email</span>
    fmt.Printf(<span class="hljs-string">"OTP: %s\n"</span>, token)

    <span class="hljs-comment">// Simulate user entering the OTP for verification</span>
    enteredToken := <span class="hljs-string">"abc123"</span> <span class="hljs-comment">// Replace with the OTP entered by the user</span>

    <span class="hljs-comment">// Verify the OTP</span>
    isValid := manager.VerifyOTP(email, enteredToken)
    <span class="hljs-keyword">if</span> isValid {
        fmt.Println(<span class="hljs-string">"Verification successful!"</span>)
        <span class="hljs-comment">// Mark the user's account as verified</span>
        <span class="hljs-comment">// Update the verification status in the user table or session data</span>
    } <span class="hljs-keyword">else</span> {
        fmt.Println(<span class="hljs-string">"Verification failed!"</span>)
        <span class="hljs-comment">// Handle the verification failure</span>
    }
}
</code></pre>
<p>In this example, the <code>OTPManager</code> struct manages the generation and verification of OTPs. The <code>GenerateOTP</code> method generates a random token/OTP, associates it with the provided email, and stores it in the <code>otps</code> map along with its expiration time. The <code>VerifyOTP</code> method retrieves the stored OTP for the email and compares it with the provided token to validate the verification.</p>
<p>You can integrate the <code>OTPManager</code> into your application's</p>
<p>verification flow, associating each generated OTP with the user's email or session data for proper verification. Remember to adjust the length and expiration time of the OTPs as per your specific requirements.</p>
]]></content:encoded></item><item><title><![CDATA[PHP: Send Personalized Emails to Multiple Users]]></title><description><![CDATA[Have you ever wanted to send bulk emails that have dynamic content to multiple users? Well, you are not alone and I'll be showing you the exact code snippet I used for this purpose but in PHP. In order to successfully send emails, I made use of SendG...]]></description><link>https://blog.codemon.me/php-send-personalized-emails-to-multiple-users</link><guid isPermaLink="true">https://blog.codemon.me/php-send-personalized-emails-to-multiple-users</guid><category><![CDATA[PHP]]></category><category><![CDATA[sendgri]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Thu, 02 Mar 2023 13:07:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/guiQYiRxkZY/upload/afddddf934038e840f4b4449d41e52c2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you ever wanted to send bulk emails that have dynamic content to multiple users? Well, you are not alone and I'll be showing you the exact code snippet I used for this purpose but in PHP. In order to successfully send emails, I made use of <a target="_blank" href="https://github.com/sendgrid/sendgrid-php/">SendGrid PHP SDK</a> which is a library by the Sendgrid team for sending emails efficiently and for FREE too.</p>
<h2 id="heading-install-package">Install Package</h2>
<p>Add Twilio SendGrid to your <code>composer.json</code> file. If you are not using <a target="_blank" href="http://getcomposer.org/">Composer</a>, I highly recommend it. It's an excellent way to manage dependencies in your PHP application.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"require"</span>: {
    <span class="hljs-attr">"sendgrid/sendgrid"</span>: <span class="hljs-string">"~7"</span>
  }
}
</code></pre>
<p>or simply just install via the terminal using the command:</p>
<pre><code class="lang-bash">composer require <span class="hljs-string">"sendgrid/sendgrid"</span>
</code></pre>
<h1 id="heading-get-api-key">Get API key</h1>
<p>An API key is required to authenticate your request and you can always get one when you signup on <a target="_blank" href="https://sendgrid.com">SendGrid</a>. Once you have this key, copy and paste it somewhere in your project, for me, I've been able to read environment variables from a <code>.env</code> file using this <a target="_blank" href="https://github.com/vlucas/phpdotenv">package</a>. Just find a way to store your API key and the security of that key is your concern, try not to push that key to public version control platforms like GitHub, Sendgrid would disable this API Key once they find out ( don't ask me how ), and this is bad for production.</p>
<h2 id="heading-code">Code</h2>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">require</span> <span class="hljs-string">'vendor/autoload.php'</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">SendGrid</span>\<span class="hljs-title">Mail</span>\<span class="hljs-title">From</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">SendGrid</span>\<span class="hljs-title">Mail</span>\<span class="hljs-title">Mail</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">SendGrid</span>\<span class="hljs-title">Mail</span>\<span class="hljs-title">Personalization</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">SendGrid</span>\<span class="hljs-title">Mail</span>\<span class="hljs-title">Subject</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">SendGrid</span>\<span class="hljs-title">Mail</span>\<span class="hljs-title">To</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">SendGrid</span>\<span class="hljs-title">Mail</span>\<span class="hljs-title">HtmlContent</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">SendGrid</span>\<span class="hljs-title">Mail</span>\<span class="hljs-title">Substitution</span>;


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendBulkMail</span>(<span class="hljs-params">$receipientsData, $from, $subject, $message, $fromName</span>)
    </span>{


        $from_ = <span class="hljs-keyword">new</span> <span class="hljs-keyword">From</span>($from, $fromName);
        $htmlContent = <span class="hljs-keyword">new</span> HtmlContent(
            $message
        );
        $email = <span class="hljs-keyword">new</span> Mail($from_,<span class="hljs-literal">null</span>,$subject,<span class="hljs-literal">null</span>, $htmlContent);

        <span class="hljs-keyword">foreach</span> ($receipientsData <span class="hljs-keyword">as</span> $reciepient) {

            $personalization = <span class="hljs-keyword">new</span> Personalization();
            $personalization-&gt;addTo(<span class="hljs-keyword">new</span> To(
                $reciepient[<span class="hljs-number">0</span>],
                $reciepient[<span class="hljs-number">1</span>]
            ));

            $personalization-&gt;setSubject(<span class="hljs-keyword">new</span> Subject($subject));
             $personalization-&gt;addDynamicTemplateData(<span class="hljs-keyword">new</span> Substitution(<span class="hljs-string">"-first_name-"</span>,$reciepient[<span class="hljs-number">1</span>]));            

        }

        $sendgrid = <span class="hljs-keyword">new</span> \SendGrid($_ENV[<span class="hljs-string">'SEND_GRID'</span>]);
        <span class="hljs-keyword">try</span> {
           $response =  $sendgrid-&gt;send($email);
            <span class="hljs-keyword">print</span> $response-&gt;statusCode() . <span class="hljs-string">"\n"</span>;

            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">catch</span> (<span class="hljs-built_in">Exception</span> $e) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

$message = <span class="hljs-string">"&lt;div&gt;Hello -first_name-&lt;/div&gt;"</span>;
sendBulkMail([[<span class="hljs-string">"test@gmail.com"</span>,<span class="hljs-string">"Alfred"</span>],[<span class="hljs-string">"test2@gmail.com"</span>,<span class="hljs-string">"Star"</span>]],<span class="hljs-string">"alfred@codemon.me"</span>,<span class="hljs-string">"Test"</span>,$message,<span class="hljs-string">"Alfred"</span>);
</code></pre>
<p>The <code>sendBulkMail</code> function accepts the following parameter</p>
<ul>
<li><p>A Multidimensional array of your users' data, each user has an email and a name, think of this as an array of arrays.</p>
</li>
<li><p>Senders email</p>
</li>
<li><p>Email Subject</p>
</li>
<li><p>HTML content ( you can use twig to load your HTML template )</p>
</li>
<li><p>Senders Name</p>
</li>
</ul>
<h2 id="heading-code-explanation">Code Explanation</h2>
<pre><code class="lang-php"> $personalization = <span class="hljs-keyword">new</span> Personalization();
 $personalization-&gt;addDynamicTemplateData(<span class="hljs-keyword">new</span> Substitution(<span class="hljs-string">"-first_name-"</span>,$reciepient[<span class="hljs-number">1</span>]));
</code></pre>
<p>In order to personalize emails for each user, we construct a new <code>Personalization</code> class which has helpful methods to set dynamic data for each user. Calling the <code>addDynamicTemplateData</code> method on this class lets us substitute a placeholder with the actual valid on the HTML template. In our case, we want to replace <code>-first_name-</code> with the name of the current user.</p>
<p>It's important to note that your placeholder string (<code>-first_name-)</code> can take any format as you wish, it can look like this <code>{{first_name}}</code> as well.</p>
<pre><code class="lang-php"> $sendgrid = <span class="hljs-keyword">new</span> \SendGrid($_ENV[<span class="hljs-string">'SEND_GRID'</span>]);
</code></pre>
<p>This line of code simply sets our API key and like mentioned earlier, I'm currently loading environment variables from a <code>.env</code> file, but you can as well just hardcode your API Key( not recommended).</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Thanks to Sendgrid, you do not need to set up a ridiculous code block to send emails to multiple users, using this method is fast and saves some costs too. In this blog post, you've learned how to send personalized emails to multiple users using SendGrid PHP SDK, hope it made sense. Leave a comment with your questions and kind words, see you!</p>
]]></content:encoded></item><item><title><![CDATA[2022 Done & ?]]></title><description><![CDATA[Hello guys and welcome to my youtube channel 😂😂😂😂 .. Yo! What's good fam? It's that time of the year again, actually, the third time doing this review thingy, but this time around it's even more interesting, a lot of interesting actions generally...]]></description><link>https://blog.codemon.me/2022-done</link><guid isPermaLink="true">https://blog.codemon.me/2022-done</guid><category><![CDATA[2022]]></category><category><![CDATA[yearinreview]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Sat, 31 Dec 2022 16:34:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/abdea9299ea3e9b5914468e1f6831872.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello guys and welcome to my youtube channel 😂😂😂😂 .. Yo! What's good fam? It's that time of the year again, actually, the third time doing this review thingy, but this time around it's even more interesting, a lot of interesting actions generally, ups and downs choke, more of the good part.</p>
<p>So, in case you are in a hurry to read through I suggest you plan another time/day to come back here with your popcorn and Hennessy. Now, for those who are ready for some undiluted content, get your seat belt crossed, it's about to be a long ride because I'm about to tell a story that has never been told 😌.</p>
<p>For a while, I've been contemplating writing things and just needed a valid reason. I'm certain I might not be able to capture every single thing that happened this year, so this is me giving it a shot and putting my brain to the test.</p>
<h1 id="heading-flashback-to-2021">Flashback to 2021</h1>
<p>Last year was a good one and had a good number of achievements and all whatnot, you can check out my 2021 review here so I won't repeat them here. Skipping to the good part, I made a few goals for myself regarding the year 2022 and it's quite interesting how much I was able to check on that list, I say interesting because the moment that article got published was the last time I checked it consciously to look through what I had planned for the new year and create a road map for myself.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672401912922/354beefb-6dbc-486f-abd6-c90ef8449d73.png" alt class="image--center mx-auto" /></p>
<p>Quite an interesting list all around money and web3, and you know web3 is all about the money not literally, so it's safe to create a formula for this purpose <code>Money === Web3</code>. I'm happy for the much I was able to achieve excluding the blockchain course and attending Davido's concert. About the blockchain course, I had made reasonable progress and this reviewer just kept making life hard for me, or was it just me and my poor writing skills? Anyway, I got paid for trying to make sense and also sincerely wished the course went live. About Davido's concert, omoh! I did not really take that too serious but remember trying to check and enquire about his concerts in Lagos, but later found one in Ghana on the 31st of December. I love you OBO but my parents would kill me 😂, missing cross-over service for what?.</p>
<h1 id="heading-how-it-started">How it Started</h1>
<p>Just like many, kicked off the year in church while attending a cross-over service in a different parish for the first time in years. Something quite spectacular about this service, boy oh boy! I prayed 💀. Wasn't sure why but it was different and intense, felt like the likes of those who attend mountain of fire church without screaming "fire fire fire". After the whole prayer thing, this confidence showed up and the thought of "this is my year" kept running from that day onwards. 2022 Shall we?</p>
<p>For each month in the year, I'll talk about a few highlights and end it with a photo to crown it all up. Ready? Go!</p>
<h2 id="heading-jan-2022">Jan 2022.</h2>
<p>One of my goals for the new year was to fully transition into the web3 space. I made intentional moves by improving myself technically in preparation for what was to come. I figured it was time to move on from my current role as a front-end engineer because I personally believed I had made significant impacts and played important roles for the three years spent. For two reasons I was so down to leaving, one which was the salary pay, and secondly, I got so engrossed with blockchain technology.</p>
<p>Two months before 2022, I started job hunting for web3 roles via LinkedIn, and even with the normal rejections, I was able to land two different roles, part-time and contract work. The funny thing about the contract role was, I didn't realize it was a contract role till a few months later 😂, one of those companies that hire without the need for a signed agreement. You can check my <a target="_blank" href="https://linkedin.com/in/alfred-Johnson-awah">LinkedIn</a> for more details on the two roles.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672404226938/1e5622ee-175f-4ad6-b69a-f82631acda3b.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-feb-2022">Feb 2022</h2>
<p>Love is in the air, wahlauuur! This month, I started making plans to purchase one fine Lexus like that, as a birthday gift for myself, but a few talks and bad dreams about this idea made it die off. I think this was the month where we had that heartbreak song that says " break up na national cake e go touch everybody " 🫣.</p>
<p>A few days into the month, while on blockchain salary, I randomly stepped into a shop at the mall in Owerri and made my first apple product purchase after forming that I don't like them. I think part of the reason was that a friend of mine needed my help to make a phone purchase for his girl for valentines day then I also had a bulk of cash at hand that same day and decided to let go of a few on a new phone, I guess the iPhone was my valentines gift to myself from myself.</p>
<p>If you are a student of FUTO, you'll understand the struggles of getting a reasonable internet speed, for this purpose I had exhausted all options to get good internet and the last on my mind was to get a network booster, which I later did and only worked on the first day of installation, this has to be one hell of an annoying purchase.</p>
<p>Lastly, I finally graduated from 6 months of blockchain training with Emurgo academy thanks to <a target="_blank" href="https://www.abcdevs.com">ABCD (African Blochain center for developers)</a>. Fun fact; I was given the opportunity to work on the front end of their website.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672405895666/0e8b7293-a4ae-4e6a-86da-14268b2094fc.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672405938815/05816d0b-5b1b-426f-b964-a818cb9549f8.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672405952757/02210799-3944-41a4-b464-ef15600aef23.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-march-2022">March 2022</h1>
<p>My birth month, and have never been so excited about this year's celebration. As usual, had my cake done by a very good friend of mine, Faith. She's been doing this since 2020 and is good at what she does, so if you need her cake services leave a comment and I'll find a way to link you up.</p>
<p>My birthday is on the 5th of March, and for this, I made sure it was a little different by taking my first studio picture and then trying to get myself a reasonable birthday present.</p>
<p>Oh, yea, I paid for food and drinks for friends and we had a crazy party that night. My initial plan was to actually just disguise and share money on the streets as a way of showing love but could not get hold of neat naira notes before my birthday. So instead, during the late-night party, I decided to let go of some dollar notes and a few naira note to spray while we all danced to loud music. I personally had fun for the day and was close to attempting a ridiculous giveaway for my WhatsApp contacts( around 2M) , and no I was not high at all, thank God for the gift of sense.</p>
<p>As usual, received warm wishes and a few gifts but one which made good sense was a framed photo of myself by Elvis and Tobe. After setting my eyes on this frame, I fell in love with the whole concept of framing people's photos. But please if you are to frame somebody, use a fine picture abeg. The whole concept and design put into making the frame was what made it unique, had this shine shine thing on it and I loved it.</p>
<p>Not to forget, I interviewed with x-team for some senior blockchain role and got served a chilled breakfast when I felt it was all settled.</p>
<p>ASUU Strike 2022 😂 was also a thing that began this month.</p>
<p>It was an interesting month indeed, can't say it all here.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672406278453/026e23d6-27ca-422a-9312-5adc6a3a2bb4.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672406696531/2158108e-8e78-4d2f-b6e2-00efef82830f.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-april-2022">April 2022</h2>
<p>I got back home because of the ASUU strike (which started the previous month) to escape debit alert and bad network too. For the first time, I visited a spa to begin my skincare journey but nothing prepared me for the pain, I came out with a face looking rather swollen 😂. This month came with its difficulties at work because I was trying to balance organizing an event which took plenty of my time and work too.</p>
<p>While scrolling Twitter, I came across a blockchain event happening in Enugu, I didn't want to be in the crowd and that was how I reached out to Uche to co-organize that event, and our friendship began, cool story.</p>
<p>Remember this song, "Show me a jigga lemme see, and let me see a woman that he is with", remixed with mayorkun ? Yea, it was this month too, feeling old? 🫣 I almost attempted to shame myself again by participating in that dance challenge, it was indeed an addictive jam and was all over ticktok.</p>
<p>Public servants attempted to stress me while trying to make changes to my NIN credentials, but money stopped the nonsense. I started making plans to renew my passport this month.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672478149442/481e643c-8acd-4ae8-9316-2049dd07fb14.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-may-2022">May 2022</h1>
<p>Because of the love I have for drones, I figured it would be a nice addition to my gadget collection. I always admired the way that baby moves so quickly and high. A few people advised me not to get the drone from jumia, but because I've got a coconut head, I went ahead to make the order together with a terrible HD camera.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672478540450/89569f04-37f6-489d-8366-93997337b235.png" alt class="image--center mx-auto" /></p>
<p>12th May was the day to pick up my items, I went to the pickup station myself after it could not be delivered to my doorstep for some silly reasons. Got to the pickup station and it was my turn to claim my order, I was excited to see my baby drone. On receiving the items, the box containing the drone felt really light and I did not want to believe what I was thinking, I took it all to the car and went back home.</p>
<p>Finally, I unboxed the drone, and looking at the inferior parts it came with, I immediately knew that was a red flag, how could this thing possibly fly, I asked myself. Oh well, I thought it might not be that bad and went ahead to fix the parts together piece by piece till I was done. The drone looked like a bad guy already, and I turned on the camera, sad to say but this stuff had one of the worst pixels I've seen, redmi phones have better cameras. I ignored the camera and took it out to perform a flight test together with my little cousin.</p>
<p>Feeling like a drone pilot already, I made the first attempt to make the drone take off and it seemed like every control was the direct opposite and this stuff could not fly above my knees, I was mad at that point. Guess who was excited? My little cousin was amazed by the ability of that shit to at least try to get up from the ground, girl was having the time of her life and then there was me on the other end thinking of how to return this piece of a joke.</p>
<h2 id="heading-others">Others</h2>
<ul>
<li><p>Attended my first tech meetup in Enugu, it was a flutter developer meetup. I Met Mrs. Cynthia Peter and Sage for the first time physically.</p>
</li>
<li><p>25th May, I had the privilege to meet up with Ayo who was a speaker at the polygon Guild event in Enugu. Two days later, I also met Big Joe who also was a speaker.</p>
</li>
<li><p>May 27th was a Friday, end-of-the-month party at Xend finance and I was in attendance together with organizers &amp; Speakers for the Polygon Guild event.</p>
</li>
<li><p>Polygon Guild Enugu had its maiden event on the 28th of May, 2022. It was a big one, with amazing techies around.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672479367989/ee82a4cd-e385-4e39-b698-e31b83d917ab.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672479439413/49e0e3e3-5fbe-4b35-bfc8-b7d6543f4d54.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672479550585/2f068fab-7038-4854-afce-065947c66c11.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672479693510/ae6a524a-49bd-4b1a-b2b9-0c6206080a53.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-june-2022">June 2022</h1>
<p>Back to work after I had almost messed up by not informing my colleagues about my unavailability due to my commitment to organizing Polygon Guild last month. Another Big Tech event was about to hit Enugu again; The Binance BCAT event is one I'll love to refer to as a "tech concert", reasons because it featured celebrities like Dan dizzy and Alex Ekubo, with over 4000 in attendance.</p>
<p>I personally did not want to get involved with organizing because of work, and my goal for this event was to get away with as many swags as possible together with IK, my guy. Before the main BCAT event, there was another mini event that happened to be the reason why I own a <a target="_blank" href="https://wicrypt.com/">wicrypt</a> device, got that baby for free, and this was the beginning of my swag hunt and it felt good.</p>
<p>June got me a connection with Ernest, "onyeoma" at <a target="_blank" href="https://www.boundlesspay.com/">boundless pay</a>. We started talking after I informed him of my intentions to fly to Lagos for a blockchain event just to perform some Ticktok wonders, he felt it was a good idea and this was the beginning of my preparation for another web3 event called "Blockchain Vibes Lagos".</p>
<h3 id="heading-others-1">Others</h3>
<ul>
<li><p>Purchased a MacBook</p>
</li>
<li><p>Attempted to do a pedicure for the first time, which turned out to be the last time because this left me with a serious injury.</p>
</li>
<li><p>Finally got my international passport in preparation for my trip to Dubai for the world cup with my friends and somebody's daughter.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672480326408/e11d1b63-e6cd-4211-a9d3-c4212981e250.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672480384356/3c5ee3f8-f022-4871-9d50-b3448cf277ba.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672480446224/d0579c33-dcb1-49b5-994b-797662a5bd0c.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-july-2022">July 2022</h1>
<p>The Blockchain vibes event was drawing closer and had to book flights to Lagos and the cost felt like I should just use Peace Mass instead of air peace.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672481113660/21a4e821-0f6c-4b9a-a7ae-fd2890b2cc6f.jpeg" alt class="image--center mx-auto" /></p>
<p>God no go shame me, on the 8th of July, I was excited and already packed my bag the previous day. Like any Lagos flight, you'll most likely see one celebrity, in my case, it was Yul Edochie sitting comfortably in business class while I walked past shamelessly to economy class.</p>
<p>The flight was smooth and got to Lagos to meet heavy rain which almost got my Mac spoilt. The cost of transportation from the airport to my Airbnb on the island reminded me of the reasons why I will not pitch my tent in Lagos.</p>
<p>Speaking of my Airbnb, it is a true definition of beauty. You know when people do "what you ordered vs what you got" and what you got was terrible, well this wasn't my case, the environment on the inside out felt it was made just for me.</p>
<p>A few days before 23rd Jul, Uche called me and needed me to show up for a wedding engagement which he tried to deny wasn't for him.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672481457834/b5af9bd6-52fc-4a51-9bc7-39a06a72fc88.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672481482291/413c7c22-33df-4f95-818d-685618c0cb88.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672481571047/2c0efdae-8034-43df-8558-97785ecd05ce.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672483051321/1584ef71-2079-4065-a5ed-c3dbd87e4b8f.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-others-2">Others</h3>
<ul>
<li><p>Attended Blockchain Vibes Lagos on the 9th of Jul, and was it worth it? It's either a yes or No, so No.</p>
</li>
<li><p>Visited Landmark beach to compensate for the disappointment the previous day.</p>
</li>
<li><p>Got back to Enugu and attended Google I/O.</p>
</li>
<li><p>I registered for my PVC</p>
</li>
</ul>
<h1 id="heading-august-2022">August 2022</h1>
<p>August felt like my breakthrough month regarding my skincare routine, felt like this was finally making sense after all. This same month I got the information about the Dubai visa ban on Nigerians and my plans to make the trip was immediately ruined, but the money was saved.</p>
<p>I started working on an idea of mine, called this "Kira", Kira is a WhatsApp bot that provides automated buying and selling of goods and services without the need for a web or mobile app. Because of this, I created and registered a parent company together with Chibueze and Anderson, called Vendbase.</p>
<p>On a sad note and for some reason, my employers could not pay salaries anymore due to bankruptcy, this gave rise to thoughts of moving to a new place where I'll be challenged beyond what I already know and get better pay as well. I began job hunting through Linkedin and other web3 career listing platforms.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672483249178/c2b0a65f-a96d-4f0b-9a0e-49bd42b62152.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672483703246/93e9b6c9-37f2-4d80-a279-1fe5e2e50362.jpeg" alt class="image--center mx-auto" /></p>
<h3 id="heading-others-3">Others</h3>
<ul>
<li>Had my first virtual speaking engagement hosted by mara.</li>
</ul>
<h1 id="heading-sept-2022">Sept 2022</h1>
<p>Have you ever anticipated rejection emails? Well, this was my mindset because of the way I submitted my applications in bulk and most times without reading job requirements; I was desperate, tired, and on the verge of just giving up on job hunting. Coupled with the fact that companies were laying off workers in large numbers, how do I even tell my mum I'm trying to compete with someone who just left Google or Microsoft? 😂 I realized this and kept using this as an excuse for the massive rejection emails.</p>
<p>A few days into the month, Apple released the iPhone 14 series and other amazing gadgets and it felt like a good time to appreciate the hard work they had put in and purchase a second iPhone. The main reason behind the purchase was my constant nagging about how small my initial device was compared to my palm size, as usual, I randomly stepped into a dealer's shop and performed magic.</p>
<p>I got invited to speak at GDG Enugu Code jam, on "The fun side of Coding, Creative Problem solving". If you asked me what transpired on that virtual call, I shamed myself but na only me notice am. I really didn't have time to think deeply about the topic and the timing too was not the best for me because I was on some mini vacation outside Enugu during that period and had plans to just chill and do less brain work.</p>
<p>About the vacation, I traveled to Owerri and spent most of my days indoors at BonTripod Hotel. If you are looking for a very nice environment and got the money to spend, <a target="_blank" href="https://www.google.com/search?gs_ssp=eJzj4tVP1zc0TCsoKTDIyDI0YLRSNagwNDAxMrVMNjBJszRLSzIxtTKoSEuyTDZJTU01MTEwNU4xsPDiSsrPUygpyizITwEAZuQTIA&amp;q=bon+tripod&amp;oq=bontripod&amp;aqs=chrome.1.69i57j46i13i175i199i512j0i8i13i30i625l2j0i8i13i30.3323j0j1&amp;sourceid=chrome&amp;ie=UTF-8">bon tripod</a> hotel is a place to try out.</p>
<p>Just before the month ended, I started working on <a target="_blank" href="https://github.com/CeoFred/bonpay-ui">Bonpay</a>, which is a crypto payment framework for accepting payments on your existing apps in crypto or NFT. I'm currently looking for designers to jump on this project to create a landing page for this in the spirit of open source. Check out a demo <a target="_blank" href="https://bonpay-js.vercel.app/">here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672487658610/1ed73901-42c3-4d8b-801c-41b29302765f.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672487993363/478dfc04-41a3-4b8f-bb28-94d37f644e70.heic" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672488519148/02312487-29f2-4ca1-b641-bea5fe423da1.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-oct-2022">Oct 2022</h1>
<p>To start the month with bliss, Uche got married to his baby on the 8th of Oct where I served as not just a hot kid but a shameless &amp; humble pilot for his baby.</p>
<p>Still semi-jobless, ASUU decided to call off the 8-months strike without collecting payment, DumbFucks! I'm sorry but hear me out, why would you do shakara and still trip? why? mtcheww .... I wasn't entirely happy with the news because my goal to resume school working in a new web3 role looked far-fetched.</p>
<p>On the 5th of Oct, I finally completed the bonPay project in two weeks and it was ready for production use, it shipped with a web and <a target="_blank" href="https://github.com/CeoFred/bonpay-react">react SDK</a>. Yay!! Felt like codemon again.🫣</p>
<p>Back to the whole job hunting thing, I realized sending applications were no longer working and decided to make use of my network. Reached out to my boss, mentor, and <a target="_blank" href="https://twitter.com/AronuUgochukwu">CEO</a> of <a target="_blank" href="https://xend.finance/">xend finance</a> informing him about my difficulties and need for a new role, he requested what I looked for in a role which I sent in immediately, and after three days he informed me about a possible role coming from a friend of his.</p>
<p>The next Saturday morning, I got a call from Sir Eke who's the <a target="_blank" href="https://twitter.com/eldivyn">CEO</a> of <a target="_blank" href="https://risevest.com/">risevest</a>, and spoke for about 20 mins, there and then was the end of my job hunting. Let me re-phrase something sir Eke said during the call, he said "Feel free to end your job hunting", and this was how I resumed a Senior Blockchain engineering role without any interviews or DSA tests, I also was able to resume school the happiest and most recent employee at <a target="_blank" href="https://twitter.com/assetbaseHQ">assetBase</a>.</p>
<h3 id="heading-others-4">Others</h3>
<ul>
<li><p>Got accepted into the Master track of the Polygon African Bootcamp</p>
</li>
<li><p>Selected to advocate for blockchain adoption as a Mara Campus Campus in FUTO.</p>
</li>
<li><p>My eyesight got bad and visited a clinic for a checkup and expensive test just to be given an eye drop to go home with and return next year.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672489965211/17748195-7870-46d6-8ab8-317cada90035.heic" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672490035983/ea6687fc-aea3-459e-a10d-90f1e55206a2.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672490999846/f39f5169-464d-4139-92d2-401ded44f7a1.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672488752816/762082a2-491d-43c0-866b-4a33d4d1c75a.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672488713884/d3f8d573-fbcf-4115-98d7-6875cc5e49c9.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672490013580/ad131be4-fac9-4d0d-a692-f69e4b203636.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672490151665/8f0a564e-1bdc-4e17-8340-5c9c6e450e7c.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-nov-2022">Nov 2022</h1>
<p>On the 1st of Nov, we lost my own son, ifeanyi Adeleke 😩. How could such a bad thing happen to my own Davido, he's such a good man for God's sake nau!</p>
<p>Back to school, feeling all pumped up and ready to finally finish a 5-year course turned almost 7 years. I resumed on the 4th of Nov and Immediately remembered how terrible my network would get and how many debit alert I would be getting during this period.</p>
<p>A few days after the resumption, Chidera invited me to meet with the core-team members of the GDSC community on campus and that exactly was something I had in mind, reason because I admired the team spirit and needed the same type of energy for the Mara developer community.</p>
<p>Everyone on that team felt normal, just one person's character stood out, not for bad though. <a target="_blank" href="https://twitter.com/Amarasview01">Amarachi</a> pulled up late, and even though she apologized, I was so certain e no really concern her, this move and more made me pick interest to know what was inside the girl's head, but sha na just first impression, nothing much 😂. Although she didn't get to be a campus captain, I made sure she was part of the team.</p>
<p>During the meeting, I did some motivational talks and finally was able to refer a few persons as Mara campus captains, Cisca and Chidera emerged captains thereafter.</p>
<h3 id="heading-register-to-join-mara-on-campus">Register to join Mara on Campus</h3>
<p><a target="_blank" href="https://docs.google.com/forms/d/e/1FAIpQLSfRTJsg-zZX3WAuMhA5eKy7jsLSi2JbHr6JOyEUWDaZgx-kRQ/viewform">https://docs.google.com/forms/d/e/1FAIpQLSfRTJsg-zZX3WAuMhA5eKy7jsLSi2JbHr6JOyEUWDaZgx-kRQ/viewform</a></p>
<p>As a way to show fan love, I mounted a frame of my fav artist just side by side with my own picture frame on my wall, at some point it felt like we had some resemblance but no, it's just my brain playing with me.</p>
<p>Later into the month, specifically on the 21st of Nov, I had my first project defense and it was a success even though I did not have my project ready beforehand.</p>
<h3 id="heading-others-5">Others</h3>
<ul>
<li><p>Spoke at a Twitter Space hosted by sendchamp</p>
</li>
<li><p>Preparations for Mara developer Campus Club meetup started.</p>
</li>
<li><p>Final year exams started on the 28th of Nov.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672490337717/0de9c8a2-330e-4a3c-a1c1-e65e812c6287.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672491112810/eaa12c69-4cb6-4439-bc44-e7093595ac6f.heic" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672491460155/14602dbe-ced1-488b-ab7d-856f2076e611.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672491431116/bebce07e-d30a-4650-852c-25fc1027e664.heic" alt class="image--center mx-auto" /></p>
<h1 id="heading-dec-2022">Dec 2022</h1>
<p>Finally, we are here! Exams, Events, Debits, etc. It was just a lot and remember I still got work to do ooh! Spotify sent in my wrap for the year and I only wondered why Davido did not make number one on my Top Fav Artists, he's number one in my heart always.</p>
<p>GDG Owerri DevFest was on the 10th of Dec and even though I wasn't ready to make any technical presentations, I still ended up taking up the role of " Minister of Enjoyment" and this meant I was going to lose money to make people happy, well played <a target="_blank" href="https://twitter.com/AmadikwaJoy">Joy</a>. Thanks to Chidera and the upper echelons at Google, we were able to transport a good number of students in FUTO, to and fro.</p>
<p>The following day was my fellowship send forth, I attend RCF on campus once once 😂. I left the fellowship with just one friend; Do You remember Faith from the month of March? She's one big aunty in whom I'm well pleased, patronize her.</p>
<p>With an amazing team, together we successfully organized an info session for the Mara Developer Campus Club on the 17th of Dec, and the event was graced by the presence of both <a target="_blank" href="https://twitter.com/olanetsoft">Idris</a> and <a target="_blank" href="https://twitter.com/web3paloma">Paloma</a> who are both Dev Rel and Dev Advocate at mara, respectively. Later that day, I attended a picnic organized by my departmental-level mates because I needed to taste chicken.</p>
<h3 id="heading-others-6">Others</h3>
<ul>
<li><p>9th of Dec, I wrote my last final year exams.</p>
</li>
<li><p>Got a Christmas package from sendchamp.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672491740952/dd1eb595-f464-4e76-be04-9b1accd80844.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672492075365/84af6812-c59e-41e0-ae83-2d7a5b6e4ab9.heic" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672492024125/312eaf4a-dfcd-40ce-8ea6-21c921ba244a.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672492510734/ee5fc667-fd13-4ded-8e54-a85adfacd743.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672492746565/84bf4477-a76d-4016-a877-d70e621f7b65.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672494029592/08ead6d7-e55b-44e5-8ffb-e8419c08cd52.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672494085938/50846ec7-53bb-474d-aa5e-ece0789b87ba.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>I'm eternally grateful to God for the gift of men and for constantly directing my steps in the right direction. I had a wonderful 2022, hope you did too.</p>
<h2 id="heading-shout-out">Shout Out</h2>
<p>To you! Yes, you. For taking out time to read this long article. And to my baby, who's my baby? 😂</p>
<p>Did you get something out of this article? Let me know in the comment section, I'll be happy you did.</p>
<h1 id="heading-plans-for-2023">Plans for 2023</h1>
<ul>
<li><p>Support more people in the web3 Space with my full chest.</p>
</li>
<li><p>Attempt to contribute to the <a target="_blank" href="https://github.com/ethereum/go-ethereum">go-ethereum</a> project.</p>
</li>
<li><p>Move to a new apartment.</p>
</li>
<li><p>Catch more flights.</p>
</li>
<li><p>Improve my technical competence.</p>
</li>
<li><p>Attempt building a startup.</p>
</li>
<li><p>Make more meaningful connections.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Polymorphism in Go lang]]></title><description><![CDATA[Polymorphism is the ability of an object or function to take on multiple forms. In the Go programming language, polymorphism is supported through the use of interfaces.
An interface in Go defines a set of methods that a type must implement to satisfy...]]></description><link>https://blog.codemon.me/polymorphism-in-go-lang</link><guid isPermaLink="true">https://blog.codemon.me/polymorphism-in-go-lang</guid><category><![CDATA[golang]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Tue, 13 Dec 2022 15:13:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1670944393164/Otajlh4kJG.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Polymorphism is the ability of an object or function to take on multiple forms. In the Go programming language, polymorphism is supported through the use of interfaces.</p>
<p>An interface in Go defines a set of methods that a type must implement to satisfy the interface. This means that any type that implements the methods defined in an interface is said to implement the interface.</p>
<p>For example, suppose we have an interface called <code>Shape</code> that defines the methods <code>Area()</code> and <code>Perimeter()</code> for calculating the area and perimeter of a shape. We could define the <code>Shape</code> interface like this:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Shape <span class="hljs-keyword">interface</span> {
    Area() <span class="hljs-keyword">float64</span>
    Perimeter() <span class="hljs-keyword">float64</span>
}
</code></pre>
<p>Now, any type that implements the <code>Area()</code> and <code>Perimeter()</code> methods can be said to implement the <code>Shape</code> interface. For example, we could define a <code>Rectangle</code> type that satisfies the <code>Shape</code> interface like this:</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Rectangle <span class="hljs-keyword">struct</span> {
    width  <span class="hljs-keyword">float64</span>
    height <span class="hljs-keyword">float64</span>
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r *Rectangle)</span> <span class="hljs-title">Area</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> r.width * r.height
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r *Rectangle)</span> <span class="hljs-title">Perimeter</span><span class="hljs-params">()</span> <span class="hljs-title">float64</span></span> {
    <span class="hljs-keyword">return</span> <span class="hljs-number">2</span> * (r.width + r.height)
}
</code></pre>
<p>Here, the <code>Rectangle</code> type implements the <code>Area()</code> and <code>Perimeter()</code> methods, so it satisfies the <code>Shape</code> interface. This means that we can use a <code>Rectangle</code> value wherever a <code>Shape</code> is expected, and the appropriate method will be called automatically.</p>
<p>In this way, polymorphism in Go allows us to write code that can work with multiple types in a consistent manner, without needing to know the specific type of an object at compile time.</p>
<h1 id="heading-example-code">Example Code</h1>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-keyword">type</span> person <span class="hljs-keyword">struct</span>{
    firstname <span class="hljs-keyword">string</span>;
    lastname <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">type</span> human <span class="hljs-keyword">interface</span>{
   talk()
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p person)</span> <span class="hljs-title">talk</span><span class="hljs-params">()</span></span>{
  fmt.Println(<span class="hljs-string">"My name is"</span>, p.firstname)
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    person1 := person{
        firstname: <span class="hljs-string">"Alfred"</span>,
        lastname: <span class="hljs-string">"Johnson-awah"</span>,
    }

    person1.talk()
}
</code></pre>
<p>In the code above we created a person <code>struct</code> which has the <code>firstname</code> and <code>lastname</code>properties. To showcase polymorphism, we created an interface with a function of talk. Lastly, we have implemented the talk function and attached it to a struct type of <code>person</code> . This means that any identifier of type <code>person</code> would always have a method <code>talk</code> and at the end of the day, we can boldly say that the identifier (<code>person1</code> in our case) is of both <code>person</code> and <code>human</code> type, this is polymorphism.</p>
<p>You can still go ahead and add more complex code by implementing type assertion using a <code>switch</code> statement as seen below.</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-keyword">type</span> person <span class="hljs-keyword">struct</span> {
    firstname <span class="hljs-keyword">string</span>
    lastname  <span class="hljs-keyword">string</span>
}

<span class="hljs-keyword">type</span> seniorMan <span class="hljs-keyword">struct</span> {
    person
    hasACar <span class="hljs-keyword">bool</span>
}

<span class="hljs-keyword">type</span> human <span class="hljs-keyword">interface</span> {
    talk()
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p person)</span> <span class="hljs-title">talk</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"My name is"</span>, p.firstname)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(p seniorMan)</span> <span class="hljs-title">talk</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"I am a person and senior man, see my ID"</span>, p, <span class="hljs-string">"and i have a car too"</span>, p.hasACar)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">resolveType</span><span class="hljs-params">(h human)</span></span> {
    <span class="hljs-keyword">switch</span> t := h.(<span class="hljs-keyword">type</span>) {
    <span class="hljs-keyword">case</span> person:
        fmt.Println(<span class="hljs-string">"This is a normal person"</span>, t.firstname)
    <span class="hljs-keyword">case</span> seniorMan:
        fmt.Println(<span class="hljs-string">"This is a senior man, does this person have a car?"</span>, t.hasACar)

    }
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    person1 := person{
        firstname: <span class="hljs-string">"Alfred"</span>,
        lastname:  <span class="hljs-string">"Johnson-awah"</span>,
    }

    seniorMan1 := seniorMan{
        person: person{
            firstname: <span class="hljs-string">"Joe"</span>,
            lastname:  <span class="hljs-string">"Biden"</span>,
        },
        hasACar: <span class="hljs-literal">true</span>,
    }

    resolveType(seniorMan1)
    resolveType(person1)

    person1.talk()
}
</code></pre>
<p>Running this code on the console, your output should be like the below:</p>
<pre><code class="lang-markdown">This is a senior man, does this person have a car? true
This is a normal person Alfred
My name is Alfred
</code></pre>
<p>The <code>seniorMan</code> struct type inherits properties of the <code>person</code> struct type with an additional property <code>hasACar</code> . The most important exerpt of this code is the <code>resolveType</code> function which uses a switch state to person type assertion on interfaces to find out their underlying types and execute the correct block of code.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog post, we learnt about polymorphism and how it stems from interface implementation.</p>
]]></content:encoded></item><item><title><![CDATA[Upgradeable Smart Contract on Polygon Network]]></title><description><![CDATA[Genesis 1:1
In this blog post, we will learn about upgradeable smart contracts, different upgrade patterns, reasons behind smart contract upgrades, and finally, how to utilize the Hardhat framework to aid in deploying and implementing smart contracts...]]></description><link>https://blog.codemon.me/deploy-upgradeable-smart-contract-on-polygon-network</link><guid isPermaLink="true">https://blog.codemon.me/deploy-upgradeable-smart-contract-on-polygon-network</guid><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Sun, 04 Dec 2022 13:40:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/0219d43a55ef29ce299ff0da12b3e09a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-genesis-11">Genesis 1:1</h1>
<p>In this blog post, we will learn about upgradeable smart contracts, different upgrade patterns, reasons behind smart contract upgrades, and finally, how to utilize the Hardhat framework to aid in deploying and implementing smart contracts that can be upgraded or updated. You can always deploy and interact with upgraded smart contracts on different chains or networks, but we would deploy our contracts to the polygon network for speed, low gas fees, and security.</p>
<p>Prerequisites for this article include fundamental knowledge of smart contract development with solidity, some level of familiarity with terminal (bash/cmd), and good knowledge of javascript. Going forward, I'll assume you understand how the blockchain works, have prior programming experience, know what smart contracts are, and have had some time to review some polygon basics.</p>
<p>If you are not interested in the theoretical aspect, feel free to jump to the code section of this blog post and begin to implement an upgradeable smart contract.</p>
<h2 id="heading-what-are-upgradeable-smart-contracts">What are Upgradeable Smart Contracts</h2>
<p>Before proceeding to discuss upgradeable smart contracts, let's briefly talk a bit about some characteristics of smart contracts and the EVM. Smart contracts were created to be immutable once deployed ( assigned a hex address ), for this reason, the term "upgradable smart contracts" might be counterintuitive, but hold on 🫣.</p>
<p>During the process of upgrading smart contracts, you are still following the immutability law of smart contracts, but instead of making changes to the contract to be updated, you replace it with a new copy of a smart contract. It's almost like upgrading your Lexus car; upgrades are typically accomplished through "facelifting," which is the process of removing the old exterior and replacing it with new parts that are similar to those found in a later model of your Lexus car.</p>
<p>Let's quickly see a few reasons why you might want to make your smart contracts upgradeable:</p>
<ul>
<li><p>Bug fixes before an exploit take place. to boost performance.</p>
</li>
<li><p>Modifying functionality that is no longer necessary or deemed useful. to make the code more efficient in its use of Ethereum gas. to adapt to changes in society, markets, or technology. to avoid the necessity of transferring an entire user base to a new version of the application.</p>
</li>
</ul>
<h2 id="heading-how-to-upgrade-smart-contracts">How to upgrade smart contracts</h2>
<p>There exist various methods of implementing upgradeable smart contracts, but all follow the proxy principle. The proxy principle is a software engineering practice that involves eliminating direct messaging or access to another system. For example, instead of sending requests directly to a backend server, there would exist a proxy server that receives this request and later sends it on behalf of the client or sender; this process is called a reverse proxy. A proxy would serve as a middleman between two software programs. A similar approach is implemented for an upgradeable smart contract.</p>
<p>So, in the context of smart contracts, there would be a proxy contract and a logic contract. Dapp users would always interact with the proxy contract, and a similar function call is made on the logic contract. Like any other smart contract, the proxy contract includes functions and data storage. As mentioned initially, users communicate directly with the proxy contract instead of the logic contract, and one would expect that a proxy contract contains similar functions as the logic contract. But that's not the case; I'll explain.</p>
<p>When a function call is made to a proxy contract, the contract checks if that function exists; otherwise, a fallback function is called on the proxy contract. Inside this callback function on the proxy contract are implementations that attempt to call the same function made by the user on the logic contract but in the context of the proxy contract.</p>
<p>In conclusion, utilizing the proxy pattern would include the need for a proxy contract and a logic or implementation contract. It's also important to note that logic contracts are the only ones that would get replaced while keeping the address of the proxy contract the same.</p>
<p>There are three methods of implementing a proxy pattern, which includes:</p>
<ol>
<li><p>Simple Proxy Pattern</p>
</li>
<li><p>Transparent Proxy Pattern</p>
</li>
<li><p>Universal Upgradable Proxy Standard (UUPS)</p>
</li>
</ol>
<p>To save time, we would cover just the simple proxy pattern and the transparent proxy pattern because I am kind enough.</p>
<h3 id="heading-simple-proxy-pattern">Simple Proxy Pattern</h3>
<p>This method of implementing an upgradeable contract basically involves a user directly calling a proxy contract instead of the logic contract. Both the proxy and logic contracts have something in common: an execution context. An execution context is basically an environment or space where code is run. Every smart contract has its own execution context. Also like any other contract, the proxy contract has its own state and by taking advantage of this we can easily replace the logic contract and still retain the state on the proxy contract.</p>
<p>The proxy contract uses storage variables to keep track of the address of the logic smart contract. This is how it can redirect transactions and invoke the relevant logic smart contract. Proxy contracts can make calls to the relevant logic smart contract by making use of something called a [delegateCall] (https://docs.soliditylang.org/en/v0.8.6/introduction-to-smart-contracts.html?highlight=delegatecall#delegatecall-callcode-and-libraries).</p>
<p>A delegate call is somehow different from a regular function call in the sense that the code at the target address is executed in the context of the calling contract. In our case, the code from the logic contract is executed in the context of the proxy contract, and state changes are eventually made on the proxy contract, therefore decoupling the application. If the logic contract’s code is meant to cause a change in storage variables, those changes are reflected in the proxy contract’s storage variables, i.e., in the proxy contract’s state.</p>
<p>From the look of things, we can refer to the proxy contract as the data contract, and for this reason, the proxy contract should not be replaced but rather the logic contract.</p>
<p>When the proxy contract receives a function call for a function that it does not support, the proxy contract’s fallback function will be invoked to handle that function. The proxy contract uses custom logic inside its fallback function, where a delegate call would be implemented to redirect calls to logic contracts.</p>
<p>Now that the application state and the application logic are decoupled in the EVM, we can upgrade the application by changing the logic contracts and giving the new addresses to the proxy. But the application’s state isn’t affected by this upgrade.</p>
<h2 id="heading-transparent-proxy-pattern">Transparent Proxy Pattern</h2>
<p>Function calls initiated by the end user are always routed to the logic contract rather than the proxy contract. If the caller is an administrator of the proxy, however, the proxy will invoke its own administrative function.</p>
<p>Calling administrative functions in the proxy contract to manage upgradeability and other administrative tasks should only be performed by an administrator, and if a conflict occurs, it is reasonable to assume that the administrator intended to call the proxy contract's function and not the logic contract's function. If the caller is a non-administrator address, however, the proxy will always delegate the call to the relevant logic contract. The caller can be identified by examining the <code>message.sender</code> value.</p>
<p>In this pattern, the proxy contract would have logic in its fallback function to parse message.sender and the function selector that is being called, and accordingly invoke one of its own functions or delegate out to a logic contract.</p>
<h2 id="heading-code-time-upgradeable-smart-contracts-with-hardhat">Code Time: Upgradeable smart contracts with hardhat</h2>
<p>In this section, we will be making use of the transparent proxy pattern, utilizing contracts from OpenZeppelin and Hardhat for development.</p>
<p>Within the Hardhat development tool lie functions like deployProxy that track the logic contract for us and give us easy access to upgrade functionality. By default, the address that deployed the contract is the one that has admin rights to upgrade it.</p>
<p>To create a new Hardhat project, create a new directory and name it whatever you want, then copy and run the commands below.</p>
<pre><code class="lang-plaintext"> npm init --y
</code></pre>
<pre><code class="lang-plaintext"> yarn add -D @openzeppelin/contracts-upgradeable @openzeppelin/hardhat-upgrades @nomiclabs/hardhat-ethers ethers dotenv
</code></pre>
<p>The first command will simply generate an empty npm project without going through an interactive process. The y stands for yes. The latter will download the necessary dependencies for our project.</p>
<p>Finally, to complete the setup for hardhat, run <code>yarn hardhat</code>, you'll be faced with an interactive terminal. Create a javascript project, place the hardhat project at the root, add a .gitignore file and you should be good to go.</p>
<p>This command would create a default ``hardhat.config.js```. This file created would be placed at the root of your project directory and comes along with some default settings which you should overwrite by pasting in the code below.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">require</span>(<span class="hljs-string">'dotenv'</span>).config()
<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-keyword">const</span> MUMBAI_RPC_URL = process.env.MUMBAI_RPC_URL
<span class="hljs-keyword">const</span> PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY_DEV;

<span class="hljs-built_in">module</span>.exports = {
 <span class="hljs-attr">solidity</span>: <span class="hljs-string">"0.8.17"</span>,
 <span class="hljs-attr">defaultNetwork</span>: <span class="hljs-string">"mumbai"</span>,
 <span class="hljs-attr">networks</span>: {
   <span class="hljs-attr">localhost</span>: {
     <span class="hljs-attr">chainId</span>: <span class="hljs-number">31337</span>,
   },
   <span class="hljs-attr">mumbai</span>: {
     <span class="hljs-attr">url</span>: MUMBAI_RPC_URL,
     <span class="hljs-attr">accounts</span>: PRIVATE_KEY ? [PRIVATE_KEY] : [],
     <span class="hljs-attr">chainId</span>: <span class="hljs-number">80001</span>,
   },
 }
};
</code></pre>
<p>Mumbai is the testnet for the polygon network, to get an RPC URL head to <a target="_blank" href="https://dashboard.alchemy.com/">alchemy</a> and create a new app setting the network to Polygon Mumbai, then copy the HTTPS URL and paste it into your <code>.env</code> file. Your <code>.env</code> file should be placed at the root of your project and should have contents like:</p>
<pre><code class="lang-plaintext">MUMBAI_RPC_URL=https://polygon-mumbai.g.alchemy.com/v2/&lt;APIKAY&gt;
WALLET_PRIVATE_KEY_DEV=&lt;YourPrivateKey&gt;
</code></pre>
<p>You can test your setup by compiling the contracts created for you by running the command: <code>yarn hardhat compile</code> . This would compile all contract files in the <code>contracts</code> directory if it has not compiled the files in that folder before or one of the solidity files has changed beforehand, you have two new folders, “Artifacts” and “cache,” in your project directory.</p>
<p>Next, we would make use of the existing contract created for us by hardhat and prepare this contract to be upgradeable. To make this happen, the <code>Lock</code> contract needs to inherit the <code>Initializable</code> from openzeppelin upgradeable contract and lastly, create one important function with a name <code>initialize</code>. Copy and Paste the code below into your <code>contracts/Lock.sol</code> file and after that, I'll explain some important patterns noticed.</p>
<pre><code class="lang-solidity"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.9;</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"</span>;
<span class="hljs-comment">// Uncomment this line to use console.log</span>
<span class="hljs-comment">// import "hardhat/console.sol";</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Lock</span> <span class="hljs-keyword">is</span> <span class="hljs-title">Initializable</span> </span>{
    <span class="hljs-keyword">uint</span> <span class="hljs-keyword">public</span> unlockTime;
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> <span class="hljs-keyword">public</span> owner;
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> <span class="hljs-keyword">private</span> admin;

    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">Withdrawal</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> amount, <span class="hljs-keyword">uint</span> when</span>)</span>;

   <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initialize</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _admin</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">initializer</span> </span>{
       admin <span class="hljs-operator">=</span> <span class="hljs-keyword">payable</span>(_admin);
       owner <span class="hljs-operator">=</span> <span class="hljs-keyword">payable</span>(_admin);
   }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdraw</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        <span class="hljs-comment">// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal</span>
        <span class="hljs-comment">// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);</span>

        <span class="hljs-built_in">require</span>(<span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span> <span class="hljs-operator">&gt;</span><span class="hljs-operator">=</span> unlockTime, <span class="hljs-string">"You can't withdraw yet"</span>);
        <span class="hljs-built_in">require</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span> owner, <span class="hljs-string">"You aren't the owner"</span>);

        <span class="hljs-keyword">emit</span> Withdrawal(<span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>).<span class="hljs-built_in">balance</span>, <span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span>);

        owner.<span class="hljs-built_in">transfer</span>(<span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>).<span class="hljs-built_in">balance</span>);
    }
}
</code></pre>
<p>One thing to notice is that this contract does not have a <code>constructor</code> function which is weird. The reason behind this stems from a rule which states that when using Open Zeppelin upgradable contracts, we cannot include a constructor in our smart contracts.</p>
<p>Instead, we create our own construtor-like functionality by extending the Initializable base contract, which helps us apply an initializer modifier to the <code>initialize()</code> function. We can name the initialize function anything we like, but by using initialize, the Hardhat plugin will recognize it and will call that function by default. If we have an initializer function by another name, we would need to specify the name of our initializer. OpenZeppelin Contracts provides the Initializable base contract that allows you to tag a method as initializer, ensuring it can be run only once.</p>
<h3 id="heading-deploy-contract">Deploy Contract</h3>
<p>When deploying this contract, we will need to specify the initializer function name (only when the name is not the default of initialize) and provide the admin address that we want to use. To deploy our contract, we need to update the deploy script found in <code>scripts/deploy.js</code>, copy and paste the code below into the deploy file.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// The Open Zeppelin upgrades plugin adds the `upgrades` property</span>
<span class="hljs-comment">// to the Hardhat Runtime Environment.</span>
<span class="hljs-keyword">const</span> { ethers, network, upgrades } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</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">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">var</span> dir = <span class="hljs-string">'./deployed'</span>;

  <span class="hljs-keyword">if</span> (!fs.existsSync(dir)){
    fs.mkdirSync(dir);
  }


 <span class="hljs-comment">// Obtain reference to contract and ABI.</span>
 <span class="hljs-keyword">const</span> LockContract = <span class="hljs-keyword">await</span> ethers.getContractFactory(<span class="hljs-string">"Lock"</span>);
 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Deploying Lock to "</span>, network.name);

 <span class="hljs-comment">// Get the first account from the list of 20 created for you by Hardhat</span>
 <span class="hljs-keyword">const</span> [account1] = <span class="hljs-keyword">await</span> ethers.getSigners();

 <span class="hljs-comment">//  Deploy logic contract using the proxy pattern.</span>
 <span class="hljs-keyword">const</span> LockContract_ = <span class="hljs-keyword">await</span> upgrades.deployProxy(
   LockContract,

   <span class="hljs-comment">//Since the logic contract has an initialize() function</span>
   <span class="hljs-comment">// we need to pass in the arguments to the initialize()</span>
   <span class="hljs-comment">// function here.</span>
   [account1.address],

   <span class="hljs-comment">// We don't need to expressly specify this</span>
   <span class="hljs-comment">// as the Hardhat runtime will default to the name 'initialize'</span>
   { <span class="hljs-attr">initializer</span>: <span class="hljs-string">"initialize"</span> }
 );
 <span class="hljs-keyword">await</span> LockContract_.deployed();
  <span class="hljs-keyword">await</span> fs.writeFileSync(<span class="hljs-string">`<span class="hljs-subst">${dir}</span>/proxy.txt`</span>,LockContract_.address)

 <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"LockContract deployed to:"</span>, LockContract_.address);
}

main();
</code></pre>
<p>In other to run the script and deploy our contract to the mumbai testnet, we make use of hardhat on the terminal by running the following command:</p>
<pre><code class="lang-plaintext">yarn hardhat run ./scripts/deploy.js
</code></pre>
<p>The script does a couple of interesting things:</p>
<ol>
<li><p>Creates a text file under a directory where we save our deployed proxy address for easy retrieval.</p>
</li>
<li><p>Deploys our logic contract using proxy pattern and contracts interface by open zeppelin.</p>
</li>
<li><p>Initialize the contract by setting your wallet address as the admin.</p>
</li>
<li><p>Saves the address of our proxy/data contract to a file in our working directory.</p>
</li>
</ol>
<h3 id="heading-upgrade-contract">Upgrade Contract</h3>
<p>Previously we have deployed our logic contract using the proxy pattern and saved our address to a file. Moving forward, let's create an upgraded version of the lock contract. Create a new file under the <code>contracts</code> folder and name it <code>contracts/upgrade_lock.sol</code>, copy and paste the upgraded contents and we would review the code in a bit.</p>
<pre><code class="lang-solidity"><span class="hljs-comment">// SPDX-License-Identifier: UNLICENSED</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.9;</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"</span>;
<span class="hljs-comment">// Uncomment this line to use console.log</span>
<span class="hljs-comment">// import "hardhat/console.sol";</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">UpgradedLock</span> <span class="hljs-keyword">is</span> <span class="hljs-title">Initializable</span> </span>{
    <span class="hljs-keyword">uint</span> <span class="hljs-keyword">public</span> unlockTime;
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> <span class="hljs-keyword">public</span> owner;
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> <span class="hljs-keyword">private</span> admin;

    <span class="hljs-keyword">uint</span> <span class="hljs-keyword">public</span> ownerBalance;

    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">Withdrawal</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> amount, <span class="hljs-keyword">uint</span> when</span>)</span>;

   <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initialize</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _admin</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">initializer</span> </span>{
       admin <span class="hljs-operator">=</span> <span class="hljs-keyword">payable</span>(_admin);
       owner <span class="hljs-operator">=</span> <span class="hljs-keyword">payable</span>(_admin);
       unlockTime <span class="hljs-operator">=</span> <span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span>;
       ownerBalance <span class="hljs-operator">=</span> <span class="hljs-number">50</span>;
   }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdraw</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> amount</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{

        <span class="hljs-built_in">require</span>(<span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span> <span class="hljs-operator">&gt;</span><span class="hljs-operator">=</span> unlockTime, <span class="hljs-string">"You can't withdraw yet"</span>);
        <span class="hljs-built_in">require</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span> owner, <span class="hljs-string">"You aren't the owner"</span>);
        <span class="hljs-built_in">require</span>(ownerBalance<span class="hljs-operator">-</span>amount <span class="hljs-operator">&gt;</span> amount, <span class="hljs-string">"You can't withdraw that amount,too much"</span>);
        <span class="hljs-keyword">emit</span> Withdrawal(amount, <span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span>);

        ownerBalance <span class="hljs-operator">-</span><span class="hljs-operator">=</span> amount;
    }
}
</code></pre>
<p>In our previous Lock contract, the withdraw function was defined in such a way that it would drain the contract's funds and send them to the owner. But in our current implementation of the upgraded Lock contract, we want the owner to specify the amount they wish to withdraw and also introduced a new variable to track the amount the owner has left which we can later on read because it is a public variable.</p>
<p>Now we have our upgraded Contract, it's time to actually write a script that would help us to upgrade our previous logic contract with a new and improved version. To do this, create a new script file and call this one <code>scripts/upgrade_lock.js</code> , then copy and paste the code below.</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> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">"fs"</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> deployedProxyAddress = fs.readFileSync(<span class="hljs-string">'./deployed/proxy.txt'</span>,{
    <span class="hljs-attr">encoding</span>: <span class="hljs-string">'utf8'</span>
  })
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Lock Contract Proxy Address: '</span> + deployedProxyAddress)

  <span class="hljs-keyword">const</span> UpgradedLockV2 = <span class="hljs-keyword">await</span> ethers.getContractFactory(
    <span class="hljs-string">"UpgradedLock"</span>
  );

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Upgrading Lock Contract to V2..."</span>);

  <span class="hljs-keyword">await</span> upgrades.upgradeProxy(deployedProxyAddress, UpgradedLockV2);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Lock Proxy upgraded"</span>);
}

main();
</code></pre>
<p>In the above script we retrieve our proxy address previously deployed from the text file and supply it to the <code>upgradeProxy</code> function together with the contract factory of the new version of our Lock contract. Now everything looks good and ready, you can now run and upgrade your lock contract by running the following command below.</p>
<pre><code class="lang-javascript">yarn hardhat run ./scripts/upgrade_lock.js
</code></pre>
<p>If your script runs successfully, your terminal should have a similar output as below but a different proxy contract address.</p>
<pre><code class="lang-javascript">Lock Contract <span class="hljs-built_in">Proxy</span> Address: <span class="hljs-number">0x7C40C2af5073132f5C3c5cc04A270a8104Dd5E19</span> 
Upgrading Lock Contract...
Lock <span class="hljs-built_in">Proxy</span> upgraded
✨  Done <span class="hljs-keyword">in</span> <span class="hljs-number">55.41</span>s.
</code></pre>
<p>To actually verify that the contract has been upgraded, you shouldd visit the address on polygon ether scan and navigate to the events tab where you would see the latest event emitted, which is a <code>deployed</code> event. In my case the url for my deployed contract is <a target="_blank" href="https://mumbai.polygonscan.com/address/0x7C40C2af5073132f5C3c5cc04A270a8104Dd5E19#events">https://mumbai.polygonscan.com/address/0x7C40C2af5073132f5C3c5cc04A270a8104Dd5E19#events</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1670158048069/N4xO9Md3k.png" alt /></p>
<p>You probably noticed the highlighted address, this is the address of the upgraded contract. So this obviously means that for every upgrade, there's a new implementation contract deployed and this is the only address that gets to change, the proxy contract address always remains constant.</p>
<h3 id="heading-interact-with-deployed-contract">Interact with deployed contract</h3>
<p>To interact with our deployed contract, it's usually easier to visit the address on the block explorer and play with the contracts method but in this case, it's going to be a little bit technical to carry out because we are dealing with proxy contracts and we also have imports from GitHub which would also be an issue at some point and would require getting API keys from polygon scan. So to tackle this, we are going to be interacting with our contract using the hardhat tool on the terminal.</p>
<p>Now let’s use the Hardhat console to interact with the upgraded contract.</p>
<p>Run the following command to enter into hardhats interactive node environment.</p>
<pre><code class="lang-javascript">yarn hardhat <span class="hljs-built_in">console</span>
</code></pre>
<p>Your output should look like blow:</p>
<pre><code class="lang-javascript">Welcome to Node.js v14<span class="hljs-number">.19</span><span class="hljs-number">.3</span>.
Type <span class="hljs-string">".help"</span> <span class="hljs-keyword">for</span> more information.
&gt;
</code></pre>
<p>Currently, the terminal expects some javascript code and right now, we are set to start writing some code, something you probably are already used to. You can copy and paste the following code into your terminal.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> LockV2 = <span class="hljs-keyword">await</span> ethers.getContractFactory(<span class="hljs-string">"UpgradedLock"</span>)

 <span class="hljs-keyword">const</span> deployedlockV2 = <span class="hljs-keyword">await</span> LockV2.attach(<span class="hljs-string">"0x7C40C2af5073132f5C3c5cc04A270a8104Dd5E19"</span>)

 <span class="hljs-keyword">await</span> deployedlockV2.withdraw(<span class="hljs-number">1</span>)

 <span class="hljs-keyword">let</span> currentBalance =  <span class="hljs-keyword">await</span> deployedlockV2.ownerBalance()
</code></pre>
<p>Here's a brief explanation of what's going on there:</p>
<ul>
<li><p>We are getting the upgraded contract factory.</p>
</li>
<li><p>Attaching the deployed proxy address to the contract factory.</p>
</li>
<li><p>Call the withdraw function.</p>
</li>
<li><p>check the new balance of the owner.</p>
</li>
</ul>
<p>You might end up with a fail transaction due to errors from your HttpProvider, alchemy. One solution to this is to change to another provider or switch to the goerli test net and make sure to update your RPC URL with one that interacts with the Ethereum goerli network.</p>
<h2 id="heading-why-polygon">Why Polygon?</h2>
<p>Things are hard, why make life even harder for yourself or your team? There are a couple of drawbacks with most blockchain networks which include the High cost of transactions on-chain, very slow speed, security concerns, etc. Deploying on the polygon network gives you unbeatable access to very low transaction cost ( almost costs nothing), super fast transaction settlement, high throughput, and still implements the best of security strategies (zk proofs). Polygon offers a variety of solutions for everyone including the polygon supernet, polygon zkEVM, which I strongly recommend you check out and explore one of these unique products and what they have to offer. Want to get started with polygon? Visit their <a target="_blank" href="https://polygon.technology">website</a> today and thank me later.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this long blog post, we have learned how to use the hardhat development framework to deploy smart contracts, upgrade a smart contract using the Transparent proxy pattern, view and read events on the block explorer and finally interact with your deployed contract via the hardhat interactive console. I hope you've learned a couple of new things, in case you have issues with running the code feel free to drop a comment or reach out to me on Twitter. Here's a <a target="_blank" href="https://github.com/CeoFred/upgradeable-contract">link</a> to the repository that contains all the code in this tutorial.</p>
]]></content:encoded></item><item><title><![CDATA[Openzeppelin Defender]]></title><description><![CDATA[Are you a seasoned smart contract developer or a regular subscriber to the "Patrick collins" youtube channel? Then you probably have heard about OpenZeppelin, or even used some solutions and products by this amazing web3 company. Just in case you are...]]></description><link>https://blog.codemon.me/openzeppelin-defender</link><guid isPermaLink="true">https://blog.codemon.me/openzeppelin-defender</guid><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Fri, 09 Sep 2022 18:10:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662747001553/MtWOwvW4V.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you a seasoned smart contract developer or a regular subscriber to the "Patrick collins" <a target="_blank" href="https://www.youtube.com/c/PatrickCollins">youtube</a> channel? Then you probably have heard about OpenZeppelin, or even used some solutions and products by this amazing web3 company. Just in case you are a first-timer, like in any formal gathering, I'll give you a rundown of OpenZeppelin, just basically what they do, and finally, we would talk about the " OpenZeppelin Defender " product in detail.</p>
<h1 id="heading-what-is-openzeppelin">What is OpenZeppelin</h1>
<p>The standard for secure blockchain applications. <a target="_blank" href="https://www.openzeppelin.com">OpenZeppelin</a> provides security products to build, automate, and operate decentralized applications. They also protect leading organizations by performing security audits on their systems and products. Cool yeah? Openzeppelin provides standard interfaces that smart contract developers can use to build tokens of various ERC standards.</p>
<h3 id="heading-build-secure-smart-contracts-in-solidity">Build Secure Smart Contracts in Solidity</h3>
<p>OpenZeppelin Contracts helps you minimize risk by using battle-tested libraries of smart contracts for Ethereum and other blockchains. It includes the most used implementations of ERC standards. If you are feeling like you've been doing things the wrong way, now is the time to repent, get started with using <a target="_blank" href="https://www.openzeppelin.com/contracts">Openzeppelin </a> contracts today.</p>
<h1 id="heading-openzeppelin-defender">Openzeppelin Defender</h1>
<p>Now you know a little bit about openzeppelin, it's about time to talk about Openzeppelin Defender. Going further I'll be referring to "Openzeppelin Defender
" as just "defender". Defender is a web application that helps you to manage your already deployed smart contract with lower risk, on most EVM-compatible chains. Defender comes with four different sub-features which include admin, relay, autotask, and sentinel. We'll go through each of these sub-features one after the other and in another blog post, I'll explain how to use these individual sub-features.</p>
<h3 id="heading-admin">Admin</h3>
<p>The admin feature in defender provides an interface to automate and secure all your smart contract administration. Administration mistakes on protocols and applications put user funds at risk. With Defender Admin, you can seamlessly manage all smart contract administration including access controls, upgrades, and pausing. And one exciting thing is that it works with popular multi-sigs including Gnosis Safe. With admin, you get to add contracts using the address and create proposals. </p>
<p>A proposal is basically a request to make certain administrative function calls to the contract. It would typically include functions from your contract that modifies the state of your contract. To get the best out of this feature, it's recommended that your contract is EIP-1967 compliant. You can still add a contract to Defender Admin and run admin operations on it. Proposals must be approved by all admins before the function in there can be executed. </p>
<h3 id="heading-relay">Relay</h3>
<p>The Defender Relay service allows you to send transactions via a simple HTTP API or directly from your Autotasks, via unique accounts assigned exclusively to you. Relay takes care of private key secure storage, transaction signing, nonce management, gas price estimation, and resubmissions. Another good side is, all your transactions are broadcasted through multiple network providers for high availability. With relayers in the picture, you don’t need to worry about securing your private keys in your backend scripts or monitoring your transactions to ensure they get mined. Relayers are perfect solutions for most back-end tasks such as air-dropping NFTs, moving funds, and administrative management for your protocol. In conclusion, relay eliminates the need to use private keys which usually would serve as a signer or provider on your back-end during transaction calls.</p>
<h3 id="heading-autotasks">Autotasks</h3>
<p>Just as the name implies, autotasks allow users to schedule and automate calls to the smart contract. Think of cron jobs for your contracts. In a nutshell, an Autotask is a snippet of javascript code invoked at a regular interval, similar to a serverless function. And as a matter of fact, they are implemented with Lambda functions. With Autotasks, you can also use features from the relay service as well, the defender has a way to connect the two to create magic. Autotasks are quite interesting and I'll dedicate a whole article talking about how to get the best out of them.</p>
<h3 id="heading-sentinel">Sentinel</h3>
<p>The sentinel services offer transaction monitoring capabilities to your smart contracts based on certain pre-defined conditions. Conditions could be when an event has been triggered, a function has been called, or transaction calls with certain critical parameters. You can use Sentinel to report to the government a suspicious transaction that has occurred. Sentinels do not stop a transaction from occurring, they basically let you know certain conditions were met during a transaction or function call. For instance, you want to get an alert when an address deposits a particular amount of ether to your contract. Notifications to such triggers can be gotten via email, slack, discord, datadog, or telegram.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Defender provides components that you probably have written yourself, you should consider moving that to a more secure and battle-tested platform and save yourself the thought of things going wrong with your implementation. To me, the defender is a mini cloud service provider and another awesome web2/3 implementation. </p>
<p>Lastly, if any of these four components interests you and would want to ensure I make a dedicated blog post for each of them, leave a comment below and that would make sure they would leave my drafts. See you on the other side 🇳🇬.</p>
]]></content:encoded></item><item><title><![CDATA[Two Number Sum]]></title><description><![CDATA[The Question

Write a function that takes in a non-empty array of distinct integers and an
  integer representing a target sum. If any two numbers in the input array sum
  up to the target sum, the function should return them in an array, in any
  or...]]></description><link>https://blog.codemon.me/two-number-sum</link><guid isPermaLink="true">https://blog.codemon.me/two-number-sum</guid><category><![CDATA[algorithms]]></category><category><![CDATA[hashmap]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Thu, 04 Aug 2022 20:47:06 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-the-question">The Question</h1>
<blockquote>
<p><strong><em>Write a function that takes in a non-empty array of distinct integers and an
  integer representing a target sum. If any two numbers in the input array sum
  up to the target sum, the function should return them in an array, in any
  order. If no two numbers sum up to the target sum, the function should return
  an empty array.</em></strong></p>
<p>Note that the target sum has to be obtained by summing two different integers
in the array; you can't add a single integer to itself in order to obtain the
target sum.</p>
</blockquote>
<h2 id="heading-explaining-the-problem">Explaining the Problem</h2>
<p>The task is to find two unique numbers from an array that would sum up to a particular target value given. These two numbers that sum up to the target value must be different and should be part of the unique numbers in the given array.</p>
<p>Check this example input, given <code>[1,2,3,4,5]</code> as the array and 8 as the target value. Two different numbers from this array should sum up to 8. In this case, the two numbers are 5 and 3, so <code>[5,3]</code> is the expected output.</p>
<h2 id="heading-solution-1-hashmap-o1">Solution 1 ( hashMap ) O(1)</h2>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">twoNumberSum</span>(<span class="hljs-params">array, targetSum</span>) </span>{
  <span class="hljs-comment">// Write your code here.</span>
  const availableNumbersInArray <span class="hljs-operator">=</span> {};
    <span class="hljs-comment">// [1,2,3,4,5] is the array </span>
    <span class="hljs-keyword">for</span> (let index <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; index <span class="hljs-operator">&lt;</span> array.<span class="hljs-built_in">length</span> ; index<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
      <span class="hljs-comment">// assume we are at the fourth index</span>
      const currentNum <span class="hljs-operator">=</span> array[index];  <span class="hljs-comment">// 5</span>
      const numberToLookFor <span class="hljs-operator">=</span> targetSum <span class="hljs-operator">-</span> currentNum; <span class="hljs-comment">// 3 = 8 -5</span>

      <span class="hljs-keyword">if</span>(numberToLookFor in availableNumbersInArray){ 
<span class="hljs-comment">// 3 would have been added to the hashmap so the</span>
<span class="hljs-comment">//  pair 5 and 3 are valid, because both are in </span>
<span class="hljs-comment">// the array and sum up to 8</span>
        <span class="hljs-keyword">return</span> [numberToLookFor, currentNum]
      } <span class="hljs-keyword">else</span> {
        availableNumbersInArray[currentNum] <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>; 
<span class="hljs-comment">// assume index 0 to 3 got to this point and were</span>
<span class="hljs-comment">// added to the hash map making them valid</span>
      }

    }
  <span class="hljs-keyword">return</span> [];
}
</code></pre><h3 id="heading-explanation">Explanation</h3>
<pre><code><span class="hljs-keyword">const</span> availableNumbersInArray = {}
</code></pre><p>We create a hashmap or object to easily store all available numbers in the array for future reference. We could easily discard this and just make use of the <code>.includes()</code> function. But this is not optimal, unlike searching in a hashmap that is just O(1).</p>
<pre><code>   <span class="hljs-keyword">for</span> (let index <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; index <span class="hljs-operator">&lt;</span> array.<span class="hljs-built_in">length</span> ; index<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
</code></pre><p>Regular looping using a for loop ( very efficient way to loop anyways)</p>
<pre><code>  <span class="hljs-keyword">const</span> currentNum = <span class="hljs-keyword">array</span>[index];
      <span class="hljs-keyword">const</span> numberToLookFor = targetSum - currentNum;
</code></pre><p><code>currentNum</code> is the current number the loop is currently at. Next, let's create a simple logical formula, basic maths. Initially, we are looking for two numbers whose sum would lead to the <code>targetSum</code>. i.e <code>currentNum + y = targetSum</code> , therefore <code>y = targetSum - currentNum</code>.  So when we get the value of <code>y</code> , this means that it's a valid pair that when added together  with <code>currentNum</code> would give the <code>targetSum</code>. </p>
<p>That answer <code>y</code> is the step one to finding a solution and we could actually just return <code>y</code> and <code>currentNum</code> because they sum up to the target. But the question is this, is the value <code>y</code> in the array given?? That's where the next line of code comes in.</p>
<pre><code>     <span class="hljs-selector-tag">if</span>(numberToLookFor in availableNumbersInArray){
        <span class="hljs-selector-tag">return</span> <span class="hljs-selector-attr">[numberToLookFor, currentNum]</span>
</code></pre><p>Here, we are checking to see if <code>numberToLookFor</code> is actually a number in the array we are working with. In the simple formula we created above, we want to check if <code>y</code> is in the given array. <code>y</code> would represent <code>numberToLookFor</code> in our case.  If we have the number stored yet, then we can return the two numbers. Else, we add the current number to the hash map created, meaning the <code>currentNum</code> is available to be paired with and it's a valid number from the array.</p>
<pre><code>
<span class="hljs-keyword">else</span> {
        availableNumbersInArray[currentNum] = <span class="hljs-keyword">true</span>; // number <span class="hljs-keyword">is</span> <span class="hljs-keyword">in</span> <span class="hljs-keyword">array</span>
      }
</code></pre><p>Like said earlier, we just saying that the <code>currentNum</code>  is a valid number from the array. and could be a valid and accurate pair that can be summed up with another number being looped through to get the <code>targetSum</code>. </p>
<p>Again, all we are saying is, " hey! this <code>currentNum</code> is in the array we are working with, so do me a favor and keep this in mind just in case you come across this number and it's the same as the solution to <code>const numberToLookFor = targetSum - currentNum;</code> in a future interation.</p>
<h2 id="heading-solution-2-arrayincludes-on">Solution 2 ( Array.includes) O(n)</h2>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">twoNumberSum</span>(<span class="hljs-params">array, targetSum</span>) </span>{
  <span class="hljs-comment">// Write your code here.</span>
   let pairs <span class="hljs-operator">=</span> [];

      <span class="hljs-keyword">for</span> (let index <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; index <span class="hljs-operator">&lt;</span> array.<span class="hljs-built_in">length</span>; index<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
          const currentNum <span class="hljs-operator">=</span> array[index];
          const  pair <span class="hljs-operator">=</span> targetSum <span class="hljs-operator">-</span> currentNum; 
          <span class="hljs-keyword">if</span>(array.includes(pair) <span class="hljs-operator">&amp;</span><span class="hljs-operator">&amp;</span> pair <span class="hljs-operator">!</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> currentNum){
            pairs <span class="hljs-operator">=</span> [pair, currentNum]
         }
      }
  <span class="hljs-keyword">return</span> pairs;
}
</code></pre><p>This is similar to solution 1 but we are using the <code>array.includes()</code> method.</p>
<h2 id="heading-solution-3-two-loops-on2">Solution 3 ( Two Loops ) O(n^2)</h2>
<p>Don't bother about this solution 😪</p>
]]></content:encoded></item><item><title><![CDATA[Hash Tables]]></title><description><![CDATA[What's a Hash Table
This is a data structure seen and proven to be very efficient for data storage, insertion, and retrieval. Unlike an array data structure, hash tables store their data in a key to value pair format, at least on a higher level. 
Con...]]></description><link>https://blog.codemon.me/hash-tables</link><guid isPermaLink="true">https://blog.codemon.me/hash-tables</guid><category><![CDATA[algorithms]]></category><category><![CDATA[Hashing]]></category><category><![CDATA[data structures]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Thu, 04 Aug 2022 16:19:17 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-whats-a-hash-table">What's a Hash Table</h2>
<p>This is a data structure seen and proven to be very efficient for data storage, insertion, and retrieval. Unlike an array data structure, hash tables store their data in a key to value pair format, at least on a higher level. </p>
<p>Conceptually, if you need to store a value in a hash table, a key that serves as a pointer is required. For example, say you want to store a users information which includes their name, age, and gender in a hash table, we could have a structure like the below:</p>
<pre><code><span class="hljs-comment">// user data</span>
 <span class="hljs-string">"name"</span> <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> <span class="hljs-string">"Alfred"</span>
  <span class="hljs-string">"age"</span> <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> <span class="hljs-string">"22"</span>
  <span class="hljs-string">"gender"</span> <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> <span class="hljs-string">"male"</span>
</code></pre><p>From the above, we've mapped specific data about a user by pointing a value to a key ( I call this an identity ). We'll look at this data structure in depth in more sections.</p>
<h2 id="heading-the-underlying-structure-of-a-hash-table">The underlying structure of a hash table</h2>
<p>Hash tables are typically a dynamic array of linked lists, where an item has to form a linked list type of data structure at a given index.</p>
<h2 id="heading-the-big-o-notation">The Big O Notation</h2>
<p>For inserting, retrieving, and deleting an item, a hash table offers a time complexity of O(1) on an average, this could change to O(n) considering edge cases which I'll explain in a bit.</p>
<h2 id="heading-inserting-an-item-into-a-hash-table">Inserting an item into a hash table.</h2>
<p>Remember we said hash tables have key =&gt; value pair type of data structure, and this key could either be a string or a number. In some programming languages, it could be just more than just a string or a number. </p>
<p>Let's say we want to create a hash table data structure for a car. Assuming we want to store the model of my Ferrari, what happens under the hood is this,</p>
<ul>
<li><p>We have a key/value pair like  <code>"model" =&gt; "Ferrari</code>. </p>
</li>
<li><p>Then the key, which is "model" (a string) is passed through a hashing function to produce an integer, this integer represents the index where the value would be stored in an array. Now you see where the name "hash" comes from. </p>
</li>
</ul>
<p>A hash function receives input and performs mathematical operations on the input to produce an output. There a various hash function algorithms implemented by really smart people and they are very powerful. Maybe in our case, our hash function operation converts each string item to its ASCII value and sums them up to produce a value.</p>
<p>For instance, assuming our key "model"  represents "30121", the sum of each individual string item in their respective ASCII format would be the number "7". So the value "Ferrari" would be stored at index 7. Now there's an edge case, it's possible that two strings produce the same output "7" after hashing, this is called a collision.</p>
<p> In such a case, this is where the linked list data structure comes in, at each index in the array we have a linked list that contains values that point to each other.</p>
<p>In real life, hash functions are extremely powerful to avoid such collisions and produce unique integer values. Note that the hashing function also takes note of the size of the underlying array to create a number, not more than the length of the array. </p>
<h3 id="heading-the-resizing-case">The resizing case</h3>
<p>Let's say we have an underlying array of length 3 which has just 3 key =&gt; value pairs, this would fit in well into that array after hashing and there's no collision. This means that retrieving would be O(1) because, at each index, we have just one node in the linked list. </p>
<p>Assuming we have 100 keys to store in this same array of length 3, they could fit in well after hashing but we would end up with at least 30 nodes for a linked list in indexes 1,2, and 3. Having 30 nodes or a long linked list makes retrieving, inserting, and deleting an O(n) time operation which is a linear time operation, not very efficient. </p>
<p>To fix this, hash tables are smart enough to resize the array and eliminate a long linked list. There are various ways to implement resizing in hash tables but let's look at a simple implementation of resizing. </p>
<p>Let's say your array has a length of 10, as you insert key=&gt;values into the array and get filled to 70% or 80% (index 7 or 8), your hash table is going to be smart enough to know that it has to resize itself by maybe creating a copy of the array and doubling its size then performs a new hashing on previous keys and fills them up into the newly created array, leaving no room for no deep-linked list and more space available. The same thing happens when deleting items from the array, it might reduce its size but still enough to leave no room for a giant linked list.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Generics in Rust lang]]></title><description><![CDATA[Generics is a fundamental part of the rust programming language and can sometimes be a pain to truly understand its use and purpose. In this article, I'll try and explain this concept like you are a kid ( if you are not ).
How to identify a generic
G...]]></description><link>https://blog.codemon.me/understanding-generics-in-rust-lang</link><guid isPermaLink="true">https://blog.codemon.me/understanding-generics-in-rust-lang</guid><category><![CDATA[Rust]]></category><category><![CDATA[generics]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Wed, 15 Jun 2022 19:28:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1655321281032/7gQz5ywKP.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Generics is a fundamental part of the rust programming language and can sometimes be a pain to truly understand its use and purpose. In this article, I'll try and explain this concept like you are a kid ( if you are not ).</p>
<h2 id="heading-how-to-identify-a-generic">How to identify a generic</h2>
<p>Generics can be associated with functions, enums, structs, return type and variables.</p>
<h3 id="heading-in-function-definitions">In Function Definitions</h3>
<pre><code><span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">returnData</span> </span>(name: &amp;<span class="hljs-built_in">char</span>) -&gt; &amp;<span class="hljs-built_in">char</span>{
  name
}
</code></pre><pre><code><span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">returnData</span></span>&lt;T&gt; (name: T) -&gt; T{
  name
}
</code></pre><p>The first function can be identified as a regular function with no generic syntax, but on the other hand, we have another function, which does the same thing but this time uses a generic.
We can consider the second function as a better approach, why? Utilizing generics, in this case, gives us the freedom to pass any data type as a parameter, unlike the first function which requires only a parameter of data type <code>&amp;char</code>.</p>
<p><code>returnData&lt;T&gt;</code> means, this function accepts one parameter of type T. <code>T</code> literally means, any type e.g int, uint, floats, struct, etc. You could actually name is anything but the convention is <code>T</code> which means Type, we can decide to re-write the function using a new name like <code>returnData&lt;MyType&gt;</code>, and this works fine so far as you use this same name as the parameter type (<code>name: MyType</code>) and maybe a return type (  <code>-&gt; MyType</code>). The whole <code>&lt;T&gt;</code> thing you see is the presence and usage of a generic.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {

<span class="hljs-keyword">pub</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">returnData</span></span>&lt;T&gt; (name: T) -&gt; T{
  name
}
<span class="hljs-keyword">let</span> data = returnData(<span class="hljs-built_in">String</span>::from(<span class="hljs-string">"Alfred"</span>));

<span class="hljs-keyword">let</span> age = returnData(<span class="hljs-number">27</span>);
<span class="hljs-built_in">println!</span>(<span class="hljs-string">"{} is my name"</span>, data);
<span class="hljs-built_in">println!</span>(<span class="hljs-string">"{} is my age"</span>, age);

}
</code></pre><p>Try it <a target="_blank" href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=335f6c5a81246c6532ff2de6444b0ac0">here</a>.</p>
<h3 id="heading-in-struct-definitions">In Struct Definitions</h3>
<pre><code><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">User</span></span> {
  name: &amp;<span class="hljs-built_in">String</span>,
  email: &amp;<span class="hljs-built_in">String</span>,
  age: <span class="hljs-built_in">u8</span>
}
</code></pre><pre><code><span class="hljs-selector-tag">struct</span> <span class="hljs-selector-tag">User</span>&lt;<span class="hljs-selector-tag">T</span>,<span class="hljs-selector-tag">U</span>&gt; {
    <span class="hljs-attribute">name</span>: T,
    email: T,
    age: U
}
</code></pre><p>Structs are used to create user-defined data structures, and we can use generics to make them even better. You can see the difference between the two structs, the second introduced the generic data type. </p>
<p>Focusing on the second struct, with name as <code>User</code>, we expect this struct to have fields with either a data type of <code>T</code> or/and <code>U</code>. Again, <code>T</code> could be of any type i.e signed integer, unsigned integer, floating-point numbers, or even char. </p>
<pre><code>fn main(){

<span class="hljs-keyword">struct</span> <span class="hljs-title">User</span>&lt;<span class="hljs-title">T</span>,<span class="hljs-title">U</span>,<span class="hljs-title">V</span>&gt; {
    name: T,
    email: U,
    age: V
}

<span class="hljs-keyword">struct</span> <span class="hljs-title">Fullname</span> {
 fname: String,
 lname: String
}

let user1: User<span class="hljs-operator">&lt;</span><span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str, f64<span class="hljs-operator">&gt;</span> <span class="hljs-operator">=</span> User { name: <span class="hljs-string">"Alfred"</span>, 
email: <span class="hljs-string">"alfred@codemon.me"</span>, age:<span class="hljs-number">10.1</span>};




let _fullname <span class="hljs-operator">=</span> Fullname { fname: String::<span class="hljs-keyword">from</span>(<span class="hljs-string">"alfred"</span>), 
lname: String::<span class="hljs-keyword">from</span>(<span class="hljs-string">"johnson"</span>) };

let user2: User<span class="hljs-operator">&lt;</span>Fullname, <span class="hljs-operator">&amp;</span>str, u8<span class="hljs-operator">&gt;</span> <span class="hljs-operator">=</span> User { name: _fullname, 
email: <span class="hljs-string">"fred@gmail.com"</span>, age: <span class="hljs-number">32</span>};


println<span class="hljs-operator">!</span>(<span class="hljs-string">"User 1: name is {}, email is {} and age is {}"</span>,
user1.<span class="hljs-built_in">name</span>, user1.email, user1.age);

println<span class="hljs-operator">!</span>(<span class="hljs-string">"User 2: first name is {}, last name is {}, email is {} and age is {}"</span>,
user2.<span class="hljs-built_in">name</span>.fname, user2.<span class="hljs-built_in">name</span>.lname, user2.email, user2.age)

}
</code></pre><p>Try it <a target="_blank" href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=267a14680f81fc3ae18c7764caf3fac9">here</a>.</p>
<h3 id="heading-in-enums">In enums</h3>
<p>Enums are similar to structs mostly in syntax but personally, it's used to define custom data types just like structs. The fields in an enum are expected to be related in some way, unlike struct which gives more flexibility.</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Colors</span></span> {
  red,
  green,
  blue,
  custom(<span class="hljs-built_in">String</span>)
}
</code></pre><pre><code>enum Colors &lt;<span class="hljs-literal">T</span>&gt;{
  red,
  green,
  blue,
  custom(<span class="hljs-literal">T</span>)
}
</code></pre><p>Web developers know we can represent colors in different ways, hex, RGB, or by their name. The first enum does not give room for us to create a custom color, it must be a string. But with the second enum, we can define a custom color in our enum. Assuming we want to represent a custom RGB color, we can proffer a solution as seen below.</p>
<pre><code>

<span class="solidity">fn main(){

<span class="hljs-keyword">enum</span> <span class="hljs-title">Colors</span> &lt;<span class="hljs-title">T</span>&gt;{
  Green,
  Blue,
  Custom(T)
}

let white_tuple <span class="hljs-operator">=</span> (<span class="hljs-string">"#"</span>,<span class="hljs-string">"f"</span>,<span class="hljs-string">"f"</span>,<span class="hljs-string">"f"</span>);
let white: Colors<span class="hljs-operator">&lt;</span>(<span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str)<span class="hljs-operator">&gt;</span> <span class="hljs-operator">=</span> Colors::Custom(white_tuple);
let blue: Colors<span class="hljs-operator">&lt;</span>(<span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str)<span class="hljs-operator">&gt;</span> <span class="hljs-operator">=</span> Colors::Blue;
let green: Colors<span class="hljs-operator">&lt;</span>(<span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str, <span class="hljs-operator">&amp;</span>str)<span class="hljs-operator">&gt;</span> <span class="hljs-operator">=</span> Colors::Green;
}</span>
</code></pre><h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you've been able to understand the generic syntax and maybe give you a solution to a problem you have been trying to solve.</p>
]]></content:encoded></item><item><title><![CDATA[Deploy an Existing React Application to Heroku in 2022]]></title><description><![CDATA[Lee to the Mao (Lmao) , yes in 2022! Because all those articles out there are really old and do not work anymore. So if you are like me who almost lost your job because this react app just refused to deploy properly to Heroku, well You might just tip...]]></description><link>https://blog.codemon.me/deploy-an-existing-react-application-to-heroku-in-2022</link><guid isPermaLink="true">https://blog.codemon.me/deploy-an-existing-react-application-to-heroku-in-2022</guid><category><![CDATA[React]]></category><category><![CDATA[Heroku]]></category><category><![CDATA[cli]]></category><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Tue, 26 Apr 2022 15:43:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1650987740738/Sc_hgMh3n.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lee to the Mao (Lmao) , yes in 2022! Because all those articles out there are really old and do not work anymore. So if you are like me who almost lost your job because this react app just refused to deploy properly to Heroku, well You might just tip me, my favorite address is at the end of the article and also somewhere in between.</p>
<h2 id="heading-shoutout">Shoutout</h2>
<p>Basically, I personally do not think react apps should be deployed to Heroku, just find the likes of <a target="_blank" href="https://www.netlify.com/">netlify</a>or <a target="_blank" href="https://vercel.com/login?next=%2Fdashboard">vercel</a>, they do better with deploying react applications.</p>
<h2 id="heading-tools-you-would-need">Tools you would need</h2>
<ul>
<li>heroku cli</li>
<li>node and npm</li>
<li>git bash</li>
<li>existing react app scafolded from create-react-app package</li>
</ul>
<h2 id="heading-lets-deploy-that-app">Let's Deploy that App</h2>
<p>I'll have to say this, the best way to get your react app to heroku is via the cli tool. Deploying from a  GitHub repository would show you pepper you might not have enough milk to help you. Below are the steps to follow, we are assuming you have your terminal open inside the projects folder. Follow the steps below to reach your promised land.</p>
<h3 id="heading-step-1-login-to-your-heroku-account">Step 1: Login to your heroku Account</h3>
<p>After running the command below, you would be required to hit any key and you'll be redirected to a web interface to login to the account you'll want to use for this deployment.</p>
<pre><code class="lang-ssh">heroku login
</code></pre>
<h3 id="heading-step-2-create-an-app-on-heroku">Step 2: Create an App on Heroku</h3>
<p>You can skip this if you already have an app created on your Heroku account to where your react app should be deployed to.</p>
<pre><code>heroku create react<span class="hljs-operator">-</span>heroku<span class="hljs-operator">-</span>codemon<span class="hljs-operator">-</span>way
</code></pre><p>A successful creation would output the URL of your newly created app, something like <code>https://react-heroku-codemon-way.herokuapp.com | https://git.heroku.com/react-heroku-codemon-way.git</code></p>
<h4 id="heading-0x687d0848507f90dce542d13d5a824575df5abbe0">0x687d0848507F90dCE542d13D5A824575Df5aBBe0</h4>
<p>You know what to do</p>
<h3 id="heading-step-3-add-project-to-github-remote">Step 3: Add project to github remote</h3>
<p>If you did not skip step 2, copy the git remote URL with a <code>.git</code> extension and keep. For an existing application, your URL should look similar to what we have in step 2, something like this <code>https://git.heroku.com/your-app-name.git</code>,  copy that and keep. You can always get your Remote git url from your app dashboard, under the settings tab.</p>
<p>Now run the command below</p>
<pre><code>git remote add heroku URL<span class="hljs-operator">-</span>You<span class="hljs-operator">-</span>copied
</code></pre><h3 id="heading-step-4-stage-commit-and-push-to-github">Step 4: Stage, Commit and Push to Github</h3>
<pre><code>git add .
git commit <span class="hljs-operator">-</span>m <span class="hljs-string">"Deploy in jesus Name"</span>
git push heroku [branchName]
</code></pre><p>Branch Name could be <code>main</code>, <code>master</code> or <code>rubbish</code> , it's basically the branch you want to push to heroku. At this point, heroku does the remaining work , building a production build and then preparing your application to go live, it might take a while but it must work.</p>
<p>NB: If your react app uses environment variables, do not forget to add them from your heroku app dashboard, under settings.</p>
<h3 id="heading-bye">Bye!!!</h3>
<h2 id="heading-0x687d0848507f90dce542d13d5a824575df5abbe0">0x687d0848507F90dCE542d13D5A824575Df5aBBe0</h2>
]]></content:encoded></item><item><title><![CDATA[Unit Testing your Smart Contracts]]></title><description><![CDATA[Writing tests for your smart contracts are just as important as running audits on them too. There are a few reasons why you might want to write full coverage tests for your smart contracts, one of which would be to save you some bucks. How? Deploying...]]></description><link>https://blog.codemon.me/unit-testing-your-smart-contracts</link><guid isPermaLink="true">https://blog.codemon.me/unit-testing-your-smart-contracts</guid><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Tue, 19 Apr 2022 18:49:53 GMT</pubDate><content:encoded><![CDATA[<p>Writing tests for your smart contracts are just as important as running audits on them too. There are a few reasons why you might want to write full coverage tests for your smart contracts, one of which would be to save you some bucks. How? Deploying to a public testnet cost no dime (  love don't cost a dime ), unlike moving your contracts to the mainnet. </p>
<p>Imagine deploying multiple times to the mainnet because of minor issues like forgetting to use the correct name for your token or even using the wrong decimals ( ERC-20 tokens), these little things happen. One way to save some cash and maybe send them to me instead is to develop a culture of writing tests for your smart contract, they really are not smart enough ( trust no man ).</p>
<p>For me, I prefer using hardhat to develop, test and deploy my contracts for so many reasons, this might also work for truffle. To get started with writing tests, there are a few libraries I use for this purpose which include:</p>
<ul>
<li>Chai</li>
<li>Chai-as-promised </li>
<li>ethers</li>
</ul>
<p>You are probably wondering, ethers?? yes!! ethers.js .. I mean, who is gonna help us communicate with the blockchain? You?? (Lol). So basically, we need ethers to make those function calls and state variable retrievals. Talk is cheap, let me show you the way already. Below is the contract we would be running our test against.</p>
<h3 id="heading-things-to-do">Things to do</h3>
<ul>
<li>Create a file with the name <code>Instagram.sol</code> for your contracts.</li>
<li>Create a test file under the test directory named instagram.test.js </li>
<li>Compile your contract</li>
<li>Ensure your hardhat is configured to compile contracts using version <code>0.8.4</code>.</li>
</ul>
<pre><code>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.4;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Instagram</span> </span>{
  <span class="hljs-keyword">string</span> <span class="hljs-keyword">public</span> name <span class="hljs-operator">=</span> <span class="hljs-string">"Instagram"</span>;

  <span class="hljs-comment">// Store Posts</span>
  <span class="hljs-keyword">uint</span> <span class="hljs-keyword">public</span> imageCount <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;
  <span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">uint</span> <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> Image) <span class="hljs-keyword">public</span> images;

  <span class="hljs-keyword">struct</span> <span class="hljs-title">Image</span> {
  <span class="hljs-keyword">uint</span> id;
  <span class="hljs-keyword">string</span> url;
  <span class="hljs-keyword">string</span> description;
  <span class="hljs-keyword">uint</span> tipAmount;
  <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> author;
} 

<span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">ImageCreated</span>(<span class="hljs-params">
  <span class="hljs-keyword">uint</span> id,
  <span class="hljs-keyword">string</span> url,
  <span class="hljs-keyword">string</span> description,
  <span class="hljs-keyword">uint</span> tipAmount,
  <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> author
</span>)</span>;

<span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">ImageTipped</span>(<span class="hljs-params">
  <span class="hljs-keyword">uint</span> id,
  <span class="hljs-keyword">string</span> url,
  <span class="hljs-keyword">string</span> description,
  <span class="hljs-keyword">uint</span> tipAmount,
  <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> author
</span>)</span>;


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">uploadImage</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> imageUrl, <span class="hljs-keyword">string</span> <span class="hljs-keyword">memory</span> _description</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{

  <span class="hljs-built_in">require</span>(<span class="hljs-keyword">bytes</span>(imageUrl).<span class="hljs-built_in">length</span> <span class="hljs-operator">&gt;</span> <span class="hljs-number">0</span>, <span class="hljs-string">'Image imgHash is required'</span>);
  <span class="hljs-built_in">require</span>(<span class="hljs-keyword">bytes</span>(_description).<span class="hljs-built_in">length</span> <span class="hljs-operator">&gt;</span> <span class="hljs-number">0</span>, <span class="hljs-string">'Image description is required'</span>);
  <span class="hljs-built_in">require</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span> <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0x0</span>),<span class="hljs-string">'Fake ass address'</span>);
  imageCount<span class="hljs-operator">+</span><span class="hljs-operator">+</span>;
  <span class="hljs-comment">// Add Image to contract</span>
  images[imageCount] <span class="hljs-operator">=</span> Image(imageCount, imageUrl,  _description, <span class="hljs-number">0</span>, <span class="hljs-keyword">payable</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>));
  <span class="hljs-comment">// Trigger an event</span>
  <span class="hljs-keyword">emit</span> ImageCreated(imageCount, imageUrl, _description, <span class="hljs-number">0</span>, <span class="hljs-keyword">payable</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>));
}
  <span class="hljs-comment">// Create Images</span>

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tipImageOwner</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> _id</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
    <span class="hljs-comment">// Make sure that the id is valid</span>
    <span class="hljs-built_in">require</span>(_id <span class="hljs-operator">&gt;</span> <span class="hljs-number">0</span> <span class="hljs-operator">&amp;</span><span class="hljs-operator">&amp;</span> _id <span class="hljs-operator">&lt;</span><span class="hljs-operator">=</span> imageCount);
    <span class="hljs-comment">// Fetch the image</span>
    Image <span class="hljs-keyword">memory</span> _image <span class="hljs-operator">=</span> images[_id];

    <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> _author <span class="hljs-operator">=</span> <span class="hljs-keyword">payable</span>(_image.author);

    _author.<span class="hljs-built_in">transfer</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>);

    _image.tipAmount <span class="hljs-operator">=</span> _image.tipAmount <span class="hljs-operator">+</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>;

    images[_id] <span class="hljs-operator">=</span> _image;

    <span class="hljs-keyword">emit</span> ImageTipped(_id, _image.url, _image.description, _image.tipAmount, _author);

  }


}
</code></pre><h2 id="heading-step-1-import-dependencies">Step 1 : Import dependencies</h2>
<pre><code>const { expect, use } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"chai"</span>);
const { ethers } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"hardhat"</span>);

use(<span class="hljs-built_in">require</span>(<span class="hljs-string">"chai-as-promised"</span>)).should();
</code></pre><h2 id="heading-step-2-deploy-contract">Step 2: Deploy Contract</h2>
<pre><code><span class="hljs-comment">// below the previous code add this line of code</span>
describe(<span class="hljs-string">"Deploy Instagram"</span>, async () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
 let instagram;

  before(async () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
    const Instagram <span class="hljs-operator">=</span> await ethers.getContractFactory(<span class="hljs-string">"Instagram"</span>);
    instagram<span class="hljs-operator">=</span> await Instagram .deploy();
    await instagram.deployed();
  })

  <span class="hljs-comment">// other code below here</span>

})
</code></pre><p>All we are doing here is to deploy our contract first in order to interact with its function in future test cases. You are typically saying, before anything, please deploy my contract and finally store the instance of that contract in a global variable <code>Instagram</code></p>
<h2 id="heading-test-case-1-ensure-deployment-was-successful-and-has-the-correct-name">Test Case 1 : Ensure deployment was successful and has the correct name</h2>
<pre><code> <span class="hljs-comment">// add below previous code</span>

  it(<span class="hljs-string">'deploys successfully'</span>, async () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
      const <span class="hljs-keyword">address</span> <span class="hljs-operator">=</span> await instagram.<span class="hljs-built_in">address</span>
      expect(<span class="hljs-keyword">address</span>).to.not.equal(<span class="hljs-number">0x0</span>);
      expect(<span class="hljs-keyword">address</span>).to.not.be.equal(null);
    })

    it(<span class="hljs-string">'has a name'</span>, async () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
      const name <span class="hljs-operator">=</span> await instagram.<span class="hljs-built_in">name</span>()
      expect(name).to.be.equal(<span class="hljs-string">'Instagram'</span>)
    })
</code></pre><p>We have two test cases here, first ensures that we have an address for the deployed contract. The second case tries to assert that the name remained the same. You might be wondering why we are calling <code>name</code> as a function. That's typical of ethers, to retrieve state variables you need to call them like it's a function.</p>
<p>Go ahead and run </p>
<pre><code>npx hardhat <span class="hljs-built_in">test</span> <span class="hljs-built_in">test</span>/instagram.test.js
</code></pre><h2 id="heading-test-case-2-ensure-we-can-upload-an-image">Test Case 2: Ensure we can upload an image</h2>
<pre><code>it(<span class="hljs-string">"creates image"</span>, async () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
      const { <span class="hljs-keyword">address</span>: deployer } <span class="hljs-operator">=</span> await ethers.getSigner()
      await instagram.uploadImage(<span class="hljs-string">'HTTP'</span>, <span class="hljs-string">'Image description'</span>)

      const imageCount <span class="hljs-operator">=</span> await instagram.imageCount();
      const lastUploadedImage <span class="hljs-operator">=</span> await instagram.images(<span class="hljs-number">1</span>);

      expect(imageCount).to.equal(<span class="hljs-number">1</span>)
      expect(lastUploadedImage.author).to.equal(deployer)
      expect(lastUploadedImage.url).to.equal(<span class="hljs-string">'HTTP'</span>)
      expect(lastUploadedImage.description).to.equal(<span class="hljs-string">'Image description'</span>)
    })
</code></pre><p><code>ethers.getSigner</code> simply retrieves the account or wallet used to deploy the contracts, this represents <code>msg.sender</code> . So, we call the<code>uploadImage</code> function passing parameters as well. After this, we can test that there was an increment in <code>imageCount</code>, the author matches the deployers address and URL and description are both correct.</p>
<h2 id="heading-test-case-3-test-for-failure">Test case 3: Test for failure</h2>
<pre><code> it(<span class="hljs-string">"Should fail to upload image"</span>, async () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
       await instagram.uploadImage(<span class="hljs-string">''</span>, <span class="hljs-string">'Image Description'</span>).should.be.rejected;
    await instagram.uploadImage(<span class="hljs-string">'https://image.com'</span>, <span class="hljs-string">''</span>).should.be.rejected;
    })
</code></pre><p>This case happens to be the reason for writing, to test for failure. Currently, in our contract, we have guards that ensure both image URL and description are not empty.</p>
<pre><code><span class="hljs-built_in">require</span>(<span class="hljs-keyword">bytes</span>(imageUrl).<span class="hljs-built_in">length</span> <span class="hljs-operator">&gt;</span> <span class="hljs-number">0</span>, <span class="hljs-string">'Image imgHash is required'</span>);
  <span class="hljs-built_in">require</span>(<span class="hljs-keyword">bytes</span>(_description).<span class="hljs-built_in">length</span> <span class="hljs-operator">&gt;</span> <span class="hljs-number">0</span>, <span class="hljs-string">'Image description is required'</span>);
</code></pre><p>It's not typical to test for failures, but I recommend this for full coverage tests on your contracts. </p>
<h2 id="heading-the-end">The End</h2>
<p>Happy Hacking</p>
]]></content:encoded></item><item><title><![CDATA[How to use Uniswap Interface in Hardhat]]></title><description><![CDATA[For some extraordinary reasons, you need to make use of uniswap to swap assets, perform some liquidity operations, or any other cool thing uniswap has to offer. You probably started off from remix IDE, and now you want to bring it down to your local ...]]></description><link>https://blog.codemon.me/how-to-use-uniswap-interface-in-hardhat</link><guid isPermaLink="true">https://blog.codemon.me/how-to-use-uniswap-interface-in-hardhat</guid><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Mon, 18 Apr 2022 15:37:48 GMT</pubDate><content:encoded><![CDATA[<p>For some extraordinary reasons, you need to make use of uniswap to swap assets, perform some liquidity operations, or any other cool thing uniswap has to offer. You probably started off from remix IDE, and now you want to bring it down to your local machine to compile and test properly and more conveniently using the hardhat framework.</p>
<p>This might be new to you but currently, the hardhat framework does not support HTTPS import, this is what I mean.</p>
<pre><code><span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> 0.8.4;</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">"https://github.com/Uniswap/v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router01.sol"</span>;
</code></pre><p>you would end up with an error when you try to compile using  <code>npx hardhat compile</code> , and end up with a bloody terminal with messages like :</p>
<pre><code><span class="hljs-attribute">Error</span> HH<span class="hljs-number">406</span>: Invalid import https://github.com/Uniswap/uniswap-v<span class="hljs-number">2</span>-periphery/blob/master/contracts/interfaces/IUniswapV<span class="hljs-number">2</span>Router<span class="hljs-number">02</span>.sol from contracts/Swap.sol. Hardhat doesn't support imports via HTTPS.
</code></pre><h2 id="heading-solution">Solution</h2>
<p>The solution is very simple, you would need to navigate to the GitHub URL, copy the contents and also make sure to include the files that might also be imported by the <code>IUniswapV2Router02.sol</code> file.</p>
<p>So instead of using HTTPS which works fine using remix IDE, do something like this.</p>
<ul>
<li>Create <code>IUniswapV2Router02.sol</code> file</li>
<li>Navigate to <a target="_blank" href="https://github.com/Uniswap/v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router01.sol">the GitHub repo</a></li>
<li>Copy the contents</li>
<li>Paste inside the newly created file.</li>
<li>You would notice that the content also has a dependency, so go ahead and also fetch the files content and you should be good to go.</li>
</ul>
<h3 id="heading-bye">Bye!!</h3>
<p>Happy Hacking</p>
]]></content:encoded></item><item><title><![CDATA[PART 2: OminiSwap Project Setup]]></title><description><![CDATA[In a previous article which can be found here, we talked about this awesome project to be built. I asked a few questions concerning the project, one of which was "What shall we name our token?" From the look of things, we've got a name already. 
Thro...]]></description><link>https://blog.codemon.me/part-2-ominiswap-project-setup</link><guid isPermaLink="true">https://blog.codemon.me/part-2-ominiswap-project-setup</guid><dc:creator><![CDATA[Johnson awah Alfred]]></dc:creator><pubDate>Tue, 05 Apr 2022 20:23:41 GMT</pubDate><content:encoded><![CDATA[<p>In a previous article which can be found <a target="_blank" href="https://blog.codemon.me/part-1-build-a-decentralized-exchange-on-ethereum-blockchain-fullstack-dapp">here</a>, we talked about this awesome project to be built. I asked a few questions concerning the project, one of which was "What shall we name our token?" From the look of things, we've got a name already. </p>
<p>Throughout this series, we would call our app OminiSwap, yunno.. like Uniswap. The reason behind this name is that, I've considered introducing an additional blockchain, you'll get to know about this new chain later on in this course. So there we have it, let the party begin already!!!!</p>
<h2 id="heading-smart-contract-framework">Smart Contract Framework</h2>
<p>For building and deploying the necessary contracts, I decided we make use of hardhat framework for this. So feel free to head over to their official <a target="_blank" href="https://hardhat.org/">website</a> to see what they've got cooking. The reason behind hardhat over of course truffle is that hardhat features a better debugging experience, nothing else. For example, hardhat offers a "console.log" feature, this is useful to print out messages while you run or compile your contracts. It's as simple as importing the console package and just using console.log anywhere in the contract.</p>
<pre><code class="lang-sh">
pragma solidity ^0.6.0;

import <span class="hljs-string">"hardhat/console.sol"</span>;

contract Token {
 <span class="hljs-keyword">function</span> transfer(address to, uint256 amount) external {
    console.log(<span class="hljs-string">"Sender balance is %s tokens"</span>, balances[msg.sender]);
    console.log(<span class="hljs-string">"Trying to send %s tokens to %s"</span>, amount, to);

    require(balances[msg.sender] &gt;= amount, <span class="hljs-string">"Not enough tokens"</span>);

    balances[msg.sender] -= amount;
    balances[to] += amount;
}
}
</code></pre>
<h2 id="heading-front-end-development">Front End Development</h2>
<p>You know this already, we are taking the react route to building out a public-facing user interface. In it would be some starter files from the <a target="_blank" href="https://ethereumboilerplate.com/">ethereum-boilerplate</a>. Currently, It has this swap functionality that uses some cool library, but that's not our goal. We want to write the smart contract ourselves and see how the thing goes.</p>
<h2 id="heading-some-heads-up">Some heads Up</h2>
<p>In as much as I'll try my very best to actually explain something that I feel would be confusing, I'll advise every beginner out there to just get some solidity superpowers from this <a target="_blank" href="https://solidity-by-example.org/">Resource</a>.
One last thing, I'm not gonna be teaching javascript or react here, but I'll explain stuff I think could be complicated ( doubt if any would rise though).</p>
<h2 id="heading-starter-files">Starter Files</h2>
<p>Head over to <a target="_blank" href="https://github.com/CeoFred/ominiswap">github</a> and clone the repo where our contracts would live. It contains a fruit of the spirit,  the sword of solidity (hardhat framework), and over <a target="_blank" href="https://github.com/CeoFred/ominiswap-frontend">here</a> holds the breast blate of javascript ( react project).</p>
<h2 id="heading-set-up">Set-Up</h2>
<p>Just take your time and look through the READMEfiles for each project. For our contract project here are a few things you could do to make me happy. Run the following commands after you've gone through the whole process on the README file.</p>
<pre><code class="lang-sh">npx hardhat compile
</code></pre>
<p>Compiles all .sol files found inside the contracts folder.</p>
<pre><code class="lang-sh">npx hardhat <span class="hljs-built_in">test</span>
</code></pre>
<p>Runs any available test suite, which can be found inside the test folder.</p>
<pre><code class="lang-sh">npx hardhat run scripts/deploy.js --network rinkeby
</code></pre>
<p>Deploys your contracts to the rinkeby network</p>
]]></content:encoded></item></channel></rss>