<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gerald Nash ⚡️</title>
    <description>The latest articles on DEV Community by Gerald Nash ⚡️ (@aunyks).</description>
    <link>https://dev.to/aunyks</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2310%2F2bea0d44-fa6b-46f7-b7df-97748b334b3d.png</url>
      <title>DEV Community: Gerald Nash ⚡️</title>
      <link>https://dev.to/aunyks</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aunyks"/>
    <language>en</language>
    <item>
      <title>Mixed Reality in Transit</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Sat, 12 Sep 2020 01:31:44 +0000</pubDate>
      <link>https://dev.to/aunyks/mixed-reality-in-transit-3jfl</link>
      <guid>https://dev.to/aunyks/mixed-reality-in-transit-3jfl</guid>
      <description>&lt;h2&gt;
  
  
  A Background
&lt;/h2&gt;

&lt;p&gt;The weekend was coming and I decided to save a bit of my free time after work for some creative expression. "Lemme get some practice in with these filters," I thought, referring to my &lt;a href="https://twitter.com/aunyks/status/1256386499362410496"&gt;starting to make Instagram filters&lt;/a&gt; around last month.&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--QgZf5U96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1300988364498317312/HL5Rk7dI_normal.jpg" alt="Nash (刘光瑞） profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Nash (刘光瑞）
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/aunyks"&gt;@aunyks&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      I started making IG filters last week. Here’s a running thread
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      00:54 AM - 02 May 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1256386499362410496" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1256386499362410496" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      14
      &lt;a href="https://twitter.com/intent/like?tweet_id=1256386499362410496" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      46
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  An Idea
&lt;/h2&gt;

&lt;p&gt;I didn't really have a project idea, though. I laid in my bed for another thirty minutes before remembering that I had to go to DC in a few days to finish moving out of my dorm. That reminded me of the DC Metro and how the system was a bit tricky for me to navigate at times.&lt;/p&gt;

&lt;p&gt;Then it hit me. I'm gonna make the Metro map pop up when the Metro card is in view. That's a cool thing that I'd use regularly if I were new to the system again. I opened up &lt;a href="https://sparkar.facebook.com/ar-studio"&gt;Spark AR&lt;/a&gt; and got to work on the core functionality. After adding some hints and animations, I tested the effect on my phone with an actual Metro card. My eyes lit up. I thought it was really cool! So, I quickly designed a logo, came up with a name, and submitted it to Facebook.&lt;/p&gt;

&lt;p&gt;The following day I recorded a short demo video showing the effect and posted it to Instagram and Twitter since I thought the project was so cool.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MUW5Q38D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.aunyks.com/img/tech/smartmap-card-ig-demo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MUW5Q38D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.aunyks.com/img/tech/smartmap-card-ig-demo.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Rejection
&lt;/h2&gt;

&lt;p&gt;I logged back out of them to get some more work done only to check Facebook every couple hours to check on the status of the filter submission. At the end of the day, it was denied with feedback saying that there was "Too much text". "Too much text? It's an image of a map, and some published filters already have maps with more text in them". I instantly hit the resubmit button with examples of effects with the same amount of or more text.&lt;/p&gt;

&lt;p&gt;The work day was coming to an end so I signed back in to Instagram and Twitter to see the posts getting lots of attention. A couple hundred likes, comments, and retweets were beyond the normalcy of my notifications tabs, so they certainly caught my eye. One last check on the resubmission status resulted in another rejection by Facebook citing the same issue.&lt;/p&gt;

&lt;p&gt;I wasn't gonna change the filter, since it did exactly what I wanted. I was incredibly annoyed. I wanted to let people experience the filter, otherwise the effect in the video was indistinguishable from something made in software like After Effects. I slept on it and woke up to tell people what happened.&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--QgZf5U96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1300988364498317312/HL5Rk7dI_normal.jpg" alt="Nash (刘光瑞） profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Nash (刘光瑞）
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/aunyks"&gt;@aunyks&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Facebook denied this filter so I can’t give it to you without sending a link smh &lt;a href="https://t.co/nS3T0Bg2DB"&gt;twitter.com/aunyks/status/…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      14:03 PM - 11 Jun 2020
    &lt;/div&gt;

      &lt;div class="ltag__twitter-tweet__quote"&gt;
        &lt;div class="ltag__twitter-tweet__quote__header"&gt;
          &lt;span class="ltag__twitter-tweet__quote__header__name"&gt;
            Nash (刘光瑞）
          &lt;/span&gt;
          &lt;a class="comment-mentioned-user" href="https://dev.to/aunyks"&gt;@aunyks&lt;/a&gt;

        &lt;/div&gt;
        Smartmap Card https://t.co/xxGVrCHrp6
      &lt;/div&gt;

    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1271080531560718339" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1271080531560718339" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      16
      &lt;a href="https://twitter.com/intent/like?tweet_id=1271080531560718339" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      133
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  An Alternative
&lt;/h2&gt;

&lt;p&gt;I remembered that Facebook/Instagram wasn't the only social platform that lets creators make AR effects, so I turned to Snapchat. I'd been a bit intimidated by the idea of making Snapchat filters, as I'd never understood how to use its &lt;a href="https://lensstudio.snapchat.com/"&gt;Lens Studio&lt;/a&gt; software, and there wasn't as much easy-to-find content teaching people how to make stuff with it as for Facebook's Spark AR Studio. But, I was so focused on getting this idea in people's hands that I spent some hours learning how to use it so I could port my filter to Snapchat's platform.&lt;/p&gt;

&lt;p&gt;By the end of the day, I'd overcome my fear and learned just enough of the platform to get my idea going.&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--QgZf5U96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1300988364498317312/HL5Rk7dI_normal.jpg" alt="Nash (刘光瑞） profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Nash (刘光瑞）
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/aunyks"&gt;@aunyks&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      I’m remaking it in Snapchat out of spite
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      00:48 AM - 12 Jun 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1271242884679860231" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1271242884679860231" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1271242884679860231" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      30
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;br&gt;
I finished it. By the end of the night, I'd successfully ported Smartmap Card from FB/IG to Snapchat. I submitted the filter and felt needed excitement when I saw that it was accepted and live in minutes, much faster than Facebook's hours to weeks. I went to sleep knowing I was gonna record a new demo video to show off the better marker tracking that Snapchat offered in addition to a link to the filter that people could use whenever they wanted to use the filter.&lt;br&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media ltag__twitter-tweet__media__video-wrapper"&gt;
        &lt;div class="ltag__twitter-tweet__media--video-preview"&gt;
          &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nw7GUB2P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/ext_tw_video_thumb/1271480393917763585/pu/img/xOA0BnDUnCenLJ3n.jpg" alt="unknown tweet media content"&gt;
          &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/play-butt.svg" class="ltag__twitter-tweet__play-butt" alt="Play butt"&gt;
        &lt;/div&gt;
        &lt;div class="ltag__twitter-tweet__video"&gt;
          
            
          
        &lt;/div&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--QgZf5U96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1300988364498317312/HL5Rk7dI_normal.jpg" alt="Nash (刘光瑞） profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Nash (刘光瑞）
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/aunyks"&gt;@aunyks&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Smartmap Card works on Snapchat &lt;a href="https://t.co/4sSyBhpEwq"&gt;snapchat.com/unlock/?type=S…&lt;/a&gt; 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:33 PM - 12 Jun 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1271480724609290241" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1271480724609290241" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      2871
      &lt;a href="https://twitter.com/intent/like?tweet_id=1271480724609290241" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      8465
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;br&gt;
I posted the filter to Twitter in its new form, very satisfied that I got a really cool project out that people can actually use. I then edited the caption in my original Instagram post instructing people to DM me if they wanted to try the filter out on Snapchat.

&lt;h2&gt;
  
  
  Virality
&lt;/h2&gt;

&lt;p&gt;About an hour passed and the tweet blew up with likes, replies, and retweets (with and without comment). The Instagram post was still garnering an unusually great amount of interest. My Instagram DMs were blowing up with people requesting access, so I just linked directly to the filter from my website and updated the Instagram caption to have people check the link in my bio to use the filter.&lt;/p&gt;

&lt;p&gt;For the next week, both my posts reached some six figures in impressions per day, and with each passing day more people were recording themselves being wowed while trying the filter out on their Metro cards. A couple of TikToks (&lt;a href="https://vm.tiktok.com/J1VEswP/"&gt;one&lt;/a&gt;, &lt;a href="https://vm.tiktok.com/J1EmWXM/"&gt;two&lt;/a&gt;), &lt;a href="https://www.reddit.com/r/nextfuckinglevel/comments/hamvdk/washington_dc_metro_pass_that_displays_the_metro/"&gt;Reddit threads&lt;/a&gt;, and &lt;a href="https://www.instagram.com/p/CBbX8fXh33u/"&gt;Instagram reposts&lt;/a&gt; came about. At this point, the filter was much bigger than me. Literally so, as accounts were now sharing and reposting without giving credit. It's part of the game, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Conclusion
&lt;/h2&gt;

&lt;p&gt;In the midst of all that, I'd gained a couple hundred new followers on Instagram and Twitter, saw some 3,000 visits to my website, and made a few more filters very similar to this one. These newer filters featured maps for &lt;a href="https://twitter.com/aunyks/status/1271487797199765505"&gt;the Bay Area's BART&lt;/a&gt; and &lt;a href="https://twitter.com/aunyks/status/1274372466480201729"&gt;Atlanta's MARTA&lt;/a&gt;, and they're exclusive to Snapchat. I'd been reminded that metro systems also have limited edition cards and that in some systems those who are disabled get cards with unique designs.&lt;/p&gt;

&lt;p&gt;I learned that Snapchat's AR platform has much better technology than Facebook's with respect to marker tracking, face+hand tracking, segmentation, and more respects. Snap's Lens Studio and publishing workflow also provides a much better experience than that of Facebook's Spark. So the only ways that Facebook's platform beats Snap's are by providing a more approachable programming experience to creators through its &lt;a href="https://twitter.com/aunyks/status/1259231337170558977"&gt;Patch Editor&lt;/a&gt;, allowing creators to program &lt;a href="https://en.wikipedia.org/wiki/Shader"&gt;shaders&lt;/a&gt; into their filters, and by having a larger user base.&lt;/p&gt;

&lt;p&gt;In the end I don't quite know what's next for these projects, if anything, but it was certainly interesting getting a taste of Internet virality.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Substack Open URL Redirection / Reflected XSS Vulnerability Writeup</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Sat, 04 Apr 2020 02:36:27 +0000</pubDate>
      <link>https://dev.to/aunyks/substack-open-url-redirection-reflected-xss-vulnerability-writeup-269h</link>
      <guid>https://dev.to/aunyks/substack-open-url-redirection-reflected-xss-vulnerability-writeup-269h</guid>
      <description>&lt;p&gt;This post was originally featured on my &lt;a href="https://blog.aunyks.com/2020/3/substack-open-redirect-w-xss"&gt;blog&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;NOTE: The content in this post is solely for educational purposes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://substack.com/"&gt;Substack&lt;/a&gt; team was kind enough to allow me to disclose this vulnerability. As stated by the title, I found an &lt;a href="https://owasp.org/www-project-cheat-sheets/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet"&gt;Open URL Redirection&lt;/a&gt; vulnerability and a Reflected &lt;a href="https://owasp.org/www-community/attacks/xss"&gt;Cross-Site Scripting (XSS)&lt;/a&gt; vulnerability in the company's web application. If you want to learn more about the nature of these types of vulnerabilities and how they can relate in this case, &lt;a href="https://dev.to/aunyks/how-d-i-get-here-exploiting-redirection-1aga"&gt;here's an article&lt;/a&gt; that explains it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Discovery
&lt;/h1&gt;

&lt;p&gt;While setting up a newsletter for &lt;a href="https://lettermatch.co/"&gt;LetterMatch&lt;/a&gt;, I noticed that a visitor to a Substack newsletter's subscribe page will sometimes see a &lt;code&gt;next&lt;/code&gt; URL query parameter that describes where they'll be redirected after subscribing. The URL would follow the form &lt;code&gt;lettermatch.substack.com/subscribe?next={target_endpoint}&lt;/code&gt;, where &lt;code&gt;{target_endpoint}&lt;/code&gt; is the location to which the visitor will be directed after subscribing. &lt;em&gt;Note that this applies to &lt;em&gt;any&lt;/em&gt; Substack newsletter, not just LetterMatch's.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Exploitation
&lt;/h1&gt;

&lt;p&gt;Because redirection schemes that look like this are, at times, susceptible to Open URL Redirection, I tried visiting the URL &lt;code&gt;lettermatch.substack.com/subscribe?next=https://example.com&lt;/code&gt; and subscribing. After doing so, I was redirected to example.com. Now that this case was validated, I tried finding methods of obscuring the destination URL. This is because a victim may notice the second, potentially malicious URL and choose not to visit the link. With that said, I tested &lt;a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Open%20Redirect/Intruder/openredirects.txt"&gt;several different ways to encode an URL&lt;/a&gt; and saw that most of the variations worked in place of the plain &lt;code&gt;https://example.com&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Impact
&lt;/h1&gt;

&lt;p&gt;Vulnerabilities of this type are typically used in a chain with others to exploit victims, but conceptually this can be used to redirect users to phishing sites or sites that exploit browsers to install malware on a victim's device, like when hackers &lt;a href="https://www.bleepingcomputer.com/news/security/hhsgov-open-redirect-used-by-coronavirus-phishing-to-spread-malware/"&gt;exploited an Open Redirection vulnerability in a U.S. Department of Health &amp;amp; Human Services web page to install malware on visitors' machines&lt;/a&gt;. A bit more detail &lt;a href="https://blog.aunyks.com/2020/2/howd-i-get-here.html#craft-the-attack"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Increasing the Impact
&lt;/h1&gt;

&lt;p&gt;Some Open Redirect vulns can also lead to &lt;a href="https://owasp.org/www-community/attacks/xss"&gt;Cross Site Scripting (XSS) attacks&lt;/a&gt;, most often Reflected XSS attacks, if the payload or, in this case, the destination URL is valid JavaScript.&lt;/p&gt;

&lt;p&gt;Interestingly, injecting script tags as the parameter value didn't have an effect, but injecting JavaScript "URLs" of the form &lt;code&gt;javascript:{some-code-here}&lt;/code&gt; as the parameter value results in the injected code being executed. An example of this can be found in the demo below, where I inject a window alert.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://blog.aunyks.com/img/tech/substack-open-redir-poc.mp4"&gt;Here's a video demo&lt;/a&gt; of the this vulnerability being exploited before the patch. I don't consider it a proof of concept, as I demonstrate the exploitation with a benign redirection location and injected code.&lt;/p&gt;

&lt;h1&gt;
  
  
  In Conclusion
&lt;/h1&gt;

&lt;p&gt;I raised this issue with medium severity because of the Reflected XSS that's involved. The Substack team was very considerate in finding time to fix this vulnerability so quickly. They're a relatively small team with a lot of responsibilities, so their diligence was appreciated, especially as we all adapt to the circumstances of current events.&lt;/p&gt;

&lt;p&gt;Timeline&lt;br&gt;
&lt;strong&gt;Jan 28, 2020&lt;/strong&gt; - Initial email disclosing vulnerability details&lt;br&gt;
&lt;strong&gt;Jan 31, 2020&lt;/strong&gt; - Response from Substack and patch of XSS&lt;br&gt;
&lt;strong&gt;Mar 26, 2020&lt;/strong&gt; - Notification of full patch (Open Redirect and XSS)&lt;br&gt;
&lt;strong&gt;Mar 26, 2020&lt;/strong&gt; - Request to fully disclose findings&lt;br&gt;
&lt;strong&gt;Mar 30, 2020&lt;/strong&gt; - Permission to fully disclose findings granted&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>hacking</category>
      <category>pentest</category>
    </item>
    <item>
      <title>Repl.it Open URL Redirection Vulnerability Writeup</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Sat, 04 Apr 2020 02:28:44 +0000</pubDate>
      <link>https://dev.to/aunyks/repl-it-open-url-redirection-vulnerability-writeup-4ejh</link>
      <guid>https://dev.to/aunyks/repl-it-open-url-redirection-vulnerability-writeup-4ejh</guid>
      <description>&lt;p&gt;This post was originally featured on my &lt;a href="https://blog.aunyks.com/2020/3/replit-open-redirect.html"&gt;blog&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;NOTE: The content in this post is solely for educational purposes. Do NOT attack entities that did not provide consent beforehand.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://repl.it"&gt;Repl.it&lt;/a&gt; team was kind enough to allow me to disclose this vulnerability. As stated by the title, I found an &lt;a href="https://owasp.org/www-project-cheat-sheets/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet"&gt;Open URL Redirection&lt;/a&gt; vulnerability in the company's web application. If you want to learn more about the nature of this type of vulnerability, &lt;a href="https://dev.to/aunyks/how-d-i-get-here-exploiting-redirection-1aga"&gt;here's an article&lt;/a&gt; that explains it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Discovery
&lt;/h1&gt;

&lt;p&gt;In the Computer Science department at my university, we regularly use Repl.it for rapid testing of ideas for our programming assignments, and in some classes we use it for official assignment submission. While logging in to the platform one time, I took note of a &lt;code&gt;goto&lt;/code&gt; parameter in the login URL. The URL followed the form &lt;code&gt;repl.it/login?goto={target_endpoint}&lt;/code&gt;, where &lt;code&gt;{target_endpoint}&lt;/code&gt; is the location to which the user is redirected after logging in.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exploitation
&lt;/h1&gt;

&lt;p&gt;Because post-authentication redirection schemes that look like this are, at times, susceptible to Open URL Redirection, I tried visiting the URL &lt;code&gt;repl.it/login?goto=https://example.com&lt;/code&gt; and logging in. To my surprise, I was redirected to example.com! Now that this case was validated, I tried finding methods of obscuring the destination URL. This is because a victim may notice the second, potentially malicious URL and choose not to visit the link. With that said, I tested &lt;a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Open%20Redirect/Intruder/openredirects.txt"&gt;several different ways to encode an URL&lt;/a&gt; and saw that most of the variations worked in place of the plain &lt;code&gt;https://example.com&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Impact
&lt;/h1&gt;

&lt;p&gt;Vulnerabilities of this type are typically used in a chain with others to exploit victims, but conceptually this can be used to redirect users to phishing sites or sites that exploit browsers to install malware on a victim's device. A bit more detail &lt;a href="https://blog.aunyks.com/2020/2/howd-i-get-here.html#craft-the-attack"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  (Not) Increasing the Impact
&lt;/h1&gt;

&lt;p&gt;Some Open Redirect Vulns can also lead to &lt;a href="https://owasp.org/www-community/attacks/xss"&gt;Cross Site Scripting (XSS) attacks&lt;/a&gt; if the payload or, in this case, the destination URL is valid JavaScript. Fortunately, injecting script tags or &lt;code&gt;javascript:{some-code-here}&lt;/code&gt; as the parameter value didn't appear to have an effect.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://blog.aunyks.com/img/tech/repl-open-redir-poc.mov"&gt;Here's&lt;/a&gt; a video demo of the this vulnerability being exploited before the patch. I don't consider it a proof of concept, as I demonstrate the exploitation with a benign redirection location.&lt;/p&gt;

&lt;h1&gt;
  
  
  In Conclusion
&lt;/h1&gt;

&lt;p&gt;I raised this issue with medium severity, as opposed to the typical low severity, given the nature of Repl.it's REPL sharing feature and the ease of a user mistaking a malicious login link for shared REPL or other asset. The Repl.it team was very considerate in finding time to fix this vulnerability. They're a relatively small team with a lot of responsibilities, so their diligence was appreciated.&lt;/p&gt;

&lt;h1&gt;
  
  
  Timeline
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Oct 24, 2019&lt;/strong&gt; - Initial email asking for preferred means of disclosure&lt;br&gt;
&lt;strong&gt;Dec 31, 2019&lt;/strong&gt; - Response from Repl and disclosure of vulnerability details&lt;br&gt;
Unknown - Full patch&lt;br&gt;
&lt;strong&gt;Mar 03, 2020&lt;/strong&gt; - Discovery of patch and request to fully disclose findings&lt;br&gt;
&lt;strong&gt;Mar 04, 2020&lt;/strong&gt; - Permission to fully disclose findings granted&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>hacking</category>
      <category>pentest</category>
    </item>
    <item>
      <title>How'd I Get Here? Exploiting Redirection</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Sat, 04 Apr 2020 02:15:36 +0000</pubDate>
      <link>https://dev.to/aunyks/how-d-i-get-here-exploiting-redirection-1aga</link>
      <guid>https://dev.to/aunyks/how-d-i-get-here-exploiting-redirection-1aga</guid>
      <description>&lt;p&gt;This post was first featured on &lt;a href="https://blog.aunyks.com/2020/2/howd-i-get-here"&gt;my blog&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;NOTE: The content in this post is solely for educational purposes. Do NOT attack entities that did not provide consent beforehand.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this post, we'll cover what Open URL Redirection Vulnerabilties are, how to exploit them, and how to prevent them. I was motivated to write this, because I've lately been discovering these vulnerabilities in the wild, and I want to increase developers', users', and security researchers' awareness of them.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is URL Redirection?
&lt;/h1&gt;

&lt;p&gt;URL Redirection is a method used by web applications to manage a user's navigation throughout the app. This is often seen during authentication, where a user is registering for or logging into an application, and the application wishes to redirect the user to another page once they've been authenticated.&lt;/p&gt;

&lt;h1&gt;
  
  
  So, what's the problem?
&lt;/h1&gt;

&lt;p&gt;What happens when we set the location to which a user will be redirected to a completely different website? If the application still redirects us to the website, its URL redirection logic could be too "open". If we can have it redirect us to any website we'd like, we &lt;em&gt;might&lt;/em&gt; be able to use this to attack users of the website.&lt;/p&gt;

&lt;h1&gt;
  
  
  What does this look like?
&lt;/h1&gt;

&lt;p&gt;Sometimes when you're at a login page for some website like &lt;code&gt;hackus.now.sh&lt;/code&gt;, you might see the URL looks like &lt;code&gt;hackus.now.sh/login?next=/dashboard&lt;/code&gt;. That URL communicates that, once you've logged in, you'll be redirected to the dashboard page, which looks like &lt;code&gt;hackus.now.sh/dashboard&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We established earlier that URLs that contain the location to which we'll be redirected are potentially vulnerable to Open URL Redirection. This is because the target doesn't perform adequate verification or sanitization of the values of the &lt;code&gt;next&lt;/code&gt; parameter. With that being said, what happens if we instead set the destination to &lt;code&gt;example.com&lt;/code&gt;? To see that, we can visit &lt;code&gt;hackus.now.sh/login?next=https://example.com&lt;/code&gt;. If, after logging in, we're redirected to &lt;code&gt;example.com&lt;/code&gt;, our target is definitely susceptible to Open URL Redirection.&lt;/p&gt;

&lt;h1&gt;
  
  
  How can we craft an attack?
&lt;/h1&gt;

&lt;p&gt;As with many high-impact attacks, we can chain our exploitation of this vulnerability with other exploits to achieve certain effects on a target or targets. For example, we can utilize social engineering and &lt;a href="https://www.cvedetails.com/cve/CVE-2019-11708"&gt;a CVE that lets us break out of the browser sandbox and execute code on the host computer&lt;/a&gt; to take control of a target's device.&lt;/p&gt;

&lt;p&gt;In theory, this could be achieved by using the social engineering to have our target visit &lt;code&gt;hackus.now.sh/login?next=imdangerous.com&lt;/code&gt; and log in. In this case, our target's visit to &lt;code&gt;imdangerous.com&lt;/code&gt; will cause our exploitation of the aforementioned CVE to take place, allowing us to run code on the target's machine and likely take control of it.&lt;/p&gt;

&lt;h1&gt;
  
  
  What if there's no &lt;code&gt;next&lt;/code&gt; parameter?
&lt;/h1&gt;

&lt;p&gt;These redirect parameters vary across web applications and frameworks. In my experience, I've seen &lt;code&gt;next&lt;/code&gt;, &lt;code&gt;goto&lt;/code&gt;, &lt;code&gt;redirect&lt;/code&gt;, and &lt;code&gt;redirect_to&lt;/code&gt;. They could take so many forms that you could even use a wordlist and fuzz for valid redirection parameters to test for openness.&lt;/p&gt;

&lt;h1&gt;
  
  
  How creative can we get with this?
&lt;/h1&gt;

&lt;p&gt;Very! If we wanna get creative with the redirection payload, we can change the form of the URL. For example, if the payload looks like &lt;code&gt;?next=/dashboard&lt;/code&gt; and we want to redirect to &lt;code&gt;example.com&lt;/code&gt;, we can try the URL with protocol included (&lt;code&gt;?next=https://example.com&lt;/code&gt;), just the host (&lt;code&gt;?next=example.com&lt;/code&gt; / &lt;code&gt;?next=/example.com&lt;/code&gt;), URL without protocol (&lt;code&gt;?next=//example.com&lt;/code&gt;), or even URL-encoded versions of any of the previous examples (&lt;code&gt;?next=%2F%2Fexample.com&lt;/code&gt; et al.).&lt;/p&gt;

&lt;p&gt;Another creative approach is to try different protocols in the payload! Some browsers support FTP and IPFS URLs, so we could plug those kinds of URLs in the payload and observe effects. A payload that often increases the impact of vulnerabilities of this type is using JavaScript as the payload's protocol. Using payloads of the form &lt;code&gt;?next=javascript:{some-code}&lt;/code&gt; can sometimes be used to perform &lt;a href="https://owasp.org/www-community/attacks/DOM_Based_XSS"&gt;DOM-based XSS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Attack in the Wild&lt;br&gt;
An Open Redirect vulnerability was exploited in the United States Department of Health and Human Services' &lt;a href="https://dcis.hhs.gov/"&gt;Departmental Contracts Information System&lt;/a&gt; during the novel coronavirus disease (COVID-19) pandemic. In short, attackers sent crafted a URL of the form &lt;code&gt;https://dcis.hhs.gov/cas/login?service=malicioussite.com&amp;amp;gateway=true&lt;/code&gt; that redirected victims to a website that has a victim unknowingly download and execute malware. More information on this particular attack can be found here.&lt;/p&gt;

&lt;h1&gt;
  
  
  In Conclusion
&lt;/h1&gt;

&lt;p&gt;Open URL Redirection is a type of vulnerability where an application redirects users to any location provided in its URL. This type of vulnerability is typically used in a chain of exploits to achieve higher impact attacks. At times, these vulnerabilities could even lead to XSS! To mitigate the risk of an application's vulnerability to Open URL Redirection, developers and security engineers must ensure that their applications whitelist and/or sanitize the values of their redirection parameters.&lt;/p&gt;

&lt;p&gt;I typically report these vulnerabilities with low severity, although depending on the nature of the application or range of allowed payloads I might give medium or high severity to my findings.&lt;/p&gt;




&lt;p&gt;Thanks for reading. If you have any questions for me about this post or anything else, please feel free to message me on &lt;a href="https://twitter.com/aunyks"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>hacking</category>
      <category>pentest</category>
    </item>
    <item>
      <title>The Anatomy of ERC20</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Tue, 03 Oct 2017 00:03:42 +0000</pubDate>
      <link>https://dev.to/aunyks/the-anatomy-of-erc20-bfg</link>
      <guid>https://dev.to/aunyks/the-anatomy-of-erc20-bfg</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://news.21.co/the-anatomy-of-erc20-6ab09d4206a5" rel="noopener noreferrer"&gt;This article was first published to 21.co's blog.&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AFD2cH_XiSw8oIlT2ojfPdQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AFD2cH_XiSw8oIlT2ojfPdQ.png" alt="ERC20 Photo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In light of today’s ICO launches, digital token sales during which companies and organizations &lt;a href="https://storj.io/tokensale.html" rel="noopener noreferrer"&gt;raise millions of dollars instantly&lt;/a&gt; while giving out digital assets, it’s important to recognize the underlying technology that nearly all of these tokens possess: ERC20.  &lt;/p&gt;

&lt;p&gt;Ethereum &lt;a href="https://en.wikipedia.org/wiki/Request_for_Comments" rel="noopener noreferrer"&gt;Request for Comments&lt;/a&gt; 20, or ERC20, is an &lt;a href="https://github.com/ethereum/EIPs" rel="noopener noreferrer"&gt;Ethereum Improvement Proposal&lt;/a&gt; introduced by Fabian Vogelsteller in late 2015. It’s a standard by which many popular Ethereum smart contracts abide. It effectively allows smart contracts to act very similarly to a conventional cryptocurrency like Bitcoin, or Ethereum itself. In saying this, a token hosted on the Ethereum blockchain can be sent, received, checked of its total supply, and checked for the amount that is available on an individual address. This is analogous to sending and receiving Ether or Bitcoin from a wallet, knowing the total amount of coins in circulation, and knowing a particular wallet’s balance of a coin. A smart contract that follows this standard is called an ERC20 token.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ethereum/EIPs/issues/20" rel="noopener noreferrer"&gt;The Original ERC20 Proposal&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;All of the previously described functionality is able to exist by defining a set of functions that allow a smart contract to emulate a digital token. &lt;em&gt;But how does that work?&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;ERC20 defines the functions balanceOf , totalSupply , transfer , transferFrom , approve , and allowance . It also has a few optional fields like the token name, symbol, and the number of decimal places with which it will be measured.&lt;br&gt;
Note: This is a concise declaration of an example ERC20 contract.  &lt;/p&gt;

&lt;p&gt;ERC20 defines the functions &lt;code&gt;balanceOf&lt;/code&gt; , &lt;code&gt;totalSupply&lt;/code&gt; , &lt;code&gt;transfer&lt;/code&gt; , &lt;code&gt;transferFrom&lt;/code&gt; , &lt;code&gt;approve&lt;/code&gt; , and &lt;code&gt;allowance&lt;/code&gt; . It also has a few optional fields like the token name, symbol, and the number of decimal places with which it will be measured.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This is a concise declaration of an example ERC20 contract.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Grabbed from: https://github.com/ethereum/EIPs/issues/20
contract ERC20 {
   function totalSupply() constant returns (uint theTotalSupply);
   function balanceOf(address _owner) constant returns (uint balance);
   function transfer(address _to, uint _value) returns (bool success);
   function transferFrom(address _from, address _to, uint _value) returns (bool success);
   function approve(address _spender, uint _value) returns (bool success);
   function allowance(address _owner, address _spender) constant returns (uint remaining);
   event Transfer(address indexed _from, address indexed _to, uint _value);
   event Approval(address indexed _owner, address indexed _spender, uint _value);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An overview and example of each field within the contract is as follows.  &lt;/p&gt;

&lt;h2&gt;
  
  
  totalSupply()
&lt;/h2&gt;

&lt;p&gt;Although the supply could easily be fixed, as it is with Bitcoin, this function allows an instance of the contract to calculate and return the total amount of the token that exists in circulation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  // In this case, the total supply
  // of MyERCToken is fixed, but
  // it can very much be changed
  uint256 _totalSupply = 1000000;

  function totalSupply() constant returns (uint256 theTotalSupply) {
    // Because our function signature
    // states that the returning variable
    // is "theTotalSupply", we'll just set that variable
    // to the value of the instance variable "_totalSupply"
    // and return it
    theTotalSupply = _totalSupply;
    return theTotalSupply;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  balanceOf()
&lt;/h2&gt;

&lt;p&gt;This function allows a smart contract to store and return the balance of the provided address. The function accepts an address as a parameter, so it should be known that the balance of any address is public.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  // Create a table so that we can map addresses
  // to the balances associated with them
  mapping(address =&amp;gt; uint256) balances;
  // Owner of this contract
  address public owner;

  function balanceOf(address _owner) constant returns (uint256 balance) {
    // Return the balance for the specific address
    return balances[_owner];
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  approve()
&lt;/h2&gt;

&lt;p&gt;When calling this function, the owner of the contract authorizes, or approves, the given address to withdraw instances of the token from the owner’s address.  &lt;/p&gt;

&lt;p&gt;Here, and in later snippets, you may see a variable &lt;code&gt;msg&lt;/code&gt;. This is an implicit field provided by external applications such as wallets so that they can better interact with the contract. The Ethereum Virtual Machine (EVM) lets us use this field to store and process data given by the external application.  &lt;/p&gt;

&lt;p&gt;In this example, &lt;code&gt;msg.sender&lt;/code&gt; is the address of the contract owner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  // Create a table so that we can map
  // the addresses of contract owners to
  // those who are allowed to utilize the owner's contract
  mapping(address =&amp;gt; mapping (address =&amp;gt; uint256)) allowed;

  function approve(address _spender, uint256 _amount) returns (bool success) {
    allowed[msg.sender][_spender] = _amount;
    // Fire the event "Approval" to execute any logic
    // that was listening to it
    Approval(msg.sender, _spender, _amount);
    return true;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  transfer()
&lt;/h2&gt;

&lt;p&gt;This function lets the owner of the contract send a given amount of the token to another address just like a conventional cryptocurrency transaction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  mapping(address =&amp;gt; uint256) balances;

  // Note: This function returns a boolean value
  //       indicating whether the transfer was successful
  function transfer(address _to, uint256 _amount) returns (bool success) {
    // If the sender has sufficient funds to send
    // and the amount is not zero, then send to
    // the given address
    if (balances[msg.sender] &amp;gt;= _amount 
      &amp;amp;&amp;amp; _amount &amp;gt; 0
      &amp;amp;&amp;amp; balances[_to] + _amount &amp;gt; balances[_to]) {
      balances[msg.sender] -= _amount;
      balances[_to] += _amount;
      // Fire a transfer event for any
      // logic that's listening
      Transfer(msg.sender, _to, _amount);
        return true;
      } else {
        return false;
      }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  transferFrom()
&lt;/h2&gt;

&lt;p&gt;This function allows a smart contract to automate the transfer process and send a given amount of the token on behalf of the owner.  &lt;/p&gt;

&lt;p&gt;Seeing this might raise a few eyebrows. One may question why we need both &lt;code&gt;transfer()&lt;/code&gt; and &lt;code&gt;transferFrom()&lt;/code&gt; functions.  &lt;/p&gt;

&lt;p&gt;Consider transferring money to pay a bill. It’s extremely common to send money manually by taking the time to write a check and mail it to pay the bill off. This is like using &lt;code&gt;transfer()&lt;/code&gt; : you’re doing the money transfer process yourself, without the help of another party.  &lt;/p&gt;

&lt;p&gt;In another situation, you could set up automatic bill pay with your bank. This is like using &lt;code&gt;transferFrom()&lt;/code&gt; : your bank’s machines send money to pay off the bill on your behalf, automatically. With this function, a contract can send a certain amount of the token to another address on your behalf, without your intervention.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  mapping(address =&amp;gt; uint256) balances;

  function transferFrom(address _from, address _to, uint256 _amount) returns (bool success) {
    if (balances[_from] &amp;gt;= _amount
      &amp;amp;&amp;amp; allowed[_from][msg.sender] &amp;gt;= _amount
      &amp;amp;&amp;amp; _amount &amp;gt; 0
      &amp;amp;&amp;amp; balances[_to] + _amount &amp;gt; balances[_to]) {
    balances[_from] -= _amount;
    balances[_to] += _amount;
    Transfer(_from, _to, _amount);
      return true;
    } else {
      return false;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Token Name
&lt;/h2&gt;

&lt;p&gt;This is an optional field, but many popular tokens include it so that popular wallets like Mist and MyEtherWallet are able to identify them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  string public constant name = "My Custom ERC20 Token";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Token Symbol
&lt;/h2&gt;

&lt;p&gt;Another optional field used to identify a token, this is a three or four letter abbreviation of the token, just like BTC, ETH, AUG, or SJCX.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  string public constant symbol = "MET";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Number of Decimals
&lt;/h2&gt;

&lt;p&gt;An optional field used to determine to what decimal place the amount of the token will be calculated. The most common number of decimals to consider is 18.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MyERCToken {
  uint8 public constant decimals = 18;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The total source code of ERC20 token that we just created can be found &lt;a href="https://gist.github.com/aunyks/aa97affc1dc47ba6ca881f9bf7897637" rel="noopener noreferrer"&gt;here&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;In the end, &lt;a href="https://github.com/ethereum/EIPs/issues/20" rel="noopener noreferrer"&gt;the original ERC20 proposal&lt;/a&gt; is somewhat unappreciated. It opened up avenues for a new set of smart contracts that could be created and distributed in the same fashion as Bitcoin or Ethereum. This proves to be very enticing for young companies, as the entire ERC20 ecosystem is hosted on the Ethereum blockchain, a large pre-existing network of computers. This means that developers and young companies don’t have to attract miners in order to sustain their tokens, something that can save a lot of money. And, these tokens can be hosted on exchanges to be traded like other assets, so investors can easily buy and sell these tokens like more popular currencies.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>solidity</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>Let’s Make the Tiniest Blockchain Bigger</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Wed, 26 Jul 2017 14:50:44 +0000</pubDate>
      <link>https://dev.to/aunyks/lets-make-the-tiniest-blockchain-bigger</link>
      <guid>https://dev.to/aunyks/lets-make-the-tiniest-blockchain-bigger</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUBjF_ql6iUiT6bWRiwDpNg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AUBjF_ql6iUiT6bWRiwDpNg.jpeg" alt="Banner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This article assumes you’ve read &lt;a href="https://medium.com/crypto-currently/lets-build-the-tiniest-blockchain-e70965a248b" rel="noopener noreferrer"&gt;part one&lt;/a&gt;.&lt;/em&gt;&lt;br&gt;
The tiniest blockchain was extremely simple, and it was relatively easy to make. But, with its simplicity came a few flaws. First, SnakeCoin only ran on one single machine, so it was far from distributed, let alone decentralized. Second, blocks could be added to the chain as fast as the host computer could create a Python object and add it to a list. In the case of a simple blockchain, that’s not a problem, but we’re now going to let SnakeCoin be an actual cryptocurrency so we’ll need control the amount of blocks (and coins) that can be created at a time.  &lt;/p&gt;

&lt;p&gt;From now on, SnakeCoin’s data will be transactions, so each block’s data field will be a list of some transactions. We’ll define a transaction as follows. Each transaction will be a JSON object detailing the sender of the coin, the receiver of the coin, and the amount of SnakeCoin that is being transferred. &lt;em&gt;Note: Transactions are in JSON format for a reason I’ll detail shortly.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;from&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;to&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we know what our transactions will look like, we need a way to add them to one of the computers in our blockchain network, called a node. To do that, we’ll create a simple HTTP server so that any user can let our nodes know that a new transaction has occurred. A node will be able to accept a POST request with a transaction (like above) as the request body. This is why transactions are JSON formatted; we need them to be transmitted to our server in a request body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install flask # Install our web server framework first
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Store the transactions that
# this node has in a list
&lt;/span&gt;&lt;span class="n"&gt;this_nodes_transactions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="nd"&gt;@node.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/txion&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# On each new POST request,
&lt;/span&gt;    &lt;span class="c1"&gt;# we extract the transaction data
&lt;/span&gt;    &lt;span class="n"&gt;new_txion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Then we add the transaction to our list
&lt;/span&gt;    &lt;span class="n"&gt;this_nodes_transactions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_txion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Because the transaction was successfully
&lt;/span&gt;    &lt;span class="c1"&gt;# submitted, we log it to our console
&lt;/span&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;New transaction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FROM: {}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_txion&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TO: {}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_txion&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMOUNT: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_txion&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="c1"&gt;# Then we let the client know it worked out
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Transaction submission successful&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! Now we have a way to keep a record of users when they send SnakeCoins to each other. This is why people refer to blockchains as public, distributed ledgers: all transactions are stored for all to see and are stored on every node in the network.  &lt;/p&gt;

&lt;p&gt;But, a question arises: &lt;em&gt;where do people get SnakeCoins from?&lt;/em&gt; Nowhere, yet. There’s no such thing as a SnakeCoin yet, because not one coin has been created and issued yet. To create new coins, people have to &lt;em&gt;mine&lt;/em&gt; new blocks of SnakeCoin. When they successfully mine new blocks, a new SnakeCoin is created and rewarded to the person who mined the block. The coin then gets circulated once the miner sends the SnakeCoin to another person.  &lt;/p&gt;

&lt;p&gt;We don’t want it to be too easy to mine new SnakeCoin blocks, because that will create too many SnakeCoins and they will have little value. Conversely, we don’t want it to be too hard to mine new blocks, because there wouldn’t be enough coins for everyone to spend, and they would be too expensive for our liking. To control the difficulty of mining new SnakeCoins, we’ll implement a &lt;a href="https://en.bitcoin.it/wiki/Proof_of_work" rel="noopener noreferrer"&gt;Proof-of-Work&lt;/a&gt; (PoW) algorithm. A Proof-of-Work algorithm is essentially an algorithm that generates an item that is difficult to create but easy to verify. The item is called the proof and, as it sounds, it is proof that a computer performed a certain amount of work.  &lt;/p&gt;

&lt;p&gt;In SnakeCoin, we’ll create a somewhat simple Proof-of-Work algorithm. To create a new block, a miner’s computer will have to increment a number. When that number is divisible by 9 (the number of letters in “SnakeCoin”) and the proof number of the last block, a new SnakeCoin block will be mined and the miner will be given a brand new SnakeCoin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ...blockchain
# ...Block class definition
&lt;/span&gt;
&lt;span class="n"&gt;miner_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q3nf394hjg-random-miner-address-34nf3i4nflkn3oi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;proof_of_work&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last_proof&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="c1"&gt;# Create a variable that we will use to find
&lt;/span&gt;  &lt;span class="c1"&gt;# our next proof of work
&lt;/span&gt;  &lt;span class="n"&gt;incrementor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_proof&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="c1"&gt;# Keep incrementing the incrementor until
&lt;/span&gt;  &lt;span class="c1"&gt;# it's equal to a number divisible by 9
&lt;/span&gt;  &lt;span class="c1"&gt;# and the proof of work of the previous
&lt;/span&gt;  &lt;span class="c1"&gt;# block in the chain
&lt;/span&gt;  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;incrementor&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;incrementor&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;last_proof&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;incrementor&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="c1"&gt;# Once that number is found,
&lt;/span&gt;  &lt;span class="c1"&gt;# we can return it as a proof
&lt;/span&gt;  &lt;span class="c1"&gt;# of our work
&lt;/span&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;incrementor&lt;/span&gt;

&lt;span class="nd"&gt;@node.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/mine&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mine&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="c1"&gt;# Get the last proof of work
&lt;/span&gt;  &lt;span class="n"&gt;last_block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blockchain&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockchain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;last_proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;proof-of-work&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="c1"&gt;# Find the proof of work for
&lt;/span&gt;  &lt;span class="c1"&gt;# the current block being mined
&lt;/span&gt;  &lt;span class="c1"&gt;# Note: The program will hang here until a new
&lt;/span&gt;  &lt;span class="c1"&gt;#       proof of work is found
&lt;/span&gt;  &lt;span class="n"&gt;proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;proof_of_work&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last_proof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# Once we find a valid proof of work,
&lt;/span&gt;  &lt;span class="c1"&gt;# we know we can mine a block so 
&lt;/span&gt;  &lt;span class="c1"&gt;# we reward the miner by adding a transaction
&lt;/span&gt;  &lt;span class="n"&gt;this_nodes_transactions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;network&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;miner_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# Now we can gather the data needed
&lt;/span&gt;  &lt;span class="c1"&gt;# to create the new block
&lt;/span&gt;  &lt;span class="n"&gt;new_block_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;proof-of-work&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transactions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_nodes_transactions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;new_block_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;new_block_timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;this_timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;last_block_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;
  &lt;span class="c1"&gt;# Empty transaction list
&lt;/span&gt;  &lt;span class="n"&gt;this_nodes_transactions&lt;/span&gt;&lt;span class="p"&gt;[:]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="c1"&gt;# Now create the
&lt;/span&gt;  &lt;span class="c1"&gt;# new block!
&lt;/span&gt;  &lt;span class="n"&gt;mined_block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;new_block_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;new_block_timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;new_block_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;last_block_hash&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;blockchain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mined_block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# Let the client know we mined a block
&lt;/span&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;new_block_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_block_timestamp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;new_block_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;last_block_hash&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can control the number of blocks mined in a certain time period, and we can issue new coins for people in the network to send to each other. But like we said, we’re only doing this on one computer. &lt;em&gt;If blockchains are decentralized, how do we make sure that the same chain is on every node?&lt;/em&gt; To do this, we make each node broadcast its version of the chain to the others and allow them to receive the chains of other nodes. After that, each node has to verify the other nodes’ chains so that the every node in the network can come to a consensus of what the resulting blockchain will look like. This is called a &lt;a href="https://en.wikipedia.org/wiki/Consensus_%28computer_science%29" rel="noopener noreferrer"&gt;consensus algorithm&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Our consensus algorithm will be rather simple: if a node’s chain is different from another’s (i.e. there is a conflict), then the longest chain in the network stays and all shorter chains will be deleted. If there is no conflict between the chains in our network, then we carry on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@node.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/blocks&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_blocks&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;chain_to_send&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blockchain&lt;/span&gt;
  &lt;span class="c1"&gt;# Convert our blocks into dictionaries
&lt;/span&gt;  &lt;span class="c1"&gt;# so we can send them as json objects later
&lt;/span&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;chain_to_send&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;block_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;block_timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;block_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;block_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;
    &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;block_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;block_timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;block_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;block_hash&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;# Send our chain to whomever requested it
&lt;/span&gt;  &lt;span class="n"&gt;chain_to_send&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain_to_send&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;chain_to_send&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_new_chains&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="c1"&gt;# Get the blockchains of every
&lt;/span&gt;  &lt;span class="c1"&gt;# other node
&lt;/span&gt;  &lt;span class="n"&gt;other_chains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;node_url&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;peer_nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Get their chains using a GET request
&lt;/span&gt;    &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node_url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/blocks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
    &lt;span class="c1"&gt;# Convert the JSON object to a Python dictionary
&lt;/span&gt;    &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Add it to our list
&lt;/span&gt;    &lt;span class="n"&gt;other_chains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;other_chains&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;consensus&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="c1"&gt;# Get the blocks from other nodes
&lt;/span&gt;  &lt;span class="n"&gt;other_chains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;find_new_chains&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;# If our chain isn't longest,
&lt;/span&gt;  &lt;span class="c1"&gt;# then we store the longest chain
&lt;/span&gt;  &lt;span class="n"&gt;longest_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blockchain&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;other_chains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;longest_chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;longest_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;
  &lt;span class="c1"&gt;# If the longest chain wasn't ours,
&lt;/span&gt;  &lt;span class="c1"&gt;# then we set our chain to the longest
&lt;/span&gt;  &lt;span class="n"&gt;blockchain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;longest_chain&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re just about done now. After running the &lt;a href="https://gist.github.com/aunyks/47d157f8bc7d1829a729c2a6a919c173" rel="noopener noreferrer"&gt;full SnakeCoin server code&lt;/a&gt;, run the following commands in your terminal. &lt;em&gt;Assuming you have cURL installed.&lt;/em&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a transaction.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl "localhost:5000/txion" \
     -H "Content-Type: application/json" \
     -d '{"from": "akjflw", "to":"fjlakdj", "amount": 3}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; Mine a new block.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl localhost:5000/mine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check out the results. From the client window, we see this.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AqCaWQM7Rzj-gJrJB_J0uJw.png" alt="Console Output"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With a little bit of pretty printing we see that after mining we get some cool information on our new block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "index": 2,
  "data": {
    "transactions": [
      {
        "to": "fjlakdj",
        "amount": 3,
        "from": "akjflw"
      },
      {
        "to": "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi",
        "amount": 1,
        "from": "network"
      }
    ],
    "proof-of-work": 36
  },
  "hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18",
  "timestamp": "2017-07-23 11:23:10.140996"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it! We’ve made a fairly sized blockchain at this point. Now, SnakeCoin can be launched on multiple machines to create a network, and real SnakeCoins can be mined. Please feel free to tinker with &lt;a href="https://gist.github.com/aunyks/47d157f8bc7d1829a729c2a6a919c173" rel="noopener noreferrer"&gt;the SnakeCoin server code&lt;/a&gt; as much as you’d like, and ask as many questions as you need! &lt;strong&gt;In the next part, we’ll discuss creating a SnakeCoin wallet, so users can send, receive, and store their SnakeCoins.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" alt="Thank You"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you very much for reading!&lt;br&gt;
&lt;a href="https://twitter.com/aunyks" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/aunyks" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, &lt;a href="https://snapchat.com/add/aunyks" rel="noopener noreferrer"&gt;Snapchat&lt;/a&gt;, &lt;a href="https://medium.com/@aunyks" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;, &lt;a href="https://instagram.com/aunyks" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bitcoin</category>
      <category>blockchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Let's Build the Tiniest Blockchain</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Mon, 17 Jul 2017 22:28:44 +0000</pubDate>
      <link>https://dev.to/aunyks/lets-build-the-tiniest-blockchain</link>
      <guid>https://dev.to/aunyks/lets-build-the-tiniest-blockchain</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This article was originally published to &lt;a href="https://medium.com/crypto-currently" rel="noopener noreferrer"&gt;Crypto Currently&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Av5Ra8k9iLKDWT-fTtoZ4Rg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Av5Ra8k9iLKDWT-fTtoZ4Rg.jpeg" alt="Bitcoin Logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although some think blockchain is a solution waiting for problems, there’s no doubt that this novel technology is a marvel of computing. But, what exactly is a blockchain?  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blockchain&lt;/strong&gt;  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.google.com/search?q=blockchain+definition&amp;amp;oq=blockchain+definition&amp;amp;aqs=chrome.0.0l6.2941j0j7&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;a digital ledger in which transactions made in bitcoin or another cryptocurrency are recorded chronologically and publicly.&lt;/a&gt; &amp;gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In more general terms, &lt;em&gt;it’s a public database where new data are stored in a container called a block and are added to an immutable chain (hence blockchain) with data added in the past.&lt;/em&gt; In the case of Bitcoin and other cryptocurrencies, these data are groups of transactions. But, the data can be of any type, of course.  &lt;/p&gt;

&lt;p&gt;Blockchain technology has given rise to new, fully digital currencies like Bitcoin and Litecoin that aren’t issued or managed by a central authority. This brings new freedom to individuals who believe that today’s banking systems are a scam or subject to failure. Blockchain has also revolutionized distributed computing in the form of technologies like Ethereum, which has introduced interesting concepts like &lt;a href="https://blockgeeks.com/guides/smart-contracts/" rel="noopener noreferrer"&gt;smart contracts&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;In this article, I’ll make a simple blockchain in less than 50 lines of Python 2 code. It’ll be called SnakeCoin.  &lt;/p&gt;

&lt;p&gt;We’ll start by first defining what our blocks will look like. In blockchain, each block is stored with a timestamp and, optionally, an index. In SnakeCoin, we’re going to store both. And to help ensure integrity throughout the blockchain, each block will have a self-identifying hash. Like Bitcoin, each block’s hash will be a cryptographic hash of the block’s index, timestamp, data, and the hash of the previous block’s hash. Oh, and the data can be anything you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;hasher&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;previous_hash&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;previous_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;previous_hash&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash_block&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hash_block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;sha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hasher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;sha&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
               &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
               &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
               &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;previous_hash&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sha&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! We have our block structure, but we’re creating a block &lt;strong&gt;chain&lt;/strong&gt;. We need to start adding blocks to the actual chain. As I mentioned earlier, each block requires information from the previous block. But with that being said, a question arises: &lt;strong&gt;how does the first block in the blockchain get there?&lt;/strong&gt; Well, the first block, or &lt;em&gt;genesis block&lt;/em&gt;, is a special block. In many cases, it’s added manually or has unique logic allowing it to be added.  &lt;/p&gt;

&lt;p&gt;We’ll create a function that simply returns a genesis block to make things easy. This block is of index 0, and it has an arbitrary data value and an arbitrary value in the “previous hash” parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_genesis_block&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="c1"&gt;# Manually construct a block with
&lt;/span&gt;  &lt;span class="c1"&gt;# index zero and arbitrary previous hash
&lt;/span&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Genesis Block&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we’re able to create a genesis block, we need a function that will generate succeeding blocks in the blockchain. This function will take the previous block in the chain as a parameter, create the data for the block to be generated, and return the new block with its appropriate data. When new blocks hash information from previous blocks, the integrity of the blockchain increases with each new block. If we didn’t do this, it would be easier for an outside party to “change the past” and replace our chain with an entirely new one of their own. This chain of hashes acts as cryptographic proof and helps ensure that once a block is added to the blockchain it cannot be replaced or removed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;next_block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last_block&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;this_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;this_timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;this_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hey! I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;m block &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;this_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;this_timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;this_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;this_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s the majority of the hard work. Now, we can create our blockchain! In our case, the blockchain itself is a simple Python list. The first element of the list is the genesis block. And of course, we need to add the succeeding blocks. Because SnakeCoin is the tiniest blockchain, we’ll only add 20 new blocks. We can do this with a for loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Create the blockchain and add the genesis block
&lt;/span&gt;&lt;span class="n"&gt;blockchain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;create_genesis_block&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="n"&gt;previous_block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blockchain&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# How many blocks should we add to the chain
# after the genesis block
&lt;/span&gt;&lt;span class="n"&gt;num_of_blocks_to_add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;

&lt;span class="c1"&gt;# Add blocks to the chain
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num_of_blocks_to_add&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;block_to_add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next_block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previous_block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;blockchain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block_to_add&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;previous_block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block_to_add&lt;/span&gt;
  &lt;span class="c1"&gt;# Tell everyone about it!
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Block #{} has been added to the blockchain!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block_to_add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hash: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block_to_add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s test what we’ve made so far.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2Anjl6-UdLUWTLRFsHc4D-tA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1600%2F1%2Anjl6-UdLUWTLRFsHc4D-tA.png" alt="Terminal Output"&gt;&lt;/a&gt;&lt;br&gt;
There we go! Our blockchain works. If you want to see more information in the console, you could &lt;a href="https://gist.github.com/aunyks/8f2c2fd51cc17f342737917e1c2582e2" rel="noopener noreferrer"&gt;edit the complete source file&lt;/a&gt; and print each block’s timestamp or data.  &lt;/p&gt;

&lt;p&gt;That’s about all that SnakeCoin has to offer. To make SnakeCoin scale to the size of today’s production blockchains, we’d have to add more features like a server layer to track changes to the chain on multiple machines and a &lt;a href="https://en.bitcoin.it/wiki/Proof_of_work" rel="noopener noreferrer"&gt;proof-of-work algorithm&lt;/a&gt; to limit the amount of blocks added in a given time period.  &lt;/p&gt;

&lt;p&gt;If you’d like to get more technical, you can view the original Bitcoin whitepaper &lt;a href="https://bitcoin.org/bitcoin.pdf" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Best of luck and happy hacking!  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" alt="Thank You"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you very much for reading!&lt;br&gt;
&lt;a href="https://twitter.com/aunyks" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/aunyks" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, &lt;a href="https://snapchat.com/add/aunyks" rel="noopener noreferrer"&gt;Snapchat&lt;/a&gt;, &lt;a href="https://medium.com/@aunyks" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;, &lt;a href="https://instagram.com/aunyks" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Chose TypeScript For the Nostalgia</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Wed, 21 Jun 2017 13:46:40 +0000</pubDate>
      <link>https://dev.to/aunyks/i-chose-typescript-for-the-nostalgia</link>
      <guid>https://dev.to/aunyks/i-chose-typescript-for-the-nostalgia</guid>
      <description>&lt;p&gt;Back when I was 13 years old and beginning my freshman year of high school, I wasn’t sure what programming language I wanted to learn first. After browsing a lot of fora and viewing a few old YouTube videos, people almost always recommended Java as a practical and profitable first language. So, that’s what learned.  &lt;/p&gt;

&lt;p&gt;Fast forward to Junior year and I’ve had my fair share of class files, NullPointerExceptions, and a gamut of compilation errors. I’m breezing through my AP Computer Science course (which, as you guessed, teaches Java), and I’m starting to look into open sourcing my work and building more practical projects.  &lt;/p&gt;

&lt;p&gt;I decided to write a web server with Java EE and Apache Tomcat, and, since I grew tired of what felt like writing more syntax than semantics, let’s just say I got much too frustrated with Java at this point, so I ventured into a different ecosystem.  &lt;/p&gt;

&lt;p&gt;After some Google searches, I discovered Node.js and &lt;a href="https://expressjs.com"&gt;Express&lt;/a&gt;. After seeing an example Hello World server, I fell in love with the conciseness and abstraction that these technologies provided.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Example app listening on port 3000!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so, I kind of became a JavaScript developer. I starting learning about callbacks, prototypes, and other cool stuff JS provides new developers. I started using Javascript for projects of all kinds: front end, back end, desktop, command line, etc. I fell in love with JavaScript’s ubiquity and simplicity (dynamic typing and not having to use semicolons seemed so awesome…at first).  &lt;/p&gt;

&lt;p&gt;But, now I graduated high school and I’ve written thousands of lines of JavaScript. The things that originally brought me over to the language are now reasons for me to dislike it. I’m starting to see the flaws in dynamic typing, non-strict syntax, and other facets of the language. I’m starting to look for a compile-to-JS language to keep my faith before I (maybe) leave the ecosystem. Java’s syntax and typing never looked so attractive…  &lt;/p&gt;

&lt;p&gt;And, that’s when I found &lt;a href="https://typescriptlang.org"&gt;TypeScript&lt;/a&gt;, a &lt;em&gt;typed&lt;/em&gt; superset of JavaScript. Coming from ES5, I liked that TypeScript automatically included ES6 and beyond features (like that sweet, sweet &lt;code&gt;class&lt;/code&gt; syntax) without needing complicated Babel configurations. At this point, I was happy to see some syntax that somewhat reminded me of my Java days.  &lt;/p&gt;

&lt;p&gt;But, ES6 doesn’t natively provide great typing functionality: that’s where TypeScript’s true advantages come out. In the same way that Java’s types are enforcements, TypeScript’s types are suggestions. So, you have the opportunity to see how types semantically flow throughout your application similar to compiled languages like Java and C#, but you don’t necessarily have to abide by type inconsistencies, because it’s still JavaScript under the hood. &lt;em&gt;And that’s good enough for me.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;The syntax is essentially JavaScript as you know it, except for &lt;a href="https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html"&gt;type declaration files&lt;/a&gt;. Take a look at the example code below. Borrowed from &lt;a href="https://tutorialzine.com/2016/07/learn-typescript-in-30-minutes"&gt;this page&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;burger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hamburger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// String &lt;/span&gt;
    &lt;span class="nx"&gt;calories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// Numeric&lt;/span&gt;
    &lt;span class="nx"&gt;tasty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="c1"&gt;// Boolean&lt;/span&gt;

&lt;span class="c1"&gt;// Alternatively, you can omit the type declaration:&lt;/span&gt;
&lt;span class="c1"&gt;// var burger = 'hamburger';&lt;/span&gt;

&lt;span class="c1"&gt;// The function expects a string and an integer.&lt;/span&gt;
&lt;span class="c1"&gt;// It doesn't return anything so the type of the function itself is void.&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;food&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;energy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Our &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;food&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; has &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;energy&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; calories.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;burger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;calories&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like I said before, it looks just like normal JS, except you optionally define the types of each variable and function return with colon syntax. No trouble!😉  &lt;/p&gt;

&lt;p&gt;Although TypeScript’s typing is more of a recommendation, it’s close enough to remind me of a more strictly typed language like my starting point, Java. It helps provide a bit of needed structure when building large scale projects and applications by adding typing, which is what keeps languages like C#, Java, and C++ in use.  &lt;/p&gt;

&lt;p&gt;Although I grew tired of the forced verbosity that compiled languages require of their developers, it turns out that I may have taken it for granted. When given the freedom of dynamic typing, optional semicolons, and the rest of the works, it seems that it gets noticeably harder to build and debug large applications because of the lenience. TypeScript’s illusion of static typing provides that bit of structure that one might need to keep code clean and readable. As you can see, I chose TypeScript for the nostalgia. What might you choose it for?  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" alt="Thank you"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading this! Feel free to give me some feedback on how it was and whether or not you would ever use TypeScript, and why.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/aunyks"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/aunyks"&gt;Github&lt;/a&gt;, &lt;a href="https://snapchat.com/add/aunyks"&gt;Snapchat&lt;/a&gt;, &lt;a href="https://medium.com/@aunyks"&gt;Medium&lt;/a&gt;, &lt;a href="https://instagram.com/aunyks"&gt;Instagram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>syntax</category>
    </item>
    <item>
      <title>How do you pronounce "PostgreSQL"?</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Tue, 20 Jun 2017 15:25:43 +0000</pubDate>
      <link>https://dev.to/aunyks/how-do-you-pronounce-postgresql</link>
      <guid>https://dev.to/aunyks/how-do-you-pronounce-postgresql</guid>
      <description>&lt;p&gt;I've heard POAST-GREH-SEE-QUEL, POST-GER-ESS-CUE-ELL, and so many others. How do you pronounce it?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>The Importance of Open Sourcing Innovation</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Sun, 18 Jun 2017 22:50:26 +0000</pubDate>
      <link>https://dev.to/aunyks/the-importance-of-open-sourcing-innovation</link>
      <guid>https://dev.to/aunyks/the-importance-of-open-sourcing-innovation</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fopensource.org%2Ffiles%2Fosi_keyhole_300X300_90ppi_0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fopensource.org%2Ffiles%2Fosi_keyhole_300X300_90ppi_0.png" alt="Open Source"&gt;&lt;/a&gt;&lt;br&gt;
Now that I've finished my first week at my internship at &lt;a href="https://cinchapi.com" rel="noopener noreferrer"&gt;Cinchapi&lt;/a&gt;, I've learned so much already. I've gotten a taste of a lot of skills and platforms that a software engineer may come across in their career. I finally have the opportunity to use Jira and other Atlassian products, I use Slack much more often, and I'm becoming &lt;em&gt;much&lt;/em&gt; more aware of Git and the Github workflow.  &lt;/p&gt;

&lt;p&gt;But, in addition to learning of the non-development sides of the position, I'm learning more about database technologies and how to augment antiquated practices. One interesting thing that I've learned is the technology behind one of Cinchapi's core products, &lt;a href="https://github.com/cinchapi/concourse" rel="noopener noreferrer"&gt;ConcourseDB&lt;/a&gt;. Concourse is extremely innovative, because it has features such as granular just-in-time locking, self-tuning, buffered storage, and other cool stuff. Although, I think that most important feature of ConcourseDB is that &lt;em&gt;it's open source&lt;/em&gt;. Concourse's open source nature has come to remind me of the importance of open sourcing technological advances whether they're in computing or not.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftctechcrunch2011.files.wordpress.com%2F2015%2F04%2Fcodecode.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftctechcrunch2011.files.wordpress.com%2F2015%2F04%2Fcodecode.jpg" alt="Code"&gt;&lt;/a&gt;&lt;br&gt;
Open sourcing innovation is important, first, because it opens doors to further innovation. This is the "standing on the shoulders of giants" that one person can do when another reaches a technological advancement. It has been the release of knowledge and innovation by an innumerable amount of people in thousands of fields that has gotten us to where we are today, and we shouldn't stop sharing these ideas for the sole purpose of accruing profit. Look back at greats like Sir Isaac Newton,  Richard Feynman, Nicola Tesla, and many others whose contributions in their respective fields have accelerated the technological development of society.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fspeedendurance.com%2Fwp-content%2Fuploads%2F2014%2F10%2Fquote-if-i-have-seen-further-than-others-it-is-by-standing-upon-the-shoulders-of-giants-isaac-newton-135288.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fspeedendurance.com%2Fwp-content%2Fuploads%2F2014%2F10%2Fquote-if-i-have-seen-further-than-others-it-is-by-standing-upon-the-shoulders-of-giants-isaac-newton-135288.jpg" alt="Newton Quote"&gt;&lt;/a&gt;&lt;br&gt;
Open sourcing innovation is also important because it makes life easier. Without open innovation, we quite literally wouldn't be able to experience life in the same fashion. Open innovation has allowed society to advance in a unified manner, as opposed to a small group of individuals and corporations leading the advancement.  &lt;/p&gt;

&lt;p&gt;Open innovation also induces competitive pressure among individuals and organizations. This competition leverages the aforementioned idea that a technological breakthrough in a field leads to more subsequent innovation, which in turn causes more advancement. In short, open sourcing new technology starts a recurring cycle that lets the industry move faster than if it were kept secret.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcSWXOboGM90HnFsJ-e6Hrrz2MzPgNGYr1FP2oVVGDxxvhbVrXvUZQ" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcSWXOboGM90HnFsJ-e6Hrrz2MzPgNGYr1FP2oVVGDxxvhbVrXvUZQ" alt="Cycle"&gt;&lt;/a&gt;&lt;br&gt;
So, ultimately I'm proud of the Cinchapi team for open sourcing ConcourseDB, as I'm sure its technological advances will further the computing industry and, hopefully, society as a whole. But Cinchapi's not the only one doing this: Facebook open sourced &lt;a href="https://github.com/facebook/buck" rel="noopener noreferrer"&gt;buck&lt;/a&gt;, OpenAI and others are publishing new advancements in AI research, and Google kind of&lt;a href="https://vr.google.com/cardboard/" rel="noopener noreferrer"&gt;open sourced VR a while back&lt;/a&gt;. It's open innovation like this that lets this industry move as fast as it does. I hope to see more of it as time passes!  &lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;br&gt;
&lt;a href="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3otPoUkg3hBxQKRJ7y/giphy.gif" alt="Obama Thank You"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/aunyks" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/aunyks" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, &lt;a href="https://snapchat.com/add/aunyks" rel="noopener noreferrer"&gt;Snapchat&lt;/a&gt;, &lt;a href="https://medium.com/@aunyks" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;, &lt;a href="https://instagram.com/aunyks" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>innovation</category>
    </item>
    <item>
      <title>So I Graduated High School, Now What?</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Sat, 17 Jun 2017 15:22:43 +0000</pubDate>
      <link>https://dev.to/aunyks/so-i-graduated-high-school-now-what</link>
      <guid>https://dev.to/aunyks/so-i-graduated-high-school-now-what</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aNN4kwCF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A8yMRhfBMi2P9PyUR9c5hmA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aNN4kwCF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A8yMRhfBMi2P9PyUR9c5hmA.jpeg" alt="grad"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s done…finished…over. I’ve finally finished an unforgettable 4 years of my life. 4 years full of smiles, stress, sweat, and software. Throughout all of this I’ve made a few small achievements: I made the varsity soccer team in my freshman year, managed to keep straight A’s while playing three sports in one year, made my first &lt;a href="https://github.com/aunyks/newton-api"&gt;100-star project&lt;/a&gt; on Github, started a tech blog, and many more.&lt;/p&gt;

&lt;h2&gt;
  
  
  I graduated high school, now what?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3U0tsw1o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A11mbPap2sCrzZpTGz1ivNQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3U0tsw1o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A11mbPap2sCrzZpTGz1ivNQ.png" alt="Howard University"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, I’m continuing my education. After thoughtful consideration, I’ve decided to attend Howard University in Washington, DC. At Howard, I’ll be majoring in Computer Science and minoring in a study that is to be determined. I’m beyond excited to join the Bison family!&lt;/p&gt;

&lt;h2&gt;
  
  
  What does all this mean for me as a software developer?
&lt;/h2&gt;

&lt;p&gt;Well, I got access to the Github Student Pack, so that’s kind of cool 😉. Lol but now that I’m a university student, I have access to a lot of opportunities that were previously not available to me: I can attend as many hackathons as my heart desires, apply for internships, and actually study computing &lt;em&gt;in&lt;/em&gt; school. I’m extremely excited for what’s to come.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what am I doing now?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iolzNkUZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AftWHMegx9BcOO9oI0E46uQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iolzNkUZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AftWHMegx9BcOO9oI0E46uQ.png" alt="Cinchapi"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve been blessed with the opportunity to work with Jeff Nelson and the &lt;a href="https://cinchapi.com"&gt;Cinchapi&lt;/a&gt; team as a Software Engineer Intern this summer before I start college. I’m incredibly happy to be working here and I thank everyone who’s helped me become a better developer leading up to this opportunity!  &lt;/p&gt;

&lt;p&gt;Now that I’m finished with high school, I can’t wait to see all that is to come! I can’t thank everyone enough, and I thank you for reading this piece.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect with me on social media:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://twitter.com/aunyks"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/aunyks"&gt;Github&lt;/a&gt;, &lt;a href="https://snapchat.com/add/aunyks"&gt;Snapchat&lt;/a&gt;, &lt;a href="https://medium.com/@aunyks"&gt;Medium&lt;/a&gt;, &lt;a href="https://instagram.com/aunyks"&gt;Instagram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>graduation</category>
      <category>future</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How I Built a Serverless Function Without Knowing It, I Think*</title>
      <dc:creator>Gerald Nash ⚡️</dc:creator>
      <pubDate>Sun, 09 Apr 2017 15:06:29 +0000</pubDate>
      <link>https://dev.to/aunyks/how-i-built-a-serverless-function-without-knowing-it-i-think</link>
      <guid>https://dev.to/aunyks/how-i-built-a-serverless-function-without-knowing-it-i-think</guid>
      <description>&lt;p&gt;It’s the weekend after a week full of exams. I’m exhausted and am just waiting to graduate high school. But, like any other developer I feel the urge to go ahead and start another weekend project. I’m learning some pretty interesting stuff in AP Calculus, but I get tired of doing algebra during homework at times. I think to myself: &lt;em&gt;Why not build something that does my math homework for me?&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZtYgogX_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A-70TkZq3o32UoAbYzpXwdA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZtYgogX_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A-70TkZq3o32UoAbYzpXwdA.gif" alt="Not a Bad Idea"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s where I got the idea to build Newton, &lt;a href="https://newton.now.sh/"&gt;a really micro micro-service for math&lt;/a&gt;. I wanted to make it easier for developers to do math without being constrained by codebase sizes or non-existant APIs in their preferred language.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e1BG0i22--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AT-e_QTO3qzrBBr004w55Yw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e1BG0i22--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AT-e_QTO3qzrBBr004w55Yw.png" alt="Newton API Front Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what makes it interesting?&lt;/strong&gt; Other then being super cool and functional, of course, Newton requires no storage space other than its source files. It doesn’t access or modify a database, and it doesn’t even dynamically create configuration files or any of the matter. Each request and response is protected by &lt;a href="https://now.sh/"&gt;Zeit Now’s&lt;/a&gt; HTTPS encryption. Plus, it runs solely on simple GET requests.  &lt;/p&gt;

&lt;p&gt;I didn’t think much of those characteristics, but after a bit of interaction with the tech community I think Newton is a serverless function.  &lt;/p&gt;


&lt;blockquote data-lang="en"&gt;
&lt;p&gt;Explain "serverless architecture" to me like I'm five years old. &lt;a href="https://twitter.com/hashtag/DevDiscuss?src=hash"&gt;#DevDiscuss&lt;/a&gt;&lt;/p&gt;— The Practical Dev (&lt;a class="mentioned-user" href="https://dev.to/thepracticaldev"&gt;@thepracticaldev&lt;/a&gt;
) &lt;a href="https://twitter.com/ThePracticalDev/status/849427700192342018"&gt;April 5, 2017&lt;/a&gt;
&lt;/blockquote&gt; 


&lt;blockquote data-conversation="none" data-lang="en"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/ThePracticalDev"&gt;@ThePracticalDev&lt;/a&gt; Very small machines on a network; LOTS of them work at the same time. But their brains are very small, they can't remember what they did!&lt;/p&gt;— Eric Elliott (@_ericelliott) &lt;a href="https://twitter.com/_ericelliott/status/849431273865084928"&gt;April 5, 2017&lt;/a&gt;
&lt;/blockquote&gt;   

&lt;p&gt;Eric Elliott gave an unexpected yet informative response. Newton fits those characteristics. Zeit abstracts global hosting for Now, so that satisfies the machines on a network. Newton is a relatively small package (~3.3kB), so that fits the small brain, and like I said it doesn’t access or process persistant memory. Seems like serverless to me.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WzDRarYc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AcklQSFmsnnxoq6a4q2vJHw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WzDRarYc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AcklQSFmsnnxoq6a4q2vJHw.gif" alt="Shoulder Shrug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anything else?  &lt;/p&gt;


&lt;blockquote data-lang="en"&gt;
&lt;p&gt;&lt;a href="https://twitter.com/ThePracticalDev"&gt;@ThePracticalDev&lt;/a&gt; Write code as a bunch of function and then pretend infrastructure doesn't matter.&lt;/p&gt;— Elliot Blackburn (&lt;a class="mentioned-user" href="https://dev.to/elliotblackburn"&gt;@elliotblackburn&lt;/a&gt;
) &lt;a href="https://twitter.com/elliotblackburn/status/849559703520780288"&gt;April 5, 2017&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;That seals the deal. I use Now, because I don’t have to worry about anything other than how my code runs. And, &lt;em&gt;Newton does one thing: math.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Wait, math is a lot of things.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pDbJKoVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AB5F6wHEB1ggA-teT8DhgsA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pDbJKoVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AB5F6wHEB1ggA-teT8DhgsA.gif" alt="Hmm..."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We get the point. But just to be sure, I took to &lt;a href="https://www.reddit.com/r/serverless/"&gt;r/serverless&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BpwviKnl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2ACTh4EJi0b8a_pBh1Nhnfxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BpwviKnl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2ACTh4EJi0b8a_pBh1Nhnfxw.png" alt="My Reddit Question"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eh, that answer is good enough for me.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VWHKwoH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A5z9WhbaPEGmuwzvg1Ymb1g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VWHKwoH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A5z9WhbaPEGmuwzvg1Ymb1g.gif" alt="Why not?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, in the end I built a small serverless function as a weekend project to help me do my math homework and help others make cool things. Newton has &lt;a href="https://github.com/aunyks/newton-api"&gt;grown to become more popular than I initially expected&lt;/a&gt;, and I‘d love to witness its expansion and see what others make with it.  &lt;/p&gt;

&lt;p&gt;And don’t forget: &lt;strong&gt;it’s serverless, I think.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xC8nS10L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AooNmdP20-7HGbe0-Lzbqfw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xC8nS10L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AooNmdP20-7HGbe0-Lzbqfw.gif" alt="You're Awesome"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading! As always, you’re awesome.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more information on serverless architecture, start &lt;a href="https://aws.amazon.com/serverless/"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>javascript</category>
      <category>api</category>
    </item>
  </channel>
</rss>
